[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/tinymce/themes/inlite/ -> theme.js (source)

   1  (function () {
   2  var inlite = (function (domGlobals) {
   3      'use strict';
   4  
   5      var global = tinymce.util.Tools.resolve('tinymce.ThemeManager');
   6  
   7      var global$1 = tinymce.util.Tools.resolve('tinymce.Env');
   8  
   9      var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
  10  
  11      var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  12  
  13      var flatten = function (arr) {
  14        return arr.reduce(function (results, item) {
  15          return Array.isArray(item) ? results.concat(flatten(item)) : results.concat(item);
  16        }, []);
  17      };
  18      var DeepFlatten = { flatten: flatten };
  19  
  20      var result = function (id, rect) {
  21        return {
  22          id: id,
  23          rect: rect
  24        };
  25      };
  26      var match = function (editor, matchers) {
  27        for (var i = 0; i < matchers.length; i++) {
  28          var f = matchers[i];
  29          var result_1 = f(editor);
  30          if (result_1) {
  31            return result_1;
  32          }
  33        }
  34        return null;
  35      };
  36      var Matcher = {
  37        match: match,
  38        result: result
  39      };
  40  
  41      var fromClientRect = function (clientRect) {
  42        return {
  43          x: clientRect.left,
  44          y: clientRect.top,
  45          w: clientRect.width,
  46          h: clientRect.height
  47        };
  48      };
  49      var toClientRect = function (geomRect) {
  50        return {
  51          left: geomRect.x,
  52          top: geomRect.y,
  53          width: geomRect.w,
  54          height: geomRect.h,
  55          right: geomRect.x + geomRect.w,
  56          bottom: geomRect.y + geomRect.h
  57        };
  58      };
  59      var Convert = {
  60        fromClientRect: fromClientRect,
  61        toClientRect: toClientRect
  62      };
  63  
  64      var toAbsolute = function (rect) {
  65        var vp = global$2.DOM.getViewPort();
  66        return {
  67          x: rect.x + vp.x,
  68          y: rect.y + vp.y,
  69          w: rect.w,
  70          h: rect.h
  71        };
  72      };
  73      var measureElement = function (elm) {
  74        var clientRect = elm.getBoundingClientRect();
  75        return toAbsolute({
  76          x: clientRect.left,
  77          y: clientRect.top,
  78          w: Math.max(elm.clientWidth, elm.offsetWidth),
  79          h: Math.max(elm.clientHeight, elm.offsetHeight)
  80        });
  81      };
  82      var getElementRect = function (editor, elm) {
  83        return measureElement(elm);
  84      };
  85      var getPageAreaRect = function (editor) {
  86        return measureElement(editor.getElement().ownerDocument.body);
  87      };
  88      var getContentAreaRect = function (editor) {
  89        return measureElement(editor.getContentAreaContainer() || editor.getBody());
  90      };
  91      var getSelectionRect = function (editor) {
  92        var clientRect = editor.selection.getBoundingClientRect();
  93        return clientRect ? toAbsolute(Convert.fromClientRect(clientRect)) : null;
  94      };
  95      var Measure = {
  96        getElementRect: getElementRect,
  97        getPageAreaRect: getPageAreaRect,
  98        getContentAreaRect: getContentAreaRect,
  99        getSelectionRect: getSelectionRect
 100      };
 101  
 102      var element = function (element, predicateIds) {
 103        return function (editor) {
 104          for (var i = 0; i < predicateIds.length; i++) {
 105            if (predicateIds[i].predicate(element)) {
 106              var result = Matcher.result(predicateIds[i].id, Measure.getElementRect(editor, element));
 107              return result;
 108            }
 109          }
 110          return null;
 111        };
 112      };
 113      var parent = function (elements, predicateIds) {
 114        return function (editor) {
 115          for (var i = 0; i < elements.length; i++) {
 116            for (var x = 0; x < predicateIds.length; x++) {
 117              if (predicateIds[x].predicate(elements[i])) {
 118                return Matcher.result(predicateIds[x].id, Measure.getElementRect(editor, elements[i]));
 119              }
 120            }
 121          }
 122          return null;
 123        };
 124      };
 125      var ElementMatcher = {
 126        element: element,
 127        parent: parent
 128      };
 129  
 130      var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools');
 131  
 132      var create = function (id, predicate) {
 133        return {
 134          id: id,
 135          predicate: predicate
 136        };
 137      };
 138      var fromContextToolbars = function (toolbars) {
 139        return global$4.map(toolbars, function (toolbar) {
 140          return create(toolbar.id, toolbar.predicate);
 141        });
 142      };
 143      var PredicateId = {
 144        create: create,
 145        fromContextToolbars: fromContextToolbars
 146      };
 147  
 148      var textSelection = function (id) {
 149        return function (editor) {
 150          if (!editor.selection.isCollapsed()) {
 151            var result = Matcher.result(id, Measure.getSelectionRect(editor));
 152            return result;
 153          }
 154          return null;
 155        };
 156      };
 157      var emptyTextBlock = function (elements, id) {
 158        return function (editor) {
 159          var i;
 160          var textBlockElementsMap = editor.schema.getTextBlockElements();
 161          for (i = 0; i < elements.length; i++) {
 162            if (elements[i].nodeName === 'TABLE') {
 163              return null;
 164            }
 165          }
 166          for (i = 0; i < elements.length; i++) {
 167            if (elements[i].nodeName in textBlockElementsMap) {
 168              if (editor.dom.isEmpty(elements[i])) {
 169                return Matcher.result(id, Measure.getSelectionRect(editor));
 170              }
 171              return null;
 172            }
 173          }
 174          return null;
 175        };
 176      };
 177      var SelectionMatcher = {
 178        textSelection: textSelection,
 179        emptyTextBlock: emptyTextBlock
 180      };
 181  
 182      var fireSkinLoaded = function (editor) {
 183        editor.fire('SkinLoaded');
 184      };
 185      var fireBeforeRenderUI = function (editor) {
 186        return editor.fire('BeforeRenderUI');
 187      };
 188      var Events = {
 189        fireSkinLoaded: fireSkinLoaded,
 190        fireBeforeRenderUI: fireBeforeRenderUI
 191      };
 192  
 193      var global$5 = tinymce.util.Tools.resolve('tinymce.EditorManager');
 194  
 195      var isType = function (type) {
 196        return function (value) {
 197          return typeof value === type;
 198        };
 199      };
 200      var isArray = function (value) {
 201        return Array.isArray(value);
 202      };
 203      var isNull = function (value) {
 204        return value === null;
 205      };
 206      var isObject = function (predicate) {
 207        return function (value) {
 208          return !isNull(value) && !isArray(value) && predicate(value);
 209        };
 210      };
 211      var isString = function (value) {
 212        return isType('string')(value);
 213      };
 214      var isNumber = function (value) {
 215        return isType('number')(value);
 216      };
 217      var isFunction = function (value) {
 218        return isType('function')(value);
 219      };
 220      var isBoolean = function (value) {
 221        return isType('boolean')(value);
 222      };
 223      var Type = {
 224        isString: isString,
 225        isNumber: isNumber,
 226        isBoolean: isBoolean,
 227        isFunction: isFunction,
 228        isObject: isObject(isType('object')),
 229        isNull: isNull,
 230        isArray: isArray
 231      };
 232  
 233      var validDefaultOrDie = function (value, predicate) {
 234        if (predicate(value)) {
 235          return true;
 236        }
 237        throw new Error('Default value doesn\'t match requested type.');
 238      };
 239      var getByTypeOr = function (predicate) {
 240        return function (editor, name, defaultValue) {
 241          var settings = editor.settings;
 242          validDefaultOrDie(defaultValue, predicate);
 243          return name in settings && predicate(settings[name]) ? settings[name] : defaultValue;
 244        };
 245      };
 246      var splitNoEmpty = function (str, delim) {
 247        return str.split(delim).filter(function (item) {
 248          return item.length > 0;
 249        });
 250      };
 251      var itemsToArray = function (value, defaultValue) {
 252        var stringToItemsArray = function (value) {
 253          return typeof value === 'string' ? splitNoEmpty(value, /[ ,]/) : value;
 254        };
 255        var boolToItemsArray = function (value, defaultValue) {
 256          return value === false ? [] : defaultValue;
 257        };
 258        if (Type.isArray(value)) {
 259          return value;
 260        } else if (Type.isString(value)) {
 261          return stringToItemsArray(value);
 262        } else if (Type.isBoolean(value)) {
 263          return boolToItemsArray(value, defaultValue);
 264        }
 265        return defaultValue;
 266      };
 267      var getToolbarItemsOr = function (predicate) {
 268        return function (editor, name, defaultValue) {
 269          var value = name in editor.settings ? editor.settings[name] : defaultValue;
 270          validDefaultOrDie(defaultValue, predicate);
 271          return itemsToArray(value, defaultValue);
 272        };
 273      };
 274      var EditorSettings = {
 275        getStringOr: getByTypeOr(Type.isString),
 276        getBoolOr: getByTypeOr(Type.isBoolean),
 277        getNumberOr: getByTypeOr(Type.isNumber),
 278        getHandlerOr: getByTypeOr(Type.isFunction),
 279        getToolbarItemsOr: getToolbarItemsOr(Type.isArray)
 280      };
 281  
 282      var global$6 = tinymce.util.Tools.resolve('tinymce.geom.Rect');
 283  
 284      var result$1 = function (rect, position) {
 285        return {
 286          rect: rect,
 287          position: position
 288        };
 289      };
 290      var moveTo = function (rect, toRect) {
 291        return {
 292          x: toRect.x,
 293          y: toRect.y,
 294          w: rect.w,
 295          h: rect.h
 296        };
 297      };
 298      var calcByPositions = function (testPositions1, testPositions2, targetRect, contentAreaRect, panelRect) {
 299        var relPos, relRect, outputPanelRect;
 300        var paddedContentRect = {
 301          x: contentAreaRect.x,
 302          y: contentAreaRect.y,
 303          w: contentAreaRect.w + (contentAreaRect.w < panelRect.w + targetRect.w ? panelRect.w : 0),
 304          h: contentAreaRect.h + (contentAreaRect.h < panelRect.h + targetRect.h ? panelRect.h : 0)
 305        };
 306        relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions1);
 307        targetRect = global$6.clamp(targetRect, paddedContentRect);
 308        if (relPos) {
 309          relRect = global$6.relativePosition(panelRect, targetRect, relPos);
 310          outputPanelRect = moveTo(panelRect, relRect);
 311          return result$1(outputPanelRect, relPos);
 312        }
 313        targetRect = global$6.intersect(paddedContentRect, targetRect);
 314        if (targetRect) {
 315          relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions2);
 316          if (relPos) {
 317            relRect = global$6.relativePosition(panelRect, targetRect, relPos);
 318            outputPanelRect = moveTo(panelRect, relRect);
 319            return result$1(outputPanelRect, relPos);
 320          }
 321          outputPanelRect = moveTo(panelRect, targetRect);
 322          return result$1(outputPanelRect, relPos);
 323        }
 324        return null;
 325      };
 326      var calcInsert = function (targetRect, contentAreaRect, panelRect) {
 327        return calcByPositions([
 328          'cr-cl',
 329          'cl-cr'
 330        ], [
 331          'bc-tc',
 332          'bl-tl',
 333          'br-tr'
 334        ], targetRect, contentAreaRect, panelRect);
 335      };
 336      var calc = function (targetRect, contentAreaRect, panelRect) {
 337        return calcByPositions([
 338          'tc-bc',
 339          'bc-tc',
 340          'tl-bl',
 341          'bl-tl',
 342          'tr-br',
 343          'br-tr',
 344          'cr-cl',
 345          'cl-cr'
 346        ], [
 347          'bc-tc',
 348          'bl-tl',
 349          'br-tr',
 350          'cr-cl'
 351        ], targetRect, contentAreaRect, panelRect);
 352      };
 353      var userConstrain = function (handler, targetRect, contentAreaRect, panelRect) {
 354        var userConstrainedPanelRect;
 355        if (typeof handler === 'function') {
 356          userConstrainedPanelRect = handler({
 357            elementRect: Convert.toClientRect(targetRect),
 358            contentAreaRect: Convert.toClientRect(contentAreaRect),
 359            panelRect: Convert.toClientRect(panelRect)
 360          });
 361          return Convert.fromClientRect(userConstrainedPanelRect);
 362        }
 363        return panelRect;
 364      };
 365      var defaultHandler = function (rects) {
 366        return rects.panelRect;
 367      };
 368      var Layout = {
 369        calcInsert: calcInsert,
 370        calc: calc,
 371        userConstrain: userConstrain,
 372        defaultHandler: defaultHandler
 373      };
 374  
 375      var toAbsoluteUrl = function (editor, url) {
 376        return editor.documentBaseURI.toAbsolute(url);
 377      };
 378      var urlFromName = function (name) {
 379        var prefix = global$5.baseURL + '/skins/';
 380        return name ? prefix + name : prefix + 'lightgray';
 381      };
 382      var getTextSelectionToolbarItems = function (editor) {
 383        return EditorSettings.getToolbarItemsOr(editor, 'selection_toolbar', [
 384          'bold',
 385          'italic',
 386          '|',
 387          'quicklink',
 388          'h2',
 389          'h3',
 390          'blockquote'
 391        ]);
 392      };
 393      var getInsertToolbarItems = function (editor) {
 394        return EditorSettings.getToolbarItemsOr(editor, 'insert_toolbar', [
 395          'quickimage',
 396          'quicktable'
 397        ]);
 398      };
 399      var getPositionHandler = function (editor) {
 400        return EditorSettings.getHandlerOr(editor, 'inline_toolbar_position_handler', Layout.defaultHandler);
 401      };
 402      var getSkinUrl = function (editor) {
 403        var settings = editor.settings;
 404        return settings.skin_url ? toAbsoluteUrl(editor, settings.skin_url) : urlFromName(settings.skin);
 405      };
 406      var isSkinDisabled = function (editor) {
 407        return editor.settings.skin === false;
 408      };
 409      var Settings = {
 410        getTextSelectionToolbarItems: getTextSelectionToolbarItems,
 411        getInsertToolbarItems: getInsertToolbarItems,
 412        getPositionHandler: getPositionHandler,
 413        getSkinUrl: getSkinUrl,
 414        isSkinDisabled: isSkinDisabled
 415      };
 416  
 417      var fireSkinLoaded$1 = function (editor, callback) {
 418        var done = function () {
 419          editor._skinLoaded = true;
 420          Events.fireSkinLoaded(editor);
 421          callback();
 422        };
 423        if (editor.initialized) {
 424          done();
 425        } else {
 426          editor.on('init', done);
 427        }
 428      };
 429      var load = function (editor, callback) {
 430        var skinUrl = Settings.getSkinUrl(editor);
 431        var done = function () {
 432          fireSkinLoaded$1(editor, callback);
 433        };
 434        if (Settings.isSkinDisabled(editor)) {
 435          done();
 436        } else {
 437          global$2.DOM.styleSheetLoader.load(skinUrl + '/skin.min.css', done);
 438          editor.contentCSS.push(skinUrl + '/content.inline.min.css');
 439        }
 440      };
 441      var SkinLoader = { load: load };
 442  
 443      var getSelectionElements = function (editor) {
 444        var node = editor.selection.getNode();
 445        var elms = editor.dom.getParents(node, '*');
 446        return elms;
 447      };
 448      var createToolbar = function (editor, selector, id, items) {
 449        var selectorPredicate = function (elm) {
 450          return editor.dom.is(elm, selector);
 451        };
 452        return {
 453          predicate: selectorPredicate,
 454          id: id,
 455          items: items
 456        };
 457      };
 458      var getToolbars = function (editor) {
 459        var contextToolbars = editor.contextToolbars;
 460        return DeepFlatten.flatten([
 461          contextToolbars ? contextToolbars : [],
 462          createToolbar(editor, 'img', 'image', 'alignleft aligncenter alignright')
 463        ]);
 464      };
 465      var findMatchResult = function (editor, toolbars) {
 466        var result, elements, contextToolbarsPredicateIds;
 467        elements = getSelectionElements(editor);
 468        contextToolbarsPredicateIds = PredicateId.fromContextToolbars(toolbars);
 469        result = Matcher.match(editor, [
 470          ElementMatcher.element(elements[0], contextToolbarsPredicateIds),
 471          SelectionMatcher.textSelection('text'),
 472          SelectionMatcher.emptyTextBlock(elements, 'insert'),
 473          ElementMatcher.parent(elements, contextToolbarsPredicateIds)
 474        ]);
 475        return result && result.rect ? result : null;
 476      };
 477      var editorHasFocus = function (editor) {
 478        return domGlobals.document.activeElement === editor.getBody();
 479      };
 480      var togglePanel = function (editor, panel) {
 481        var toggle = function () {
 482          var toolbars = getToolbars(editor);
 483          var result = findMatchResult(editor, toolbars);
 484          if (result) {
 485            panel.show(editor, result.id, result.rect, toolbars);
 486          } else {
 487            panel.hide();
 488          }
 489        };
 490        return function () {
 491          if (!editor.removed && editorHasFocus(editor)) {
 492            toggle();
 493          }
 494        };
 495      };
 496      var repositionPanel = function (editor, panel) {
 497        return function () {
 498          var toolbars = getToolbars(editor);
 499          var result = findMatchResult(editor, toolbars);
 500          if (result) {
 501            panel.reposition(editor, result.id, result.rect);
 502          }
 503        };
 504      };
 505      var ignoreWhenFormIsVisible = function (editor, panel, f) {
 506        return function () {
 507          if (!editor.removed && !panel.inForm()) {
 508            f();
 509          }
 510        };
 511      };
 512      var bindContextualToolbarsEvents = function (editor, panel) {
 513        var throttledTogglePanel = global$3.throttle(togglePanel(editor, panel), 0);
 514        var throttledTogglePanelWhenNotInForm = global$3.throttle(ignoreWhenFormIsVisible(editor, panel, togglePanel(editor, panel)), 0);
 515        var reposition = repositionPanel(editor, panel);
 516        editor.on('blur hide ObjectResizeStart', panel.hide);
 517        editor.on('click', throttledTogglePanel);
 518        editor.on('nodeChange mouseup', throttledTogglePanelWhenNotInForm);
 519        editor.on('ResizeEditor keyup', throttledTogglePanel);
 520        editor.on('ResizeWindow', reposition);
 521        global$2.DOM.bind(global$1.container, 'scroll', reposition);
 522        editor.on('remove', function () {
 523          global$2.DOM.unbind(global$1.container, 'scroll', reposition);
 524          panel.remove();
 525        });
 526        editor.shortcuts.add('Alt+F10,F10', '', panel.focus);
 527      };
 528      var overrideLinkShortcut = function (editor, panel) {
 529        editor.shortcuts.remove('meta+k');
 530        editor.shortcuts.add('meta+k', '', function () {
 531          var toolbars = getToolbars(editor);
 532          var result = Matcher.match(editor, [SelectionMatcher.textSelection('quicklink')]);
 533          if (result) {
 534            panel.show(editor, result.id, result.rect, toolbars);
 535          }
 536        });
 537      };
 538      var renderInlineUI = function (editor, panel) {
 539        SkinLoader.load(editor, function () {
 540          bindContextualToolbarsEvents(editor, panel);
 541          overrideLinkShortcut(editor, panel);
 542        });
 543        return {};
 544      };
 545      var fail = function (message) {
 546        throw new Error(message);
 547      };
 548      var renderUI = function (editor, panel) {
 549        return editor.inline ? renderInlineUI(editor, panel) : fail('inlite theme only supports inline mode.');
 550      };
 551      var Render = { renderUI: renderUI };
 552  
 553      var noop = function () {
 554      };
 555      var constant = function (value) {
 556        return function () {
 557          return value;
 558        };
 559      };
 560      var never = constant(false);
 561      var always = constant(true);
 562  
 563      var none = function () {
 564        return NONE;
 565      };
 566      var NONE = function () {
 567        var eq = function (o) {
 568          return o.isNone();
 569        };
 570        var call = function (thunk) {
 571          return thunk();
 572        };
 573        var id = function (n) {
 574          return n;
 575        };
 576        var me = {
 577          fold: function (n, s) {
 578            return n();
 579          },
 580          is: never,
 581          isSome: never,
 582          isNone: always,
 583          getOr: id,
 584          getOrThunk: call,
 585          getOrDie: function (msg) {
 586            throw new Error(msg || 'error: getOrDie called on none.');
 587          },
 588          getOrNull: constant(null),
 589          getOrUndefined: constant(undefined),
 590          or: id,
 591          orThunk: call,
 592          map: none,
 593          each: noop,
 594          bind: none,
 595          exists: never,
 596          forall: always,
 597          filter: none,
 598          equals: eq,
 599          equals_: eq,
 600          toArray: function () {
 601            return [];
 602          },
 603          toString: constant('none()')
 604        };
 605        if (Object.freeze) {
 606          Object.freeze(me);
 607        }
 608        return me;
 609      }();
 610      var some = function (a) {
 611        var constant_a = constant(a);
 612        var self = function () {
 613          return me;
 614        };
 615        var bind = function (f) {
 616          return f(a);
 617        };
 618        var me = {
 619          fold: function (n, s) {
 620            return s(a);
 621          },
 622          is: function (v) {
 623            return a === v;
 624          },
 625          isSome: always,
 626          isNone: never,
 627          getOr: constant_a,
 628          getOrThunk: constant_a,
 629          getOrDie: constant_a,
 630          getOrNull: constant_a,
 631          getOrUndefined: constant_a,
 632          or: self,
 633          orThunk: self,
 634          map: function (f) {
 635            return some(f(a));
 636          },
 637          each: function (f) {
 638            f(a);
 639          },
 640          bind: bind,
 641          exists: bind,
 642          forall: bind,
 643          filter: function (f) {
 644            return f(a) ? me : NONE;
 645          },
 646          toArray: function () {
 647            return [a];
 648          },
 649          toString: function () {
 650            return 'some(' + a + ')';
 651          },
 652          equals: function (o) {
 653            return o.is(a);
 654          },
 655          equals_: function (o, elementEq) {
 656            return o.fold(never, function (b) {
 657              return elementEq(a, b);
 658            });
 659          }
 660        };
 661        return me;
 662      };
 663      var from = function (value) {
 664        return value === null || value === undefined ? NONE : some(value);
 665      };
 666      var Option = {
 667        some: some,
 668        none: none,
 669        from: from
 670      };
 671  
 672      var typeOf = function (x) {
 673        if (x === null) {
 674          return 'null';
 675        }
 676        var t = typeof x;
 677        if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
 678          return 'array';
 679        }
 680        if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
 681          return 'string';
 682        }
 683        return t;
 684      };
 685      var isType$1 = function (type) {
 686        return function (value) {
 687          return typeOf(value) === type;
 688        };
 689      };
 690      var isArray$1 = isType$1('array');
 691      var isFunction$1 = isType$1('function');
 692      var isNumber$1 = isType$1('number');
 693  
 694      var nativeSlice = Array.prototype.slice;
 695      var nativeIndexOf = Array.prototype.indexOf;
 696      var nativePush = Array.prototype.push;
 697      var rawIndexOf = function (ts, t) {
 698        return nativeIndexOf.call(ts, t);
 699      };
 700      var indexOf = function (xs, x) {
 701        var r = rawIndexOf(xs, x);
 702        return r === -1 ? Option.none() : Option.some(r);
 703      };
 704      var exists = function (xs, pred) {
 705        for (var i = 0, len = xs.length; i < len; i++) {
 706          var x = xs[i];
 707          if (pred(x, i)) {
 708            return true;
 709          }
 710        }
 711        return false;
 712      };
 713      var map = function (xs, f) {
 714        var len = xs.length;
 715        var r = new Array(len);
 716        for (var i = 0; i < len; i++) {
 717          var x = xs[i];
 718          r[i] = f(x, i);
 719        }
 720        return r;
 721      };
 722      var each = function (xs, f) {
 723        for (var i = 0, len = xs.length; i < len; i++) {
 724          var x = xs[i];
 725          f(x, i);
 726        }
 727      };
 728      var filter = function (xs, pred) {
 729        var r = [];
 730        for (var i = 0, len = xs.length; i < len; i++) {
 731          var x = xs[i];
 732          if (pred(x, i)) {
 733            r.push(x);
 734          }
 735        }
 736        return r;
 737      };
 738      var foldl = function (xs, f, acc) {
 739        each(xs, function (x) {
 740          acc = f(acc, x);
 741        });
 742        return acc;
 743      };
 744      var find = function (xs, pred) {
 745        for (var i = 0, len = xs.length; i < len; i++) {
 746          var x = xs[i];
 747          if (pred(x, i)) {
 748            return Option.some(x);
 749          }
 750        }
 751        return Option.none();
 752      };
 753      var flatten$1 = function (xs) {
 754        var r = [];
 755        for (var i = 0, len = xs.length; i < len; ++i) {
 756          if (!isArray$1(xs[i])) {
 757            throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
 758          }
 759          nativePush.apply(r, xs[i]);
 760        }
 761        return r;
 762      };
 763      var from$1 = isFunction$1(Array.from) ? Array.from : function (x) {
 764        return nativeSlice.call(x);
 765      };
 766  
 767      var count = 0;
 768      var funcs = {
 769        id: function () {
 770          return 'mceu_' + count++;
 771        },
 772        create: function (name, attrs, children) {
 773          var elm = domGlobals.document.createElement(name);
 774          global$2.DOM.setAttribs(elm, attrs);
 775          if (typeof children === 'string') {
 776            elm.innerHTML = children;
 777          } else {
 778            global$4.each(children, function (child) {
 779              if (child.nodeType) {
 780                elm.appendChild(child);
 781              }
 782            });
 783          }
 784          return elm;
 785        },
 786        createFragment: function (html) {
 787          return global$2.DOM.createFragment(html);
 788        },
 789        getWindowSize: function () {
 790          return global$2.DOM.getViewPort();
 791        },
 792        getSize: function (elm) {
 793          var width, height;
 794          if (elm.getBoundingClientRect) {
 795            var rect = elm.getBoundingClientRect();
 796            width = Math.max(rect.width || rect.right - rect.left, elm.offsetWidth);
 797            height = Math.max(rect.height || rect.bottom - rect.bottom, elm.offsetHeight);
 798          } else {
 799            width = elm.offsetWidth;
 800            height = elm.offsetHeight;
 801          }
 802          return {
 803            width: width,
 804            height: height
 805          };
 806        },
 807        getPos: function (elm, root) {
 808          return global$2.DOM.getPos(elm, root || funcs.getContainer());
 809        },
 810        getContainer: function () {
 811          return global$1.container ? global$1.container : domGlobals.document.body;
 812        },
 813        getViewPort: function (win) {
 814          return global$2.DOM.getViewPort(win);
 815        },
 816        get: function (id) {
 817          return domGlobals.document.getElementById(id);
 818        },
 819        addClass: function (elm, cls) {
 820          return global$2.DOM.addClass(elm, cls);
 821        },
 822        removeClass: function (elm, cls) {
 823          return global$2.DOM.removeClass(elm, cls);
 824        },
 825        hasClass: function (elm, cls) {
 826          return global$2.DOM.hasClass(elm, cls);
 827        },
 828        toggleClass: function (elm, cls, state) {
 829          return global$2.DOM.toggleClass(elm, cls, state);
 830        },
 831        css: function (elm, name, value) {
 832          return global$2.DOM.setStyle(elm, name, value);
 833        },
 834        getRuntimeStyle: function (elm, name) {
 835          return global$2.DOM.getStyle(elm, name, true);
 836        },
 837        on: function (target, name, callback, scope) {
 838          return global$2.DOM.bind(target, name, callback, scope);
 839        },
 840        off: function (target, name, callback) {
 841          return global$2.DOM.unbind(target, name, callback);
 842        },
 843        fire: function (target, name, args) {
 844          return global$2.DOM.fire(target, name, args);
 845        },
 846        innerHtml: function (elm, html) {
 847          global$2.DOM.setHTML(elm, html);
 848        }
 849      };
 850  
 851      var global$7 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery');
 852  
 853      var global$8 = tinymce.util.Tools.resolve('tinymce.util.Class');
 854  
 855      var global$9 = tinymce.util.Tools.resolve('tinymce.util.EventDispatcher');
 856  
 857      var BoxUtils = {
 858        parseBox: function (value) {
 859          var len;
 860          var radix = 10;
 861          if (!value) {
 862            return;
 863          }
 864          if (typeof value === 'number') {
 865            value = value || 0;
 866            return {
 867              top: value,
 868              left: value,
 869              bottom: value,
 870              right: value
 871            };
 872          }
 873          value = value.split(' ');
 874          len = value.length;
 875          if (len === 1) {
 876            value[1] = value[2] = value[3] = value[0];
 877          } else if (len === 2) {
 878            value[2] = value[0];
 879            value[3] = value[1];
 880          } else if (len === 3) {
 881            value[3] = value[1];
 882          }
 883          return {
 884            top: parseInt(value[0], radix) || 0,
 885            right: parseInt(value[1], radix) || 0,
 886            bottom: parseInt(value[2], radix) || 0,
 887            left: parseInt(value[3], radix) || 0
 888          };
 889        },
 890        measureBox: function (elm, prefix) {
 891          function getStyle(name) {
 892            var defaultView = elm.ownerDocument.defaultView;
 893            if (defaultView) {
 894              var computedStyle = defaultView.getComputedStyle(elm, null);
 895              if (computedStyle) {
 896                name = name.replace(/[A-Z]/g, function (a) {
 897                  return '-' + a;
 898                });
 899                return computedStyle.getPropertyValue(name);
 900              } else {
 901                return null;
 902              }
 903            }
 904            return elm.currentStyle[name];
 905          }
 906          function getSide(name) {
 907            var val = parseFloat(getStyle(name));
 908            return isNaN(val) ? 0 : val;
 909          }
 910          return {
 911            top: getSide(prefix + 'TopWidth'),
 912            right: getSide(prefix + 'RightWidth'),
 913            bottom: getSide(prefix + 'BottomWidth'),
 914            left: getSide(prefix + 'LeftWidth')
 915          };
 916        }
 917      };
 918  
 919      function noop$1() {
 920      }
 921      function ClassList(onchange) {
 922        this.cls = [];
 923        this.cls._map = {};
 924        this.onchange = onchange || noop$1;
 925        this.prefix = '';
 926      }
 927      global$4.extend(ClassList.prototype, {
 928        add: function (cls) {
 929          if (cls && !this.contains(cls)) {
 930            this.cls._map[cls] = true;
 931            this.cls.push(cls);
 932            this._change();
 933          }
 934          return this;
 935        },
 936        remove: function (cls) {
 937          if (this.contains(cls)) {
 938            var i = void 0;
 939            for (i = 0; i < this.cls.length; i++) {
 940              if (this.cls[i] === cls) {
 941                break;
 942              }
 943            }
 944            this.cls.splice(i, 1);
 945            delete this.cls._map[cls];
 946            this._change();
 947          }
 948          return this;
 949        },
 950        toggle: function (cls, state) {
 951          var curState = this.contains(cls);
 952          if (curState !== state) {
 953            if (curState) {
 954              this.remove(cls);
 955            } else {
 956              this.add(cls);
 957            }
 958            this._change();
 959          }
 960          return this;
 961        },
 962        contains: function (cls) {
 963          return !!this.cls._map[cls];
 964        },
 965        _change: function () {
 966          delete this.clsValue;
 967          this.onchange.call(this);
 968        }
 969      });
 970      ClassList.prototype.toString = function () {
 971        var value;
 972        if (this.clsValue) {
 973          return this.clsValue;
 974        }
 975        value = '';
 976        for (var i = 0; i < this.cls.length; i++) {
 977          if (i > 0) {
 978            value += ' ';
 979          }
 980          value += this.prefix + this.cls[i];
 981        }
 982        return value;
 983      };
 984  
 985      function unique(array) {
 986        var uniqueItems = [];
 987        var i = array.length, item;
 988        while (i--) {
 989          item = array[i];
 990          if (!item.__checked) {
 991            uniqueItems.push(item);
 992            item.__checked = 1;
 993          }
 994        }
 995        i = uniqueItems.length;
 996        while (i--) {
 997          delete uniqueItems[i].__checked;
 998        }
 999        return uniqueItems;
1000      }
1001      var expression = /^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i;
1002      var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g;
1003      var whiteSpace = /^\s*|\s*$/g;
1004      var Collection;
1005      var Selector = global$8.extend({
1006        init: function (selector) {
1007          var match = this.match;
1008          function compileNameFilter(name) {
1009            if (name) {
1010              name = name.toLowerCase();
1011              return function (item) {
1012                return name === '*' || item.type === name;
1013              };
1014            }
1015          }
1016          function compileIdFilter(id) {
1017            if (id) {
1018              return function (item) {
1019                return item._name === id;
1020              };
1021            }
1022          }
1023          function compileClassesFilter(classes) {
1024            if (classes) {
1025              classes = classes.split('.');
1026              return function (item) {
1027                var i = classes.length;
1028                while (i--) {
1029                  if (!item.classes.contains(classes[i])) {
1030                    return false;
1031                  }
1032                }
1033                return true;
1034              };
1035            }
1036          }
1037          function compileAttrFilter(name, cmp, check) {
1038            if (name) {
1039              return function (item) {
1040                var value = item[name] ? item[name]() : '';
1041                return !cmp ? !!check : cmp === '=' ? value === check : cmp === '*=' ? value.indexOf(check) >= 0 : cmp === '~=' ? (' ' + value + ' ').indexOf(' ' + check + ' ') >= 0 : cmp === '!=' ? value !== check : cmp === '^=' ? value.indexOf(check) === 0 : cmp === '$=' ? value.substr(value.length - check.length) === check : false;
1042              };
1043            }
1044          }
1045          function compilePsuedoFilter(name) {
1046            var notSelectors;
1047            if (name) {
1048              name = /(?:not\((.+)\))|(.+)/i.exec(name);
1049              if (!name[1]) {
1050                name = name[2];
1051                return function (item, index, length) {
1052                  return name === 'first' ? index === 0 : name === 'last' ? index === length - 1 : name === 'even' ? index % 2 === 0 : name === 'odd' ? index % 2 === 1 : item[name] ? item[name]() : false;
1053                };
1054              }
1055              notSelectors = parseChunks(name[1], []);
1056              return function (item) {
1057                return !match(item, notSelectors);
1058              };
1059            }
1060          }
1061          function compile(selector, filters, direct) {
1062            var parts;
1063            function add(filter) {
1064              if (filter) {
1065                filters.push(filter);
1066              }
1067            }
1068            parts = expression.exec(selector.replace(whiteSpace, ''));
1069            add(compileNameFilter(parts[1]));
1070            add(compileIdFilter(parts[2]));
1071            add(compileClassesFilter(parts[3]));
1072            add(compileAttrFilter(parts[4], parts[5], parts[6]));
1073            add(compilePsuedoFilter(parts[7]));
1074            filters.pseudo = !!parts[7];
1075            filters.direct = direct;
1076            return filters;
1077          }
1078          function parseChunks(selector, selectors) {
1079            var parts = [];
1080            var extra, matches, i;
1081            do {
1082              chunker.exec('');
1083              matches = chunker.exec(selector);
1084              if (matches) {
1085                selector = matches[3];
1086                parts.push(matches[1]);
1087                if (matches[2]) {
1088                  extra = matches[3];
1089                  break;
1090                }
1091              }
1092            } while (matches);
1093            if (extra) {
1094              parseChunks(extra, selectors);
1095            }
1096            selector = [];
1097            for (i = 0; i < parts.length; i++) {
1098              if (parts[i] !== '>') {
1099                selector.push(compile(parts[i], [], parts[i - 1] === '>'));
1100              }
1101            }
1102            selectors.push(selector);
1103            return selectors;
1104          }
1105          this._selectors = parseChunks(selector, []);
1106        },
1107        match: function (control, selectors) {
1108          var i, l, si, sl, selector, fi, fl, filters, index, length, siblings, count, item;
1109          selectors = selectors || this._selectors;
1110          for (i = 0, l = selectors.length; i < l; i++) {
1111            selector = selectors[i];
1112            sl = selector.length;
1113            item = control;
1114            count = 0;
1115            for (si = sl - 1; si >= 0; si--) {
1116              filters = selector[si];
1117              while (item) {
1118                if (filters.pseudo) {
1119                  siblings = item.parent().items();
1120                  index = length = siblings.length;
1121                  while (index--) {
1122                    if (siblings[index] === item) {
1123                      break;
1124                    }
1125                  }
1126                }
1127                for (fi = 0, fl = filters.length; fi < fl; fi++) {
1128                  if (!filters[fi](item, index, length)) {
1129                    fi = fl + 1;
1130                    break;
1131                  }
1132                }
1133                if (fi === fl) {
1134                  count++;
1135                  break;
1136                } else {
1137                  if (si === sl - 1) {
1138                    break;
1139                  }
1140                }
1141                item = item.parent();
1142              }
1143            }
1144            if (count === sl) {
1145              return true;
1146            }
1147          }
1148          return false;
1149        },
1150        find: function (container) {
1151          var matches = [], i, l;
1152          var selectors = this._selectors;
1153          function collect(items, selector, index) {
1154            var i, l, fi, fl, item;
1155            var filters = selector[index];
1156            for (i = 0, l = items.length; i < l; i++) {
1157              item = items[i];
1158              for (fi = 0, fl = filters.length; fi < fl; fi++) {
1159                if (!filters[fi](item, i, l)) {
1160                  fi = fl + 1;
1161                  break;
1162                }
1163              }
1164              if (fi === fl) {
1165                if (index === selector.length - 1) {
1166                  matches.push(item);
1167                } else {
1168                  if (item.items) {
1169                    collect(item.items(), selector, index + 1);
1170                  }
1171                }
1172              } else if (filters.direct) {
1173                return;
1174              }
1175              if (item.items) {
1176                collect(item.items(), selector, index);
1177              }
1178            }
1179          }
1180          if (container.items) {
1181            for (i = 0, l = selectors.length; i < l; i++) {
1182              collect(container.items(), selectors[i], 0);
1183            }
1184            if (l > 1) {
1185              matches = unique(matches);
1186            }
1187          }
1188          if (!Collection) {
1189            Collection = Selector.Collection;
1190          }
1191          return new Collection(matches);
1192        }
1193      });
1194  
1195      var Collection$1, proto;
1196      var push = Array.prototype.push, slice = Array.prototype.slice;
1197      proto = {
1198        length: 0,
1199        init: function (items) {
1200          if (items) {
1201            this.add(items);
1202          }
1203        },
1204        add: function (items) {
1205          var self = this;
1206          if (!global$4.isArray(items)) {
1207            if (items instanceof Collection$1) {
1208              self.add(items.toArray());
1209            } else {
1210              push.call(self, items);
1211            }
1212          } else {
1213            push.apply(self, items);
1214          }
1215          return self;
1216        },
1217        set: function (items) {
1218          var self = this;
1219          var len = self.length;
1220          var i;
1221          self.length = 0;
1222          self.add(items);
1223          for (i = self.length; i < len; i++) {
1224            delete self[i];
1225          }
1226          return self;
1227        },
1228        filter: function (selector) {
1229          var self = this;
1230          var i, l;
1231          var matches = [];
1232          var item, match;
1233          if (typeof selector === 'string') {
1234            selector = new Selector(selector);
1235            match = function (item) {
1236              return selector.match(item);
1237            };
1238          } else {
1239            match = selector;
1240          }
1241          for (i = 0, l = self.length; i < l; i++) {
1242            item = self[i];
1243            if (match(item)) {
1244              matches.push(item);
1245            }
1246          }
1247          return new Collection$1(matches);
1248        },
1249        slice: function () {
1250          return new Collection$1(slice.apply(this, arguments));
1251        },
1252        eq: function (index) {
1253          return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
1254        },
1255        each: function (callback) {
1256          global$4.each(this, callback);
1257          return this;
1258        },
1259        toArray: function () {
1260          return global$4.toArray(this);
1261        },
1262        indexOf: function (ctrl) {
1263          var self = this;
1264          var i = self.length;
1265          while (i--) {
1266            if (self[i] === ctrl) {
1267              break;
1268            }
1269          }
1270          return i;
1271        },
1272        reverse: function () {
1273          return new Collection$1(global$4.toArray(this).reverse());
1274        },
1275        hasClass: function (cls) {
1276          return this[0] ? this[0].classes.contains(cls) : false;
1277        },
1278        prop: function (name, value) {
1279          var self = this;
1280          var item;
1281          if (value !== undefined) {
1282            self.each(function (item) {
1283              if (item[name]) {
1284                item[name](value);
1285              }
1286            });
1287            return self;
1288          }
1289          item = self[0];
1290          if (item && item[name]) {
1291            return item[name]();
1292          }
1293        },
1294        exec: function (name) {
1295          var self = this, args = global$4.toArray(arguments).slice(1);
1296          self.each(function (item) {
1297            if (item[name]) {
1298              item[name].apply(item, args);
1299            }
1300          });
1301          return self;
1302        },
1303        remove: function () {
1304          var i = this.length;
1305          while (i--) {
1306            this[i].remove();
1307          }
1308          return this;
1309        },
1310        addClass: function (cls) {
1311          return this.each(function (item) {
1312            item.classes.add(cls);
1313          });
1314        },
1315        removeClass: function (cls) {
1316          return this.each(function (item) {
1317            item.classes.remove(cls);
1318          });
1319        }
1320      };
1321      global$4.each('fire on off show hide append prepend before after reflow'.split(' '), function (name) {
1322        proto[name] = function () {
1323          var args = global$4.toArray(arguments);
1324          this.each(function (ctrl) {
1325            if (name in ctrl) {
1326              ctrl[name].apply(ctrl, args);
1327            }
1328          });
1329          return this;
1330        };
1331      });
1332      global$4.each('text name disabled active selected checked visible parent value data'.split(' '), function (name) {
1333        proto[name] = function (value) {
1334          return this.prop(name, value);
1335        };
1336      });
1337      Collection$1 = global$8.extend(proto);
1338      Selector.Collection = Collection$1;
1339      var Collection$2 = Collection$1;
1340  
1341      var Binding = function (settings) {
1342        this.create = settings.create;
1343      };
1344      Binding.create = function (model, name) {
1345        return new Binding({
1346          create: function (otherModel, otherName) {
1347            var bindings;
1348            var fromSelfToOther = function (e) {
1349              otherModel.set(otherName, e.value);
1350            };
1351            var fromOtherToSelf = function (e) {
1352              model.set(name, e.value);
1353            };
1354            otherModel.on('change:' + otherName, fromOtherToSelf);
1355            model.on('change:' + name, fromSelfToOther);
1356            bindings = otherModel._bindings;
1357            if (!bindings) {
1358              bindings = otherModel._bindings = [];
1359              otherModel.on('destroy', function () {
1360                var i = bindings.length;
1361                while (i--) {
1362                  bindings[i]();
1363                }
1364              });
1365            }
1366            bindings.push(function () {
1367              model.off('change:' + name, fromSelfToOther);
1368            });
1369            return model.get(name);
1370          }
1371        });
1372      };
1373  
1374      var global$a = tinymce.util.Tools.resolve('tinymce.util.Observable');
1375  
1376      function isNode(node) {
1377        return node.nodeType > 0;
1378      }
1379      function isEqual(a, b) {
1380        var k, checked;
1381        if (a === b) {
1382          return true;
1383        }
1384        if (a === null || b === null) {
1385          return a === b;
1386        }
1387        if (typeof a !== 'object' || typeof b !== 'object') {
1388          return a === b;
1389        }
1390        if (global$4.isArray(b)) {
1391          if (a.length !== b.length) {
1392            return false;
1393          }
1394          k = a.length;
1395          while (k--) {
1396            if (!isEqual(a[k], b[k])) {
1397              return false;
1398            }
1399          }
1400        }
1401        if (isNode(a) || isNode(b)) {
1402          return a === b;
1403        }
1404        checked = {};
1405        for (k in b) {
1406          if (!isEqual(a[k], b[k])) {
1407            return false;
1408          }
1409          checked[k] = true;
1410        }
1411        for (k in a) {
1412          if (!checked[k] && !isEqual(a[k], b[k])) {
1413            return false;
1414          }
1415        }
1416        return true;
1417      }
1418      var ObservableObject = global$8.extend({
1419        Mixins: [global$a],
1420        init: function (data) {
1421          var name, value;
1422          data = data || {};
1423          for (name in data) {
1424            value = data[name];
1425            if (value instanceof Binding) {
1426              data[name] = value.create(this, name);
1427            }
1428          }
1429          this.data = data;
1430        },
1431        set: function (name, value) {
1432          var key, args;
1433          var oldValue = this.data[name];
1434          if (value instanceof Binding) {
1435            value = value.create(this, name);
1436          }
1437          if (typeof name === 'object') {
1438            for (key in name) {
1439              this.set(key, name[key]);
1440            }
1441            return this;
1442          }
1443          if (!isEqual(oldValue, value)) {
1444            this.data[name] = value;
1445            args = {
1446              target: this,
1447              name: name,
1448              value: value,
1449              oldValue: oldValue
1450            };
1451            this.fire('change:' + name, args);
1452            this.fire('change', args);
1453          }
1454          return this;
1455        },
1456        get: function (name) {
1457          return this.data[name];
1458        },
1459        has: function (name) {
1460          return name in this.data;
1461        },
1462        bind: function (name) {
1463          return Binding.create(this, name);
1464        },
1465        destroy: function () {
1466          this.fire('destroy');
1467        }
1468      });
1469  
1470      var dirtyCtrls = {}, animationFrameRequested;
1471      var ReflowQueue = {
1472        add: function (ctrl) {
1473          var parent = ctrl.parent();
1474          if (parent) {
1475            if (!parent._layout || parent._layout.isNative()) {
1476              return;
1477            }
1478            if (!dirtyCtrls[parent._id]) {
1479              dirtyCtrls[parent._id] = parent;
1480            }
1481            if (!animationFrameRequested) {
1482              animationFrameRequested = true;
1483              global$3.requestAnimationFrame(function () {
1484                var id, ctrl;
1485                animationFrameRequested = false;
1486                for (id in dirtyCtrls) {
1487                  ctrl = dirtyCtrls[id];
1488                  if (ctrl.state.get('rendered')) {
1489                    ctrl.reflow();
1490                  }
1491                }
1492                dirtyCtrls = {};
1493              }, domGlobals.document.body);
1494            }
1495          }
1496        },
1497        remove: function (ctrl) {
1498          if (dirtyCtrls[ctrl._id]) {
1499            delete dirtyCtrls[ctrl._id];
1500          }
1501        }
1502      };
1503  
1504      var getUiContainerDelta = function (ctrl) {
1505        var uiContainer = getUiContainer(ctrl);
1506        if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') {
1507          var containerPos = global$2.DOM.getPos(uiContainer);
1508          var dx = uiContainer.scrollLeft - containerPos.x;
1509          var dy = uiContainer.scrollTop - containerPos.y;
1510          return Option.some({
1511            x: dx,
1512            y: dy
1513          });
1514        } else {
1515          return Option.none();
1516        }
1517      };
1518      var setUiContainer = function (editor, ctrl) {
1519        var uiContainer = global$2.DOM.select(editor.settings.ui_container)[0];
1520        ctrl.getRoot().uiContainer = uiContainer;
1521      };
1522      var getUiContainer = function (ctrl) {
1523        return ctrl ? ctrl.getRoot().uiContainer : null;
1524      };
1525      var inheritUiContainer = function (fromCtrl, toCtrl) {
1526        return toCtrl.uiContainer = getUiContainer(fromCtrl);
1527      };
1528      var UiContainer = {
1529        getUiContainerDelta: getUiContainerDelta,
1530        setUiContainer: setUiContainer,
1531        getUiContainer: getUiContainer,
1532        inheritUiContainer: inheritUiContainer
1533      };
1534  
1535      var hasMouseWheelEventSupport = 'onmousewheel' in domGlobals.document;
1536      var hasWheelEventSupport = false;
1537      var classPrefix = 'mce-';
1538      var Control, idCounter = 0;
1539      var proto$1 = {
1540        Statics: { classPrefix: classPrefix },
1541        isRtl: function () {
1542          return Control.rtl;
1543        },
1544        classPrefix: classPrefix,
1545        init: function (settings) {
1546          var self = this;
1547          var classes, defaultClasses;
1548          function applyClasses(classes) {
1549            var i;
1550            classes = classes.split(' ');
1551            for (i = 0; i < classes.length; i++) {
1552              self.classes.add(classes[i]);
1553            }
1554          }
1555          self.settings = settings = global$4.extend({}, self.Defaults, settings);
1556          self._id = settings.id || 'mceu_' + idCounter++;
1557          self._aria = { role: settings.role };
1558          self._elmCache = {};
1559          self.$ = global$7;
1560          self.state = new ObservableObject({
1561            visible: true,
1562            active: false,
1563            disabled: false,
1564            value: ''
1565          });
1566          self.data = new ObservableObject(settings.data);
1567          self.classes = new ClassList(function () {
1568            if (self.state.get('rendered')) {
1569              self.getEl().className = this.toString();
1570            }
1571          });
1572          self.classes.prefix = self.classPrefix;
1573          classes = settings.classes;
1574          if (classes) {
1575            if (self.Defaults) {
1576              defaultClasses = self.Defaults.classes;
1577              if (defaultClasses && classes !== defaultClasses) {
1578                applyClasses(defaultClasses);
1579              }
1580            }
1581            applyClasses(classes);
1582          }
1583          global$4.each('title text name visible disabled active value'.split(' '), function (name) {
1584            if (name in settings) {
1585              self[name](settings[name]);
1586            }
1587          });
1588          self.on('click', function () {
1589            if (self.disabled()) {
1590              return false;
1591            }
1592          });
1593          self.settings = settings;
1594          self.borderBox = BoxUtils.parseBox(settings.border);
1595          self.paddingBox = BoxUtils.parseBox(settings.padding);
1596          self.marginBox = BoxUtils.parseBox(settings.margin);
1597          if (settings.hidden) {
1598            self.hide();
1599          }
1600        },
1601        Properties: 'parent,name',
1602        getContainerElm: function () {
1603          var uiContainer = UiContainer.getUiContainer(this);
1604          return uiContainer ? uiContainer : funcs.getContainer();
1605        },
1606        getParentCtrl: function (elm) {
1607          var ctrl;
1608          var lookup = this.getRoot().controlIdLookup;
1609          while (elm && lookup) {
1610            ctrl = lookup[elm.id];
1611            if (ctrl) {
1612              break;
1613            }
1614            elm = elm.parentNode;
1615          }
1616          return ctrl;
1617        },
1618        initLayoutRect: function () {
1619          var self = this;
1620          var settings = self.settings;
1621          var borderBox, layoutRect;
1622          var elm = self.getEl();
1623          var width, height, minWidth, minHeight, autoResize;
1624          var startMinWidth, startMinHeight, initialSize;
1625          borderBox = self.borderBox = self.borderBox || BoxUtils.measureBox(elm, 'border');
1626          self.paddingBox = self.paddingBox || BoxUtils.measureBox(elm, 'padding');
1627          self.marginBox = self.marginBox || BoxUtils.measureBox(elm, 'margin');
1628          initialSize = funcs.getSize(elm);
1629          startMinWidth = settings.minWidth;
1630          startMinHeight = settings.minHeight;
1631          minWidth = startMinWidth || initialSize.width;
1632          minHeight = startMinHeight || initialSize.height;
1633          width = settings.width;
1634          height = settings.height;
1635          autoResize = settings.autoResize;
1636          autoResize = typeof autoResize !== 'undefined' ? autoResize : !width && !height;
1637          width = width || minWidth;
1638          height = height || minHeight;
1639          var deltaW = borderBox.left + borderBox.right;
1640          var deltaH = borderBox.top + borderBox.bottom;
1641          var maxW = settings.maxWidth || 65535;
1642          var maxH = settings.maxHeight || 65535;
1643          self._layoutRect = layoutRect = {
1644            x: settings.x || 0,
1645            y: settings.y || 0,
1646            w: width,
1647            h: height,
1648            deltaW: deltaW,
1649            deltaH: deltaH,
1650            contentW: width - deltaW,
1651            contentH: height - deltaH,
1652            innerW: width - deltaW,
1653            innerH: height - deltaH,
1654            startMinWidth: startMinWidth || 0,
1655            startMinHeight: startMinHeight || 0,
1656            minW: Math.min(minWidth, maxW),
1657            minH: Math.min(minHeight, maxH),
1658            maxW: maxW,
1659            maxH: maxH,
1660            autoResize: autoResize,
1661            scrollW: 0
1662          };
1663          self._lastLayoutRect = {};
1664          return layoutRect;
1665        },
1666        layoutRect: function (newRect) {
1667          var self = this;
1668          var curRect = self._layoutRect, lastLayoutRect, size, deltaWidth, deltaHeight, repaintControls;
1669          if (!curRect) {
1670            curRect = self.initLayoutRect();
1671          }
1672          if (newRect) {
1673            deltaWidth = curRect.deltaW;
1674            deltaHeight = curRect.deltaH;
1675            if (newRect.x !== undefined) {
1676              curRect.x = newRect.x;
1677            }
1678            if (newRect.y !== undefined) {
1679              curRect.y = newRect.y;
1680            }
1681            if (newRect.minW !== undefined) {
1682              curRect.minW = newRect.minW;
1683            }
1684            if (newRect.minH !== undefined) {
1685              curRect.minH = newRect.minH;
1686            }
1687            size = newRect.w;
1688            if (size !== undefined) {
1689              size = size < curRect.minW ? curRect.minW : size;
1690              size = size > curRect.maxW ? curRect.maxW : size;
1691              curRect.w = size;
1692              curRect.innerW = size - deltaWidth;
1693            }
1694            size = newRect.h;
1695            if (size !== undefined) {
1696              size = size < curRect.minH ? curRect.minH : size;
1697              size = size > curRect.maxH ? curRect.maxH : size;
1698              curRect.h = size;
1699              curRect.innerH = size - deltaHeight;
1700            }
1701            size = newRect.innerW;
1702            if (size !== undefined) {
1703              size = size < curRect.minW - deltaWidth ? curRect.minW - deltaWidth : size;
1704              size = size > curRect.maxW - deltaWidth ? curRect.maxW - deltaWidth : size;
1705              curRect.innerW = size;
1706              curRect.w = size + deltaWidth;
1707            }
1708            size = newRect.innerH;
1709            if (size !== undefined) {
1710              size = size < curRect.minH - deltaHeight ? curRect.minH - deltaHeight : size;
1711              size = size > curRect.maxH - deltaHeight ? curRect.maxH - deltaHeight : size;
1712              curRect.innerH = size;
1713              curRect.h = size + deltaHeight;
1714            }
1715            if (newRect.contentW !== undefined) {
1716              curRect.contentW = newRect.contentW;
1717            }
1718            if (newRect.contentH !== undefined) {
1719              curRect.contentH = newRect.contentH;
1720            }
1721            lastLayoutRect = self._lastLayoutRect;
1722            if (lastLayoutRect.x !== curRect.x || lastLayoutRect.y !== curRect.y || lastLayoutRect.w !== curRect.w || lastLayoutRect.h !== curRect.h) {
1723              repaintControls = Control.repaintControls;
1724              if (repaintControls) {
1725                if (repaintControls.map && !repaintControls.map[self._id]) {
1726                  repaintControls.push(self);
1727                  repaintControls.map[self._id] = true;
1728                }
1729              }
1730              lastLayoutRect.x = curRect.x;
1731              lastLayoutRect.y = curRect.y;
1732              lastLayoutRect.w = curRect.w;
1733              lastLayoutRect.h = curRect.h;
1734            }
1735            return self;
1736          }
1737          return curRect;
1738        },
1739        repaint: function () {
1740          var self = this;
1741          var style, bodyStyle, bodyElm, rect, borderBox;
1742          var borderW, borderH, lastRepaintRect, round, value;
1743          round = !domGlobals.document.createRange ? Math.round : function (value) {
1744            return value;
1745          };
1746          style = self.getEl().style;
1747          rect = self._layoutRect;
1748          lastRepaintRect = self._lastRepaintRect || {};
1749          borderBox = self.borderBox;
1750          borderW = borderBox.left + borderBox.right;
1751          borderH = borderBox.top + borderBox.bottom;
1752          if (rect.x !== lastRepaintRect.x) {
1753            style.left = round(rect.x) + 'px';
1754            lastRepaintRect.x = rect.x;
1755          }
1756          if (rect.y !== lastRepaintRect.y) {
1757            style.top = round(rect.y) + 'px';
1758            lastRepaintRect.y = rect.y;
1759          }
1760          if (rect.w !== lastRepaintRect.w) {
1761            value = round(rect.w - borderW);
1762            style.width = (value >= 0 ? value : 0) + 'px';
1763            lastRepaintRect.w = rect.w;
1764          }
1765          if (rect.h !== lastRepaintRect.h) {
1766            value = round(rect.h - borderH);
1767            style.height = (value >= 0 ? value : 0) + 'px';
1768            lastRepaintRect.h = rect.h;
1769          }
1770          if (self._hasBody && rect.innerW !== lastRepaintRect.innerW) {
1771            value = round(rect.innerW);
1772            bodyElm = self.getEl('body');
1773            if (bodyElm) {
1774              bodyStyle = bodyElm.style;
1775              bodyStyle.width = (value >= 0 ? value : 0) + 'px';
1776            }
1777            lastRepaintRect.innerW = rect.innerW;
1778          }
1779          if (self._hasBody && rect.innerH !== lastRepaintRect.innerH) {
1780            value = round(rect.innerH);
1781            bodyElm = bodyElm || self.getEl('body');
1782            if (bodyElm) {
1783              bodyStyle = bodyStyle || bodyElm.style;
1784              bodyStyle.height = (value >= 0 ? value : 0) + 'px';
1785            }
1786            lastRepaintRect.innerH = rect.innerH;
1787          }
1788          self._lastRepaintRect = lastRepaintRect;
1789          self.fire('repaint', {}, false);
1790        },
1791        updateLayoutRect: function () {
1792          var self = this;
1793          self.parent()._lastRect = null;
1794          funcs.css(self.getEl(), {
1795            width: '',
1796            height: ''
1797          });
1798          self._layoutRect = self._lastRepaintRect = self._lastLayoutRect = null;
1799          self.initLayoutRect();
1800        },
1801        on: function (name, callback) {
1802          var self = this;
1803          function resolveCallbackName(name) {
1804            var callback, scope;
1805            if (typeof name !== 'string') {
1806              return name;
1807            }
1808            return function (e) {
1809              if (!callback) {
1810                self.parentsAndSelf().each(function (ctrl) {
1811                  var callbacks = ctrl.settings.callbacks;
1812                  if (callbacks && (callback = callbacks[name])) {
1813                    scope = ctrl;
1814                    return false;
1815                  }
1816                });
1817              }
1818              if (!callback) {
1819                e.action = name;
1820                this.fire('execute', e);
1821                return;
1822              }
1823              return callback.call(scope, e);
1824            };
1825          }
1826          getEventDispatcher(self).on(name, resolveCallbackName(callback));
1827          return self;
1828        },
1829        off: function (name, callback) {
1830          getEventDispatcher(this).off(name, callback);
1831          return this;
1832        },
1833        fire: function (name, args, bubble) {
1834          var self = this;
1835          args = args || {};
1836          if (!args.control) {
1837            args.control = self;
1838          }
1839          args = getEventDispatcher(self).fire(name, args);
1840          if (bubble !== false && self.parent) {
1841            var parent = self.parent();
1842            while (parent && !args.isPropagationStopped()) {
1843              parent.fire(name, args, false);
1844              parent = parent.parent();
1845            }
1846          }
1847          return args;
1848        },
1849        hasEventListeners: function (name) {
1850          return getEventDispatcher(this).has(name);
1851        },
1852        parents: function (selector) {
1853          var self = this;
1854          var ctrl, parents = new Collection$2();
1855          for (ctrl = self.parent(); ctrl; ctrl = ctrl.parent()) {
1856            parents.add(ctrl);
1857          }
1858          if (selector) {
1859            parents = parents.filter(selector);
1860          }
1861          return parents;
1862        },
1863        parentsAndSelf: function (selector) {
1864          return new Collection$2(this).add(this.parents(selector));
1865        },
1866        next: function () {
1867          var parentControls = this.parent().items();
1868          return parentControls[parentControls.indexOf(this) + 1];
1869        },
1870        prev: function () {
1871          var parentControls = this.parent().items();
1872          return parentControls[parentControls.indexOf(this) - 1];
1873        },
1874        innerHtml: function (html) {
1875          this.$el.html(html);
1876          return this;
1877        },
1878        getEl: function (suffix) {
1879          var id = suffix ? this._id + '-' + suffix : this._id;
1880          if (!this._elmCache[id]) {
1881            this._elmCache[id] = global$7('#' + id)[0];
1882          }
1883          return this._elmCache[id];
1884        },
1885        show: function () {
1886          return this.visible(true);
1887        },
1888        hide: function () {
1889          return this.visible(false);
1890        },
1891        focus: function () {
1892          try {
1893            this.getEl().focus();
1894          } catch (ex) {
1895          }
1896          return this;
1897        },
1898        blur: function () {
1899          this.getEl().blur();
1900          return this;
1901        },
1902        aria: function (name, value) {
1903          var self = this, elm = self.getEl(self.ariaTarget);
1904          if (typeof value === 'undefined') {
1905            return self._aria[name];
1906          }
1907          self._aria[name] = value;
1908          if (self.state.get('rendered')) {
1909            elm.setAttribute(name === 'role' ? name : 'aria-' + name, value);
1910          }
1911          return self;
1912        },
1913        encode: function (text, translate) {
1914          if (translate !== false) {
1915            text = this.translate(text);
1916          }
1917          return (text || '').replace(/[&<>"]/g, function (match) {
1918            return '&#' + match.charCodeAt(0) + ';';
1919          });
1920        },
1921        translate: function (text) {
1922          return Control.translate ? Control.translate(text) : text;
1923        },
1924        before: function (items) {
1925          var self = this, parent = self.parent();
1926          if (parent) {
1927            parent.insert(items, parent.items().indexOf(self), true);
1928          }
1929          return self;
1930        },
1931        after: function (items) {
1932          var self = this, parent = self.parent();
1933          if (parent) {
1934            parent.insert(items, parent.items().indexOf(self));
1935          }
1936          return self;
1937        },
1938        remove: function () {
1939          var self = this;
1940          var elm = self.getEl();
1941          var parent = self.parent();
1942          var newItems, i;
1943          if (self.items) {
1944            var controls = self.items().toArray();
1945            i = controls.length;
1946            while (i--) {
1947              controls[i].remove();
1948            }
1949          }
1950          if (parent && parent.items) {
1951            newItems = [];
1952            parent.items().each(function (item) {
1953              if (item !== self) {
1954                newItems.push(item);
1955              }
1956            });
1957            parent.items().set(newItems);
1958            parent._lastRect = null;
1959          }
1960          if (self._eventsRoot && self._eventsRoot === self) {
1961            global$7(elm).off();
1962          }
1963          var lookup = self.getRoot().controlIdLookup;
1964          if (lookup) {
1965            delete lookup[self._id];
1966          }
1967          if (elm && elm.parentNode) {
1968            elm.parentNode.removeChild(elm);
1969          }
1970          self.state.set('rendered', false);
1971          self.state.destroy();
1972          self.fire('remove');
1973          return self;
1974        },
1975        renderBefore: function (elm) {
1976          global$7(elm).before(this.renderHtml());
1977          this.postRender();
1978          return this;
1979        },
1980        renderTo: function (elm) {
1981          global$7(elm || this.getContainerElm()).append(this.renderHtml());
1982          this.postRender();
1983          return this;
1984        },
1985        preRender: function () {
1986        },
1987        render: function () {
1988        },
1989        renderHtml: function () {
1990          return '<div id="' + this._id + '" class="' + this.classes + '"></div>';
1991        },
1992        postRender: function () {
1993          var self = this;
1994          var settings = self.settings;
1995          var elm, box, parent, name, parentEventsRoot;
1996          self.$el = global$7(self.getEl());
1997          self.state.set('rendered', true);
1998          for (name in settings) {
1999            if (name.indexOf('on') === 0) {
2000              self.on(name.substr(2), settings[name]);
2001            }
2002          }
2003          if (self._eventsRoot) {
2004            for (parent = self.parent(); !parentEventsRoot && parent; parent = parent.parent()) {
2005              parentEventsRoot = parent._eventsRoot;
2006            }
2007            if (parentEventsRoot) {
2008              for (name in parentEventsRoot._nativeEvents) {
2009                self._nativeEvents[name] = true;
2010              }
2011            }
2012          }
2013          bindPendingEvents(self);
2014          if (settings.style) {
2015            elm = self.getEl();
2016            if (elm) {
2017              elm.setAttribute('style', settings.style);
2018              elm.style.cssText = settings.style;
2019            }
2020          }
2021          if (self.settings.border) {
2022            box = self.borderBox;
2023            self.$el.css({
2024              'border-top-width': box.top,
2025              'border-right-width': box.right,
2026              'border-bottom-width': box.bottom,
2027              'border-left-width': box.left
2028            });
2029          }
2030          var root = self.getRoot();
2031          if (!root.controlIdLookup) {
2032            root.controlIdLookup = {};
2033          }
2034          root.controlIdLookup[self._id] = self;
2035          for (var key in self._aria) {
2036            self.aria(key, self._aria[key]);
2037          }
2038          if (self.state.get('visible') === false) {
2039            self.getEl().style.display = 'none';
2040          }
2041          self.bindStates();
2042          self.state.on('change:visible', function (e) {
2043            var state = e.value;
2044            var parentCtrl;
2045            if (self.state.get('rendered')) {
2046              self.getEl().style.display = state === false ? 'none' : '';
2047              self.getEl().getBoundingClientRect();
2048            }
2049            parentCtrl = self.parent();
2050            if (parentCtrl) {
2051              parentCtrl._lastRect = null;
2052            }
2053            self.fire(state ? 'show' : 'hide');
2054            ReflowQueue.add(self);
2055          });
2056          self.fire('postrender', {}, false);
2057        },
2058        bindStates: function () {
2059        },
2060        scrollIntoView: function (align) {
2061          function getOffset(elm, rootElm) {
2062            var x, y, parent = elm;
2063            x = y = 0;
2064            while (parent && parent !== rootElm && parent.nodeType) {
2065              x += parent.offsetLeft || 0;
2066              y += parent.offsetTop || 0;
2067              parent = parent.offsetParent;
2068            }
2069            return {
2070              x: x,
2071              y: y
2072            };
2073          }
2074          var elm = this.getEl(), parentElm = elm.parentNode;
2075          var x, y, width, height, parentWidth, parentHeight;
2076          var pos = getOffset(elm, parentElm);
2077          x = pos.x;
2078          y = pos.y;
2079          width = elm.offsetWidth;
2080          height = elm.offsetHeight;
2081          parentWidth = parentElm.clientWidth;
2082          parentHeight = parentElm.clientHeight;
2083          if (align === 'end') {
2084            x -= parentWidth - width;
2085            y -= parentHeight - height;
2086          } else if (align === 'center') {
2087            x -= parentWidth / 2 - width / 2;
2088            y -= parentHeight / 2 - height / 2;
2089          }
2090          parentElm.scrollLeft = x;
2091          parentElm.scrollTop = y;
2092          return this;
2093        },
2094        getRoot: function () {
2095          var ctrl = this, rootControl;
2096          var parents = [];
2097          while (ctrl) {
2098            if (ctrl.rootControl) {
2099              rootControl = ctrl.rootControl;
2100              break;
2101            }
2102            parents.push(ctrl);
2103            rootControl = ctrl;
2104            ctrl = ctrl.parent();
2105          }
2106          if (!rootControl) {
2107            rootControl = this;
2108          }
2109          var i = parents.length;
2110          while (i--) {
2111            parents[i].rootControl = rootControl;
2112          }
2113          return rootControl;
2114        },
2115        reflow: function () {
2116          ReflowQueue.remove(this);
2117          var parent = this.parent();
2118          if (parent && parent._layout && !parent._layout.isNative()) {
2119            parent.reflow();
2120          }
2121          return this;
2122        }
2123      };
2124      global$4.each('text title visible disabled active value'.split(' '), function (name) {
2125        proto$1[name] = function (value) {
2126          if (arguments.length === 0) {
2127            return this.state.get(name);
2128          }
2129          if (typeof value !== 'undefined') {
2130            this.state.set(name, value);
2131          }
2132          return this;
2133        };
2134      });
2135      Control = global$8.extend(proto$1);
2136      function getEventDispatcher(obj) {
2137        if (!obj._eventDispatcher) {
2138          obj._eventDispatcher = new global$9({
2139            scope: obj,
2140            toggleEvent: function (name, state) {
2141              if (state && global$9.isNative(name)) {
2142                if (!obj._nativeEvents) {
2143                  obj._nativeEvents = {};
2144                }
2145                obj._nativeEvents[name] = true;
2146                if (obj.state.get('rendered')) {
2147                  bindPendingEvents(obj);
2148                }
2149              }
2150            }
2151          });
2152        }
2153        return obj._eventDispatcher;
2154      }
2155      function bindPendingEvents(eventCtrl) {
2156        var i, l, parents, eventRootCtrl, nativeEvents, name;
2157        function delegate(e) {
2158          var control = eventCtrl.getParentCtrl(e.target);
2159          if (control) {
2160            control.fire(e.type, e);
2161          }
2162        }
2163        function mouseLeaveHandler() {
2164          var ctrl = eventRootCtrl._lastHoverCtrl;
2165          if (ctrl) {
2166            ctrl.fire('mouseleave', { target: ctrl.getEl() });
2167            ctrl.parents().each(function (ctrl) {
2168              ctrl.fire('mouseleave', { target: ctrl.getEl() });
2169            });
2170            eventRootCtrl._lastHoverCtrl = null;
2171          }
2172        }
2173        function mouseEnterHandler(e) {
2174          var ctrl = eventCtrl.getParentCtrl(e.target), lastCtrl = eventRootCtrl._lastHoverCtrl, idx = 0, i, parents, lastParents;
2175          if (ctrl !== lastCtrl) {
2176            eventRootCtrl._lastHoverCtrl = ctrl;
2177            parents = ctrl.parents().toArray().reverse();
2178            parents.push(ctrl);
2179            if (lastCtrl) {
2180              lastParents = lastCtrl.parents().toArray().reverse();
2181              lastParents.push(lastCtrl);
2182              for (idx = 0; idx < lastParents.length; idx++) {
2183                if (parents[idx] !== lastParents[idx]) {
2184                  break;
2185                }
2186              }
2187              for (i = lastParents.length - 1; i >= idx; i--) {
2188                lastCtrl = lastParents[i];
2189                lastCtrl.fire('mouseleave', { target: lastCtrl.getEl() });
2190              }
2191            }
2192            for (i = idx; i < parents.length; i++) {
2193              ctrl = parents[i];
2194              ctrl.fire('mouseenter', { target: ctrl.getEl() });
2195            }
2196          }
2197        }
2198        function fixWheelEvent(e) {
2199          e.preventDefault();
2200          if (e.type === 'mousewheel') {
2201            e.deltaY = -1 / 40 * e.wheelDelta;
2202            if (e.wheelDeltaX) {
2203              e.deltaX = -1 / 40 * e.wheelDeltaX;
2204            }
2205          } else {
2206            e.deltaX = 0;
2207            e.deltaY = e.detail;
2208          }
2209          e = eventCtrl.fire('wheel', e);
2210        }
2211        nativeEvents = eventCtrl._nativeEvents;
2212        if (nativeEvents) {
2213          parents = eventCtrl.parents().toArray();
2214          parents.unshift(eventCtrl);
2215          for (i = 0, l = parents.length; !eventRootCtrl && i < l; i++) {
2216            eventRootCtrl = parents[i]._eventsRoot;
2217          }
2218          if (!eventRootCtrl) {
2219            eventRootCtrl = parents[parents.length - 1] || eventCtrl;
2220          }
2221          eventCtrl._eventsRoot = eventRootCtrl;
2222          for (l = i, i = 0; i < l; i++) {
2223            parents[i]._eventsRoot = eventRootCtrl;
2224          }
2225          var eventRootDelegates = eventRootCtrl._delegates;
2226          if (!eventRootDelegates) {
2227            eventRootDelegates = eventRootCtrl._delegates = {};
2228          }
2229          for (name in nativeEvents) {
2230            if (!nativeEvents) {
2231              return false;
2232            }
2233            if (name === 'wheel' && !hasWheelEventSupport) {
2234              if (hasMouseWheelEventSupport) {
2235                global$7(eventCtrl.getEl()).on('mousewheel', fixWheelEvent);
2236              } else {
2237                global$7(eventCtrl.getEl()).on('DOMMouseScroll', fixWheelEvent);
2238              }
2239              continue;
2240            }
2241            if (name === 'mouseenter' || name === 'mouseleave') {
2242              if (!eventRootCtrl._hasMouseEnter) {
2243                global$7(eventRootCtrl.getEl()).on('mouseleave', mouseLeaveHandler).on('mouseover', mouseEnterHandler);
2244                eventRootCtrl._hasMouseEnter = 1;
2245              }
2246            } else if (!eventRootDelegates[name]) {
2247              global$7(eventRootCtrl.getEl()).on(name, delegate);
2248              eventRootDelegates[name] = true;
2249            }
2250            nativeEvents[name] = false;
2251          }
2252        }
2253      }
2254      var Control$1 = Control;
2255  
2256      var isStatic = function (elm) {
2257        return funcs.getRuntimeStyle(elm, 'position') === 'static';
2258      };
2259      var isFixed = function (ctrl) {
2260        return ctrl.state.get('fixed');
2261      };
2262      function calculateRelativePosition(ctrl, targetElm, rel) {
2263        var ctrlElm, pos, x, y, selfW, selfH, targetW, targetH, viewport, size;
2264        viewport = getWindowViewPort();
2265        pos = funcs.getPos(targetElm, UiContainer.getUiContainer(ctrl));
2266        x = pos.x;
2267        y = pos.y;
2268        if (isFixed(ctrl) && isStatic(domGlobals.document.body)) {
2269          x -= viewport.x;
2270          y -= viewport.y;
2271        }
2272        ctrlElm = ctrl.getEl();
2273        size = funcs.getSize(ctrlElm);
2274        selfW = size.width;
2275        selfH = size.height;
2276        size = funcs.getSize(targetElm);
2277        targetW = size.width;
2278        targetH = size.height;
2279        rel = (rel || '').split('');
2280        if (rel[0] === 'b') {
2281          y += targetH;
2282        }
2283        if (rel[1] === 'r') {
2284          x += targetW;
2285        }
2286        if (rel[0] === 'c') {
2287          y += Math.round(targetH / 2);
2288        }
2289        if (rel[1] === 'c') {
2290          x += Math.round(targetW / 2);
2291        }
2292        if (rel[3] === 'b') {
2293          y -= selfH;
2294        }
2295        if (rel[4] === 'r') {
2296          x -= selfW;
2297        }
2298        if (rel[3] === 'c') {
2299          y -= Math.round(selfH / 2);
2300        }
2301        if (rel[4] === 'c') {
2302          x -= Math.round(selfW / 2);
2303        }
2304        return {
2305          x: x,
2306          y: y,
2307          w: selfW,
2308          h: selfH
2309        };
2310      }
2311      var getUiContainerViewPort = function (customUiContainer) {
2312        return {
2313          x: 0,
2314          y: 0,
2315          w: customUiContainer.scrollWidth - 1,
2316          h: customUiContainer.scrollHeight - 1
2317        };
2318      };
2319      var getWindowViewPort = function () {
2320        var win = domGlobals.window;
2321        var x = Math.max(win.pageXOffset, domGlobals.document.body.scrollLeft, domGlobals.document.documentElement.scrollLeft);
2322        var y = Math.max(win.pageYOffset, domGlobals.document.body.scrollTop, domGlobals.document.documentElement.scrollTop);
2323        var w = win.innerWidth || domGlobals.document.documentElement.clientWidth;
2324        var h = win.innerHeight || domGlobals.document.documentElement.clientHeight;
2325        return {
2326          x: x,
2327          y: y,
2328          w: w,
2329          h: h
2330        };
2331      };
2332      var getViewPortRect = function (ctrl) {
2333        var customUiContainer = UiContainer.getUiContainer(ctrl);
2334        return customUiContainer && !isFixed(ctrl) ? getUiContainerViewPort(customUiContainer) : getWindowViewPort();
2335      };
2336      var Movable = {
2337        testMoveRel: function (elm, rels) {
2338          var viewPortRect = getViewPortRect(this);
2339          for (var i = 0; i < rels.length; i++) {
2340            var pos = calculateRelativePosition(this, elm, rels[i]);
2341            if (isFixed(this)) {
2342              if (pos.x > 0 && pos.x + pos.w < viewPortRect.w && pos.y > 0 && pos.y + pos.h < viewPortRect.h) {
2343                return rels[i];
2344              }
2345            } else {
2346              if (pos.x > viewPortRect.x && pos.x + pos.w < viewPortRect.w + viewPortRect.x && pos.y > viewPortRect.y && pos.y + pos.h < viewPortRect.h + viewPortRect.y) {
2347                return rels[i];
2348              }
2349            }
2350          }
2351          return rels[0];
2352        },
2353        moveRel: function (elm, rel) {
2354          if (typeof rel !== 'string') {
2355            rel = this.testMoveRel(elm, rel);
2356          }
2357          var pos = calculateRelativePosition(this, elm, rel);
2358          return this.moveTo(pos.x, pos.y);
2359        },
2360        moveBy: function (dx, dy) {
2361          var self = this, rect = self.layoutRect();
2362          self.moveTo(rect.x + dx, rect.y + dy);
2363          return self;
2364        },
2365        moveTo: function (x, y) {
2366          var self = this;
2367          function constrain(value, max, size) {
2368            if (value < 0) {
2369              return 0;
2370            }
2371            if (value + size > max) {
2372              value = max - size;
2373              return value < 0 ? 0 : value;
2374            }
2375            return value;
2376          }
2377          if (self.settings.constrainToViewport) {
2378            var viewPortRect = getViewPortRect(this);
2379            var layoutRect = self.layoutRect();
2380            x = constrain(x, viewPortRect.w + viewPortRect.x, layoutRect.w);
2381            y = constrain(y, viewPortRect.h + viewPortRect.y, layoutRect.h);
2382          }
2383          var uiContainer = UiContainer.getUiContainer(self);
2384          if (uiContainer && isStatic(uiContainer) && !isFixed(self)) {
2385            x -= uiContainer.scrollLeft;
2386            y -= uiContainer.scrollTop;
2387          }
2388          if (uiContainer) {
2389            x += 1;
2390            y += 1;
2391          }
2392          if (self.state.get('rendered')) {
2393            self.layoutRect({
2394              x: x,
2395              y: y
2396            }).repaint();
2397          } else {
2398            self.settings.x = x;
2399            self.settings.y = y;
2400          }
2401          self.fire('move', {
2402            x: x,
2403            y: y
2404          });
2405          return self;
2406        }
2407      };
2408  
2409      var Tooltip = Control$1.extend({
2410        Mixins: [Movable],
2411        Defaults: { classes: 'widget tooltip tooltip-n' },
2412        renderHtml: function () {
2413          var self = this, prefix = self.classPrefix;
2414          return '<div id="' + self._id + '" class="' + self.classes + '" role="presentation">' + '<div class="' + prefix + 'tooltip-arrow"></div>' + '<div class="' + prefix + 'tooltip-inner">' + self.encode(self.state.get('text')) + '</div>' + '</div>';
2415        },
2416        bindStates: function () {
2417          var self = this;
2418          self.state.on('change:text', function (e) {
2419            self.getEl().lastChild.innerHTML = self.encode(e.value);
2420          });
2421          return self._super();
2422        },
2423        repaint: function () {
2424          var self = this;
2425          var style, rect;
2426          style = self.getEl().style;
2427          rect = self._layoutRect;
2428          style.left = rect.x + 'px';
2429          style.top = rect.y + 'px';
2430          style.zIndex = 65535 + 65535;
2431        }
2432      });
2433  
2434      var Widget = Control$1.extend({
2435        init: function (settings) {
2436          var self = this;
2437          self._super(settings);
2438          settings = self.settings;
2439          self.canFocus = true;
2440          if (settings.tooltip && Widget.tooltips !== false) {
2441            self.on('mouseenter', function (e) {
2442              var tooltip = self.tooltip().moveTo(-65535);
2443              if (e.control === self) {
2444                var rel = tooltip.text(settings.tooltip).show().testMoveRel(self.getEl(), [
2445                  'bc-tc',
2446                  'bc-tl',
2447                  'bc-tr'
2448                ]);
2449                tooltip.classes.toggle('tooltip-n', rel === 'bc-tc');
2450                tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl');
2451                tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr');
2452                tooltip.moveRel(self.getEl(), rel);
2453              } else {
2454                tooltip.hide();
2455              }
2456            });
2457            self.on('mouseleave mousedown click', function () {
2458              self.tooltip().remove();
2459              self._tooltip = null;
2460            });
2461          }
2462          self.aria('label', settings.ariaLabel || settings.tooltip);
2463        },
2464        tooltip: function () {
2465          if (!this._tooltip) {
2466            this._tooltip = new Tooltip({ type: 'tooltip' });
2467            UiContainer.inheritUiContainer(this, this._tooltip);
2468            this._tooltip.renderTo();
2469          }
2470          return this._tooltip;
2471        },
2472        postRender: function () {
2473          var self = this, settings = self.settings;
2474          self._super();
2475          if (!self.parent() && (settings.width || settings.height)) {
2476            self.initLayoutRect();
2477            self.repaint();
2478          }
2479          if (settings.autofocus) {
2480            self.focus();
2481          }
2482        },
2483        bindStates: function () {
2484          var self = this;
2485          function disable(state) {
2486            self.aria('disabled', state);
2487            self.classes.toggle('disabled', state);
2488          }
2489          function active(state) {
2490            self.aria('pressed', state);
2491            self.classes.toggle('active', state);
2492          }
2493          self.state.on('change:disabled', function (e) {
2494            disable(e.value);
2495          });
2496          self.state.on('change:active', function (e) {
2497            active(e.value);
2498          });
2499          if (self.state.get('disabled')) {
2500            disable(true);
2501          }
2502          if (self.state.get('active')) {
2503            active(true);
2504          }
2505          return self._super();
2506        },
2507        remove: function () {
2508          this._super();
2509          if (this._tooltip) {
2510            this._tooltip.remove();
2511            this._tooltip = null;
2512          }
2513        }
2514      });
2515  
2516      var Progress = Widget.extend({
2517        Defaults: { value: 0 },
2518        init: function (settings) {
2519          var self = this;
2520          self._super(settings);
2521          self.classes.add('progress');
2522          if (!self.settings.filter) {
2523            self.settings.filter = function (value) {
2524              return Math.round(value);
2525            };
2526          }
2527        },
2528        renderHtml: function () {
2529          var self = this, id = self._id, prefix = this.classPrefix;
2530          return '<div id="' + id + '" class="' + self.classes + '">' + '<div class="' + prefix + 'bar-container">' + '<div class="' + prefix + 'bar"></div>' + '</div>' + '<div class="' + prefix + 'text">0%</div>' + '</div>';
2531        },
2532        postRender: function () {
2533          var self = this;
2534          self._super();
2535          self.value(self.settings.value);
2536          return self;
2537        },
2538        bindStates: function () {
2539          var self = this;
2540          function setValue(value) {
2541            value = self.settings.filter(value);
2542            self.getEl().lastChild.innerHTML = value + '%';
2543            self.getEl().firstChild.firstChild.style.width = value + '%';
2544          }
2545          self.state.on('change:value', function (e) {
2546            setValue(e.value);
2547          });
2548          setValue(self.state.get('value'));
2549          return self._super();
2550        }
2551      });
2552  
2553      var updateLiveRegion = function (ctx, text) {
2554        ctx.getEl().lastChild.textContent = text + (ctx.progressBar ? ' ' + ctx.progressBar.value() + '%' : '');
2555      };
2556      var Notification = Control$1.extend({
2557        Mixins: [Movable],
2558        Defaults: { classes: 'widget notification' },
2559        init: function (settings) {
2560          var self = this;
2561          self._super(settings);
2562          self.maxWidth = settings.maxWidth;
2563          if (settings.text) {
2564            self.text(settings.text);
2565          }
2566          if (settings.icon) {
2567            self.icon = settings.icon;
2568          }
2569          if (settings.color) {
2570            self.color = settings.color;
2571          }
2572          if (settings.type) {
2573            self.classes.add('notification-' + settings.type);
2574          }
2575          if (settings.timeout && (settings.timeout < 0 || settings.timeout > 0) && !settings.closeButton) {
2576            self.closeButton = false;
2577          } else {
2578            self.classes.add('has-close');
2579            self.closeButton = true;
2580          }
2581          if (settings.progressBar) {
2582            self.progressBar = new Progress();
2583          }
2584          self.on('click', function (e) {
2585            if (e.target.className.indexOf(self.classPrefix + 'close') !== -1) {
2586              self.close();
2587            }
2588          });
2589        },
2590        renderHtml: function () {
2591          var self = this;
2592          var prefix = self.classPrefix;
2593          var icon = '', closeButton = '', progressBar = '', notificationStyle = '';
2594          if (self.icon) {
2595            icon = '<i class="' + prefix + 'ico' + ' ' + prefix + 'i-' + self.icon + '"></i>';
2596          }
2597          notificationStyle = ' style="max-width: ' + self.maxWidth + 'px;' + (self.color ? 'background-color: ' + self.color + ';"' : '"');
2598          if (self.closeButton) {
2599            closeButton = '<button type="button" class="' + prefix + 'close" aria-hidden="true">\xD7</button>';
2600          }
2601          if (self.progressBar) {
2602            progressBar = self.progressBar.renderHtml();
2603          }
2604          return '<div id="' + self._id + '" class="' + self.classes + '"' + notificationStyle + ' role="presentation">' + icon + '<div class="' + prefix + 'notification-inner">' + self.state.get('text') + '</div>' + progressBar + closeButton + '<div style="clip: rect(1px, 1px, 1px, 1px);height: 1px;overflow: hidden;position: absolute;width: 1px;"' + ' aria-live="assertive" aria-relevant="additions" aria-atomic="true"></div>' + '</div>';
2605        },
2606        postRender: function () {
2607          var self = this;
2608          global$3.setTimeout(function () {
2609            self.$el.addClass(self.classPrefix + 'in');
2610            updateLiveRegion(self, self.state.get('text'));
2611          }, 100);
2612          return self._super();
2613        },
2614        bindStates: function () {
2615          var self = this;
2616          self.state.on('change:text', function (e) {
2617            self.getEl().firstChild.innerHTML = e.value;
2618            updateLiveRegion(self, e.value);
2619          });
2620          if (self.progressBar) {
2621            self.progressBar.bindStates();
2622            self.progressBar.state.on('change:value', function (e) {
2623              updateLiveRegion(self, self.state.get('text'));
2624            });
2625          }
2626          return self._super();
2627        },
2628        close: function () {
2629          var self = this;
2630          if (!self.fire('close').isDefaultPrevented()) {
2631            self.remove();
2632          }
2633          return self;
2634        },
2635        repaint: function () {
2636          var self = this;
2637          var style, rect;
2638          style = self.getEl().style;
2639          rect = self._layoutRect;
2640          style.left = rect.x + 'px';
2641          style.top = rect.y + 'px';
2642          style.zIndex = 65535 - 1;
2643        }
2644      });
2645  
2646      function NotificationManagerImpl (editor) {
2647        var getEditorContainer = function (editor) {
2648          return editor.inline ? editor.getElement() : editor.getContentAreaContainer();
2649        };
2650        var getContainerWidth = function () {
2651          var container = getEditorContainer(editor);
2652          return funcs.getSize(container).width;
2653        };
2654        var prePositionNotifications = function (notifications) {
2655          each(notifications, function (notification) {
2656            notification.moveTo(0, 0);
2657          });
2658        };
2659        var positionNotifications = function (notifications) {
2660          if (notifications.length > 0) {
2661            var firstItem = notifications.slice(0, 1)[0];
2662            var container = getEditorContainer(editor);
2663            firstItem.moveRel(container, 'tc-tc');
2664            each(notifications, function (notification, index) {
2665              if (index > 0) {
2666                notification.moveRel(notifications[index - 1].getEl(), 'bc-tc');
2667              }
2668            });
2669          }
2670        };
2671        var reposition = function (notifications) {
2672          prePositionNotifications(notifications);
2673          positionNotifications(notifications);
2674        };
2675        var open = function (args, closeCallback) {
2676          var extendedArgs = global$4.extend(args, { maxWidth: getContainerWidth() });
2677          var notif = new Notification(extendedArgs);
2678          notif.args = extendedArgs;
2679          if (extendedArgs.timeout > 0) {
2680            notif.timer = setTimeout(function () {
2681              notif.close();
2682              closeCallback();
2683            }, extendedArgs.timeout);
2684          }
2685          notif.on('close', function () {
2686            closeCallback();
2687          });
2688          notif.renderTo();
2689          return notif;
2690        };
2691        var close = function (notification) {
2692          notification.close();
2693        };
2694        var getArgs = function (notification) {
2695          return notification.args;
2696        };
2697        return {
2698          open: open,
2699          close: close,
2700          reposition: reposition,
2701          getArgs: getArgs
2702        };
2703      }
2704  
2705      function getDocumentSize(doc) {
2706        var documentElement, body, scrollWidth, clientWidth;
2707        var offsetWidth, scrollHeight, clientHeight, offsetHeight;
2708        var max = Math.max;
2709        documentElement = doc.documentElement;
2710        body = doc.body;
2711        scrollWidth = max(documentElement.scrollWidth, body.scrollWidth);
2712        clientWidth = max(documentElement.clientWidth, body.clientWidth);
2713        offsetWidth = max(documentElement.offsetWidth, body.offsetWidth);
2714        scrollHeight = max(documentElement.scrollHeight, body.scrollHeight);
2715        clientHeight = max(documentElement.clientHeight, body.clientHeight);
2716        offsetHeight = max(documentElement.offsetHeight, body.offsetHeight);
2717        return {
2718          width: scrollWidth < offsetWidth ? clientWidth : scrollWidth,
2719          height: scrollHeight < offsetHeight ? clientHeight : scrollHeight
2720        };
2721      }
2722      function updateWithTouchData(e) {
2723        var keys, i;
2724        if (e.changedTouches) {
2725          keys = 'screenX screenY pageX pageY clientX clientY'.split(' ');
2726          for (i = 0; i < keys.length; i++) {
2727            e[keys[i]] = e.changedTouches[0][keys[i]];
2728          }
2729        }
2730      }
2731      function DragHelper (id, settings) {
2732        var $eventOverlay;
2733        var doc = settings.document || domGlobals.document;
2734        var downButton;
2735        var start, stop, drag, startX, startY;
2736        settings = settings || {};
2737        var handleElement = doc.getElementById(settings.handle || id);
2738        start = function (e) {
2739          var docSize = getDocumentSize(doc);
2740          var handleElm, cursor;
2741          updateWithTouchData(e);
2742          e.preventDefault();
2743          downButton = e.button;
2744          handleElm = handleElement;
2745          startX = e.screenX;
2746          startY = e.screenY;
2747          if (domGlobals.window.getComputedStyle) {
2748            cursor = domGlobals.window.getComputedStyle(handleElm, null).getPropertyValue('cursor');
2749          } else {
2750            cursor = handleElm.runtimeStyle.cursor;
2751          }
2752          $eventOverlay = global$7('<div></div>').css({
2753            position: 'absolute',
2754            top: 0,
2755            left: 0,
2756            width: docSize.width,
2757            height: docSize.height,
2758            zIndex: 2147483647,
2759            opacity: 0.0001,
2760            cursor: cursor
2761          }).appendTo(doc.body);
2762          global$7(doc).on('mousemove touchmove', drag).on('mouseup touchend', stop);
2763          settings.start(e);
2764        };
2765        drag = function (e) {
2766          updateWithTouchData(e);
2767          if (e.button !== downButton) {
2768            return stop(e);
2769          }
2770          e.deltaX = e.screenX - startX;
2771          e.deltaY = e.screenY - startY;
2772          e.preventDefault();
2773          settings.drag(e);
2774        };
2775        stop = function (e) {
2776          updateWithTouchData(e);
2777          global$7(doc).off('mousemove touchmove', drag).off('mouseup touchend', stop);
2778          $eventOverlay.remove();
2779          if (settings.stop) {
2780            settings.stop(e);
2781          }
2782        };
2783        this.destroy = function () {
2784          global$7(handleElement).off();
2785        };
2786        global$7(handleElement).on('mousedown touchstart', start);
2787      }
2788  
2789      var global$b = tinymce.util.Tools.resolve('tinymce.ui.Factory');
2790  
2791      var hasTabstopData = function (elm) {
2792        return elm.getAttribute('data-mce-tabstop') ? true : false;
2793      };
2794      function KeyboardNavigation (settings) {
2795        var root = settings.root;
2796        var focusedElement, focusedControl;
2797        function isElement(node) {
2798          return node && node.nodeType === 1;
2799        }
2800        try {
2801          focusedElement = domGlobals.document.activeElement;
2802        } catch (ex) {
2803          focusedElement = domGlobals.document.body;
2804        }
2805        focusedControl = root.getParentCtrl(focusedElement);
2806        function getRole(elm) {
2807          elm = elm || focusedElement;
2808          if (isElement(elm)) {
2809            return elm.getAttribute('role');
2810          }
2811          return null;
2812        }
2813        function getParentRole(elm) {
2814          var role, parent = elm || focusedElement;
2815          while (parent = parent.parentNode) {
2816            if (role = getRole(parent)) {
2817              return role;
2818            }
2819          }
2820        }
2821        function getAriaProp(name) {
2822          var elm = focusedElement;
2823          if (isElement(elm)) {
2824            return elm.getAttribute('aria-' + name);
2825          }
2826        }
2827        function isTextInputElement(elm) {
2828          var tagName = elm.tagName.toUpperCase();
2829          return tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';
2830        }
2831        function canFocus(elm) {
2832          if (isTextInputElement(elm) && !elm.hidden) {
2833            return true;
2834          }
2835          if (hasTabstopData(elm)) {
2836            return true;
2837          }
2838          if (/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell|slider)$/.test(getRole(elm))) {
2839            return true;
2840          }
2841          return false;
2842        }
2843        function getFocusElements(elm) {
2844          var elements = [];
2845          function collect(elm) {
2846            if (elm.nodeType !== 1 || elm.style.display === 'none' || elm.disabled) {
2847              return;
2848            }
2849            if (canFocus(elm)) {
2850              elements.push(elm);
2851            }
2852            for (var i = 0; i < elm.childNodes.length; i++) {
2853              collect(elm.childNodes[i]);
2854            }
2855          }
2856          collect(elm || root.getEl());
2857          return elements;
2858        }
2859        function getNavigationRoot(targetControl) {
2860          var navigationRoot, controls;
2861          targetControl = targetControl || focusedControl;
2862          controls = targetControl.parents().toArray();
2863          controls.unshift(targetControl);
2864          for (var i = 0; i < controls.length; i++) {
2865            navigationRoot = controls[i];
2866            if (navigationRoot.settings.ariaRoot) {
2867              break;
2868            }
2869          }
2870          return navigationRoot;
2871        }
2872        function focusFirst(targetControl) {
2873          var navigationRoot = getNavigationRoot(targetControl);
2874          var focusElements = getFocusElements(navigationRoot.getEl());
2875          if (navigationRoot.settings.ariaRemember && 'lastAriaIndex' in navigationRoot) {
2876            moveFocusToIndex(navigationRoot.lastAriaIndex, focusElements);
2877          } else {
2878            moveFocusToIndex(0, focusElements);
2879          }
2880        }
2881        function moveFocusToIndex(idx, elements) {
2882          if (idx < 0) {
2883            idx = elements.length - 1;
2884          } else if (idx >= elements.length) {
2885            idx = 0;
2886          }
2887          if (elements[idx]) {
2888            elements[idx].focus();
2889          }
2890          return idx;
2891        }
2892        function moveFocus(dir, elements) {
2893          var idx = -1;
2894          var navigationRoot = getNavigationRoot();
2895          elements = elements || getFocusElements(navigationRoot.getEl());
2896          for (var i = 0; i < elements.length; i++) {
2897            if (elements[i] === focusedElement) {
2898              idx = i;
2899            }
2900          }
2901          idx += dir;
2902          navigationRoot.lastAriaIndex = moveFocusToIndex(idx, elements);
2903        }
2904        function left() {
2905          var parentRole = getParentRole();
2906          if (parentRole === 'tablist') {
2907            moveFocus(-1, getFocusElements(focusedElement.parentNode));
2908          } else if (focusedControl.parent().submenu) {
2909            cancel();
2910          } else {
2911            moveFocus(-1);
2912          }
2913        }
2914        function right() {
2915          var role = getRole(), parentRole = getParentRole();
2916          if (parentRole === 'tablist') {
2917            moveFocus(1, getFocusElements(focusedElement.parentNode));
2918          } else if (role === 'menuitem' && parentRole === 'menu' && getAriaProp('haspopup')) {
2919            enter();
2920          } else {
2921            moveFocus(1);
2922          }
2923        }
2924        function up() {
2925          moveFocus(-1);
2926        }
2927        function down() {
2928          var role = getRole(), parentRole = getParentRole();
2929          if (role === 'menuitem' && parentRole === 'menubar') {
2930            enter();
2931          } else if (role === 'button' && getAriaProp('haspopup')) {
2932            enter({ key: 'down' });
2933          } else {
2934            moveFocus(1);
2935          }
2936        }
2937        function tab(e) {
2938          var parentRole = getParentRole();
2939          if (parentRole === 'tablist') {
2940            var elm = getFocusElements(focusedControl.getEl('body'))[0];
2941            if (elm) {
2942              elm.focus();
2943            }
2944          } else {
2945            moveFocus(e.shiftKey ? -1 : 1);
2946          }
2947        }
2948        function cancel() {
2949          focusedControl.fire('cancel');
2950        }
2951        function enter(aria) {
2952          aria = aria || {};
2953          focusedControl.fire('click', {
2954            target: focusedElement,
2955            aria: aria
2956          });
2957        }
2958        root.on('keydown', function (e) {
2959          function handleNonTabOrEscEvent(e, handler) {
2960            if (isTextInputElement(focusedElement) || hasTabstopData(focusedElement)) {
2961              return;
2962            }
2963            if (getRole(focusedElement) === 'slider') {
2964              return;
2965            }
2966            if (handler(e) !== false) {
2967              e.preventDefault();
2968            }
2969          }
2970          if (e.isDefaultPrevented()) {
2971            return;
2972          }
2973          switch (e.keyCode) {
2974          case 37:
2975            handleNonTabOrEscEvent(e, left);
2976            break;
2977          case 39:
2978            handleNonTabOrEscEvent(e, right);
2979            break;
2980          case 38:
2981            handleNonTabOrEscEvent(e, up);
2982            break;
2983          case 40:
2984            handleNonTabOrEscEvent(e, down);
2985            break;
2986          case 27:
2987            cancel();
2988            break;
2989          case 14:
2990          case 13:
2991          case 32:
2992            handleNonTabOrEscEvent(e, enter);
2993            break;
2994          case 9:
2995            tab(e);
2996            e.preventDefault();
2997            break;
2998          }
2999        });
3000        root.on('focusin', function (e) {
3001          focusedElement = e.target;
3002          focusedControl = e.control;
3003        });
3004        return { focusFirst: focusFirst };
3005      }
3006  
3007      var selectorCache = {};
3008      var Container = Control$1.extend({
3009        init: function (settings) {
3010          var self = this;
3011          self._super(settings);
3012          settings = self.settings;
3013          if (settings.fixed) {
3014            self.state.set('fixed', true);
3015          }
3016          self._items = new Collection$2();
3017          if (self.isRtl()) {
3018            self.classes.add('rtl');
3019          }
3020          self.bodyClasses = new ClassList(function () {
3021            if (self.state.get('rendered')) {
3022              self.getEl('body').className = this.toString();
3023            }
3024          });
3025          self.bodyClasses.prefix = self.classPrefix;
3026          self.classes.add('container');
3027          self.bodyClasses.add('container-body');
3028          if (settings.containerCls) {
3029            self.classes.add(settings.containerCls);
3030          }
3031          self._layout = global$b.create((settings.layout || '') + 'layout');
3032          if (self.settings.items) {
3033            self.add(self.settings.items);
3034          } else {
3035            self.add(self.render());
3036          }
3037          self._hasBody = true;
3038        },
3039        items: function () {
3040          return this._items;
3041        },
3042        find: function (selector) {
3043          selector = selectorCache[selector] = selectorCache[selector] || new Selector(selector);
3044          return selector.find(this);
3045        },
3046        add: function (items) {
3047          var self = this;
3048          self.items().add(self.create(items)).parent(self);
3049          return self;
3050        },
3051        focus: function (keyboard) {
3052          var self = this;
3053          var focusCtrl, keyboardNav, items;
3054          if (keyboard) {
3055            keyboardNav = self.keyboardNav || self.parents().eq(-1)[0].keyboardNav;
3056            if (keyboardNav) {
3057              keyboardNav.focusFirst(self);
3058              return;
3059            }
3060          }
3061          items = self.find('*');
3062          if (self.statusbar) {
3063            items.add(self.statusbar.items());
3064          }
3065          items.each(function (ctrl) {
3066            if (ctrl.settings.autofocus) {
3067              focusCtrl = null;
3068              return false;
3069            }
3070            if (ctrl.canFocus) {
3071              focusCtrl = focusCtrl || ctrl;
3072            }
3073          });
3074          if (focusCtrl) {
3075            focusCtrl.focus();
3076          }
3077          return self;
3078        },
3079        replace: function (oldItem, newItem) {
3080          var ctrlElm;
3081          var items = this.items();
3082          var i = items.length;
3083          while (i--) {
3084            if (items[i] === oldItem) {
3085              items[i] = newItem;
3086              break;
3087            }
3088          }
3089          if (i >= 0) {
3090            ctrlElm = newItem.getEl();
3091            if (ctrlElm) {
3092              ctrlElm.parentNode.removeChild(ctrlElm);
3093            }
3094            ctrlElm = oldItem.getEl();
3095            if (ctrlElm) {
3096              ctrlElm.parentNode.removeChild(ctrlElm);
3097            }
3098          }
3099          newItem.parent(this);
3100        },
3101        create: function (items) {
3102          var self = this;
3103          var settings;
3104          var ctrlItems = [];
3105          if (!global$4.isArray(items)) {
3106            items = [items];
3107          }
3108          global$4.each(items, function (item) {
3109            if (item) {
3110              if (!(item instanceof Control$1)) {
3111                if (typeof item === 'string') {
3112                  item = { type: item };
3113                }
3114                settings = global$4.extend({}, self.settings.defaults, item);
3115                item.type = settings.type = settings.type || item.type || self.settings.defaultType || (settings.defaults ? settings.defaults.type : null);
3116                item = global$b.create(settings);
3117              }
3118              ctrlItems.push(item);
3119            }
3120          });
3121          return ctrlItems;
3122        },
3123        renderNew: function () {
3124          var self = this;
3125          self.items().each(function (ctrl, index) {
3126            var containerElm;
3127            ctrl.parent(self);
3128            if (!ctrl.state.get('rendered')) {
3129              containerElm = self.getEl('body');
3130              if (containerElm.hasChildNodes() && index <= containerElm.childNodes.length - 1) {
3131                global$7(containerElm.childNodes[index]).before(ctrl.renderHtml());
3132              } else {
3133                global$7(containerElm).append(ctrl.renderHtml());
3134              }
3135              ctrl.postRender();
3136              ReflowQueue.add(ctrl);
3137            }
3138          });
3139          self._layout.applyClasses(self.items().filter(':visible'));
3140          self._lastRect = null;
3141          return self;
3142        },
3143        append: function (items) {
3144          return this.add(items).renderNew();
3145        },
3146        prepend: function (items) {
3147          var self = this;
3148          self.items().set(self.create(items).concat(self.items().toArray()));
3149          return self.renderNew();
3150        },
3151        insert: function (items, index, before) {
3152          var self = this;
3153          var curItems, beforeItems, afterItems;
3154          items = self.create(items);
3155          curItems = self.items();
3156          if (!before && index < curItems.length - 1) {
3157            index += 1;
3158          }
3159          if (index >= 0 && index < curItems.length) {
3160            beforeItems = curItems.slice(0, index).toArray();
3161            afterItems = curItems.slice(index).toArray();
3162            curItems.set(beforeItems.concat(items, afterItems));
3163          }
3164          return self.renderNew();
3165        },
3166        fromJSON: function (data) {
3167          var self = this;
3168          for (var name in data) {
3169            self.find('#' + name).value(data[name]);
3170          }
3171          return self;
3172        },
3173        toJSON: function () {
3174          var self = this, data = {};
3175          self.find('*').each(function (ctrl) {
3176            var name = ctrl.name(), value = ctrl.value();
3177            if (name && typeof value !== 'undefined') {
3178              data[name] = value;
3179            }
3180          });
3181          return data;
3182        },
3183        renderHtml: function () {
3184          var self = this, layout = self._layout, role = this.settings.role;
3185          self.preRender();
3186          layout.preRender(self);
3187          return '<div id="' + self._id + '" class="' + self.classes + '"' + (role ? ' role="' + this.settings.role + '"' : '') + '>' + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>';
3188        },
3189        postRender: function () {
3190          var self = this;
3191          var box;
3192          self.items().exec('postRender');
3193          self._super();
3194          self._layout.postRender(self);
3195          self.state.set('rendered', true);
3196          if (self.settings.style) {
3197            self.$el.css(self.settings.style);
3198          }
3199          if (self.settings.border) {
3200            box = self.borderBox;
3201            self.$el.css({
3202              'border-top-width': box.top,
3203              'border-right-width': box.right,
3204              'border-bottom-width': box.bottom,
3205              'border-left-width': box.left
3206            });
3207          }
3208          if (!self.parent()) {
3209            self.keyboardNav = KeyboardNavigation({ root: self });
3210          }
3211          return self;
3212        },
3213        initLayoutRect: function () {
3214          var self = this, layoutRect = self._super();
3215          self._layout.recalc(self);
3216          return layoutRect;
3217        },
3218        recalc: function () {
3219          var self = this;
3220          var rect = self._layoutRect;
3221          var lastRect = self._lastRect;
3222          if (!lastRect || lastRect.w !== rect.w || lastRect.h !== rect.h) {
3223            self._layout.recalc(self);
3224            rect = self.layoutRect();
3225            self._lastRect = {
3226              x: rect.x,
3227              y: rect.y,
3228              w: rect.w,
3229              h: rect.h
3230            };
3231            return true;
3232          }
3233        },
3234        reflow: function () {
3235          var i;
3236          ReflowQueue.remove(this);
3237          if (this.visible()) {
3238            Control$1.repaintControls = [];
3239            Control$1.repaintControls.map = {};
3240            this.recalc();
3241            i = Control$1.repaintControls.length;
3242            while (i--) {
3243              Control$1.repaintControls[i].repaint();
3244            }
3245            if (this.settings.layout !== 'flow' && this.settings.layout !== 'stack') {
3246              this.repaint();
3247            }
3248            Control$1.repaintControls = [];
3249          }
3250          return this;
3251        }
3252      });
3253  
3254      var Scrollable = {
3255        init: function () {
3256          var self = this;
3257          self.on('repaint', self.renderScroll);
3258        },
3259        renderScroll: function () {
3260          var self = this, margin = 2;
3261          function repaintScroll() {
3262            var hasScrollH, hasScrollV, bodyElm;
3263            function repaintAxis(axisName, posName, sizeName, contentSizeName, hasScroll, ax) {
3264              var containerElm, scrollBarElm, scrollThumbElm;
3265              var containerSize, scrollSize, ratio, rect;
3266              var posNameLower, sizeNameLower;
3267              scrollBarElm = self.getEl('scroll' + axisName);
3268              if (scrollBarElm) {
3269                posNameLower = posName.toLowerCase();
3270                sizeNameLower = sizeName.toLowerCase();
3271                global$7(self.getEl('absend')).css(posNameLower, self.layoutRect()[contentSizeName] - 1);
3272                if (!hasScroll) {
3273                  global$7(scrollBarElm).css('display', 'none');
3274                  return;
3275                }
3276                global$7(scrollBarElm).css('display', 'block');
3277                containerElm = self.getEl('body');
3278                scrollThumbElm = self.getEl('scroll' + axisName + 't');
3279                containerSize = containerElm['client' + sizeName] - margin * 2;
3280                containerSize -= hasScrollH && hasScrollV ? scrollBarElm['client' + ax] : 0;
3281                scrollSize = containerElm['scroll' + sizeName];
3282                ratio = containerSize / scrollSize;
3283                rect = {};
3284                rect[posNameLower] = containerElm['offset' + posName] + margin;
3285                rect[sizeNameLower] = containerSize;
3286                global$7(scrollBarElm).css(rect);
3287                rect = {};
3288                rect[posNameLower] = containerElm['scroll' + posName] * ratio;
3289                rect[sizeNameLower] = containerSize * ratio;
3290                global$7(scrollThumbElm).css(rect);
3291              }
3292            }
3293            bodyElm = self.getEl('body');
3294            hasScrollH = bodyElm.scrollWidth > bodyElm.clientWidth;
3295            hasScrollV = bodyElm.scrollHeight > bodyElm.clientHeight;
3296            repaintAxis('h', 'Left', 'Width', 'contentW', hasScrollH, 'Height');
3297            repaintAxis('v', 'Top', 'Height', 'contentH', hasScrollV, 'Width');
3298          }
3299          function addScroll() {
3300            function addScrollAxis(axisName, posName, sizeName, deltaPosName, ax) {
3301              var scrollStart;
3302              var axisId = self._id + '-scroll' + axisName, prefix = self.classPrefix;
3303              global$7(self.getEl()).append('<div id="' + axisId + '" class="' + prefix + 'scrollbar ' + prefix + 'scrollbar-' + axisName + '">' + '<div id="' + axisId + 't" class="' + prefix + 'scrollbar-thumb"></div>' + '</div>');
3304              self.draghelper = new DragHelper(axisId + 't', {
3305                start: function () {
3306                  scrollStart = self.getEl('body')['scroll' + posName];
3307                  global$7('#' + axisId).addClass(prefix + 'active');
3308                },
3309                drag: function (e) {
3310                  var ratio, hasScrollH, hasScrollV, containerSize;
3311                  var layoutRect = self.layoutRect();
3312                  hasScrollH = layoutRect.contentW > layoutRect.innerW;
3313                  hasScrollV = layoutRect.contentH > layoutRect.innerH;
3314                  containerSize = self.getEl('body')['client' + sizeName] - margin * 2;
3315                  containerSize -= hasScrollH && hasScrollV ? self.getEl('scroll' + axisName)['client' + ax] : 0;
3316                  ratio = containerSize / self.getEl('body')['scroll' + sizeName];
3317                  self.getEl('body')['scroll' + posName] = scrollStart + e['delta' + deltaPosName] / ratio;
3318                },
3319                stop: function () {
3320                  global$7('#' + axisId).removeClass(prefix + 'active');
3321                }
3322              });
3323            }
3324            self.classes.add('scroll');
3325            addScrollAxis('v', 'Top', 'Height', 'Y', 'Width');
3326            addScrollAxis('h', 'Left', 'Width', 'X', 'Height');
3327          }
3328          if (self.settings.autoScroll) {
3329            if (!self._hasScroll) {
3330              self._hasScroll = true;
3331              addScroll();
3332              self.on('wheel', function (e) {
3333                var bodyEl = self.getEl('body');
3334                bodyEl.scrollLeft += (e.deltaX || 0) * 10;
3335                bodyEl.scrollTop += e.deltaY * 10;
3336                repaintScroll();
3337              });
3338              global$7(self.getEl('body')).on('scroll', repaintScroll);
3339            }
3340            repaintScroll();
3341          }
3342        }
3343      };
3344  
3345      var Panel = Container.extend({
3346        Defaults: {
3347          layout: 'fit',
3348          containerCls: 'panel'
3349        },
3350        Mixins: [Scrollable],
3351        renderHtml: function () {
3352          var self = this;
3353          var layout = self._layout;
3354          var innerHtml = self.settings.html;
3355          self.preRender();
3356          layout.preRender(self);
3357          if (typeof innerHtml === 'undefined') {
3358            innerHtml = '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + layout.renderHtml(self) + '</div>';
3359          } else {
3360            if (typeof innerHtml === 'function') {
3361              innerHtml = innerHtml.call(self);
3362            }
3363            self._hasBody = false;
3364          }
3365          return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1" role="group">' + (self._preBodyHtml || '') + innerHtml + '</div>';
3366        }
3367      });
3368  
3369      var Resizable = {
3370        resizeToContent: function () {
3371          this._layoutRect.autoResize = true;
3372          this._lastRect = null;
3373          this.reflow();
3374        },
3375        resizeTo: function (w, h) {
3376          if (w <= 1 || h <= 1) {
3377            var rect = funcs.getWindowSize();
3378            w = w <= 1 ? w * rect.w : w;
3379            h = h <= 1 ? h * rect.h : h;
3380          }
3381          this._layoutRect.autoResize = false;
3382          return this.layoutRect({
3383            minW: w,
3384            minH: h,
3385            w: w,
3386            h: h
3387          }).reflow();
3388        },
3389        resizeBy: function (dw, dh) {
3390          var self = this, rect = self.layoutRect();
3391          return self.resizeTo(rect.w + dw, rect.h + dh);
3392        }
3393      };
3394  
3395      var documentClickHandler, documentScrollHandler, windowResizeHandler;
3396      var visiblePanels = [];
3397      var zOrder = [];
3398      var hasModal;
3399      function isChildOf(ctrl, parent) {
3400        while (ctrl) {
3401          if (ctrl === parent) {
3402            return true;
3403          }
3404          ctrl = ctrl.parent();
3405        }
3406      }
3407      function skipOrHidePanels(e) {
3408        var i = visiblePanels.length;
3409        while (i--) {
3410          var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target);
3411          if (panel.settings.autohide) {
3412            if (clickCtrl) {
3413              if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) {
3414                continue;
3415              }
3416            }
3417            e = panel.fire('autohide', { target: e.target });
3418            if (!e.isDefaultPrevented()) {
3419              panel.hide();
3420            }
3421          }
3422        }
3423      }
3424      function bindDocumentClickHandler() {
3425        if (!documentClickHandler) {
3426          documentClickHandler = function (e) {
3427            if (e.button === 2) {
3428              return;
3429            }
3430            skipOrHidePanels(e);
3431          };
3432          global$7(domGlobals.document).on('click touchstart', documentClickHandler);
3433        }
3434      }
3435      function bindDocumentScrollHandler() {
3436        if (!documentScrollHandler) {
3437          documentScrollHandler = function () {
3438            var i;
3439            i = visiblePanels.length;
3440            while (i--) {
3441              repositionPanel$1(visiblePanels[i]);
3442            }
3443          };
3444          global$7(domGlobals.window).on('scroll', documentScrollHandler);
3445        }
3446      }
3447      function bindWindowResizeHandler() {
3448        if (!windowResizeHandler) {
3449          var docElm_1 = domGlobals.document.documentElement;
3450          var clientWidth_1 = docElm_1.clientWidth, clientHeight_1 = docElm_1.clientHeight;
3451          windowResizeHandler = function () {
3452            if (!domGlobals.document.all || clientWidth_1 !== docElm_1.clientWidth || clientHeight_1 !== docElm_1.clientHeight) {
3453              clientWidth_1 = docElm_1.clientWidth;
3454              clientHeight_1 = docElm_1.clientHeight;
3455              FloatPanel.hideAll();
3456            }
3457          };
3458          global$7(domGlobals.window).on('resize', windowResizeHandler);
3459        }
3460      }
3461      function repositionPanel$1(panel) {
3462        var scrollY = funcs.getViewPort().y;
3463        function toggleFixedChildPanels(fixed, deltaY) {
3464          var parent;
3465          for (var i = 0; i < visiblePanels.length; i++) {
3466            if (visiblePanels[i] !== panel) {
3467              parent = visiblePanels[i].parent();
3468              while (parent && (parent = parent.parent())) {
3469                if (parent === panel) {
3470                  visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint();
3471                }
3472              }
3473            }
3474          }
3475        }
3476        if (panel.settings.autofix) {
3477          if (!panel.state.get('fixed')) {
3478            panel._autoFixY = panel.layoutRect().y;
3479            if (panel._autoFixY < scrollY) {
3480              panel.fixed(true).layoutRect({ y: 0 }).repaint();
3481              toggleFixedChildPanels(true, scrollY - panel._autoFixY);
3482            }
3483          } else {
3484            if (panel._autoFixY > scrollY) {
3485              panel.fixed(false).layoutRect({ y: panel._autoFixY }).repaint();
3486              toggleFixedChildPanels(false, panel._autoFixY - scrollY);
3487            }
3488          }
3489        }
3490      }
3491      function addRemove(add, ctrl) {
3492        var i, zIndex = FloatPanel.zIndex || 65535, topModal;
3493        if (add) {
3494          zOrder.push(ctrl);
3495        } else {
3496          i = zOrder.length;
3497          while (i--) {
3498            if (zOrder[i] === ctrl) {
3499              zOrder.splice(i, 1);
3500            }
3501          }
3502        }
3503        if (zOrder.length) {
3504          for (i = 0; i < zOrder.length; i++) {
3505            if (zOrder[i].modal) {
3506              zIndex++;
3507              topModal = zOrder[i];
3508            }
3509            zOrder[i].getEl().style.zIndex = zIndex;
3510            zOrder[i].zIndex = zIndex;
3511            zIndex++;
3512          }
3513        }
3514        var modalBlockEl = global$7('#' + ctrl.classPrefix + 'modal-block', ctrl.getContainerElm())[0];
3515        if (topModal) {
3516          global$7(modalBlockEl).css('z-index', topModal.zIndex - 1);
3517        } else if (modalBlockEl) {
3518          modalBlockEl.parentNode.removeChild(modalBlockEl);
3519          hasModal = false;
3520        }
3521        FloatPanel.currentZIndex = zIndex;
3522      }
3523      var FloatPanel = Panel.extend({
3524        Mixins: [
3525          Movable,
3526          Resizable
3527        ],
3528        init: function (settings) {
3529          var self = this;
3530          self._super(settings);
3531          self._eventsRoot = self;
3532          self.classes.add('floatpanel');
3533          if (settings.autohide) {
3534            bindDocumentClickHandler();
3535            bindWindowResizeHandler();
3536            visiblePanels.push(self);
3537          }
3538          if (settings.autofix) {
3539            bindDocumentScrollHandler();
3540            self.on('move', function () {
3541              repositionPanel$1(this);
3542            });
3543          }
3544          self.on('postrender show', function (e) {
3545            if (e.control === self) {
3546              var $modalBlockEl_1;
3547              var prefix_1 = self.classPrefix;
3548              if (self.modal && !hasModal) {
3549                $modalBlockEl_1 = global$7('#' + prefix_1 + 'modal-block', self.getContainerElm());
3550                if (!$modalBlockEl_1[0]) {
3551                  $modalBlockEl_1 = global$7('<div id="' + prefix_1 + 'modal-block" class="' + prefix_1 + 'reset ' + prefix_1 + 'fade"></div>').appendTo(self.getContainerElm());
3552                }
3553                global$3.setTimeout(function () {
3554                  $modalBlockEl_1.addClass(prefix_1 + 'in');
3555                  global$7(self.getEl()).addClass(prefix_1 + 'in');
3556                });
3557                hasModal = true;
3558              }
3559              addRemove(true, self);
3560            }
3561          });
3562          self.on('show', function () {
3563            self.parents().each(function (ctrl) {
3564              if (ctrl.state.get('fixed')) {
3565                self.fixed(true);
3566                return false;
3567              }
3568            });
3569          });
3570          if (settings.popover) {
3571            self._preBodyHtml = '<div class="' + self.classPrefix + 'arrow"></div>';
3572            self.classes.add('popover').add('bottom').add(self.isRtl() ? 'end' : 'start');
3573          }
3574          self.aria('label', settings.ariaLabel);
3575          self.aria('labelledby', self._id);
3576          self.aria('describedby', self.describedBy || self._id + '-none');
3577        },
3578        fixed: function (state) {
3579          var self = this;
3580          if (self.state.get('fixed') !== state) {
3581            if (self.state.get('rendered')) {
3582              var viewport = funcs.getViewPort();
3583              if (state) {
3584                self.layoutRect().y -= viewport.y;
3585              } else {
3586                self.layoutRect().y += viewport.y;
3587              }
3588            }
3589            self.classes.toggle('fixed', state);
3590            self.state.set('fixed', state);
3591          }
3592          return self;
3593        },
3594        show: function () {
3595          var self = this;
3596          var i;
3597          var state = self._super();
3598          i = visiblePanels.length;
3599          while (i--) {
3600            if (visiblePanels[i] === self) {
3601              break;
3602            }
3603          }
3604          if (i === -1) {
3605            visiblePanels.push(self);
3606          }
3607          return state;
3608        },
3609        hide: function () {
3610          removeVisiblePanel(this);
3611          addRemove(false, this);
3612          return this._super();
3613        },
3614        hideAll: function () {
3615          FloatPanel.hideAll();
3616        },
3617        close: function () {
3618          var self = this;
3619          if (!self.fire('close').isDefaultPrevented()) {
3620            self.remove();
3621            addRemove(false, self);
3622          }
3623          return self;
3624        },
3625        remove: function () {
3626          removeVisiblePanel(this);
3627          this._super();
3628        },
3629        postRender: function () {
3630          var self = this;
3631          if (self.settings.bodyRole) {
3632            this.getEl('body').setAttribute('role', self.settings.bodyRole);
3633          }
3634          return self._super();
3635        }
3636      });
3637      FloatPanel.hideAll = function () {
3638        var i = visiblePanels.length;
3639        while (i--) {
3640          var panel = visiblePanels[i];
3641          if (panel && panel.settings.autohide) {
3642            panel.hide();
3643            visiblePanels.splice(i, 1);
3644          }
3645        }
3646      };
3647      function removeVisiblePanel(panel) {
3648        var i;
3649        i = visiblePanels.length;
3650        while (i--) {
3651          if (visiblePanels[i] === panel) {
3652            visiblePanels.splice(i, 1);
3653          }
3654        }
3655        i = zOrder.length;
3656        while (i--) {
3657          if (zOrder[i] === panel) {
3658            zOrder.splice(i, 1);
3659          }
3660        }
3661      }
3662  
3663      var windows = [];
3664      var oldMetaValue = '';
3665      function toggleFullScreenState(state) {
3666        var noScaleMetaValue = 'width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0';
3667        var viewport = global$7('meta[name=viewport]')[0], contentValue;
3668        if (global$1.overrideViewPort === false) {
3669          return;
3670        }
3671        if (!viewport) {
3672          viewport = domGlobals.document.createElement('meta');
3673          viewport.setAttribute('name', 'viewport');
3674          domGlobals.document.getElementsByTagName('head')[0].appendChild(viewport);
3675        }
3676        contentValue = viewport.getAttribute('content');
3677        if (contentValue && typeof oldMetaValue !== 'undefined') {
3678          oldMetaValue = contentValue;
3679        }
3680        viewport.setAttribute('content', state ? noScaleMetaValue : oldMetaValue);
3681      }
3682      function toggleBodyFullScreenClasses(classPrefix, state) {
3683        if (checkFullscreenWindows() && state === false) {
3684          global$7([
3685            domGlobals.document.documentElement,
3686            domGlobals.document.body
3687          ]).removeClass(classPrefix + 'fullscreen');
3688        }
3689      }
3690      function checkFullscreenWindows() {
3691        for (var i = 0; i < windows.length; i++) {
3692          if (windows[i]._fullscreen) {
3693            return true;
3694          }
3695        }
3696        return false;
3697      }
3698      function handleWindowResize() {
3699        if (!global$1.desktop) {
3700          var lastSize_1 = {
3701            w: domGlobals.window.innerWidth,
3702            h: domGlobals.window.innerHeight
3703          };
3704          global$3.setInterval(function () {
3705            var w = domGlobals.window.innerWidth, h = domGlobals.window.innerHeight;
3706            if (lastSize_1.w !== w || lastSize_1.h !== h) {
3707              lastSize_1 = {
3708                w: w,
3709                h: h
3710              };
3711              global$7(domGlobals.window).trigger('resize');
3712            }
3713          }, 100);
3714        }
3715        function reposition() {
3716          var i;
3717          var rect = funcs.getWindowSize();
3718          var layoutRect;
3719          for (i = 0; i < windows.length; i++) {
3720            layoutRect = windows[i].layoutRect();
3721            windows[i].moveTo(windows[i].settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2), windows[i].settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2));
3722          }
3723        }
3724        global$7(domGlobals.window).on('resize', reposition);
3725      }
3726      var Window = FloatPanel.extend({
3727        modal: true,
3728        Defaults: {
3729          border: 1,
3730          layout: 'flex',
3731          containerCls: 'panel',
3732          role: 'dialog',
3733          callbacks: {
3734            submit: function () {
3735              this.fire('submit', { data: this.toJSON() });
3736            },
3737            close: function () {
3738              this.close();
3739            }
3740          }
3741        },
3742        init: function (settings) {
3743          var self = this;
3744          self._super(settings);
3745          if (self.isRtl()) {
3746            self.classes.add('rtl');
3747          }
3748          self.classes.add('window');
3749          self.bodyClasses.add('window-body');
3750          self.state.set('fixed', true);
3751          if (settings.buttons) {
3752            self.statusbar = new Panel({
3753              layout: 'flex',
3754              border: '1 0 0 0',
3755              spacing: 3,
3756              padding: 10,
3757              align: 'center',
3758              pack: self.isRtl() ? 'start' : 'end',
3759              defaults: { type: 'button' },
3760              items: settings.buttons
3761            });
3762            self.statusbar.classes.add('foot');
3763            self.statusbar.parent(self);
3764          }
3765          self.on('click', function (e) {
3766            var closeClass = self.classPrefix + 'close';
3767            if (funcs.hasClass(e.target, closeClass) || funcs.hasClass(e.target.parentNode, closeClass)) {
3768              self.close();
3769            }
3770          });
3771          self.on('cancel', function () {
3772            self.close();
3773          });
3774          self.on('move', function (e) {
3775            if (e.control === self) {
3776              FloatPanel.hideAll();
3777            }
3778          });
3779          self.aria('describedby', self.describedBy || self._id + '-none');
3780          self.aria('label', settings.title);
3781          self._fullscreen = false;
3782        },
3783        recalc: function () {
3784          var self = this;
3785          var statusbar = self.statusbar;
3786          var layoutRect, width, x, needsRecalc;
3787          if (self._fullscreen) {
3788            self.layoutRect(funcs.getWindowSize());
3789            self.layoutRect().contentH = self.layoutRect().innerH;
3790          }
3791          self._super();
3792          layoutRect = self.layoutRect();
3793          if (self.settings.title && !self._fullscreen) {
3794            width = layoutRect.headerW;
3795            if (width > layoutRect.w) {
3796              x = layoutRect.x - Math.max(0, width / 2);
3797              self.layoutRect({
3798                w: width,
3799                x: x
3800              });
3801              needsRecalc = true;
3802            }
3803          }
3804          if (statusbar) {
3805            statusbar.layoutRect({ w: self.layoutRect().innerW }).recalc();
3806            width = statusbar.layoutRect().minW + layoutRect.deltaW;
3807            if (width > layoutRect.w) {
3808              x = layoutRect.x - Math.max(0, width - layoutRect.w);
3809              self.layoutRect({
3810                w: width,
3811                x: x
3812              });
3813              needsRecalc = true;
3814            }
3815          }
3816          if (needsRecalc) {
3817            self.recalc();
3818          }
3819        },
3820        initLayoutRect: function () {
3821          var self = this;
3822          var layoutRect = self._super();
3823          var deltaH = 0, headEl;
3824          if (self.settings.title && !self._fullscreen) {
3825            headEl = self.getEl('head');
3826            var size = funcs.getSize(headEl);
3827            layoutRect.headerW = size.width;
3828            layoutRect.headerH = size.height;
3829            deltaH += layoutRect.headerH;
3830          }
3831          if (self.statusbar) {
3832            deltaH += self.statusbar.layoutRect().h;
3833          }
3834          layoutRect.deltaH += deltaH;
3835          layoutRect.minH += deltaH;
3836          layoutRect.h += deltaH;
3837          var rect = funcs.getWindowSize();
3838          layoutRect.x = self.settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2);
3839          layoutRect.y = self.settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2);
3840          return layoutRect;
3841        },
3842        renderHtml: function () {
3843          var self = this, layout = self._layout, id = self._id, prefix = self.classPrefix;
3844          var settings = self.settings;
3845          var headerHtml = '', footerHtml = '', html = settings.html;
3846          self.preRender();
3847          layout.preRender(self);
3848          if (settings.title) {
3849            headerHtml = '<div id="' + id + '-head" class="' + prefix + 'window-head">' + '<div id="' + id + '-title" class="' + prefix + 'title">' + self.encode(settings.title) + '</div>' + '<div id="' + id + '-dragh" class="' + prefix + 'dragh"></div>' + '<button type="button" class="' + prefix + 'close" aria-hidden="true">' + '<i class="mce-ico mce-i-remove"></i>' + '</button>' + '</div>';
3850          }
3851          if (settings.url) {
3852            html = '<iframe src="' + settings.url + '" tabindex="-1"></iframe>';
3853          }
3854          if (typeof html === 'undefined') {
3855            html = layout.renderHtml(self);
3856          }
3857          if (self.statusbar) {
3858            footerHtml = self.statusbar.renderHtml();
3859          }
3860          return '<div id="' + id + '" class="' + self.classes + '" hidefocus="1">' + '<div class="' + self.classPrefix + 'reset" role="application">' + headerHtml + '<div id="' + id + '-body" class="' + self.bodyClasses + '">' + html + '</div>' + footerHtml + '</div>' + '</div>';
3861        },
3862        fullscreen: function (state) {
3863          var self = this;
3864          var documentElement = domGlobals.document.documentElement;
3865          var slowRendering;
3866          var prefix = self.classPrefix;
3867          var layoutRect;
3868          if (state !== self._fullscreen) {
3869            global$7(domGlobals.window).on('resize', function () {
3870              var time;
3871              if (self._fullscreen) {
3872                if (!slowRendering) {
3873                  time = new Date().getTime();
3874                  var rect = funcs.getWindowSize();
3875                  self.moveTo(0, 0).resizeTo(rect.w, rect.h);
3876                  if (new Date().getTime() - time > 50) {
3877                    slowRendering = true;
3878                  }
3879                } else {
3880                  if (!self._timer) {
3881                    self._timer = global$3.setTimeout(function () {
3882                      var rect = funcs.getWindowSize();
3883                      self.moveTo(0, 0).resizeTo(rect.w, rect.h);
3884                      self._timer = 0;
3885                    }, 50);
3886                  }
3887                }
3888              }
3889            });
3890            layoutRect = self.layoutRect();
3891            self._fullscreen = state;
3892            if (!state) {
3893              self.borderBox = BoxUtils.parseBox(self.settings.border);
3894              self.getEl('head').style.display = '';
3895              layoutRect.deltaH += layoutRect.headerH;
3896              global$7([
3897                documentElement,
3898                domGlobals.document.body
3899              ]).removeClass(prefix + 'fullscreen');
3900              self.classes.remove('fullscreen');
3901              self.moveTo(self._initial.x, self._initial.y).resizeTo(self._initial.w, self._initial.h);
3902            } else {
3903              self._initial = {
3904                x: layoutRect.x,
3905                y: layoutRect.y,
3906                w: layoutRect.w,
3907                h: layoutRect.h
3908              };
3909              self.borderBox = BoxUtils.parseBox('0');
3910              self.getEl('head').style.display = 'none';
3911              layoutRect.deltaH -= layoutRect.headerH + 2;
3912              global$7([
3913                documentElement,
3914                domGlobals.document.body
3915              ]).addClass(prefix + 'fullscreen');
3916              self.classes.add('fullscreen');
3917              var rect = funcs.getWindowSize();
3918              self.moveTo(0, 0).resizeTo(rect.w, rect.h);
3919            }
3920          }
3921          return self.reflow();
3922        },
3923        postRender: function () {
3924          var self = this;
3925          var startPos;
3926          setTimeout(function () {
3927            self.classes.add('in');
3928            self.fire('open');
3929          }, 0);
3930          self._super();
3931          if (self.statusbar) {
3932            self.statusbar.postRender();
3933          }
3934          self.focus();
3935          this.dragHelper = new DragHelper(self._id + '-dragh', {
3936            start: function () {
3937              startPos = {
3938                x: self.layoutRect().x,
3939                y: self.layoutRect().y
3940              };
3941            },
3942            drag: function (e) {
3943              self.moveTo(startPos.x + e.deltaX, startPos.y + e.deltaY);
3944            }
3945          });
3946          self.on('submit', function (e) {
3947            if (!e.isDefaultPrevented()) {
3948              self.close();
3949            }
3950          });
3951          windows.push(self);
3952          toggleFullScreenState(true);
3953        },
3954        submit: function () {
3955          return this.fire('submit', { data: this.toJSON() });
3956        },
3957        remove: function () {
3958          var self = this;
3959          var i;
3960          self.dragHelper.destroy();
3961          self._super();
3962          if (self.statusbar) {
3963            this.statusbar.remove();
3964          }
3965          toggleBodyFullScreenClasses(self.classPrefix, false);
3966          i = windows.length;
3967          while (i--) {
3968            if (windows[i] === self) {
3969              windows.splice(i, 1);
3970            }
3971          }
3972          toggleFullScreenState(windows.length > 0);
3973        },
3974        getContentWindow: function () {
3975          var ifr = this.getEl().getElementsByTagName('iframe')[0];
3976          return ifr ? ifr.contentWindow : null;
3977        }
3978      });
3979      handleWindowResize();
3980  
3981      var MessageBox = Window.extend({
3982        init: function (settings) {
3983          settings = {
3984            border: 1,
3985            padding: 20,
3986            layout: 'flex',
3987            pack: 'center',
3988            align: 'center',
3989            containerCls: 'panel',
3990            autoScroll: true,
3991            buttons: {
3992              type: 'button',
3993              text: 'Ok',
3994              action: 'ok'
3995            },
3996            items: {
3997              type: 'label',
3998              multiline: true,
3999              maxWidth: 500,
4000              maxHeight: 200
4001            }
4002          };
4003          this._super(settings);
4004        },
4005        Statics: {
4006          OK: 1,
4007          OK_CANCEL: 2,
4008          YES_NO: 3,
4009          YES_NO_CANCEL: 4,
4010          msgBox: function (settings) {
4011            var buttons;
4012            var callback = settings.callback || function () {
4013            };
4014            function createButton(text, status, primary) {
4015              return {
4016                type: 'button',
4017                text: text,
4018                subtype: primary ? 'primary' : '',
4019                onClick: function (e) {
4020                  e.control.parents()[1].close();
4021                  callback(status);
4022                }
4023              };
4024            }
4025            switch (settings.buttons) {
4026            case MessageBox.OK_CANCEL:
4027              buttons = [
4028                createButton('Ok', true, true),
4029                createButton('Cancel', false)
4030              ];
4031              break;
4032            case MessageBox.YES_NO:
4033            case MessageBox.YES_NO_CANCEL:
4034              buttons = [
4035                createButton('Yes', 1, true),
4036                createButton('No', 0)
4037              ];
4038              if (settings.buttons === MessageBox.YES_NO_CANCEL) {
4039                buttons.push(createButton('Cancel', -1));
4040              }
4041              break;
4042            default:
4043              buttons = [createButton('Ok', true, true)];
4044              break;
4045            }
4046            return new Window({
4047              padding: 20,
4048              x: settings.x,
4049              y: settings.y,
4050              minWidth: 300,
4051              minHeight: 100,
4052              layout: 'flex',
4053              pack: 'center',
4054              align: 'center',
4055              buttons: buttons,
4056              title: settings.title,
4057              role: 'alertdialog',
4058              items: {
4059                type: 'label',
4060                multiline: true,
4061                maxWidth: 500,
4062                maxHeight: 200,
4063                text: settings.text
4064              },
4065              onPostRender: function () {
4066                this.aria('describedby', this.items()[0]._id);
4067              },
4068              onClose: settings.onClose,
4069              onCancel: function () {
4070                callback(false);
4071              }
4072            }).renderTo(domGlobals.document.body).reflow();
4073          },
4074          alert: function (settings, callback) {
4075            if (typeof settings === 'string') {
4076              settings = { text: settings };
4077            }
4078            settings.callback = callback;
4079            return MessageBox.msgBox(settings);
4080          },
4081          confirm: function (settings, callback) {
4082            if (typeof settings === 'string') {
4083              settings = { text: settings };
4084            }
4085            settings.callback = callback;
4086            settings.buttons = MessageBox.OK_CANCEL;
4087            return MessageBox.msgBox(settings);
4088          }
4089        }
4090      });
4091  
4092      function WindowManagerImpl (editor) {
4093        var open = function (args, params, closeCallback) {
4094          var win;
4095          args.title = args.title || ' ';
4096          args.url = args.url || args.file;
4097          if (args.url) {
4098            args.width = parseInt(args.width || 320, 10);
4099            args.height = parseInt(args.height || 240, 10);
4100          }
4101          if (args.body) {
4102            args.items = {
4103              defaults: args.defaults,
4104              type: args.bodyType || 'form',
4105              items: args.body,
4106              data: args.data,
4107              callbacks: args.commands
4108            };
4109          }
4110          if (!args.url && !args.buttons) {
4111            args.buttons = [
4112              {
4113                text: 'Ok',
4114                subtype: 'primary',
4115                onclick: function () {
4116                  win.find('form')[0].submit();
4117                }
4118              },
4119              {
4120                text: 'Cancel',
4121                onclick: function () {
4122                  win.close();
4123                }
4124              }
4125            ];
4126          }
4127          win = new Window(args);
4128          win.on('close', function () {
4129            closeCallback(win);
4130          });
4131          if (args.data) {
4132            win.on('postRender', function () {
4133              this.find('*').each(function (ctrl) {
4134                var name = ctrl.name();
4135                if (name in args.data) {
4136                  ctrl.value(args.data[name]);
4137                }
4138              });
4139            });
4140          }
4141          win.features = args || {};
4142          win.params = params || {};
4143          win = win.renderTo(domGlobals.document.body).reflow();
4144          return win;
4145        };
4146        var alert = function (message, choiceCallback, closeCallback) {
4147          var win;
4148          win = MessageBox.alert(message, function () {
4149            choiceCallback();
4150          });
4151          win.on('close', function () {
4152            closeCallback(win);
4153          });
4154          return win;
4155        };
4156        var confirm = function (message, choiceCallback, closeCallback) {
4157          var win;
4158          win = MessageBox.confirm(message, function (state) {
4159            choiceCallback(state);
4160          });
4161          win.on('close', function () {
4162            closeCallback(win);
4163          });
4164          return win;
4165        };
4166        var close = function (window) {
4167          window.close();
4168        };
4169        var getParams = function (window) {
4170          return window.params;
4171        };
4172        var setParams = function (window, params) {
4173          window.params = params;
4174        };
4175        return {
4176          open: open,
4177          alert: alert,
4178          confirm: confirm,
4179          close: close,
4180          getParams: getParams,
4181          setParams: setParams
4182        };
4183      }
4184  
4185      var get = function (editor, panel) {
4186        var renderUI = function () {
4187          return Render.renderUI(editor, panel);
4188        };
4189        return {
4190          renderUI: renderUI,
4191          getNotificationManagerImpl: function () {
4192            return NotificationManagerImpl(editor);
4193          },
4194          getWindowManagerImpl: function () {
4195            return WindowManagerImpl();
4196          }
4197        };
4198      };
4199      var ThemeApi = { get: get };
4200  
4201      var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();
4202  
4203      var path = function (parts, scope) {
4204        var o = scope !== undefined && scope !== null ? scope : Global;
4205        for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) {
4206          o = o[parts[i]];
4207        }
4208        return o;
4209      };
4210      var resolve = function (p, scope) {
4211        var parts = p.split('.');
4212        return path(parts, scope);
4213      };
4214  
4215      var unsafe = function (name, scope) {
4216        return resolve(name, scope);
4217      };
4218      var getOrDie = function (name, scope) {
4219        var actual = unsafe(name, scope);
4220        if (actual === undefined || actual === null) {
4221          throw new Error(name + ' not available on this browser');
4222        }
4223        return actual;
4224      };
4225      var Global$1 = { getOrDie: getOrDie };
4226  
4227      function FileReader () {
4228        var f = Global$1.getOrDie('FileReader');
4229        return new f();
4230      }
4231  
4232      var global$c = tinymce.util.Tools.resolve('tinymce.util.Promise');
4233  
4234      var blobToBase64 = function (blob) {
4235        return new global$c(function (resolve) {
4236          var reader = FileReader();
4237          reader.onloadend = function () {
4238            resolve(reader.result.split(',')[1]);
4239          };
4240          reader.readAsDataURL(blob);
4241        });
4242      };
4243      var Conversions = { blobToBase64: blobToBase64 };
4244  
4245      var pickFile = function () {
4246        return new global$c(function (resolve) {
4247          var fileInput;
4248          fileInput = domGlobals.document.createElement('input');
4249          fileInput.type = 'file';
4250          fileInput.style.position = 'fixed';
4251          fileInput.style.left = 0;
4252          fileInput.style.top = 0;
4253          fileInput.style.opacity = 0.001;
4254          domGlobals.document.body.appendChild(fileInput);
4255          fileInput.onchange = function (e) {
4256            resolve(Array.prototype.slice.call(e.target.files));
4257          };
4258          fileInput.click();
4259          fileInput.parentNode.removeChild(fileInput);
4260        });
4261      };
4262      var Picker = { pickFile: pickFile };
4263  
4264      var count$1 = 0;
4265      var seed = function () {
4266        var rnd = function () {
4267          return Math.round(Math.random() * 4294967295).toString(36);
4268        };
4269        return 's' + Date.now().toString(36) + rnd() + rnd() + rnd();
4270      };
4271      var uuid = function (prefix) {
4272        return prefix + count$1++ + seed();
4273      };
4274      var Uuid = { uuid: uuid };
4275  
4276      var create$1 = function (dom, rng) {
4277        var bookmark = {};
4278        function setupEndPoint(start) {
4279          var offsetNode, container, offset;
4280          container = rng[start ? 'startContainer' : 'endContainer'];
4281          offset = rng[start ? 'startOffset' : 'endOffset'];
4282          if (container.nodeType === 1) {
4283            offsetNode = dom.create('span', { 'data-mce-type': 'bookmark' });
4284            if (container.hasChildNodes()) {
4285              offset = Math.min(offset, container.childNodes.length - 1);
4286              if (start) {
4287                container.insertBefore(offsetNode, container.childNodes[offset]);
4288              } else {
4289                dom.insertAfter(offsetNode, container.childNodes[offset]);
4290              }
4291            } else {
4292              container.appendChild(offsetNode);
4293            }
4294            container = offsetNode;
4295            offset = 0;
4296          }
4297          bookmark[start ? 'startContainer' : 'endContainer'] = container;
4298          bookmark[start ? 'startOffset' : 'endOffset'] = offset;
4299        }
4300        setupEndPoint(true);
4301        if (!rng.collapsed) {
4302          setupEndPoint();
4303        }
4304        return bookmark;
4305      };
4306      var resolve$1 = function (dom, bookmark) {
4307        function restoreEndPoint(start) {
4308          var container, offset, node;
4309          function nodeIndex(container) {
4310            var node = container.parentNode.firstChild, idx = 0;
4311            while (node) {
4312              if (node === container) {
4313                return idx;
4314              }
4315              if (node.nodeType !== 1 || node.getAttribute('data-mce-type') !== 'bookmark') {
4316                idx++;
4317              }
4318              node = node.nextSibling;
4319            }
4320            return -1;
4321          }
4322          container = node = bookmark[start ? 'startContainer' : 'endContainer'];
4323          offset = bookmark[start ? 'startOffset' : 'endOffset'];
4324          if (!container) {
4325            return;
4326          }
4327          if (container.nodeType === 1) {
4328            offset = nodeIndex(container);
4329            container = container.parentNode;
4330            dom.remove(node);
4331          }
4332          bookmark[start ? 'startContainer' : 'endContainer'] = container;
4333          bookmark[start ? 'startOffset' : 'endOffset'] = offset;
4334        }
4335        restoreEndPoint(true);
4336        restoreEndPoint();
4337        var rng = dom.createRng();
4338        rng.setStart(bookmark.startContainer, bookmark.startOffset);
4339        if (bookmark.endContainer) {
4340          rng.setEnd(bookmark.endContainer, bookmark.endOffset);
4341        }
4342        return rng;
4343      };
4344      var Bookmark = {
4345        create: create$1,
4346        resolve: resolve$1
4347      };
4348  
4349      var global$d = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
4350  
4351      var global$e = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
4352  
4353      var getSelectedElements = function (rootElm, startNode, endNode) {
4354        var walker, node;
4355        var elms = [];
4356        walker = new global$d(startNode, rootElm);
4357        for (node = startNode; node; node = walker.next()) {
4358          if (node.nodeType === 1) {
4359            elms.push(node);
4360          }
4361          if (node === endNode) {
4362            break;
4363          }
4364        }
4365        return elms;
4366      };
4367      var unwrapElements = function (editor, elms) {
4368        var bookmark, dom, selection;
4369        dom = editor.dom;
4370        selection = editor.selection;
4371        bookmark = Bookmark.create(dom, selection.getRng());
4372        global$4.each(elms, function (elm) {
4373          editor.dom.remove(elm, true);
4374        });
4375        selection.setRng(Bookmark.resolve(dom, bookmark));
4376      };
4377      var isLink = function (elm) {
4378        return elm.nodeName === 'A' && elm.hasAttribute('href');
4379      };
4380      var getParentAnchorOrSelf = function (dom, elm) {
4381        var anchorElm = dom.getParent(elm, isLink);
4382        return anchorElm ? anchorElm : elm;
4383      };
4384      var getSelectedAnchors = function (editor) {
4385        var startElm, endElm, rootElm, anchorElms, selection, dom, rng;
4386        selection = editor.selection;
4387        dom = editor.dom;
4388        rng = selection.getRng();
4389        startElm = getParentAnchorOrSelf(dom, global$e.getNode(rng.startContainer, rng.startOffset));
4390        endElm = global$e.getNode(rng.endContainer, rng.endOffset);
4391        rootElm = editor.getBody();
4392        anchorElms = global$4.grep(getSelectedElements(rootElm, startElm, endElm), isLink);
4393        return anchorElms;
4394      };
4395      var unlinkSelection = function (editor) {
4396        unwrapElements(editor, getSelectedAnchors(editor));
4397      };
4398      var Unlink = { unlinkSelection: unlinkSelection };
4399  
4400      var createTableHtml = function (cols, rows) {
4401        var x, y, html;
4402        html = '<table data-mce-id="mce" style="width: 100%">';
4403        html += '<tbody>';
4404        for (y = 0; y < rows; y++) {
4405          html += '<tr>';
4406          for (x = 0; x < cols; x++) {
4407            html += '<td><br></td>';
4408          }
4409          html += '</tr>';
4410        }
4411        html += '</tbody>';
4412        html += '</table>';
4413        return html;
4414      };
4415      var getInsertedElement = function (editor) {
4416        var elms = editor.dom.select('*[data-mce-id]');
4417        return elms[0];
4418      };
4419      var insertTableHtml = function (editor, cols, rows) {
4420        editor.undoManager.transact(function () {
4421          var tableElm, cellElm;
4422          editor.insertContent(createTableHtml(cols, rows));
4423          tableElm = getInsertedElement(editor);
4424          tableElm.removeAttribute('data-mce-id');
4425          cellElm = editor.dom.select('td,th', tableElm);
4426          editor.selection.setCursorLocation(cellElm[0], 0);
4427        });
4428      };
4429      var insertTable = function (editor, cols, rows) {
4430        editor.plugins.table ? editor.plugins.table.insertTable(cols, rows) : insertTableHtml(editor, cols, rows);
4431      };
4432      var formatBlock = function (editor, formatName) {
4433        editor.execCommand('FormatBlock', false, formatName);
4434      };
4435      var insertBlob = function (editor, base64, blob) {
4436        var blobCache, blobInfo;
4437        blobCache = editor.editorUpload.blobCache;
4438        blobInfo = blobCache.create(Uuid.uuid('mceu'), blob, base64);
4439        blobCache.add(blobInfo);
4440        editor.insertContent(editor.dom.createHTML('img', { src: blobInfo.blobUri() }));
4441      };
4442      var collapseSelectionToEnd = function (editor) {
4443        editor.selection.collapse(false);
4444      };
4445      var unlink = function (editor) {
4446        editor.focus();
4447        Unlink.unlinkSelection(editor);
4448        collapseSelectionToEnd(editor);
4449      };
4450      var changeHref = function (editor, elm, url) {
4451        editor.focus();
4452        editor.dom.setAttrib(elm, 'href', url);
4453        collapseSelectionToEnd(editor);
4454      };
4455      var insertLink = function (editor, url) {
4456        editor.execCommand('mceInsertLink', false, { href: url });
4457        collapseSelectionToEnd(editor);
4458      };
4459      var updateOrInsertLink = function (editor, url) {
4460        var elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
4461        elm ? changeHref(editor, elm, url) : insertLink(editor, url);
4462      };
4463      var createLink = function (editor, url) {
4464        url.trim().length === 0 ? unlink(editor) : updateOrInsertLink(editor, url);
4465      };
4466      var Actions = {
4467        insertTable: insertTable,
4468        formatBlock: formatBlock,
4469        insertBlob: insertBlob,
4470        createLink: createLink,
4471        unlink: unlink
4472      };
4473  
4474      var addHeaderButtons = function (editor) {
4475        var formatBlock = function (name) {
4476          return function () {
4477            Actions.formatBlock(editor, name);
4478          };
4479        };
4480        for (var i = 1; i < 6; i++) {
4481          var name = 'h' + i;
4482          editor.addButton(name, {
4483            text: name.toUpperCase(),
4484            tooltip: 'Heading ' + i,
4485            stateSelector: name,
4486            onclick: formatBlock(name),
4487            onPostRender: function () {
4488              var span = this.getEl().firstChild.firstChild;
4489              span.style.fontWeight = 'bold';
4490            }
4491          });
4492        }
4493      };
4494      var addToEditor = function (editor, panel) {
4495        editor.addButton('quicklink', {
4496          icon: 'link',
4497          tooltip: 'Insert/Edit link',
4498          stateSelector: 'a[href]',
4499          onclick: function () {
4500            panel.showForm(editor, 'quicklink');
4501          }
4502        });
4503        editor.addButton('quickimage', {
4504          icon: 'image',
4505          tooltip: 'Insert image',
4506          onclick: function () {
4507            Picker.pickFile().then(function (files) {
4508              var blob = files[0];
4509              Conversions.blobToBase64(blob).then(function (base64) {
4510                Actions.insertBlob(editor, base64, blob);
4511              });
4512            });
4513          }
4514        });
4515        editor.addButton('quicktable', {
4516          icon: 'table',
4517          tooltip: 'Insert table',
4518          onclick: function () {
4519            panel.hide();
4520            Actions.insertTable(editor, 2, 2);
4521          }
4522        });
4523        addHeaderButtons(editor);
4524      };
4525      var Buttons = { addToEditor: addToEditor };
4526  
4527      var getUiContainerDelta$1 = function () {
4528        var uiContainer = global$1.container;
4529        if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') {
4530          var containerPos = global$2.DOM.getPos(uiContainer);
4531          var dx = containerPos.x - uiContainer.scrollLeft;
4532          var dy = containerPos.y - uiContainer.scrollTop;
4533          return Option.some({
4534            x: dx,
4535            y: dy
4536          });
4537        } else {
4538          return Option.none();
4539        }
4540      };
4541      var UiContainer$1 = { getUiContainerDelta: getUiContainerDelta$1 };
4542  
4543      var isDomainLike = function (href) {
4544        return /^www\.|\.(com|org|edu|gov|uk|net|ca|de|jp|fr|au|us|ru|ch|it|nl|se|no|es|mil)$/i.test(href.trim());
4545      };
4546      var isAbsolute = function (href) {
4547        return /^https?:\/\//.test(href.trim());
4548      };
4549      var UrlType = {
4550        isDomainLike: isDomainLike,
4551        isAbsolute: isAbsolute
4552      };
4553  
4554      var focusFirstTextBox = function (form) {
4555        form.find('textbox').eq(0).each(function (ctrl) {
4556          ctrl.focus();
4557        });
4558      };
4559      var createForm = function (name, spec) {
4560        var form = global$b.create(global$4.extend({
4561          type: 'form',
4562          layout: 'flex',
4563          direction: 'row',
4564          padding: 5,
4565          name: name,
4566          spacing: 3
4567        }, spec));
4568        form.on('show', function () {
4569          focusFirstTextBox(form);
4570        });
4571        return form;
4572      };
4573      var toggleVisibility = function (ctrl, state) {
4574        return state ? ctrl.show() : ctrl.hide();
4575      };
4576      var askAboutPrefix = function (editor, href) {
4577        return new global$c(function (resolve) {
4578          editor.windowManager.confirm('The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', function (result) {
4579            var output = result === true ? 'http://' + href : href;
4580            resolve(output);
4581          });
4582        });
4583      };
4584      var convertLinkToAbsolute = function (editor, href) {
4585        return !UrlType.isAbsolute(href) && UrlType.isDomainLike(href) ? askAboutPrefix(editor, href) : global$c.resolve(href);
4586      };
4587      var createQuickLinkForm = function (editor, hide) {
4588        var attachState = {};
4589        var unlink = function () {
4590          editor.focus();
4591          Actions.unlink(editor);
4592          hide();
4593        };
4594        var onChangeHandler = function (e) {
4595          var meta = e.meta;
4596          if (meta && meta.attach) {
4597            attachState = {
4598              href: this.value(),
4599              attach: meta.attach
4600            };
4601          }
4602        };
4603        var onShowHandler = function (e) {
4604          if (e.control === this) {
4605            var elm = void 0, linkurl = '';
4606            elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
4607            if (elm) {
4608              linkurl = editor.dom.getAttrib(elm, 'href');
4609            }
4610            this.fromJSON({ linkurl: linkurl });
4611            toggleVisibility(this.find('#unlink'), elm);
4612            this.find('#linkurl')[0].focus();
4613          }
4614        };
4615        return createForm('quicklink', {
4616          items: [
4617            {
4618              type: 'button',
4619              name: 'unlink',
4620              icon: 'unlink',
4621              onclick: unlink,
4622              tooltip: 'Remove link'
4623            },
4624            {
4625              type: 'filepicker',
4626              name: 'linkurl',
4627              placeholder: 'Paste or type a link',
4628              filetype: 'file',
4629              onchange: onChangeHandler
4630            },
4631            {
4632              type: 'button',
4633              icon: 'checkmark',
4634              subtype: 'primary',
4635              tooltip: 'Ok',
4636              onclick: 'submit'
4637            }
4638          ],
4639          onshow: onShowHandler,
4640          onsubmit: function (e) {
4641            convertLinkToAbsolute(editor, e.data.linkurl).then(function (url) {
4642              editor.undoManager.transact(function () {
4643                if (url === attachState.href) {
4644                  attachState.attach();
4645                  attachState = {};
4646                }
4647                Actions.createLink(editor, url);
4648              });
4649              hide();
4650            });
4651          }
4652        });
4653      };
4654      var Forms = { createQuickLinkForm: createQuickLinkForm };
4655  
4656      var getSelectorStateResult = function (itemName, item) {
4657        var result = function (selector, handler) {
4658          return {
4659            selector: selector,
4660            handler: handler
4661          };
4662        };
4663        var activeHandler = function (state) {
4664          item.active(state);
4665        };
4666        var disabledHandler = function (state) {
4667          item.disabled(state);
4668        };
4669        if (item.settings.stateSelector) {
4670          return result(item.settings.stateSelector, activeHandler);
4671        }
4672        if (item.settings.disabledStateSelector) {
4673          return result(item.settings.disabledStateSelector, disabledHandler);
4674        }
4675        return null;
4676      };
4677      var bindSelectorChanged = function (editor, itemName, item) {
4678        return function () {
4679          var result = getSelectorStateResult(itemName, item);
4680          if (result !== null) {
4681            editor.selection.selectorChanged(result.selector, result.handler);
4682          }
4683        };
4684      };
4685      var itemsToArray$1 = function (items) {
4686        if (Type.isArray(items)) {
4687          return items;
4688        } else if (Type.isString(items)) {
4689          return items.split(/[ ,]/);
4690        }
4691        return [];
4692      };
4693      var create$2 = function (editor, name, items) {
4694        var toolbarItems = [];
4695        var buttonGroup;
4696        if (!items) {
4697          return;
4698        }
4699        global$4.each(itemsToArray$1(items), function (item) {
4700          if (item === '|') {
4701            buttonGroup = null;
4702          } else {
4703            if (editor.buttons[item]) {
4704              if (!buttonGroup) {
4705                buttonGroup = {
4706                  type: 'buttongroup',
4707                  items: []
4708                };
4709                toolbarItems.push(buttonGroup);
4710              }
4711              var button = editor.buttons[item];
4712              if (Type.isFunction(button)) {
4713                button = button();
4714              }
4715              button.type = button.type || 'button';
4716              button = global$b.create(button);
4717              button.on('postRender', bindSelectorChanged(editor, item, button));
4718              buttonGroup.items.push(button);
4719            }
4720          }
4721        });
4722        return global$b.create({
4723          type: 'toolbar',
4724          layout: 'flow',
4725          name: name,
4726          items: toolbarItems
4727        });
4728      };
4729      var Toolbar = { create: create$2 };
4730  
4731      var create$3 = function () {
4732        var panel, currentRect;
4733        var createToolbars = function (editor, toolbars) {
4734          return global$4.map(toolbars, function (toolbar) {
4735            return Toolbar.create(editor, toolbar.id, toolbar.items);
4736          });
4737        };
4738        var hasToolbarItems = function (toolbar) {
4739          return toolbar.items().length > 0;
4740        };
4741        var create = function (editor, toolbars) {
4742          var items = createToolbars(editor, toolbars).concat([
4743            Toolbar.create(editor, 'text', Settings.getTextSelectionToolbarItems(editor)),
4744            Toolbar.create(editor, 'insert', Settings.getInsertToolbarItems(editor)),
4745            Forms.createQuickLinkForm(editor, hide)
4746          ]);
4747          return global$b.create({
4748            type: 'floatpanel',
4749            role: 'dialog',
4750            classes: 'tinymce tinymce-inline arrow',
4751            ariaLabel: 'Inline toolbar',
4752            layout: 'flex',
4753            direction: 'column',
4754            align: 'stretch',
4755            autohide: false,
4756            autofix: true,
4757            fixed: true,
4758            border: 1,
4759            items: global$4.grep(items, hasToolbarItems),
4760            oncancel: function () {
4761              editor.focus();
4762            }
4763          });
4764        };
4765        var showPanel = function (panel) {
4766          if (panel) {
4767            panel.show();
4768          }
4769        };
4770        var movePanelTo = function (panel, pos) {
4771          panel.moveTo(pos.x, pos.y);
4772        };
4773        var togglePositionClass = function (panel, relPos) {
4774          relPos = relPos ? relPos.substr(0, 2) : '';
4775          global$4.each({
4776            t: 'down',
4777            b: 'up',
4778            c: 'center'
4779          }, function (cls, pos) {
4780            panel.classes.toggle('arrow-' + cls, pos === relPos.substr(0, 1));
4781          });
4782          if (relPos === 'cr') {
4783            panel.classes.toggle('arrow-left', true);
4784            panel.classes.toggle('arrow-right', false);
4785          } else if (relPos === 'cl') {
4786            panel.classes.toggle('arrow-left', false);
4787            panel.classes.toggle('arrow-right', true);
4788          } else {
4789            global$4.each({
4790              l: 'left',
4791              r: 'right'
4792            }, function (cls, pos) {
4793              panel.classes.toggle('arrow-' + cls, pos === relPos.substr(1, 1));
4794            });
4795          }
4796        };
4797        var showToolbar = function (panel, id) {
4798          var toolbars = panel.items().filter('#' + id);
4799          if (toolbars.length > 0) {
4800            toolbars[0].show();
4801            panel.reflow();
4802            return true;
4803          }
4804          return false;
4805        };
4806        var repositionPanelAt = function (panel, id, editor, targetRect) {
4807          var contentAreaRect, panelRect, result, userConstainHandler;
4808          userConstainHandler = Settings.getPositionHandler(editor);
4809          contentAreaRect = Measure.getContentAreaRect(editor);
4810          panelRect = global$2.DOM.getRect(panel.getEl());
4811          if (id === 'insert') {
4812            result = Layout.calcInsert(targetRect, contentAreaRect, panelRect);
4813          } else {
4814            result = Layout.calc(targetRect, contentAreaRect, panelRect);
4815          }
4816          if (result) {
4817            var delta = UiContainer$1.getUiContainerDelta().getOr({
4818              x: 0,
4819              y: 0
4820            });
4821            var transposedPanelRect = {
4822              x: result.rect.x - delta.x,
4823              y: result.rect.y - delta.y,
4824              w: result.rect.w,
4825              h: result.rect.h
4826            };
4827            currentRect = targetRect;
4828            movePanelTo(panel, Layout.userConstrain(userConstainHandler, targetRect, contentAreaRect, transposedPanelRect));
4829            togglePositionClass(panel, result.position);
4830            return true;
4831          } else {
4832            return false;
4833          }
4834        };
4835        var showPanelAt = function (panel, id, editor, targetRect) {
4836          showPanel(panel);
4837          panel.items().hide();
4838          if (!showToolbar(panel, id)) {
4839            hide();
4840            return;
4841          }
4842          if (repositionPanelAt(panel, id, editor, targetRect) === false) {
4843            hide();
4844          }
4845        };
4846        var hasFormVisible = function () {
4847          return panel.items().filter('form:visible').length > 0;
4848        };
4849        var showForm = function (editor, id) {
4850          if (panel) {
4851            panel.items().hide();
4852            if (!showToolbar(panel, id)) {
4853              hide();
4854              return;
4855            }
4856            var contentAreaRect = void 0, panelRect = void 0, result = void 0, userConstainHandler = void 0;
4857            showPanel(panel);
4858            panel.items().hide();
4859            showToolbar(panel, id);
4860            userConstainHandler = Settings.getPositionHandler(editor);
4861            contentAreaRect = Measure.getContentAreaRect(editor);
4862            panelRect = global$2.DOM.getRect(panel.getEl());
4863            result = Layout.calc(currentRect, contentAreaRect, panelRect);
4864            if (result) {
4865              panelRect = result.rect;
4866              movePanelTo(panel, Layout.userConstrain(userConstainHandler, currentRect, contentAreaRect, panelRect));
4867              togglePositionClass(panel, result.position);
4868            }
4869          }
4870        };
4871        var show = function (editor, id, targetRect, toolbars) {
4872          if (!panel) {
4873            Events.fireBeforeRenderUI(editor);
4874            panel = create(editor, toolbars);
4875            panel.renderTo().reflow().moveTo(targetRect.x, targetRect.y);
4876            editor.nodeChanged();
4877          }
4878          showPanelAt(panel, id, editor, targetRect);
4879        };
4880        var reposition = function (editor, id, targetRect) {
4881          if (panel) {
4882            repositionPanelAt(panel, id, editor, targetRect);
4883          }
4884        };
4885        var hide = function () {
4886          if (panel) {
4887            panel.hide();
4888          }
4889        };
4890        var focus = function () {
4891          if (panel) {
4892            panel.find('toolbar:visible').eq(0).each(function (item) {
4893              item.focus(true);
4894            });
4895          }
4896        };
4897        var remove = function () {
4898          if (panel) {
4899            panel.remove();
4900            panel = null;
4901          }
4902        };
4903        var inForm = function () {
4904          return panel && panel.visible() && hasFormVisible();
4905        };
4906        return {
4907          show: show,
4908          showForm: showForm,
4909          reposition: reposition,
4910          inForm: inForm,
4911          hide: hide,
4912          focus: focus,
4913          remove: remove
4914        };
4915      };
4916  
4917      var Layout$1 = global$8.extend({
4918        Defaults: {
4919          firstControlClass: 'first',
4920          lastControlClass: 'last'
4921        },
4922        init: function (settings) {
4923          this.settings = global$4.extend({}, this.Defaults, settings);
4924        },
4925        preRender: function (container) {
4926          container.bodyClasses.add(this.settings.containerClass);
4927        },
4928        applyClasses: function (items) {
4929          var self = this;
4930          var settings = self.settings;
4931          var firstClass, lastClass, firstItem, lastItem;
4932          firstClass = settings.firstControlClass;
4933          lastClass = settings.lastControlClass;
4934          items.each(function (item) {
4935            item.classes.remove(firstClass).remove(lastClass).add(settings.controlClass);
4936            if (item.visible()) {
4937              if (!firstItem) {
4938                firstItem = item;
4939              }
4940              lastItem = item;
4941            }
4942          });
4943          if (firstItem) {
4944            firstItem.classes.add(firstClass);
4945          }
4946          if (lastItem) {
4947            lastItem.classes.add(lastClass);
4948          }
4949        },
4950        renderHtml: function (container) {
4951          var self = this;
4952          var html = '';
4953          self.applyClasses(container.items());
4954          container.items().each(function (item) {
4955            html += item.renderHtml();
4956          });
4957          return html;
4958        },
4959        recalc: function () {
4960        },
4961        postRender: function () {
4962        },
4963        isNative: function () {
4964          return false;
4965        }
4966      });
4967  
4968      var AbsoluteLayout = Layout$1.extend({
4969        Defaults: {
4970          containerClass: 'abs-layout',
4971          controlClass: 'abs-layout-item'
4972        },
4973        recalc: function (container) {
4974          container.items().filter(':visible').each(function (ctrl) {
4975            var settings = ctrl.settings;
4976            ctrl.layoutRect({
4977              x: settings.x,
4978              y: settings.y,
4979              w: settings.w,
4980              h: settings.h
4981            });
4982            if (ctrl.recalc) {
4983              ctrl.recalc();
4984            }
4985          });
4986        },
4987        renderHtml: function (container) {
4988          return '<div id="' + container._id + '-absend" class="' + container.classPrefix + 'abs-end"></div>' + this._super(container);
4989        }
4990      });
4991  
4992      var Button = Widget.extend({
4993        Defaults: {
4994          classes: 'widget btn',
4995          role: 'button'
4996        },
4997        init: function (settings) {
4998          var self = this;
4999          var size;
5000          self._super(settings);
5001          settings = self.settings;
5002          size = self.settings.size;
5003          self.on('click mousedown', function (e) {
5004            e.preventDefault();
5005          });
5006          self.on('touchstart', function (e) {
5007            self.fire('click', e);
5008            e.preventDefault();
5009          });
5010          if (settings.subtype) {
5011            self.classes.add(settings.subtype);
5012          }
5013          if (size) {
5014            self.classes.add('btn-' + size);
5015          }
5016          if (settings.icon) {
5017            self.icon(settings.icon);
5018          }
5019        },
5020        icon: function (icon) {
5021          if (!arguments.length) {
5022            return this.state.get('icon');
5023          }
5024          this.state.set('icon', icon);
5025          return this;
5026        },
5027        repaint: function () {
5028          var btnElm = this.getEl().firstChild;
5029          var btnStyle;
5030          if (btnElm) {
5031            btnStyle = btnElm.style;
5032            btnStyle.width = btnStyle.height = '100%';
5033          }
5034          this._super();
5035        },
5036        renderHtml: function () {
5037          var self = this, id = self._id, prefix = self.classPrefix;
5038          var icon = self.state.get('icon'), image;
5039          var text = self.state.get('text');
5040          var textHtml = '';
5041          var ariaPressed;
5042          var settings = self.settings;
5043          image = settings.image;
5044          if (image) {
5045            icon = 'none';
5046            if (typeof image !== 'string') {
5047              image = domGlobals.window.getSelection ? image[0] : image[1];
5048            }
5049            image = ' style="background-image: url(\'' + image + '\')"';
5050          } else {
5051            image = '';
5052          }
5053          if (text) {
5054            self.classes.add('btn-has-text');
5055            textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>';
5056          }
5057          icon = icon ? prefix + 'ico ' + prefix + 'i-' + icon : '';
5058          ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : '';
5059          return '<div id="' + id + '" class="' + self.classes + '" tabindex="-1"' + ariaPressed + '>' + '<button id="' + id + '-button" role="presentation" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + textHtml + '</button>' + '</div>';
5060        },
5061        bindStates: function () {
5062          var self = this, $ = self.$, textCls = self.classPrefix + 'txt';
5063          function setButtonText(text) {
5064            var $span = $('span.' + textCls, self.getEl());
5065            if (text) {
5066              if (!$span[0]) {
5067                $('button:first', self.getEl()).append('<span class="' + textCls + '"></span>');
5068                $span = $('span.' + textCls, self.getEl());
5069              }
5070              $span.html(self.encode(text));
5071            } else {
5072              $span.remove();
5073            }
5074            self.classes.toggle('btn-has-text', !!text);
5075          }
5076          self.state.on('change:text', function (e) {
5077            setButtonText(e.value);
5078          });
5079          self.state.on('change:icon', function (e) {
5080            var icon = e.value;
5081            var prefix = self.classPrefix;
5082            self.settings.icon = icon;
5083            icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : '';
5084            var btnElm = self.getEl().firstChild;
5085            var iconElm = btnElm.getElementsByTagName('i')[0];
5086            if (icon) {
5087              if (!iconElm || iconElm !== btnElm.firstChild) {
5088                iconElm = domGlobals.document.createElement('i');
5089                btnElm.insertBefore(iconElm, btnElm.firstChild);
5090              }
5091              iconElm.className = icon;
5092            } else if (iconElm) {
5093              btnElm.removeChild(iconElm);
5094            }
5095            setButtonText(self.state.get('text'));
5096          });
5097          return self._super();
5098        }
5099      });
5100  
5101      var BrowseButton = Button.extend({
5102        init: function (settings) {
5103          var self = this;
5104          settings = global$4.extend({
5105            text: 'Browse...',
5106            multiple: false,
5107            accept: null
5108          }, settings);
5109          self._super(settings);
5110          self.classes.add('browsebutton');
5111          if (settings.multiple) {
5112            self.classes.add('multiple');
5113          }
5114        },
5115        postRender: function () {
5116          var self = this;
5117          var input = funcs.create('input', {
5118            type: 'file',
5119            id: self._id + '-browse',
5120            accept: self.settings.accept
5121          });
5122          self._super();
5123          global$7(input).on('change', function (e) {
5124            var files = e.target.files;
5125            self.value = function () {
5126              if (!files.length) {
5127                return null;
5128              } else if (self.settings.multiple) {
5129                return files;
5130              } else {
5131                return files[0];
5132              }
5133            };
5134            e.preventDefault();
5135            if (files.length) {
5136              self.fire('change', e);
5137            }
5138          });
5139          global$7(input).on('click', function (e) {
5140            e.stopPropagation();
5141          });
5142          global$7(self.getEl('button')).on('click touchstart', function (e) {
5143            e.stopPropagation();
5144            input.click();
5145            e.preventDefault();
5146          });
5147          self.getEl().appendChild(input);
5148        },
5149        remove: function () {
5150          global$7(this.getEl('button')).off();
5151          global$7(this.getEl('input')).off();
5152          this._super();
5153        }
5154      });
5155  
5156      var ButtonGroup = Container.extend({
5157        Defaults: {
5158          defaultType: 'button',
5159          role: 'group'
5160        },
5161        renderHtml: function () {
5162          var self = this, layout = self._layout;
5163          self.classes.add('btn-group');
5164          self.preRender();
5165          layout.preRender(self);
5166          return '<div id="' + self._id + '" class="' + self.classes + '">' + '<div id="' + self._id + '-body">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>';
5167        }
5168      });
5169  
5170      var Checkbox = Widget.extend({
5171        Defaults: {
5172          classes: 'checkbox',
5173          role: 'checkbox',
5174          checked: false
5175        },
5176        init: function (settings) {
5177          var self = this;
5178          self._super(settings);
5179          self.on('click mousedown', function (e) {
5180            e.preventDefault();
5181          });
5182          self.on('click', function (e) {
5183            e.preventDefault();
5184            if (!self.disabled()) {
5185              self.checked(!self.checked());
5186            }
5187          });
5188          self.checked(self.settings.checked);
5189        },
5190        checked: function (state) {
5191          if (!arguments.length) {
5192            return this.state.get('checked');
5193          }
5194          this.state.set('checked', state);
5195          return this;
5196        },
5197        value: function (state) {
5198          if (!arguments.length) {
5199            return this.checked();
5200          }
5201          return this.checked(state);
5202        },
5203        renderHtml: function () {
5204          var self = this, id = self._id, prefix = self.classPrefix;
5205          return '<div id="' + id + '" class="' + self.classes + '" unselectable="on" aria-labelledby="' + id + '-al" tabindex="-1">' + '<i class="' + prefix + 'ico ' + prefix + 'i-checkbox"></i>' + '<span id="' + id + '-al" class="' + prefix + 'label">' + self.encode(self.state.get('text')) + '</span>' + '</div>';
5206        },
5207        bindStates: function () {
5208          var self = this;
5209          function checked(state) {
5210            self.classes.toggle('checked', state);
5211            self.aria('checked', state);
5212          }
5213          self.state.on('change:text', function (e) {
5214            self.getEl('al').firstChild.data = self.translate(e.value);
5215          });
5216          self.state.on('change:checked change:value', function (e) {
5217            self.fire('change');
5218            checked(e.value);
5219          });
5220          self.state.on('change:icon', function (e) {
5221            var icon = e.value;
5222            var prefix = self.classPrefix;
5223            if (typeof icon === 'undefined') {
5224              return self.settings.icon;
5225            }
5226            self.settings.icon = icon;
5227            icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : '';
5228            var btnElm = self.getEl().firstChild;
5229            var iconElm = btnElm.getElementsByTagName('i')[0];
5230            if (icon) {
5231              if (!iconElm || iconElm !== btnElm.firstChild) {
5232                iconElm = domGlobals.document.createElement('i');
5233                btnElm.insertBefore(iconElm, btnElm.firstChild);
5234              }
5235              iconElm.className = icon;
5236            } else if (iconElm) {
5237              btnElm.removeChild(iconElm);
5238            }
5239          });
5240          if (self.state.get('checked')) {
5241            checked(true);
5242          }
5243          return self._super();
5244        }
5245      });
5246  
5247      var global$f = tinymce.util.Tools.resolve('tinymce.util.VK');
5248  
5249      var ComboBox = Widget.extend({
5250        init: function (settings) {
5251          var self = this;
5252          self._super(settings);
5253          settings = self.settings;
5254          self.classes.add('combobox');
5255          self.subinput = true;
5256          self.ariaTarget = 'inp';
5257          settings.menu = settings.menu || settings.values;
5258          if (settings.menu) {
5259            settings.icon = 'caret';
5260          }
5261          self.on('click', function (e) {
5262            var elm = e.target;
5263            var root = self.getEl();
5264            if (!global$7.contains(root, elm) && elm !== root) {
5265              return;
5266            }
5267            while (elm && elm !== root) {
5268              if (elm.id && elm.id.indexOf('-open') !== -1) {
5269                self.fire('action');
5270                if (settings.menu) {
5271                  self.showMenu();
5272                  if (e.aria) {
5273                    self.menu.items()[0].focus();
5274                  }
5275                }
5276              }
5277              elm = elm.parentNode;
5278            }
5279          });
5280          self.on('keydown', function (e) {
5281            var rootControl;
5282            if (e.keyCode === 13 && e.target.nodeName === 'INPUT') {
5283              e.preventDefault();
5284              self.parents().reverse().each(function (ctrl) {
5285                if (ctrl.toJSON) {
5286                  rootControl = ctrl;
5287                  return false;
5288                }
5289              });
5290              self.fire('submit', { data: rootControl.toJSON() });
5291            }
5292          });
5293          self.on('keyup', function (e) {
5294            if (e.target.nodeName === 'INPUT') {
5295              var oldValue = self.state.get('value');
5296              var newValue = e.target.value;
5297              if (newValue !== oldValue) {
5298                self.state.set('value', newValue);
5299                self.fire('autocomplete', e);
5300              }
5301            }
5302          });
5303          self.on('mouseover', function (e) {
5304            var tooltip = self.tooltip().moveTo(-65535);
5305            if (self.statusLevel() && e.target.className.indexOf(self.classPrefix + 'status') !== -1) {
5306              var statusMessage = self.statusMessage() || 'Ok';
5307              var rel = tooltip.text(statusMessage).show().testMoveRel(e.target, [
5308                'bc-tc',
5309                'bc-tl',
5310                'bc-tr'
5311              ]);
5312              tooltip.classes.toggle('tooltip-n', rel === 'bc-tc');
5313              tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl');
5314              tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr');
5315              tooltip.moveRel(e.target, rel);
5316            }
5317          });
5318        },
5319        statusLevel: function (value) {
5320          if (arguments.length > 0) {
5321            this.state.set('statusLevel', value);
5322          }
5323          return this.state.get('statusLevel');
5324        },
5325        statusMessage: function (value) {
5326          if (arguments.length > 0) {
5327            this.state.set('statusMessage', value);
5328          }
5329          return this.state.get('statusMessage');
5330        },
5331        showMenu: function () {
5332          var self = this;
5333          var settings = self.settings;
5334          var menu;
5335          if (!self.menu) {
5336            menu = settings.menu || [];
5337            if (menu.length) {
5338              menu = {
5339                type: 'menu',
5340                items: menu
5341              };
5342            } else {
5343              menu.type = menu.type || 'menu';
5344            }
5345            self.menu = global$b.create(menu).parent(self).renderTo(self.getContainerElm());
5346            self.fire('createmenu');
5347            self.menu.reflow();
5348            self.menu.on('cancel', function (e) {
5349              if (e.control === self.menu) {
5350                self.focus();
5351              }
5352            });
5353            self.menu.on('show hide', function (e) {
5354              e.control.items().each(function (ctrl) {
5355                ctrl.active(ctrl.value() === self.value());
5356              });
5357            }).fire('show');
5358            self.menu.on('select', function (e) {
5359              self.value(e.control.value());
5360            });
5361            self.on('focusin', function (e) {
5362              if (e.target.tagName.toUpperCase() === 'INPUT') {
5363                self.menu.hide();
5364              }
5365            });
5366            self.aria('expanded', true);
5367          }
5368          self.menu.show();
5369          self.menu.layoutRect({ w: self.layoutRect().w });
5370          self.menu.moveRel(self.getEl(), self.isRtl() ? [
5371            'br-tr',
5372            'tr-br'
5373          ] : [
5374            'bl-tl',
5375            'tl-bl'
5376          ]);
5377        },
5378        focus: function () {
5379          this.getEl('inp').focus();
5380        },
5381        repaint: function () {
5382          var self = this, elm = self.getEl(), openElm = self.getEl('open'), rect = self.layoutRect();
5383          var width, lineHeight, innerPadding = 0;
5384          var inputElm = elm.firstChild;
5385          if (self.statusLevel() && self.statusLevel() !== 'none') {
5386            innerPadding = parseInt(funcs.getRuntimeStyle(inputElm, 'padding-right'), 10) - parseInt(funcs.getRuntimeStyle(inputElm, 'padding-left'), 10);
5387          }
5388          if (openElm) {
5389            width = rect.w - funcs.getSize(openElm).width - 10;
5390          } else {
5391            width = rect.w - 10;
5392          }
5393          var doc = domGlobals.document;
5394          if (doc.all && (!doc.documentMode || doc.documentMode <= 8)) {
5395            lineHeight = self.layoutRect().h - 2 + 'px';
5396          }
5397          global$7(inputElm).css({
5398            width: width - innerPadding,
5399            lineHeight: lineHeight
5400          });
5401          self._super();
5402          return self;
5403        },
5404        postRender: function () {
5405          var self = this;
5406          global$7(this.getEl('inp')).on('change', function (e) {
5407            self.state.set('value', e.target.value);
5408            self.fire('change', e);
5409          });
5410          return self._super();
5411        },
5412        renderHtml: function () {
5413          var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix;
5414          var value = self.state.get('value') || '';
5415          var icon, text, openBtnHtml = '', extraAttrs = '', statusHtml = '';
5416          if ('spellcheck' in settings) {
5417            extraAttrs += ' spellcheck="' + settings.spellcheck + '"';
5418          }
5419          if (settings.maxLength) {
5420            extraAttrs += ' maxlength="' + settings.maxLength + '"';
5421          }
5422          if (settings.size) {
5423            extraAttrs += ' size="' + settings.size + '"';
5424          }
5425          if (settings.subtype) {
5426            extraAttrs += ' type="' + settings.subtype + '"';
5427          }
5428          statusHtml = '<i id="' + id + '-status" class="mce-status mce-ico" style="display: none"></i>';
5429          if (self.disabled()) {
5430            extraAttrs += ' disabled="disabled"';
5431          }
5432          icon = settings.icon;
5433          if (icon && icon !== 'caret') {
5434            icon = prefix + 'ico ' + prefix + 'i-' + settings.icon;
5435          }
5436          text = self.state.get('text');
5437          if (icon || text) {
5438            openBtnHtml = '<div id="' + id + '-open" class="' + prefix + 'btn ' + prefix + 'open" tabIndex="-1" role="button">' + '<button id="' + id + '-action" type="button" hidefocus="1" tabindex="-1">' + (icon !== 'caret' ? '<i class="' + icon + '"></i>' : '<i class="' + prefix + 'caret"></i>') + (text ? (icon ? ' ' : '') + text : '') + '</button>' + '</div>';
5439            self.classes.add('has-open');
5440          }
5441          return '<div id="' + id + '" class="' + self.classes + '">' + '<input id="' + id + '-inp" class="' + prefix + 'textbox" value="' + self.encode(value, false) + '" hidefocus="1"' + extraAttrs + ' placeholder="' + self.encode(settings.placeholder) + '" />' + statusHtml + openBtnHtml + '</div>';
5442        },
5443        value: function (value) {
5444          if (arguments.length) {
5445            this.state.set('value', value);
5446            return this;
5447          }
5448          if (this.state.get('rendered')) {
5449            this.state.set('value', this.getEl('inp').value);
5450          }
5451          return this.state.get('value');
5452        },
5453        showAutoComplete: function (items, term) {
5454          var self = this;
5455          if (items.length === 0) {
5456            self.hideMenu();
5457            return;
5458          }
5459          var insert = function (value, title) {
5460            return function () {
5461              self.fire('selectitem', {
5462                title: title,
5463                value: value
5464              });
5465            };
5466          };
5467          if (self.menu) {
5468            self.menu.items().remove();
5469          } else {
5470            self.menu = global$b.create({
5471              type: 'menu',
5472              classes: 'combobox-menu',
5473              layout: 'flow'
5474            }).parent(self).renderTo();
5475          }
5476          global$4.each(items, function (item) {
5477            self.menu.add({
5478              text: item.title,
5479              url: item.previewUrl,
5480              match: term,
5481              classes: 'menu-item-ellipsis',
5482              onclick: insert(item.value, item.title)
5483            });
5484          });
5485          self.menu.renderNew();
5486          self.hideMenu();
5487          self.menu.on('cancel', function (e) {
5488            if (e.control.parent() === self.menu) {
5489              e.stopPropagation();
5490              self.focus();
5491              self.hideMenu();
5492            }
5493          });
5494          self.menu.on('select', function () {
5495            self.focus();
5496          });
5497          var maxW = self.layoutRect().w;
5498          self.menu.layoutRect({
5499            w: maxW,
5500            minW: 0,
5501            maxW: maxW
5502          });
5503          self.menu.repaint();
5504          self.menu.reflow();
5505          self.menu.show();
5506          self.menu.moveRel(self.getEl(), self.isRtl() ? [
5507            'br-tr',
5508            'tr-br'
5509          ] : [
5510            'bl-tl',
5511            'tl-bl'
5512          ]);
5513        },
5514        hideMenu: function () {
5515          if (this.menu) {
5516            this.menu.hide();
5517          }
5518        },
5519        bindStates: function () {
5520          var self = this;
5521          self.state.on('change:value', function (e) {
5522            if (self.getEl('inp').value !== e.value) {
5523              self.getEl('inp').value = e.value;
5524            }
5525          });
5526          self.state.on('change:disabled', function (e) {
5527            self.getEl('inp').disabled = e.value;
5528          });
5529          self.state.on('change:statusLevel', function (e) {
5530            var statusIconElm = self.getEl('status');
5531            var prefix = self.classPrefix, value = e.value;
5532            funcs.css(statusIconElm, 'display', value === 'none' ? 'none' : '');
5533            funcs.toggleClass(statusIconElm, prefix + 'i-checkmark', value === 'ok');
5534            funcs.toggleClass(statusIconElm, prefix + 'i-warning', value === 'warn');
5535            funcs.toggleClass(statusIconElm, prefix + 'i-error', value === 'error');
5536            self.classes.toggle('has-status', value !== 'none');
5537            self.repaint();
5538          });
5539          funcs.on(self.getEl('status'), 'mouseleave', function () {
5540            self.tooltip().hide();
5541          });
5542          self.on('cancel', function (e) {
5543            if (self.menu && self.menu.visible()) {
5544              e.stopPropagation();
5545              self.hideMenu();
5546            }
5547          });
5548          var focusIdx = function (idx, menu) {
5549            if (menu && menu.items().length > 0) {
5550              menu.items().eq(idx)[0].focus();
5551            }
5552          };
5553          self.on('keydown', function (e) {
5554            var keyCode = e.keyCode;
5555            if (e.target.nodeName === 'INPUT') {
5556              if (keyCode === global$f.DOWN) {
5557                e.preventDefault();
5558                self.fire('autocomplete');
5559                focusIdx(0, self.menu);
5560              } else if (keyCode === global$f.UP) {
5561                e.preventDefault();
5562                focusIdx(-1, self.menu);
5563              }
5564            }
5565          });
5566          return self._super();
5567        },
5568        remove: function () {
5569          global$7(this.getEl('inp')).off();
5570          if (this.menu) {
5571            this.menu.remove();
5572          }
5573          this._super();
5574        }
5575      });
5576  
5577      var ColorBox = ComboBox.extend({
5578        init: function (settings) {
5579          var self = this;
5580          settings.spellcheck = false;
5581          if (settings.onaction) {
5582            settings.icon = 'none';
5583          }
5584          self._super(settings);
5585          self.classes.add('colorbox');
5586          self.on('change keyup postrender', function () {
5587            self.repaintColor(self.value());
5588          });
5589        },
5590        repaintColor: function (value) {
5591          var openElm = this.getEl('open');
5592          var elm = openElm ? openElm.getElementsByTagName('i')[0] : null;
5593          if (elm) {
5594            try {
5595              elm.style.background = value;
5596            } catch (ex) {
5597            }
5598          }
5599        },
5600        bindStates: function () {
5601          var self = this;
5602          self.state.on('change:value', function (e) {
5603            if (self.state.get('rendered')) {
5604              self.repaintColor(e.value);
5605            }
5606          });
5607          return self._super();
5608        }
5609      });
5610  
5611      var PanelButton = Button.extend({
5612        showPanel: function () {
5613          var self = this, settings = self.settings;
5614          self.classes.add('opened');
5615          if (!self.panel) {
5616            var panelSettings = settings.panel;
5617            if (panelSettings.type) {
5618              panelSettings = {
5619                layout: 'grid',
5620                items: panelSettings
5621              };
5622            }
5623            panelSettings.role = panelSettings.role || 'dialog';
5624            panelSettings.popover = true;
5625            panelSettings.autohide = true;
5626            panelSettings.ariaRoot = true;
5627            self.panel = new FloatPanel(panelSettings).on('hide', function () {
5628              self.classes.remove('opened');
5629            }).on('cancel', function (e) {
5630              e.stopPropagation();
5631              self.focus();
5632              self.hidePanel();
5633            }).parent(self).renderTo(self.getContainerElm());
5634            self.panel.fire('show');
5635            self.panel.reflow();
5636          } else {
5637            self.panel.show();
5638          }
5639          var rtlRels = [
5640            'bc-tc',
5641            'bc-tl',
5642            'bc-tr'
5643          ];
5644          var ltrRels = [
5645            'bc-tc',
5646            'bc-tr',
5647            'bc-tl',
5648            'tc-bc',
5649            'tc-br',
5650            'tc-bl'
5651          ];
5652          var rel = self.panel.testMoveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? rtlRels : ltrRels));
5653          self.panel.classes.toggle('start', rel.substr(-1) === 'l');
5654          self.panel.classes.toggle('end', rel.substr(-1) === 'r');
5655          var isTop = rel.substr(0, 1) === 't';
5656          self.panel.classes.toggle('bottom', !isTop);
5657          self.panel.classes.toggle('top', isTop);
5658          self.panel.moveRel(self.getEl(), rel);
5659        },
5660        hidePanel: function () {
5661          var self = this;
5662          if (self.panel) {
5663            self.panel.hide();
5664          }
5665        },
5666        postRender: function () {
5667          var self = this;
5668          self.aria('haspopup', true);
5669          self.on('click', function (e) {
5670            if (e.control === self) {
5671              if (self.panel && self.panel.visible()) {
5672                self.hidePanel();
5673              } else {
5674                self.showPanel();
5675                self.panel.focus(!!e.aria);
5676              }
5677            }
5678          });
5679          return self._super();
5680        },
5681        remove: function () {
5682          if (this.panel) {
5683            this.panel.remove();
5684            this.panel = null;
5685          }
5686          return this._super();
5687        }
5688      });
5689  
5690      var DOM = global$2.DOM;
5691      var ColorButton = PanelButton.extend({
5692        init: function (settings) {
5693          this._super(settings);
5694          this.classes.add('splitbtn');
5695          this.classes.add('colorbutton');
5696        },
5697        color: function (color) {
5698          if (color) {
5699            this._color = color;
5700            this.getEl('preview').style.backgroundColor = color;
5701            return this;
5702          }
5703          return this._color;
5704        },
5705        resetColor: function () {
5706          this._color = null;
5707          this.getEl('preview').style.backgroundColor = null;
5708          return this;
5709        },
5710        renderHtml: function () {
5711          var self = this, id = self._id, prefix = self.classPrefix, text = self.state.get('text');
5712          var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : '';
5713          var image = self.settings.image ? ' style="background-image: url(\'' + self.settings.image + '\')"' : '';
5714          var textHtml = '';
5715          if (text) {
5716            self.classes.add('btn-has-text');
5717            textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>';
5718          }
5719          return '<div id="' + id + '" class="' + self.classes + '" role="button" tabindex="-1" aria-haspopup="true">' + '<button role="presentation" hidefocus="1" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + '<span id="' + id + '-preview" class="' + prefix + 'preview"></span>' + textHtml + '</button>' + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>';
5720        },
5721        postRender: function () {
5722          var self = this, onClickHandler = self.settings.onclick;
5723          self.on('click', function (e) {
5724            if (e.aria && e.aria.key === 'down') {
5725              return;
5726            }
5727            if (e.control === self && !DOM.getParent(e.target, '.' + self.classPrefix + 'open')) {
5728              e.stopImmediatePropagation();
5729              onClickHandler.call(self, e);
5730            }
5731          });
5732          delete self.settings.onclick;
5733          return self._super();
5734        }
5735      });
5736  
5737      var global$g = tinymce.util.Tools.resolve('tinymce.util.Color');
5738  
5739      var ColorPicker = Widget.extend({
5740        Defaults: { classes: 'widget colorpicker' },
5741        init: function (settings) {
5742          this._super(settings);
5743        },
5744        postRender: function () {
5745          var self = this;
5746          var color = self.color();
5747          var hsv, hueRootElm, huePointElm, svRootElm, svPointElm;
5748          hueRootElm = self.getEl('h');
5749          huePointElm = self.getEl('hp');
5750          svRootElm = self.getEl('sv');
5751          svPointElm = self.getEl('svp');
5752          function getPos(elm, event) {
5753            var pos = funcs.getPos(elm);
5754            var x, y;
5755            x = event.pageX - pos.x;
5756            y = event.pageY - pos.y;
5757            x = Math.max(0, Math.min(x / elm.clientWidth, 1));
5758            y = Math.max(0, Math.min(y / elm.clientHeight, 1));
5759            return {
5760              x: x,
5761              y: y
5762            };
5763          }
5764          function updateColor(hsv, hueUpdate) {
5765            var hue = (360 - hsv.h) / 360;
5766            funcs.css(huePointElm, { top: hue * 100 + '%' });
5767            if (!hueUpdate) {
5768              funcs.css(svPointElm, {
5769                left: hsv.s + '%',
5770                top: 100 - hsv.v + '%'
5771              });
5772            }
5773            svRootElm.style.background = global$g({
5774              s: 100,
5775              v: 100,
5776              h: hsv.h
5777            }).toHex();
5778            self.color().parse({
5779              s: hsv.s,
5780              v: hsv.v,
5781              h: hsv.h
5782            });
5783          }
5784          function updateSaturationAndValue(e) {
5785            var pos;
5786            pos = getPos(svRootElm, e);
5787            hsv.s = pos.x * 100;
5788            hsv.v = (1 - pos.y) * 100;
5789            updateColor(hsv);
5790            self.fire('change');
5791          }
5792          function updateHue(e) {
5793            var pos;
5794            pos = getPos(hueRootElm, e);
5795            hsv = color.toHsv();
5796            hsv.h = (1 - pos.y) * 360;
5797            updateColor(hsv, true);
5798            self.fire('change');
5799          }
5800          self._repaint = function () {
5801            hsv = color.toHsv();
5802            updateColor(hsv);
5803          };
5804          self._super();
5805          self._svdraghelper = new DragHelper(self._id + '-sv', {
5806            start: updateSaturationAndValue,
5807            drag: updateSaturationAndValue
5808          });
5809          self._hdraghelper = new DragHelper(self._id + '-h', {
5810            start: updateHue,
5811            drag: updateHue
5812          });
5813          self._repaint();
5814        },
5815        rgb: function () {
5816          return this.color().toRgb();
5817        },
5818        value: function (value) {
5819          var self = this;
5820          if (arguments.length) {
5821            self.color().parse(value);
5822            if (self._rendered) {
5823              self._repaint();
5824            }
5825          } else {
5826            return self.color().toHex();
5827          }
5828        },
5829        color: function () {
5830          if (!this._color) {
5831            this._color = global$g();
5832          }
5833          return this._color;
5834        },
5835        renderHtml: function () {
5836          var self = this;
5837          var id = self._id;
5838          var prefix = self.classPrefix;
5839          var hueHtml;
5840          var stops = '#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000';
5841          function getOldIeFallbackHtml() {
5842            var i, l, html = '', gradientPrefix, stopsList;
5843            gradientPrefix = 'filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=';
5844            stopsList = stops.split(',');
5845            for (i = 0, l = stopsList.length - 1; i < l; i++) {
5846              html += '<div class="' + prefix + 'colorpicker-h-chunk" style="' + 'height:' + 100 / l + '%;' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ');' + '-ms-' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ')' + '"></div>';
5847            }
5848            return html;
5849          }
5850          var gradientCssText = 'background: -ms-linear-gradient(top,' + stops + ');' + 'background: linear-gradient(to bottom,' + stops + ');';
5851          hueHtml = '<div id="' + id + '-h" class="' + prefix + 'colorpicker-h" style="' + gradientCssText + '">' + getOldIeFallbackHtml() + '<div id="' + id + '-hp" class="' + prefix + 'colorpicker-h-marker"></div>' + '</div>';
5852          return '<div id="' + id + '" class="' + self.classes + '">' + '<div id="' + id + '-sv" class="' + prefix + 'colorpicker-sv">' + '<div class="' + prefix + 'colorpicker-overlay1">' + '<div class="' + prefix + 'colorpicker-overlay2">' + '<div id="' + id + '-svp" class="' + prefix + 'colorpicker-selector1">' + '<div class="' + prefix + 'colorpicker-selector2"></div>' + '</div>' + '</div>' + '</div>' + '</div>' + hueHtml + '</div>';
5853        }
5854      });
5855  
5856      var DropZone = Widget.extend({
5857        init: function (settings) {
5858          var self = this;
5859          settings = global$4.extend({
5860            height: 100,
5861            text: 'Drop an image here',
5862            multiple: false,
5863            accept: null
5864          }, settings);
5865          self._super(settings);
5866          self.classes.add('dropzone');
5867          if (settings.multiple) {
5868            self.classes.add('multiple');
5869          }
5870        },
5871        renderHtml: function () {
5872          var self = this;
5873          var attrs, elm;
5874          var cfg = self.settings;
5875          attrs = {
5876            id: self._id,
5877            hidefocus: '1'
5878          };
5879          elm = funcs.create('div', attrs, '<span>' + this.translate(cfg.text) + '</span>');
5880          if (cfg.height) {
5881            funcs.css(elm, 'height', cfg.height + 'px');
5882          }
5883          if (cfg.width) {
5884            funcs.css(elm, 'width', cfg.width + 'px');
5885          }
5886          elm.className = self.classes;
5887          return elm.outerHTML;
5888        },
5889        postRender: function () {
5890          var self = this;
5891          var toggleDragClass = function (e) {
5892            e.preventDefault();
5893            self.classes.toggle('dragenter');
5894            self.getEl().className = self.classes;
5895          };
5896          var filter = function (files) {
5897            var accept = self.settings.accept;
5898            if (typeof accept !== 'string') {
5899              return files;
5900            }
5901            var re = new RegExp('(' + accept.split(/\s*,\s*/).join('|') + ')$', 'i');
5902            return global$4.grep(files, function (file) {
5903              return re.test(file.name);
5904            });
5905          };
5906          self._super();
5907          self.$el.on('dragover', function (e) {
5908            e.preventDefault();
5909          });
5910          self.$el.on('dragenter', toggleDragClass);
5911          self.$el.on('dragleave', toggleDragClass);
5912          self.$el.on('drop', function (e) {
5913            e.preventDefault();
5914            if (self.state.get('disabled')) {
5915              return;
5916            }
5917            var files = filter(e.dataTransfer.files);
5918            self.value = function () {
5919              if (!files.length) {
5920                return null;
5921              } else if (self.settings.multiple) {
5922                return files;
5923              } else {
5924                return files[0];
5925              }
5926            };
5927            if (files.length) {
5928              self.fire('change', e);
5929            }
5930          });
5931        },
5932        remove: function () {
5933          this.$el.off();
5934          this._super();
5935        }
5936      });
5937  
5938      var Path = Widget.extend({
5939        init: function (settings) {
5940          var self = this;
5941          if (!settings.delimiter) {
5942            settings.delimiter = '\xBB';
5943          }
5944          self._super(settings);
5945          self.classes.add('path');
5946          self.canFocus = true;
5947          self.on('click', function (e) {
5948            var index;
5949            var target = e.target;
5950            if (index = target.getAttribute('data-index')) {
5951              self.fire('select', {
5952                value: self.row()[index],
5953                index: index
5954              });
5955            }
5956          });
5957          self.row(self.settings.row);
5958        },
5959        focus: function () {
5960          var self = this;
5961          self.getEl().firstChild.focus();
5962          return self;
5963        },
5964        row: function (row) {
5965          if (!arguments.length) {
5966            return this.state.get('row');
5967          }
5968          this.state.set('row', row);
5969          return this;
5970        },
5971        renderHtml: function () {
5972          var self = this;
5973          return '<div id="' + self._id + '" class="' + self.classes + '">' + self._getDataPathHtml(self.state.get('row')) + '</div>';
5974        },
5975        bindStates: function () {
5976          var self = this;
5977          self.state.on('change:row', function (e) {
5978            self.innerHtml(self._getDataPathHtml(e.value));
5979          });
5980          return self._super();
5981        },
5982        _getDataPathHtml: function (data) {
5983          var self = this;
5984          var parts = data || [];
5985          var i, l, html = '';
5986          var prefix = self.classPrefix;
5987          for (i = 0, l = parts.length; i < l; i++) {
5988            html += (i > 0 ? '<div class="' + prefix + 'divider" aria-hidden="true"> ' + self.settings.delimiter + ' </div>' : '') + '<div role="button" class="' + prefix + 'path-item' + (i === l - 1 ? ' ' + prefix + 'last' : '') + '" data-index="' + i + '" tabindex="-1" id="' + self._id + '-' + i + '" aria-level="' + (i + 1) + '">' + parts[i].name + '</div>';
5989          }
5990          if (!html) {
5991            html = '<div class="' + prefix + 'path-item">\xA0</div>';
5992          }
5993          return html;
5994        }
5995      });
5996  
5997      var ElementPath = Path.extend({
5998        postRender: function () {
5999          var self = this, editor = self.settings.editor;
6000          function isHidden(elm) {
6001            if (elm.nodeType === 1) {
6002              if (elm.nodeName === 'BR' || !!elm.getAttribute('data-mce-bogus')) {
6003                return true;
6004              }
6005              if (elm.getAttribute('data-mce-type') === 'bookmark') {
6006                return true;
6007              }
6008            }
6009            return false;
6010          }
6011          if (editor.settings.elementpath !== false) {
6012            self.on('select', function (e) {
6013              editor.focus();
6014              editor.selection.select(this.row()[e.index].element);
6015              editor.nodeChanged();
6016            });
6017            editor.on('nodeChange', function (e) {
6018              var outParents = [];
6019              var parents = e.parents;
6020              var i = parents.length;
6021              while (i--) {
6022                if (parents[i].nodeType === 1 && !isHidden(parents[i])) {
6023                  var args = editor.fire('ResolveName', {
6024                    name: parents[i].nodeName.toLowerCase(),
6025                    target: parents[i]
6026                  });
6027                  if (!args.isDefaultPrevented()) {
6028                    outParents.push({
6029                      name: args.name,
6030                      element: parents[i]
6031                    });
6032                  }
6033                  if (args.isPropagationStopped()) {
6034                    break;
6035                  }
6036                }
6037              }
6038              self.row(outParents);
6039            });
6040          }
6041          return self._super();
6042        }
6043      });
6044  
6045      var FormItem = Container.extend({
6046        Defaults: {
6047          layout: 'flex',
6048          align: 'center',
6049          defaults: { flex: 1 }
6050        },
6051        renderHtml: function () {
6052          var self = this, layout = self._layout, prefix = self.classPrefix;
6053          self.classes.add('formitem');
6054          layout.preRender(self);
6055          return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + (self.settings.title ? '<div id="' + self._id + '-title" class="' + prefix + 'title">' + self.settings.title + '</div>' : '') + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>';
6056        }
6057      });
6058  
6059      var Form = Container.extend({
6060        Defaults: {
6061          containerCls: 'form',
6062          layout: 'flex',
6063          direction: 'column',
6064          align: 'stretch',
6065          flex: 1,
6066          padding: 15,
6067          labelGap: 30,
6068          spacing: 10,
6069          callbacks: {
6070            submit: function () {
6071              this.submit();
6072            }
6073          }
6074        },
6075        preRender: function () {
6076          var self = this, items = self.items();
6077          if (!self.settings.formItemDefaults) {
6078            self.settings.formItemDefaults = {
6079              layout: 'flex',
6080              autoResize: 'overflow',
6081              defaults: { flex: 1 }
6082            };
6083          }
6084          items.each(function (ctrl) {
6085            var formItem;
6086            var label = ctrl.settings.label;
6087            if (label) {
6088              formItem = new FormItem(global$4.extend({
6089                items: {
6090                  type: 'label',
6091                  id: ctrl._id + '-l',
6092                  text: label,
6093                  flex: 0,
6094                  forId: ctrl._id,
6095                  disabled: ctrl.disabled()
6096                }
6097              }, self.settings.formItemDefaults));
6098              formItem.type = 'formitem';
6099              ctrl.aria('labelledby', ctrl._id + '-l');
6100              if (typeof ctrl.settings.flex === 'undefined') {
6101                ctrl.settings.flex = 1;
6102              }
6103              self.replace(ctrl, formItem);
6104              formItem.add(ctrl);
6105            }
6106          });
6107        },
6108        submit: function () {
6109          return this.fire('submit', { data: this.toJSON() });
6110        },
6111        postRender: function () {
6112          var self = this;
6113          self._super();
6114          self.fromJSON(self.settings.data);
6115        },
6116        bindStates: function () {
6117          var self = this;
6118          self._super();
6119          function recalcLabels() {
6120            var maxLabelWidth = 0;
6121            var labels = [];
6122            var i, labelGap, items;
6123            if (self.settings.labelGapCalc === false) {
6124              return;
6125            }
6126            if (self.settings.labelGapCalc === 'children') {
6127              items = self.find('formitem');
6128            } else {
6129              items = self.items();
6130            }
6131            items.filter('formitem').each(function (item) {
6132              var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth;
6133              maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth;
6134              labels.push(labelCtrl);
6135            });
6136            labelGap = self.settings.labelGap || 0;
6137            i = labels.length;
6138            while (i--) {
6139              labels[i].settings.minWidth = maxLabelWidth + labelGap;
6140            }
6141          }
6142          self.on('show', recalcLabels);
6143          recalcLabels();
6144        }
6145      });
6146  
6147      var FieldSet = Form.extend({
6148        Defaults: {
6149          containerCls: 'fieldset',
6150          layout: 'flex',
6151          direction: 'column',
6152          align: 'stretch',
6153          flex: 1,
6154          padding: '25 15 5 15',
6155          labelGap: 30,
6156          spacing: 10,
6157          border: 1
6158        },
6159        renderHtml: function () {
6160          var self = this, layout = self._layout, prefix = self.classPrefix;
6161          self.preRender();
6162          layout.preRender(self);
6163          return '<fieldset id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + (self.settings.title ? '<legend id="' + self._id + '-title" class="' + prefix + 'fieldset-title">' + self.settings.title + '</legend>' : '') + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</fieldset>';
6164        }
6165      });
6166  
6167      var unique$1 = 0;
6168      var generate = function (prefix) {
6169        var date = new Date();
6170        var time = date.getTime();
6171        var random = Math.floor(Math.random() * 1000000000);
6172        unique$1++;
6173        return prefix + '_' + random + unique$1 + String(time);
6174      };
6175  
6176      var fromHtml = function (html, scope) {
6177        var doc = scope || domGlobals.document;
6178        var div = doc.createElement('div');
6179        div.innerHTML = html;
6180        if (!div.hasChildNodes() || div.childNodes.length > 1) {
6181          domGlobals.console.error('HTML does not have a single root node', html);
6182          throw new Error('HTML must have a single root node');
6183        }
6184        return fromDom(div.childNodes[0]);
6185      };
6186      var fromTag = function (tag, scope) {
6187        var doc = scope || domGlobals.document;
6188        var node = doc.createElement(tag);
6189        return fromDom(node);
6190      };
6191      var fromText = function (text, scope) {
6192        var doc = scope || domGlobals.document;
6193        var node = doc.createTextNode(text);
6194        return fromDom(node);
6195      };
6196      var fromDom = function (node) {
6197        if (node === null || node === undefined) {
6198          throw new Error('Node cannot be null or undefined');
6199        }
6200        return { dom: constant(node) };
6201      };
6202      var fromPoint = function (docElm, x, y) {
6203        var doc = docElm.dom();
6204        return Option.from(doc.elementFromPoint(x, y)).map(fromDom);
6205      };
6206      var Element = {
6207        fromHtml: fromHtml,
6208        fromTag: fromTag,
6209        fromText: fromText,
6210        fromDom: fromDom,
6211        fromPoint: fromPoint
6212      };
6213  
6214      var cached = function (f) {
6215        var called = false;
6216        var r;
6217        return function () {
6218          var args = [];
6219          for (var _i = 0; _i < arguments.length; _i++) {
6220            args[_i] = arguments[_i];
6221          }
6222          if (!called) {
6223            called = true;
6224            r = f.apply(null, args);
6225          }
6226          return r;
6227        };
6228      };
6229  
6230      var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;
6231      var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;
6232      var COMMENT = domGlobals.Node.COMMENT_NODE;
6233      var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;
6234      var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;
6235      var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;
6236      var ELEMENT = domGlobals.Node.ELEMENT_NODE;
6237      var TEXT = domGlobals.Node.TEXT_NODE;
6238      var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;
6239      var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;
6240      var ENTITY = domGlobals.Node.ENTITY_NODE;
6241      var NOTATION = domGlobals.Node.NOTATION_NODE;
6242  
6243      var Immutable = function () {
6244        var fields = [];
6245        for (var _i = 0; _i < arguments.length; _i++) {
6246          fields[_i] = arguments[_i];
6247        }
6248        return function () {
6249          var values = [];
6250          for (var _i = 0; _i < arguments.length; _i++) {
6251            values[_i] = arguments[_i];
6252          }
6253          if (fields.length !== values.length) {
6254            throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments');
6255          }
6256          var struct = {};
6257          each(fields, function (name, i) {
6258            struct[name] = constant(values[i]);
6259          });
6260          return struct;
6261        };
6262      };
6263  
6264      var node = function () {
6265        var f = Global$1.getOrDie('Node');
6266        return f;
6267      };
6268      var compareDocumentPosition = function (a, b, match) {
6269        return (a.compareDocumentPosition(b) & match) !== 0;
6270      };
6271      var documentPositionPreceding = function (a, b) {
6272        return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING);
6273      };
6274      var documentPositionContainedBy = function (a, b) {
6275        return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY);
6276      };
6277      var Node = {
6278        documentPositionPreceding: documentPositionPreceding,
6279        documentPositionContainedBy: documentPositionContainedBy
6280      };
6281  
6282      var firstMatch = function (regexes, s) {
6283        for (var i = 0; i < regexes.length; i++) {
6284          var x = regexes[i];
6285          if (x.test(s)) {
6286            return x;
6287          }
6288        }
6289        return undefined;
6290      };
6291      var find$1 = function (regexes, agent) {
6292        var r = firstMatch(regexes, agent);
6293        if (!r) {
6294          return {
6295            major: 0,
6296            minor: 0
6297          };
6298        }
6299        var group = function (i) {
6300          return Number(agent.replace(r, '$' + i));
6301        };
6302        return nu(group(1), group(2));
6303      };
6304      var detect = function (versionRegexes, agent) {
6305        var cleanedAgent = String(agent).toLowerCase();
6306        if (versionRegexes.length === 0) {
6307          return unknown();
6308        }
6309        return find$1(versionRegexes, cleanedAgent);
6310      };
6311      var unknown = function () {
6312        return nu(0, 0);
6313      };
6314      var nu = function (major, minor) {
6315        return {
6316          major: major,
6317          minor: minor
6318        };
6319      };
6320      var Version = {
6321        nu: nu,
6322        detect: detect,
6323        unknown: unknown
6324      };
6325  
6326      var edge = 'Edge';
6327      var chrome = 'Chrome';
6328      var ie = 'IE';
6329      var opera = 'Opera';
6330      var firefox = 'Firefox';
6331      var safari = 'Safari';
6332      var isBrowser = function (name, current) {
6333        return function () {
6334          return current === name;
6335        };
6336      };
6337      var unknown$1 = function () {
6338        return nu$1({
6339          current: undefined,
6340          version: Version.unknown()
6341        });
6342      };
6343      var nu$1 = function (info) {
6344        var current = info.current;
6345        var version = info.version;
6346        return {
6347          current: current,
6348          version: version,
6349          isEdge: isBrowser(edge, current),
6350          isChrome: isBrowser(chrome, current),
6351          isIE: isBrowser(ie, current),
6352          isOpera: isBrowser(opera, current),
6353          isFirefox: isBrowser(firefox, current),
6354          isSafari: isBrowser(safari, current)
6355        };
6356      };
6357      var Browser = {
6358        unknown: unknown$1,
6359        nu: nu$1,
6360        edge: constant(edge),
6361        chrome: constant(chrome),
6362        ie: constant(ie),
6363        opera: constant(opera),
6364        firefox: constant(firefox),
6365        safari: constant(safari)
6366      };
6367  
6368      var windows$1 = 'Windows';
6369      var ios = 'iOS';
6370      var android = 'Android';
6371      var linux = 'Linux';
6372      var osx = 'OSX';
6373      var solaris = 'Solaris';
6374      var freebsd = 'FreeBSD';
6375      var isOS = function (name, current) {
6376        return function () {
6377          return current === name;
6378        };
6379      };
6380      var unknown$2 = function () {
6381        return nu$2({
6382          current: undefined,
6383          version: Version.unknown()
6384        });
6385      };
6386      var nu$2 = function (info) {
6387        var current = info.current;
6388        var version = info.version;
6389        return {
6390          current: current,
6391          version: version,
6392          isWindows: isOS(windows$1, current),
6393          isiOS: isOS(ios, current),
6394          isAndroid: isOS(android, current),
6395          isOSX: isOS(osx, current),
6396          isLinux: isOS(linux, current),
6397          isSolaris: isOS(solaris, current),
6398          isFreeBSD: isOS(freebsd, current)
6399        };
6400      };
6401      var OperatingSystem = {
6402        unknown: unknown$2,
6403        nu: nu$2,
6404        windows: constant(windows$1),
6405        ios: constant(ios),
6406        android: constant(android),
6407        linux: constant(linux),
6408        osx: constant(osx),
6409        solaris: constant(solaris),
6410        freebsd: constant(freebsd)
6411      };
6412  
6413      var DeviceType = function (os, browser, userAgent) {
6414        var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
6415        var isiPhone = os.isiOS() && !isiPad;
6416        var isAndroid3 = os.isAndroid() && os.version.major === 3;
6417        var isAndroid4 = os.isAndroid() && os.version.major === 4;
6418        var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true;
6419        var isTouch = os.isiOS() || os.isAndroid();
6420        var isPhone = isTouch && !isTablet;
6421        var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
6422        return {
6423          isiPad: constant(isiPad),
6424          isiPhone: constant(isiPhone),
6425          isTablet: constant(isTablet),
6426          isPhone: constant(isPhone),
6427          isTouch: constant(isTouch),
6428          isAndroid: os.isAndroid,
6429          isiOS: os.isiOS,
6430          isWebView: constant(iOSwebview)
6431        };
6432      };
6433  
6434      var detect$1 = function (candidates, userAgent) {
6435        var agent = String(userAgent).toLowerCase();
6436        return find(candidates, function (candidate) {
6437          return candidate.search(agent);
6438        });
6439      };
6440      var detectBrowser = function (browsers, userAgent) {
6441        return detect$1(browsers, userAgent).map(function (browser) {
6442          var version = Version.detect(browser.versionRegexes, userAgent);
6443          return {
6444            current: browser.name,
6445            version: version
6446          };
6447        });
6448      };
6449      var detectOs = function (oses, userAgent) {
6450        return detect$1(oses, userAgent).map(function (os) {
6451          var version = Version.detect(os.versionRegexes, userAgent);
6452          return {
6453            current: os.name,
6454            version: version
6455          };
6456        });
6457      };
6458      var UaString = {
6459        detectBrowser: detectBrowser,
6460        detectOs: detectOs
6461      };
6462  
6463      var contains = function (str, substr) {
6464        return str.indexOf(substr) !== -1;
6465      };
6466  
6467      var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
6468      var checkContains = function (target) {
6469        return function (uastring) {
6470          return contains(uastring, target);
6471        };
6472      };
6473      var browsers = [
6474        {
6475          name: 'Edge',
6476          versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
6477          search: function (uastring) {
6478            return contains(uastring, 'edge/') && contains(uastring, 'chrome') && contains(uastring, 'safari') && contains(uastring, 'applewebkit');
6479          }
6480        },
6481        {
6482          name: 'Chrome',
6483          versionRegexes: [
6484            /.*?chrome\/([0-9]+)\.([0-9]+).*/,
6485            normalVersionRegex
6486          ],
6487          search: function (uastring) {
6488            return contains(uastring, 'chrome') && !contains(uastring, 'chromeframe');
6489          }
6490        },
6491        {
6492          name: 'IE',
6493          versionRegexes: [
6494            /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
6495            /.*?rv:([0-9]+)\.([0-9]+).*/
6496          ],
6497          search: function (uastring) {
6498            return contains(uastring, 'msie') || contains(uastring, 'trident');
6499          }
6500        },
6501        {
6502          name: 'Opera',
6503          versionRegexes: [
6504            normalVersionRegex,
6505            /.*?opera\/([0-9]+)\.([0-9]+).*/
6506          ],
6507          search: checkContains('opera')
6508        },
6509        {
6510          name: 'Firefox',
6511          versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
6512          search: checkContains('firefox')
6513        },
6514        {
6515          name: 'Safari',
6516          versionRegexes: [
6517            normalVersionRegex,
6518            /.*?cpu os ([0-9]+)_([0-9]+).*/
6519          ],
6520          search: function (uastring) {
6521            return (contains(uastring, 'safari') || contains(uastring, 'mobile/')) && contains(uastring, 'applewebkit');
6522          }
6523        }
6524      ];
6525      var oses = [
6526        {
6527          name: 'Windows',
6528          search: checkContains('win'),
6529          versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
6530        },
6531        {
6532          name: 'iOS',
6533          search: function (uastring) {
6534            return contains(uastring, 'iphone') || contains(uastring, 'ipad');
6535          },
6536          versionRegexes: [
6537            /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
6538            /.*cpu os ([0-9]+)_([0-9]+).*/,
6539            /.*cpu iphone os ([0-9]+)_([0-9]+).*/
6540          ]
6541        },
6542        {
6543          name: 'Android',
6544          search: checkContains('android'),
6545          versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
6546        },
6547        {
6548          name: 'OSX',
6549          search: checkContains('os x'),
6550          versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]
6551        },
6552        {
6553          name: 'Linux',
6554          search: checkContains('linux'),
6555          versionRegexes: []
6556        },
6557        {
6558          name: 'Solaris',
6559          search: checkContains('sunos'),
6560          versionRegexes: []
6561        },
6562        {
6563          name: 'FreeBSD',
6564          search: checkContains('freebsd'),
6565          versionRegexes: []
6566        }
6567      ];
6568      var PlatformInfo = {
6569        browsers: constant(browsers),
6570        oses: constant(oses)
6571      };
6572  
6573      var detect$2 = function (userAgent) {
6574        var browsers = PlatformInfo.browsers();
6575        var oses = PlatformInfo.oses();
6576        var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);
6577        var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
6578        var deviceType = DeviceType(os, browser, userAgent);
6579        return {
6580          browser: browser,
6581          os: os,
6582          deviceType: deviceType
6583        };
6584      };
6585      var PlatformDetection = { detect: detect$2 };
6586  
6587      var detect$3 = cached(function () {
6588        var userAgent = domGlobals.navigator.userAgent;
6589        return PlatformDetection.detect(userAgent);
6590      });
6591      var PlatformDetection$1 = { detect: detect$3 };
6592  
6593      var ELEMENT$1 = ELEMENT;
6594      var DOCUMENT$1 = DOCUMENT;
6595      var bypassSelector = function (dom) {
6596        return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;
6597      };
6598      var all = function (selector, scope) {
6599        var base = scope === undefined ? domGlobals.document : scope.dom();
6600        return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom);
6601      };
6602      var one = function (selector, scope) {
6603        var base = scope === undefined ? domGlobals.document : scope.dom();
6604        return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);
6605      };
6606  
6607      var regularContains = function (e1, e2) {
6608        var d1 = e1.dom();
6609        var d2 = e2.dom();
6610        return d1 === d2 ? false : d1.contains(d2);
6611      };
6612      var ieContains = function (e1, e2) {
6613        return Node.documentPositionContainedBy(e1.dom(), e2.dom());
6614      };
6615      var browser = PlatformDetection$1.detect().browser;
6616      var contains$1 = browser.isIE() ? ieContains : regularContains;
6617  
6618      var spot = Immutable('element', 'offset');
6619  
6620      var descendants = function (scope, selector) {
6621        return all(selector, scope);
6622      };
6623  
6624      var trim = global$4.trim;
6625      var hasContentEditableState = function (value) {
6626        return function (node) {
6627          if (node && node.nodeType === 1) {
6628            if (node.contentEditable === value) {
6629              return true;
6630            }
6631            if (node.getAttribute('data-mce-contenteditable') === value) {
6632              return true;
6633            }
6634          }
6635          return false;
6636        };
6637      };
6638      var isContentEditableTrue = hasContentEditableState('true');
6639      var isContentEditableFalse = hasContentEditableState('false');
6640      var create$4 = function (type, title, url, level, attach) {
6641        return {
6642          type: type,
6643          title: title,
6644          url: url,
6645          level: level,
6646          attach: attach
6647        };
6648      };
6649      var isChildOfContentEditableTrue = function (node) {
6650        while (node = node.parentNode) {
6651          var value = node.contentEditable;
6652          if (value && value !== 'inherit') {
6653            return isContentEditableTrue(node);
6654          }
6655        }
6656        return false;
6657      };
6658      var select = function (selector, root) {
6659        return map(descendants(Element.fromDom(root), selector), function (element) {
6660          return element.dom();
6661        });
6662      };
6663      var getElementText = function (elm) {
6664        return elm.innerText || elm.textContent;
6665      };
6666      var getOrGenerateId = function (elm) {
6667        return elm.id ? elm.id : generate('h');
6668      };
6669      var isAnchor = function (elm) {
6670        return elm && elm.nodeName === 'A' && (elm.id || elm.name);
6671      };
6672      var isValidAnchor = function (elm) {
6673        return isAnchor(elm) && isEditable(elm);
6674      };
6675      var isHeader = function (elm) {
6676        return elm && /^(H[1-6])$/.test(elm.nodeName);
6677      };
6678      var isEditable = function (elm) {
6679        return isChildOfContentEditableTrue(elm) && !isContentEditableFalse(elm);
6680      };
6681      var isValidHeader = function (elm) {
6682        return isHeader(elm) && isEditable(elm);
6683      };
6684      var getLevel = function (elm) {
6685        return isHeader(elm) ? parseInt(elm.nodeName.substr(1), 10) : 0;
6686      };
6687      var headerTarget = function (elm) {
6688        var headerId = getOrGenerateId(elm);
6689        var attach = function () {
6690          elm.id = headerId;
6691        };
6692        return create$4('header', getElementText(elm), '#' + headerId, getLevel(elm), attach);
6693      };
6694      var anchorTarget = function (elm) {
6695        var anchorId = elm.id || elm.name;
6696        var anchorText = getElementText(elm);
6697        return create$4('anchor', anchorText ? anchorText : '#' + anchorId, '#' + anchorId, 0, noop);
6698      };
6699      var getHeaderTargets = function (elms) {
6700        return map(filter(elms, isValidHeader), headerTarget);
6701      };
6702      var getAnchorTargets = function (elms) {
6703        return map(filter(elms, isValidAnchor), anchorTarget);
6704      };
6705      var getTargetElements = function (elm) {
6706        var elms = select('h1,h2,h3,h4,h5,h6,a:not([href])', elm);
6707        return elms;
6708      };
6709      var hasTitle = function (target) {
6710        return trim(target.title).length > 0;
6711      };
6712      var find$2 = function (elm) {
6713        var elms = getTargetElements(elm);
6714        return filter(getHeaderTargets(elms).concat(getAnchorTargets(elms)), hasTitle);
6715      };
6716      var LinkTargets = { find: find$2 };
6717  
6718      var getActiveEditor = function () {
6719        return window.tinymce ? window.tinymce.activeEditor : global$5.activeEditor;
6720      };
6721      var history = {};
6722      var HISTORY_LENGTH = 5;
6723      var clearHistory = function () {
6724        history = {};
6725      };
6726      var toMenuItem = function (target) {
6727        return {
6728          title: target.title,
6729          value: {
6730            title: { raw: target.title },
6731            url: target.url,
6732            attach: target.attach
6733          }
6734        };
6735      };
6736      var toMenuItems = function (targets) {
6737        return global$4.map(targets, toMenuItem);
6738      };
6739      var staticMenuItem = function (title, url) {
6740        return {
6741          title: title,
6742          value: {
6743            title: title,
6744            url: url,
6745            attach: noop
6746          }
6747        };
6748      };
6749      var isUniqueUrl = function (url, targets) {
6750        var foundTarget = exists(targets, function (target) {
6751          return target.url === url;
6752        });
6753        return !foundTarget;
6754      };
6755      var getSetting = function (editorSettings, name, defaultValue) {
6756        var value = name in editorSettings ? editorSettings[name] : defaultValue;
6757        return value === false ? null : value;
6758      };
6759      var createMenuItems = function (term, targets, fileType, editorSettings) {
6760        var separator = { title: '-' };
6761        var fromHistoryMenuItems = function (history) {
6762          var historyItems = history.hasOwnProperty(fileType) ? history[fileType] : [];
6763          var uniqueHistory = filter(historyItems, function (url) {
6764            return isUniqueUrl(url, targets);
6765          });
6766          return global$4.map(uniqueHistory, function (url) {
6767            return {
6768              title: url,
6769              value: {
6770                title: url,
6771                url: url,
6772                attach: noop
6773              }
6774            };
6775          });
6776        };
6777        var fromMenuItems = function (type) {
6778          var filteredTargets = filter(targets, function (target) {
6779            return target.type === type;
6780          });
6781          return toMenuItems(filteredTargets);
6782        };
6783        var anchorMenuItems = function () {
6784          var anchorMenuItems = fromMenuItems('anchor');
6785          var topAnchor = getSetting(editorSettings, 'anchor_top', '#top');
6786          var bottomAchor = getSetting(editorSettings, 'anchor_bottom', '#bottom');
6787          if (topAnchor !== null) {
6788            anchorMenuItems.unshift(staticMenuItem('<top>', topAnchor));
6789          }
6790          if (bottomAchor !== null) {
6791            anchorMenuItems.push(staticMenuItem('<bottom>', bottomAchor));
6792          }
6793          return anchorMenuItems;
6794        };
6795        var join = function (items) {
6796          return foldl(items, function (a, b) {
6797            var bothEmpty = a.length === 0 || b.length === 0;
6798            return bothEmpty ? a.concat(b) : a.concat(separator, b);
6799          }, []);
6800        };
6801        if (editorSettings.typeahead_urls === false) {
6802          return [];
6803        }
6804        return fileType === 'file' ? join([
6805          filterByQuery(term, fromHistoryMenuItems(history)),
6806          filterByQuery(term, fromMenuItems('header')),
6807          filterByQuery(term, anchorMenuItems())
6808        ]) : filterByQuery(term, fromHistoryMenuItems(history));
6809      };
6810      var addToHistory = function (url, fileType) {
6811        var items = history[fileType];
6812        if (!/^https?/.test(url)) {
6813          return;
6814        }
6815        if (items) {
6816          if (indexOf(items, url).isNone()) {
6817            history[fileType] = items.slice(0, HISTORY_LENGTH).concat(url);
6818          }
6819        } else {
6820          history[fileType] = [url];
6821        }
6822      };
6823      var filterByQuery = function (term, menuItems) {
6824        var lowerCaseTerm = term.toLowerCase();
6825        var result = global$4.grep(menuItems, function (item) {
6826          return item.title.toLowerCase().indexOf(lowerCaseTerm) !== -1;
6827        });
6828        return result.length === 1 && result[0].title === term ? [] : result;
6829      };
6830      var getTitle = function (linkDetails) {
6831        var title = linkDetails.title;
6832        return title.raw ? title.raw : title;
6833      };
6834      var setupAutoCompleteHandler = function (ctrl, editorSettings, bodyElm, fileType) {
6835        var autocomplete = function (term) {
6836          var linkTargets = LinkTargets.find(bodyElm);
6837          var menuItems = createMenuItems(term, linkTargets, fileType, editorSettings);
6838          ctrl.showAutoComplete(menuItems, term);
6839        };
6840        ctrl.on('autocomplete', function () {
6841          autocomplete(ctrl.value());
6842        });
6843        ctrl.on('selectitem', function (e) {
6844          var linkDetails = e.value;
6845          ctrl.value(linkDetails.url);
6846          var title = getTitle(linkDetails);
6847          if (fileType === 'image') {
6848            ctrl.fire('change', {
6849              meta: {
6850                alt: title,
6851                attach: linkDetails.attach
6852              }
6853            });
6854          } else {
6855            ctrl.fire('change', {
6856              meta: {
6857                text: title,
6858                attach: linkDetails.attach
6859              }
6860            });
6861          }
6862          ctrl.focus();
6863        });
6864        ctrl.on('click', function (e) {
6865          if (ctrl.value().length === 0 && e.target.nodeName === 'INPUT') {
6866            autocomplete('');
6867          }
6868        });
6869        ctrl.on('PostRender', function () {
6870          ctrl.getRoot().on('submit', function (e) {
6871            if (!e.isDefaultPrevented()) {
6872              addToHistory(ctrl.value(), fileType);
6873            }
6874          });
6875        });
6876      };
6877      var statusToUiState = function (result) {
6878        var status = result.status, message = result.message;
6879        if (status === 'valid') {
6880          return {
6881            status: 'ok',
6882            message: message
6883          };
6884        } else if (status === 'unknown') {
6885          return {
6886            status: 'warn',
6887            message: message
6888          };
6889        } else if (status === 'invalid') {
6890          return {
6891            status: 'warn',
6892            message: message
6893          };
6894        } else {
6895          return {
6896            status: 'none',
6897            message: ''
6898          };
6899        }
6900      };
6901      var setupLinkValidatorHandler = function (ctrl, editorSettings, fileType) {
6902        var validatorHandler = editorSettings.filepicker_validator_handler;
6903        if (validatorHandler) {
6904          var validateUrl_1 = function (url) {
6905            if (url.length === 0) {
6906              ctrl.statusLevel('none');
6907              return;
6908            }
6909            validatorHandler({
6910              url: url,
6911              type: fileType
6912            }, function (result) {
6913              var uiState = statusToUiState(result);
6914              ctrl.statusMessage(uiState.message);
6915              ctrl.statusLevel(uiState.status);
6916            });
6917          };
6918          ctrl.state.on('change:value', function (e) {
6919            validateUrl_1(e.value);
6920          });
6921        }
6922      };
6923      var FilePicker = ComboBox.extend({
6924        Statics: { clearHistory: clearHistory },
6925        init: function (settings) {
6926          var self = this, editor = getActiveEditor(), editorSettings = editor.settings;
6927          var actionCallback, fileBrowserCallback, fileBrowserCallbackTypes;
6928          var fileType = settings.filetype;
6929          settings.spellcheck = false;
6930          fileBrowserCallbackTypes = editorSettings.file_picker_types || editorSettings.file_browser_callback_types;
6931          if (fileBrowserCallbackTypes) {
6932            fileBrowserCallbackTypes = global$4.makeMap(fileBrowserCallbackTypes, /[, ]/);
6933          }
6934          if (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType]) {
6935            fileBrowserCallback = editorSettings.file_picker_callback;
6936            if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) {
6937              actionCallback = function () {
6938                var meta = self.fire('beforecall').meta;
6939                meta = global$4.extend({ filetype: fileType }, meta);
6940                fileBrowserCallback.call(editor, function (value, meta) {
6941                  self.value(value).fire('change', { meta: meta });
6942                }, self.value(), meta);
6943              };
6944            } else {
6945              fileBrowserCallback = editorSettings.file_browser_callback;
6946              if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) {
6947                actionCallback = function () {
6948                  fileBrowserCallback(self.getEl('inp').id, self.value(), fileType, window);
6949                };
6950              }
6951            }
6952          }
6953          if (actionCallback) {
6954            settings.icon = 'browse';
6955            settings.onaction = actionCallback;
6956          }
6957          self._super(settings);
6958          self.classes.add('filepicker');
6959          setupAutoCompleteHandler(self, editorSettings, editor.getBody(), fileType);
6960          setupLinkValidatorHandler(self, editorSettings, fileType);
6961        }
6962      });
6963  
6964      var FitLayout = AbsoluteLayout.extend({
6965        recalc: function (container) {
6966          var contLayoutRect = container.layoutRect(), paddingBox = container.paddingBox;
6967          container.items().filter(':visible').each(function (ctrl) {
6968            ctrl.layoutRect({
6969              x: paddingBox.left,
6970              y: paddingBox.top,
6971              w: contLayoutRect.innerW - paddingBox.right - paddingBox.left,
6972              h: contLayoutRect.innerH - paddingBox.top - paddingBox.bottom
6973            });
6974            if (ctrl.recalc) {
6975              ctrl.recalc();
6976            }
6977          });
6978        }
6979      });
6980  
6981      var FlexLayout = AbsoluteLayout.extend({
6982        recalc: function (container) {
6983          var i, l, items, contLayoutRect, contPaddingBox, contSettings, align, pack, spacing, totalFlex, availableSpace, direction;
6984          var ctrl, ctrlLayoutRect, ctrlSettings, flex;
6985          var maxSizeItems = [];
6986          var size, maxSize, ratio, rect, pos, maxAlignEndPos;
6987          var sizeName, minSizeName, posName, maxSizeName, beforeName, innerSizeName, deltaSizeName, contentSizeName;
6988          var alignAxisName, alignInnerSizeName, alignSizeName, alignMinSizeName, alignBeforeName, alignAfterName;
6989          var alignDeltaSizeName, alignContentSizeName;
6990          var max = Math.max, min = Math.min;
6991          items = container.items().filter(':visible');
6992          contLayoutRect = container.layoutRect();
6993          contPaddingBox = container.paddingBox;
6994          contSettings = container.settings;
6995          direction = container.isRtl() ? contSettings.direction || 'row-reversed' : contSettings.direction;
6996          align = contSettings.align;
6997          pack = container.isRtl() ? contSettings.pack || 'end' : contSettings.pack;
6998          spacing = contSettings.spacing || 0;
6999          if (direction === 'row-reversed' || direction === 'column-reverse') {
7000            items = items.set(items.toArray().reverse());
7001            direction = direction.split('-')[0];
7002          }
7003          if (direction === 'column') {
7004            posName = 'y';
7005            sizeName = 'h';
7006            minSizeName = 'minH';
7007            maxSizeName = 'maxH';
7008            innerSizeName = 'innerH';
7009            beforeName = 'top';
7010            deltaSizeName = 'deltaH';
7011            contentSizeName = 'contentH';
7012            alignBeforeName = 'left';
7013            alignSizeName = 'w';
7014            alignAxisName = 'x';
7015            alignInnerSizeName = 'innerW';
7016            alignMinSizeName = 'minW';
7017            alignAfterName = 'right';
7018            alignDeltaSizeName = 'deltaW';
7019            alignContentSizeName = 'contentW';
7020          } else {
7021            posName = 'x';
7022            sizeName = 'w';
7023            minSizeName = 'minW';
7024            maxSizeName = 'maxW';
7025            innerSizeName = 'innerW';
7026            beforeName = 'left';
7027            deltaSizeName = 'deltaW';
7028            contentSizeName = 'contentW';
7029            alignBeforeName = 'top';
7030            alignSizeName = 'h';
7031            alignAxisName = 'y';
7032            alignInnerSizeName = 'innerH';
7033            alignMinSizeName = 'minH';
7034            alignAfterName = 'bottom';
7035            alignDeltaSizeName = 'deltaH';
7036            alignContentSizeName = 'contentH';
7037          }
7038          availableSpace = contLayoutRect[innerSizeName] - contPaddingBox[beforeName] - contPaddingBox[beforeName];
7039          maxAlignEndPos = totalFlex = 0;
7040          for (i = 0, l = items.length; i < l; i++) {
7041            ctrl = items[i];
7042            ctrlLayoutRect = ctrl.layoutRect();
7043            ctrlSettings = ctrl.settings;
7044            flex = ctrlSettings.flex;
7045            availableSpace -= i < l - 1 ? spacing : 0;
7046            if (flex > 0) {
7047              totalFlex += flex;
7048              if (ctrlLayoutRect[maxSizeName]) {
7049                maxSizeItems.push(ctrl);
7050              }
7051              ctrlLayoutRect.flex = flex;
7052            }
7053            availableSpace -= ctrlLayoutRect[minSizeName];
7054            size = contPaddingBox[alignBeforeName] + ctrlLayoutRect[alignMinSizeName] + contPaddingBox[alignAfterName];
7055            if (size > maxAlignEndPos) {
7056              maxAlignEndPos = size;
7057            }
7058          }
7059          rect = {};
7060          if (availableSpace < 0) {
7061            rect[minSizeName] = contLayoutRect[minSizeName] - availableSpace + contLayoutRect[deltaSizeName];
7062          } else {
7063            rect[minSizeName] = contLayoutRect[innerSizeName] - availableSpace + contLayoutRect[deltaSizeName];
7064          }
7065          rect[alignMinSizeName] = maxAlignEndPos + contLayoutRect[alignDeltaSizeName];
7066          rect[contentSizeName] = contLayoutRect[innerSizeName] - availableSpace;
7067          rect[alignContentSizeName] = maxAlignEndPos;
7068          rect.minW = min(rect.minW, contLayoutRect.maxW);
7069          rect.minH = min(rect.minH, contLayoutRect.maxH);
7070          rect.minW = max(rect.minW, contLayoutRect.startMinWidth);
7071          rect.minH = max(rect.minH, contLayoutRect.startMinHeight);
7072          if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) {
7073            rect.w = rect.minW;
7074            rect.h = rect.minH;
7075            container.layoutRect(rect);
7076            this.recalc(container);
7077            if (container._lastRect === null) {
7078              var parentCtrl = container.parent();
7079              if (parentCtrl) {
7080                parentCtrl._lastRect = null;
7081                parentCtrl.recalc();
7082              }
7083            }
7084            return;
7085          }
7086          ratio = availableSpace / totalFlex;
7087          for (i = 0, l = maxSizeItems.length; i < l; i++) {
7088            ctrl = maxSizeItems[i];
7089            ctrlLayoutRect = ctrl.layoutRect();
7090            maxSize = ctrlLayoutRect[maxSizeName];
7091            size = ctrlLayoutRect[minSizeName] + ctrlLayoutRect.flex * ratio;
7092            if (size > maxSize) {
7093              availableSpace -= ctrlLayoutRect[maxSizeName] - ctrlLayoutRect[minSizeName];
7094              totalFlex -= ctrlLayoutRect.flex;
7095              ctrlLayoutRect.flex = 0;
7096              ctrlLayoutRect.maxFlexSize = maxSize;
7097            } else {
7098              ctrlLayoutRect.maxFlexSize = 0;
7099            }
7100          }
7101          ratio = availableSpace / totalFlex;
7102          pos = contPaddingBox[beforeName];
7103          rect = {};
7104          if (totalFlex === 0) {
7105            if (pack === 'end') {
7106              pos = availableSpace + contPaddingBox[beforeName];
7107            } else if (pack === 'center') {
7108              pos = Math.round(contLayoutRect[innerSizeName] / 2 - (contLayoutRect[innerSizeName] - availableSpace) / 2) + contPaddingBox[beforeName];
7109              if (pos < 0) {
7110                pos = contPaddingBox[beforeName];
7111              }
7112            } else if (pack === 'justify') {
7113              pos = contPaddingBox[beforeName];
7114              spacing = Math.floor(availableSpace / (items.length - 1));
7115            }
7116          }
7117          rect[alignAxisName] = contPaddingBox[alignBeforeName];
7118          for (i = 0, l = items.length; i < l; i++) {
7119            ctrl = items[i];
7120            ctrlLayoutRect = ctrl.layoutRect();
7121            size = ctrlLayoutRect.maxFlexSize || ctrlLayoutRect[minSizeName];
7122            if (align === 'center') {
7123              rect[alignAxisName] = Math.round(contLayoutRect[alignInnerSizeName] / 2 - ctrlLayoutRect[alignSizeName] / 2);
7124            } else if (align === 'stretch') {
7125              rect[alignSizeName] = max(ctrlLayoutRect[alignMinSizeName] || 0, contLayoutRect[alignInnerSizeName] - contPaddingBox[alignBeforeName] - contPaddingBox[alignAfterName]);
7126              rect[alignAxisName] = contPaddingBox[alignBeforeName];
7127            } else if (align === 'end') {
7128              rect[alignAxisName] = contLayoutRect[alignInnerSizeName] - ctrlLayoutRect[alignSizeName] - contPaddingBox.top;
7129            }
7130            if (ctrlLayoutRect.flex > 0) {
7131              size += ctrlLayoutRect.flex * ratio;
7132            }
7133            rect[sizeName] = size;
7134            rect[posName] = pos;
7135            ctrl.layoutRect(rect);
7136            if (ctrl.recalc) {
7137              ctrl.recalc();
7138            }
7139            pos += size + spacing;
7140          }
7141        }
7142      });
7143  
7144      var FlowLayout = Layout$1.extend({
7145        Defaults: {
7146          containerClass: 'flow-layout',
7147          controlClass: 'flow-layout-item',
7148          endClass: 'break'
7149        },
7150        recalc: function (container) {
7151          container.items().filter(':visible').each(function (ctrl) {
7152            if (ctrl.recalc) {
7153              ctrl.recalc();
7154            }
7155          });
7156        },
7157        isNative: function () {
7158          return true;
7159        }
7160      });
7161  
7162      var descendant = function (scope, selector) {
7163        return one(selector, scope);
7164      };
7165  
7166      var toggleFormat = function (editor, fmt) {
7167        return function () {
7168          editor.execCommand('mceToggleFormat', false, fmt);
7169        };
7170      };
7171      var addFormatChangedListener = function (editor, name, changed) {
7172        var handler = function (state) {
7173          changed(state, name);
7174        };
7175        if (editor.formatter) {
7176          editor.formatter.formatChanged(name, handler);
7177        } else {
7178          editor.on('init', function () {
7179            editor.formatter.formatChanged(name, handler);
7180          });
7181        }
7182      };
7183      var postRenderFormatToggle = function (editor, name) {
7184        return function (e) {
7185          addFormatChangedListener(editor, name, function (state) {
7186            e.control.active(state);
7187          });
7188        };
7189      };
7190  
7191      var register = function (editor) {
7192        var alignFormats = [
7193          'alignleft',
7194          'aligncenter',
7195          'alignright',
7196          'alignjustify'
7197        ];
7198        var defaultAlign = 'alignleft';
7199        var alignMenuItems = [
7200          {
7201            text: 'Left',
7202            icon: 'alignleft',
7203            onclick: toggleFormat(editor, 'alignleft')
7204          },
7205          {
7206            text: 'Center',
7207            icon: 'aligncenter',
7208            onclick: toggleFormat(editor, 'aligncenter')
7209          },
7210          {
7211            text: 'Right',
7212            icon: 'alignright',
7213            onclick: toggleFormat(editor, 'alignright')
7214          },
7215          {
7216            text: 'Justify',
7217            icon: 'alignjustify',
7218            onclick: toggleFormat(editor, 'alignjustify')
7219          }
7220        ];
7221        editor.addMenuItem('align', {
7222          text: 'Align',
7223          menu: alignMenuItems
7224        });
7225        editor.addButton('align', {
7226          type: 'menubutton',
7227          icon: defaultAlign,
7228          menu: alignMenuItems,
7229          onShowMenu: function (e) {
7230            var menu = e.control.menu;
7231            global$4.each(alignFormats, function (formatName, idx) {
7232              menu.items().eq(idx).each(function (item) {
7233                return item.active(editor.formatter.match(formatName));
7234              });
7235            });
7236          },
7237          onPostRender: function (e) {
7238            var ctrl = e.control;
7239            global$4.each(alignFormats, function (formatName, idx) {
7240              addFormatChangedListener(editor, formatName, function (state) {
7241                ctrl.icon(defaultAlign);
7242                if (state) {
7243                  ctrl.icon(formatName);
7244                }
7245              });
7246            });
7247          }
7248        });
7249        global$4.each({
7250          alignleft: [
7251            'Align left',
7252            'JustifyLeft'
7253          ],
7254          aligncenter: [
7255            'Align center',
7256            'JustifyCenter'
7257          ],
7258          alignright: [
7259            'Align right',
7260            'JustifyRight'
7261          ],
7262          alignjustify: [
7263            'Justify',
7264            'JustifyFull'
7265          ],
7266          alignnone: [
7267            'No alignment',
7268            'JustifyNone'
7269          ]
7270        }, function (item, name) {
7271          editor.addButton(name, {
7272            active: false,
7273            tooltip: item[0],
7274            cmd: item[1],
7275            onPostRender: postRenderFormatToggle(editor, name)
7276          });
7277        });
7278      };
7279      var Align = { register: register };
7280  
7281      var getFirstFont = function (fontFamily) {
7282        return fontFamily ? fontFamily.split(',')[0] : '';
7283      };
7284      var findMatchingValue = function (items, fontFamily) {
7285        var font = fontFamily ? fontFamily.toLowerCase() : '';
7286        var value;
7287        global$4.each(items, function (item) {
7288          if (item.value.toLowerCase() === font) {
7289            value = item.value;
7290          }
7291        });
7292        global$4.each(items, function (item) {
7293          if (!value && getFirstFont(item.value).toLowerCase() === getFirstFont(font).toLowerCase()) {
7294            value = item.value;
7295          }
7296        });
7297        return value;
7298      };
7299      var createFontNameListBoxChangeHandler = function (editor, items) {
7300        return function () {
7301          var self = this;
7302          self.state.set('value', null);
7303          editor.on('init nodeChange', function (e) {
7304            var fontFamily = editor.queryCommandValue('FontName');
7305            var match = findMatchingValue(items, fontFamily);
7306            self.value(match ? match : null);
7307            if (!match && fontFamily) {
7308              self.text(getFirstFont(fontFamily));
7309            }
7310          });
7311        };
7312      };
7313      var createFormats = function (formats) {
7314        formats = formats.replace(/;$/, '').split(';');
7315        var i = formats.length;
7316        while (i--) {
7317          formats[i] = formats[i].split('=');
7318        }
7319        return formats;
7320      };
7321      var getFontItems = function (editor) {
7322        var defaultFontsFormats = 'Andale Mono=andale mono,monospace;' + 'Arial=arial,helvetica,sans-serif;' + 'Arial Black=arial black,sans-serif;' + 'Book Antiqua=book antiqua,palatino,serif;' + 'Comic Sans MS=comic sans ms,sans-serif;' + 'Courier New=courier new,courier,monospace;' + 'Georgia=georgia,palatino,serif;' + 'Helvetica=helvetica,arial,sans-serif;' + 'Impact=impact,sans-serif;' + 'Symbol=symbol;' + 'Tahoma=tahoma,arial,helvetica,sans-serif;' + 'Terminal=terminal,monaco,monospace;' + 'Times New Roman=times new roman,times,serif;' + 'Trebuchet MS=trebuchet ms,geneva,sans-serif;' + 'Verdana=verdana,geneva,sans-serif;' + 'Webdings=webdings;' + 'Wingdings=wingdings,zapf dingbats';
7323        var fonts = createFormats(editor.settings.font_formats || defaultFontsFormats);
7324        return global$4.map(fonts, function (font) {
7325          return {
7326            text: { raw: font[0] },
7327            value: font[1],
7328            textStyle: font[1].indexOf('dings') === -1 ? 'font-family:' + font[1] : ''
7329          };
7330        });
7331      };
7332      var registerButtons = function (editor) {
7333        editor.addButton('fontselect', function () {
7334          var items = getFontItems(editor);
7335          return {
7336            type: 'listbox',
7337            text: 'Font Family',
7338            tooltip: 'Font Family',
7339            values: items,
7340            fixedWidth: true,
7341            onPostRender: createFontNameListBoxChangeHandler(editor, items),
7342            onselect: function (e) {
7343              if (e.control.settings.value) {
7344                editor.execCommand('FontName', false, e.control.settings.value);
7345              }
7346            }
7347          };
7348        });
7349      };
7350      var register$1 = function (editor) {
7351        registerButtons(editor);
7352      };
7353      var FontSelect = { register: register$1 };
7354  
7355      var round = function (number, precision) {
7356        var factor = Math.pow(10, precision);
7357        return Math.round(number * factor) / factor;
7358      };
7359      var toPt = function (fontSize, precision) {
7360        if (/[0-9.]+px$/.test(fontSize)) {
7361          return round(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt';
7362        }
7363        return fontSize;
7364      };
7365      var findMatchingValue$1 = function (items, pt, px) {
7366        var value;
7367        global$4.each(items, function (item) {
7368          if (item.value === px) {
7369            value = px;
7370          } else if (item.value === pt) {
7371            value = pt;
7372          }
7373        });
7374        return value;
7375      };
7376      var createFontSizeListBoxChangeHandler = function (editor, items) {
7377        return function () {
7378          var self = this;
7379          editor.on('init nodeChange', function (e) {
7380            var px, pt, precision, match;
7381            px = editor.queryCommandValue('FontSize');
7382            if (px) {
7383              for (precision = 3; !match && precision >= 0; precision--) {
7384                pt = toPt(px, precision);
7385                match = findMatchingValue$1(items, pt, px);
7386              }
7387            }
7388            self.value(match ? match : null);
7389            if (!match) {
7390              self.text(pt);
7391            }
7392          });
7393        };
7394      };
7395      var getFontSizeItems = function (editor) {
7396        var defaultFontsizeFormats = '8pt 10pt 12pt 14pt 18pt 24pt 36pt';
7397        var fontsizeFormats = editor.settings.fontsize_formats || defaultFontsizeFormats;
7398        return global$4.map(fontsizeFormats.split(' '), function (item) {
7399          var text = item, value = item;
7400          var values = item.split('=');
7401          if (values.length > 1) {
7402            text = values[0];
7403            value = values[1];
7404          }
7405          return {
7406            text: text,
7407            value: value
7408          };
7409        });
7410      };
7411      var registerButtons$1 = function (editor) {
7412        editor.addButton('fontsizeselect', function () {
7413          var items = getFontSizeItems(editor);
7414          return {
7415            type: 'listbox',
7416            text: 'Font Sizes',
7417            tooltip: 'Font Sizes',
7418            values: items,
7419            fixedWidth: true,
7420            onPostRender: createFontSizeListBoxChangeHandler(editor, items),
7421            onclick: function (e) {
7422              if (e.control.settings.value) {
7423                editor.execCommand('FontSize', false, e.control.settings.value);
7424              }
7425            }
7426          };
7427        });
7428      };
7429      var register$2 = function (editor) {
7430        registerButtons$1(editor);
7431      };
7432      var FontSizeSelect = { register: register$2 };
7433  
7434      var hideMenuObjects = function (editor, menu) {
7435        var count = menu.length;
7436        global$4.each(menu, function (item) {
7437          if (item.menu) {
7438            item.hidden = hideMenuObjects(editor, item.menu) === 0;
7439          }
7440          var formatName = item.format;
7441          if (formatName) {
7442            item.hidden = !editor.formatter.canApply(formatName);
7443          }
7444          if (item.hidden) {
7445            count--;
7446          }
7447        });
7448        return count;
7449      };
7450      var hideFormatMenuItems = function (editor, menu) {
7451        var count = menu.items().length;
7452        menu.items().each(function (item) {
7453          if (item.menu) {
7454            item.visible(hideFormatMenuItems(editor, item.menu) > 0);
7455          }
7456          if (!item.menu && item.settings.menu) {
7457            item.visible(hideMenuObjects(editor, item.settings.menu) > 0);
7458          }
7459          var formatName = item.settings.format;
7460          if (formatName) {
7461            item.visible(editor.formatter.canApply(formatName));
7462          }
7463          if (!item.visible()) {
7464            count--;
7465          }
7466        });
7467        return count;
7468      };
7469      var createFormatMenu = function (editor) {
7470        var count = 0;
7471        var newFormats = [];
7472        var defaultStyleFormats = [
7473          {
7474            title: 'Headings',
7475            items: [
7476              {
7477                title: 'Heading 1',
7478                format: 'h1'
7479              },
7480              {
7481                title: 'Heading 2',
7482                format: 'h2'
7483              },
7484              {
7485                title: 'Heading 3',
7486                format: 'h3'
7487              },
7488              {
7489                title: 'Heading 4',
7490                format: 'h4'
7491              },
7492              {
7493                title: 'Heading 5',
7494                format: 'h5'
7495              },
7496              {
7497                title: 'Heading 6',
7498                format: 'h6'
7499              }
7500            ]
7501          },
7502          {
7503            title: 'Inline',
7504            items: [
7505              {
7506                title: 'Bold',
7507                icon: 'bold',
7508                format: 'bold'
7509              },
7510              {
7511                title: 'Italic',
7512                icon: 'italic',
7513                format: 'italic'
7514              },
7515              {
7516                title: 'Underline',
7517                icon: 'underline',
7518                format: 'underline'
7519              },
7520              {
7521                title: 'Strikethrough',
7522                icon: 'strikethrough',
7523                format: 'strikethrough'
7524              },
7525              {
7526                title: 'Superscript',
7527                icon: 'superscript',
7528                format: 'superscript'
7529              },
7530              {
7531                title: 'Subscript',
7532                icon: 'subscript',
7533                format: 'subscript'
7534              },
7535              {
7536                title: 'Code',
7537                icon: 'code',
7538                format: 'code'
7539              }
7540            ]
7541          },
7542          {
7543            title: 'Blocks',
7544            items: [
7545              {
7546                title: 'Paragraph',
7547                format: 'p'
7548              },
7549              {
7550                title: 'Blockquote',
7551                format: 'blockquote'
7552              },
7553              {
7554                title: 'Div',
7555                format: 'div'
7556              },
7557              {
7558                title: 'Pre',
7559                format: 'pre'
7560              }
7561            ]
7562          },
7563          {
7564            title: 'Alignment',
7565            items: [
7566              {
7567                title: 'Left',
7568                icon: 'alignleft',
7569                format: 'alignleft'
7570              },
7571              {
7572                title: 'Center',
7573                icon: 'aligncenter',
7574                format: 'aligncenter'
7575              },
7576              {
7577                title: 'Right',
7578                icon: 'alignright',
7579                format: 'alignright'
7580              },
7581              {
7582                title: 'Justify',
7583                icon: 'alignjustify',
7584                format: 'alignjustify'
7585              }
7586            ]
7587          }
7588        ];
7589        var createMenu = function (formats) {
7590          var menu = [];
7591          if (!formats) {
7592            return;
7593          }
7594          global$4.each(formats, function (format) {
7595            var menuItem = {
7596              text: format.title,
7597              icon: format.icon
7598            };
7599            if (format.items) {
7600              menuItem.menu = createMenu(format.items);
7601            } else {
7602              var formatName = format.format || 'custom' + count++;
7603              if (!format.format) {
7604                format.name = formatName;
7605                newFormats.push(format);
7606              }
7607              menuItem.format = formatName;
7608              menuItem.cmd = format.cmd;
7609            }
7610            menu.push(menuItem);
7611          });
7612          return menu;
7613        };
7614        var createStylesMenu = function () {
7615          var menu;
7616          if (editor.settings.style_formats_merge) {
7617            if (editor.settings.style_formats) {
7618              menu = createMenu(defaultStyleFormats.concat(editor.settings.style_formats));
7619            } else {
7620              menu = createMenu(defaultStyleFormats);
7621            }
7622          } else {
7623            menu = createMenu(editor.settings.style_formats || defaultStyleFormats);
7624          }
7625          return menu;
7626        };
7627        editor.on('init', function () {
7628          global$4.each(newFormats, function (format) {
7629            editor.formatter.register(format.name, format);
7630          });
7631        });
7632        return {
7633          type: 'menu',
7634          items: createStylesMenu(),
7635          onPostRender: function (e) {
7636            editor.fire('renderFormatsMenu', { control: e.control });
7637          },
7638          itemDefaults: {
7639            preview: true,
7640            textStyle: function () {
7641              if (this.settings.format) {
7642                return editor.formatter.getCssText(this.settings.format);
7643              }
7644            },
7645            onPostRender: function () {
7646              var self = this;
7647              self.parent().on('show', function () {
7648                var formatName, command;
7649                formatName = self.settings.format;
7650                if (formatName) {
7651                  self.disabled(!editor.formatter.canApply(formatName));
7652                  self.active(editor.formatter.match(formatName));
7653                }
7654                command = self.settings.cmd;
7655                if (command) {
7656                  self.active(editor.queryCommandState(command));
7657                }
7658              });
7659            },
7660            onclick: function () {
7661              if (this.settings.format) {
7662                toggleFormat(editor, this.settings.format)();
7663              }
7664              if (this.settings.cmd) {
7665                editor.execCommand(this.settings.cmd);
7666              }
7667            }
7668          }
7669        };
7670      };
7671      var registerMenuItems = function (editor, formatMenu) {
7672        editor.addMenuItem('formats', {
7673          text: 'Formats',
7674          menu: formatMenu
7675        });
7676      };
7677      var registerButtons$2 = function (editor, formatMenu) {
7678        editor.addButton('styleselect', {
7679          type: 'menubutton',
7680          text: 'Formats',
7681          menu: formatMenu,
7682          onShowMenu: function () {
7683            if (editor.settings.style_formats_autohide) {
7684              hideFormatMenuItems(editor, this.menu);
7685            }
7686          }
7687        });
7688      };
7689      var register$3 = function (editor) {
7690        var formatMenu = createFormatMenu(editor);
7691        registerMenuItems(editor, formatMenu);
7692        registerButtons$2(editor, formatMenu);
7693      };
7694      var Formats = { register: register$3 };
7695  
7696      var defaultBlocks = 'Paragraph=p;' + 'Heading 1=h1;' + 'Heading 2=h2;' + 'Heading 3=h3;' + 'Heading 4=h4;' + 'Heading 5=h5;' + 'Heading 6=h6;' + 'Preformatted=pre';
7697      var createFormats$1 = function (formats) {
7698        formats = formats.replace(/;$/, '').split(';');
7699        var i = formats.length;
7700        while (i--) {
7701          formats[i] = formats[i].split('=');
7702        }
7703        return formats;
7704      };
7705      var createListBoxChangeHandler = function (editor, items, formatName) {
7706        return function () {
7707          var self = this;
7708          editor.on('nodeChange', function (e) {
7709            var formatter = editor.formatter;
7710            var value = null;
7711            global$4.each(e.parents, function (node) {
7712              global$4.each(items, function (item) {
7713                if (formatName) {
7714                  if (formatter.matchNode(node, formatName, { value: item.value })) {
7715                    value = item.value;
7716                  }
7717                } else {
7718                  if (formatter.matchNode(node, item.value)) {
7719                    value = item.value;
7720                  }
7721                }
7722                if (value) {
7723                  return false;
7724                }
7725              });
7726              if (value) {
7727                return false;
7728              }
7729            });
7730            self.value(value);
7731          });
7732        };
7733      };
7734      var lazyFormatSelectBoxItems = function (editor, blocks) {
7735        return function () {
7736          var items = [];
7737          global$4.each(blocks, function (block) {
7738            items.push({
7739              text: block[0],
7740              value: block[1],
7741              textStyle: function () {
7742                return editor.formatter.getCssText(block[1]);
7743              }
7744            });
7745          });
7746          return {
7747            type: 'listbox',
7748            text: blocks[0][0],
7749            values: items,
7750            fixedWidth: true,
7751            onselect: function (e) {
7752              if (e.control) {
7753                var fmt = e.control.value();
7754                toggleFormat(editor, fmt)();
7755              }
7756            },
7757            onPostRender: createListBoxChangeHandler(editor, items)
7758          };
7759        };
7760      };
7761      var buildMenuItems = function (editor, blocks) {
7762        return global$4.map(blocks, function (block) {
7763          return {
7764            text: block[0],
7765            onclick: toggleFormat(editor, block[1]),
7766            textStyle: function () {
7767              return editor.formatter.getCssText(block[1]);
7768            }
7769          };
7770        });
7771      };
7772      var register$4 = function (editor) {
7773        var blocks = createFormats$1(editor.settings.block_formats || defaultBlocks);
7774        editor.addMenuItem('blockformats', {
7775          text: 'Blocks',
7776          menu: buildMenuItems(editor, blocks)
7777        });
7778        editor.addButton('formatselect', lazyFormatSelectBoxItems(editor, blocks));
7779      };
7780      var FormatSelect = { register: register$4 };
7781  
7782      var createCustomMenuItems = function (editor, names) {
7783        var items, nameList;
7784        if (typeof names === 'string') {
7785          nameList = names.split(' ');
7786        } else if (global$4.isArray(names)) {
7787          return flatten$1(global$4.map(names, function (names) {
7788            return createCustomMenuItems(editor, names);
7789          }));
7790        }
7791        items = global$4.grep(nameList, function (name) {
7792          return name === '|' || name in editor.menuItems;
7793        });
7794        return global$4.map(items, function (name) {
7795          return name === '|' ? { text: '-' } : editor.menuItems[name];
7796        });
7797      };
7798      var isSeparator = function (menuItem) {
7799        return menuItem && menuItem.text === '-';
7800      };
7801      var trimMenuItems = function (menuItems) {
7802        var menuItems2 = filter(menuItems, function (menuItem, i) {
7803          return !isSeparator(menuItem) || !isSeparator(menuItems[i - 1]);
7804        });
7805        return filter(menuItems2, function (menuItem, i) {
7806          return !isSeparator(menuItem) || i > 0 && i < menuItems2.length - 1;
7807        });
7808      };
7809      var createContextMenuItems = function (editor, context) {
7810        var outputMenuItems = [{ text: '-' }];
7811        var menuItems = global$4.grep(editor.menuItems, function (menuItem) {
7812          return menuItem.context === context;
7813        });
7814        global$4.each(menuItems, function (menuItem) {
7815          if (menuItem.separator === 'before') {
7816            outputMenuItems.push({ text: '|' });
7817          }
7818          if (menuItem.prependToContext) {
7819            outputMenuItems.unshift(menuItem);
7820          } else {
7821            outputMenuItems.push(menuItem);
7822          }
7823          if (menuItem.separator === 'after') {
7824            outputMenuItems.push({ text: '|' });
7825          }
7826        });
7827        return outputMenuItems;
7828      };
7829      var createInsertMenu = function (editor) {
7830        var insertButtonItems = editor.settings.insert_button_items;
7831        if (insertButtonItems) {
7832          return trimMenuItems(createCustomMenuItems(editor, insertButtonItems));
7833        } else {
7834          return trimMenuItems(createContextMenuItems(editor, 'insert'));
7835        }
7836      };
7837      var registerButtons$3 = function (editor) {
7838        editor.addButton('insert', {
7839          type: 'menubutton',
7840          icon: 'insert',
7841          menu: [],
7842          oncreatemenu: function () {
7843            this.menu.add(createInsertMenu(editor));
7844            this.menu.renderNew();
7845          }
7846        });
7847      };
7848      var register$5 = function (editor) {
7849        registerButtons$3(editor);
7850      };
7851      var InsertButton = { register: register$5 };
7852  
7853      var registerFormatButtons = function (editor) {
7854        global$4.each({
7855          bold: 'Bold',
7856          italic: 'Italic',
7857          underline: 'Underline',
7858          strikethrough: 'Strikethrough',
7859          subscript: 'Subscript',
7860          superscript: 'Superscript'
7861        }, function (text, name) {
7862          editor.addButton(name, {
7863            active: false,
7864            tooltip: text,
7865            onPostRender: postRenderFormatToggle(editor, name),
7866            onclick: toggleFormat(editor, name)
7867          });
7868        });
7869      };
7870      var registerCommandButtons = function (editor) {
7871        global$4.each({
7872          outdent: [
7873            'Decrease indent',
7874            'Outdent'
7875          ],
7876          indent: [
7877            'Increase indent',
7878            'Indent'
7879          ],
7880          cut: [
7881            'Cut',
7882            'Cut'
7883          ],
7884          copy: [
7885            'Copy',
7886            'Copy'
7887          ],
7888          paste: [
7889            'Paste',
7890            'Paste'
7891          ],
7892          help: [
7893            'Help',
7894            'mceHelp'
7895          ],
7896          selectall: [
7897            'Select all',
7898            'SelectAll'
7899          ],
7900          visualaid: [
7901            'Visual aids',
7902            'mceToggleVisualAid'
7903          ],
7904          newdocument: [
7905            'New document',
7906            'mceNewDocument'
7907          ],
7908          removeformat: [
7909            'Clear formatting',
7910            'RemoveFormat'
7911          ],
7912          remove: [
7913            'Remove',
7914            'Delete'
7915          ]
7916        }, function (item, name) {
7917          editor.addButton(name, {
7918            tooltip: item[0],
7919            cmd: item[1]
7920          });
7921        });
7922      };
7923      var registerCommandToggleButtons = function (editor) {
7924        global$4.each({
7925          blockquote: [
7926            'Blockquote',
7927            'mceBlockQuote'
7928          ],
7929          subscript: [
7930            'Subscript',
7931            'Subscript'
7932          ],
7933          superscript: [
7934            'Superscript',
7935            'Superscript'
7936          ]
7937        }, function (item, name) {
7938          editor.addButton(name, {
7939            active: false,
7940            tooltip: item[0],
7941            cmd: item[1],
7942            onPostRender: postRenderFormatToggle(editor, name)
7943          });
7944        });
7945      };
7946      var registerButtons$4 = function (editor) {
7947        registerFormatButtons(editor);
7948        registerCommandButtons(editor);
7949        registerCommandToggleButtons(editor);
7950      };
7951      var registerMenuItems$1 = function (editor) {
7952        global$4.each({
7953          bold: [
7954            'Bold',
7955            'Bold',
7956            'Meta+B'
7957          ],
7958          italic: [
7959            'Italic',
7960            'Italic',
7961            'Meta+I'
7962          ],
7963          underline: [
7964            'Underline',
7965            'Underline',
7966            'Meta+U'
7967          ],
7968          strikethrough: [
7969            'Strikethrough',
7970            'Strikethrough'
7971          ],
7972          subscript: [
7973            'Subscript',
7974            'Subscript'
7975          ],
7976          superscript: [
7977            'Superscript',
7978            'Superscript'
7979          ],
7980          removeformat: [
7981            'Clear formatting',
7982            'RemoveFormat'
7983          ],
7984          newdocument: [
7985            'New document',
7986            'mceNewDocument'
7987          ],
7988          cut: [
7989            'Cut',
7990            'Cut',
7991            'Meta+X'
7992          ],
7993          copy: [
7994            'Copy',
7995            'Copy',
7996            'Meta+C'
7997          ],
7998          paste: [
7999            'Paste',
8000            'Paste',
8001            'Meta+V'
8002          ],
8003          selectall: [
8004            'Select all',
8005            'SelectAll',
8006            'Meta+A'
8007          ]
8008        }, function (item, name) {
8009          editor.addMenuItem(name, {
8010            text: item[0],
8011            icon: name,
8012            shortcut: item[2],
8013            cmd: item[1]
8014          });
8015        });
8016        editor.addMenuItem('codeformat', {
8017          text: 'Code',
8018          icon: 'code',
8019          onclick: toggleFormat(editor, 'code')
8020        });
8021      };
8022      var register$6 = function (editor) {
8023        registerButtons$4(editor);
8024        registerMenuItems$1(editor);
8025      };
8026      var SimpleControls = { register: register$6 };
8027  
8028      var toggleUndoRedoState = function (editor, type) {
8029        return function () {
8030          var self = this;
8031          var checkState = function () {
8032            var typeFn = type === 'redo' ? 'hasRedo' : 'hasUndo';
8033            return editor.undoManager ? editor.undoManager[typeFn]() : false;
8034          };
8035          self.disabled(!checkState());
8036          editor.on('Undo Redo AddUndo TypingUndo ClearUndos SwitchMode', function () {
8037            self.disabled(editor.readonly || !checkState());
8038          });
8039        };
8040      };
8041      var registerMenuItems$2 = function (editor) {
8042        editor.addMenuItem('undo', {
8043          text: 'Undo',
8044          icon: 'undo',
8045          shortcut: 'Meta+Z',
8046          onPostRender: toggleUndoRedoState(editor, 'undo'),
8047          cmd: 'undo'
8048        });
8049        editor.addMenuItem('redo', {
8050          text: 'Redo',
8051          icon: 'redo',
8052          shortcut: 'Meta+Y',
8053          onPostRender: toggleUndoRedoState(editor, 'redo'),
8054          cmd: 'redo'
8055        });
8056      };
8057      var registerButtons$5 = function (editor) {
8058        editor.addButton('undo', {
8059          tooltip: 'Undo',
8060          onPostRender: toggleUndoRedoState(editor, 'undo'),
8061          cmd: 'undo'
8062        });
8063        editor.addButton('redo', {
8064          tooltip: 'Redo',
8065          onPostRender: toggleUndoRedoState(editor, 'redo'),
8066          cmd: 'redo'
8067        });
8068      };
8069      var register$7 = function (editor) {
8070        registerMenuItems$2(editor);
8071        registerButtons$5(editor);
8072      };
8073      var UndoRedo = { register: register$7 };
8074  
8075      var toggleVisualAidState = function (editor) {
8076        return function () {
8077          var self = this;
8078          editor.on('VisualAid', function (e) {
8079            self.active(e.hasVisual);
8080          });
8081          self.active(editor.hasVisual);
8082        };
8083      };
8084      var registerMenuItems$3 = function (editor) {
8085        editor.addMenuItem('visualaid', {
8086          text: 'Visual aids',
8087          selectable: true,
8088          onPostRender: toggleVisualAidState(editor),
8089          cmd: 'mceToggleVisualAid'
8090        });
8091      };
8092      var register$8 = function (editor) {
8093        registerMenuItems$3(editor);
8094      };
8095      var VisualAid = { register: register$8 };
8096  
8097      var setupEnvironment = function () {
8098        Widget.tooltips = !global$1.iOS;
8099        Control$1.translate = function (text) {
8100          return global$5.translate(text);
8101        };
8102      };
8103      var setupUiContainer = function (editor) {
8104        if (editor.settings.ui_container) {
8105          global$1.container = descendant(Element.fromDom(domGlobals.document.body), editor.settings.ui_container).fold(constant(null), function (elm) {
8106            return elm.dom();
8107          });
8108        }
8109      };
8110      var setupRtlMode = function (editor) {
8111        if (editor.rtl) {
8112          Control$1.rtl = true;
8113        }
8114      };
8115      var setupHideFloatPanels = function (editor) {
8116        editor.on('mousedown progressstate', function () {
8117          FloatPanel.hideAll();
8118        });
8119      };
8120      var setup = function (editor) {
8121        setupRtlMode(editor);
8122        setupHideFloatPanels(editor);
8123        setupUiContainer(editor);
8124        setupEnvironment();
8125        FormatSelect.register(editor);
8126        Align.register(editor);
8127        SimpleControls.register(editor);
8128        UndoRedo.register(editor);
8129        FontSizeSelect.register(editor);
8130        FontSelect.register(editor);
8131        Formats.register(editor);
8132        VisualAid.register(editor);
8133        InsertButton.register(editor);
8134      };
8135      var FormatControls = { setup: setup };
8136  
8137      var GridLayout = AbsoluteLayout.extend({
8138        recalc: function (container) {
8139          var settings, rows, cols, items, contLayoutRect, width, height, rect, ctrlLayoutRect, ctrl, x, y, posX, posY, ctrlSettings, contPaddingBox, align, spacingH, spacingV, alignH, alignV, maxX, maxY;
8140          var colWidths = [];
8141          var rowHeights = [];
8142          var ctrlMinWidth, ctrlMinHeight, availableWidth, availableHeight, reverseRows, idx;
8143          settings = container.settings;
8144          items = container.items().filter(':visible');
8145          contLayoutRect = container.layoutRect();
8146          cols = settings.columns || Math.ceil(Math.sqrt(items.length));
8147          rows = Math.ceil(items.length / cols);
8148          spacingH = settings.spacingH || settings.spacing || 0;
8149          spacingV = settings.spacingV || settings.spacing || 0;
8150          alignH = settings.alignH || settings.align;
8151          alignV = settings.alignV || settings.align;
8152          contPaddingBox = container.paddingBox;
8153          reverseRows = 'reverseRows' in settings ? settings.reverseRows : container.isRtl();
8154          if (alignH && typeof alignH === 'string') {
8155            alignH = [alignH];
8156          }
8157          if (alignV && typeof alignV === 'string') {
8158            alignV = [alignV];
8159          }
8160          for (x = 0; x < cols; x++) {
8161            colWidths.push(0);
8162          }
8163          for (y = 0; y < rows; y++) {
8164            rowHeights.push(0);
8165          }
8166          for (y = 0; y < rows; y++) {
8167            for (x = 0; x < cols; x++) {
8168              ctrl = items[y * cols + x];
8169              if (!ctrl) {
8170                break;
8171              }
8172              ctrlLayoutRect = ctrl.layoutRect();
8173              ctrlMinWidth = ctrlLayoutRect.minW;
8174              ctrlMinHeight = ctrlLayoutRect.minH;
8175              colWidths[x] = ctrlMinWidth > colWidths[x] ? ctrlMinWidth : colWidths[x];
8176              rowHeights[y] = ctrlMinHeight > rowHeights[y] ? ctrlMinHeight : rowHeights[y];
8177            }
8178          }
8179          availableWidth = contLayoutRect.innerW - contPaddingBox.left - contPaddingBox.right;
8180          for (maxX = 0, x = 0; x < cols; x++) {
8181            maxX += colWidths[x] + (x > 0 ? spacingH : 0);
8182            availableWidth -= (x > 0 ? spacingH : 0) + colWidths[x];
8183          }
8184          availableHeight = contLayoutRect.innerH - contPaddingBox.top - contPaddingBox.bottom;
8185          for (maxY = 0, y = 0; y < rows; y++) {
8186            maxY += rowHeights[y] + (y > 0 ? spacingV : 0);
8187            availableHeight -= (y > 0 ? spacingV : 0) + rowHeights[y];
8188          }
8189          maxX += contPaddingBox.left + contPaddingBox.right;
8190          maxY += contPaddingBox.top + contPaddingBox.bottom;
8191          rect = {};
8192          rect.minW = maxX + (contLayoutRect.w - contLayoutRect.innerW);
8193          rect.minH = maxY + (contLayoutRect.h - contLayoutRect.innerH);
8194          rect.contentW = rect.minW - contLayoutRect.deltaW;
8195          rect.contentH = rect.minH - contLayoutRect.deltaH;
8196          rect.minW = Math.min(rect.minW, contLayoutRect.maxW);
8197          rect.minH = Math.min(rect.minH, contLayoutRect.maxH);
8198          rect.minW = Math.max(rect.minW, contLayoutRect.startMinWidth);
8199          rect.minH = Math.max(rect.minH, contLayoutRect.startMinHeight);
8200          if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) {
8201            rect.w = rect.minW;
8202            rect.h = rect.minH;
8203            container.layoutRect(rect);
8204            this.recalc(container);
8205            if (container._lastRect === null) {
8206              var parentCtrl = container.parent();
8207              if (parentCtrl) {
8208                parentCtrl._lastRect = null;
8209                parentCtrl.recalc();
8210              }
8211            }
8212            return;
8213          }
8214          if (contLayoutRect.autoResize) {
8215            rect = container.layoutRect(rect);
8216            rect.contentW = rect.minW - contLayoutRect.deltaW;
8217            rect.contentH = rect.minH - contLayoutRect.deltaH;
8218          }
8219          var flexV;
8220          if (settings.packV === 'start') {
8221            flexV = 0;
8222          } else {
8223            flexV = availableHeight > 0 ? Math.floor(availableHeight / rows) : 0;
8224          }
8225          var totalFlex = 0;
8226          var flexWidths = settings.flexWidths;
8227          if (flexWidths) {
8228            for (x = 0; x < flexWidths.length; x++) {
8229              totalFlex += flexWidths[x];
8230            }
8231          } else {
8232            totalFlex = cols;
8233          }
8234          var ratio = availableWidth / totalFlex;
8235          for (x = 0; x < cols; x++) {
8236            colWidths[x] += flexWidths ? flexWidths[x] * ratio : ratio;
8237          }
8238          posY = contPaddingBox.top;
8239          for (y = 0; y < rows; y++) {
8240            posX = contPaddingBox.left;
8241            height = rowHeights[y] + flexV;
8242            for (x = 0; x < cols; x++) {
8243              if (reverseRows) {
8244                idx = y * cols + cols - 1 - x;
8245              } else {
8246                idx = y * cols + x;
8247              }
8248              ctrl = items[idx];
8249              if (!ctrl) {
8250                break;
8251              }
8252              ctrlSettings = ctrl.settings;
8253              ctrlLayoutRect = ctrl.layoutRect();
8254              width = Math.max(colWidths[x], ctrlLayoutRect.startMinWidth);
8255              ctrlLayoutRect.x = posX;
8256              ctrlLayoutRect.y = posY;
8257              align = ctrlSettings.alignH || (alignH ? alignH[x] || alignH[0] : null);
8258              if (align === 'center') {
8259                ctrlLayoutRect.x = posX + width / 2 - ctrlLayoutRect.w / 2;
8260              } else if (align === 'right') {
8261                ctrlLayoutRect.x = posX + width - ctrlLayoutRect.w;
8262              } else if (align === 'stretch') {
8263                ctrlLayoutRect.w = width;
8264              }
8265              align = ctrlSettings.alignV || (alignV ? alignV[x] || alignV[0] : null);
8266              if (align === 'center') {
8267                ctrlLayoutRect.y = posY + height / 2 - ctrlLayoutRect.h / 2;
8268              } else if (align === 'bottom') {
8269                ctrlLayoutRect.y = posY + height - ctrlLayoutRect.h;
8270              } else if (align === 'stretch') {
8271                ctrlLayoutRect.h = height;
8272              }
8273              ctrl.layoutRect(ctrlLayoutRect);
8274              posX += width + spacingH;
8275              if (ctrl.recalc) {
8276                ctrl.recalc();
8277              }
8278            }
8279            posY += height + spacingV;
8280          }
8281        }
8282      });
8283  
8284      var Iframe = Widget.extend({
8285        renderHtml: function () {
8286          var self = this;
8287          self.classes.add('iframe');
8288          self.canFocus = false;
8289          return '<iframe id="' + self._id + '" class="' + self.classes + '" tabindex="-1" src="' + (self.settings.url || 'javascript:\'\'') + '" frameborder="0"></iframe>';
8290        },
8291        src: function (src) {
8292          this.getEl().src = src;
8293        },
8294        html: function (html, callback) {
8295          var self = this, body = this.getEl().contentWindow.document.body;
8296          if (!body) {
8297            global$3.setTimeout(function () {
8298              self.html(html);
8299            });
8300          } else {
8301            body.innerHTML = html;
8302            if (callback) {
8303              callback();
8304            }
8305          }
8306          return this;
8307        }
8308      });
8309  
8310      var InfoBox = Widget.extend({
8311        init: function (settings) {
8312          var self = this;
8313          self._super(settings);
8314          self.classes.add('widget').add('infobox');
8315          self.canFocus = false;
8316        },
8317        severity: function (level) {
8318          this.classes.remove('error');
8319          this.classes.remove('warning');
8320          this.classes.remove('success');
8321          this.classes.add(level);
8322        },
8323        help: function (state) {
8324          this.state.set('help', state);
8325        },
8326        renderHtml: function () {
8327          var self = this, prefix = self.classPrefix;
8328          return '<div id="' + self._id + '" class="' + self.classes + '">' + '<div id="' + self._id + '-body">' + self.encode(self.state.get('text')) + '<button role="button" tabindex="-1">' + '<i class="' + prefix + 'ico ' + prefix + 'i-help"></i>' + '</button>' + '</div>' + '</div>';
8329        },
8330        bindStates: function () {
8331          var self = this;
8332          self.state.on('change:text', function (e) {
8333            self.getEl('body').firstChild.data = self.encode(e.value);
8334            if (self.state.get('rendered')) {
8335              self.updateLayoutRect();
8336            }
8337          });
8338          self.state.on('change:help', function (e) {
8339            self.classes.toggle('has-help', e.value);
8340            if (self.state.get('rendered')) {
8341              self.updateLayoutRect();
8342            }
8343          });
8344          return self._super();
8345        }
8346      });
8347  
8348      var Label = Widget.extend({
8349        init: function (settings) {
8350          var self = this;
8351          self._super(settings);
8352          self.classes.add('widget').add('label');
8353          self.canFocus = false;
8354          if (settings.multiline) {
8355            self.classes.add('autoscroll');
8356          }
8357          if (settings.strong) {
8358            self.classes.add('strong');
8359          }
8360        },
8361        initLayoutRect: function () {
8362          var self = this, layoutRect = self._super();
8363          if (self.settings.multiline) {
8364            var size = funcs.getSize(self.getEl());
8365            if (size.width > layoutRect.maxW) {
8366              layoutRect.minW = layoutRect.maxW;
8367              self.classes.add('multiline');
8368            }
8369            self.getEl().style.width = layoutRect.minW + 'px';
8370            layoutRect.startMinH = layoutRect.h = layoutRect.minH = Math.min(layoutRect.maxH, funcs.getSize(self.getEl()).height);
8371          }
8372          return layoutRect;
8373        },
8374        repaint: function () {
8375          var self = this;
8376          if (!self.settings.multiline) {
8377            self.getEl().style.lineHeight = self.layoutRect().h + 'px';
8378          }
8379          return self._super();
8380        },
8381        severity: function (level) {
8382          this.classes.remove('error');
8383          this.classes.remove('warning');
8384          this.classes.remove('success');
8385          this.classes.add(level);
8386        },
8387        renderHtml: function () {
8388          var self = this;
8389          var targetCtrl, forName, forId = self.settings.forId;
8390          var text = self.settings.html ? self.settings.html : self.encode(self.state.get('text'));
8391          if (!forId && (forName = self.settings.forName)) {
8392            targetCtrl = self.getRoot().find('#' + forName)[0];
8393            if (targetCtrl) {
8394              forId = targetCtrl._id;
8395            }
8396          }
8397          if (forId) {
8398            return '<label id="' + self._id + '" class="' + self.classes + '"' + (forId ? ' for="' + forId + '"' : '') + '>' + text + '</label>';
8399          }
8400          return '<span id="' + self._id + '" class="' + self.classes + '">' + text + '</span>';
8401        },
8402        bindStates: function () {
8403          var self = this;
8404          self.state.on('change:text', function (e) {
8405            self.innerHtml(self.encode(e.value));
8406            if (self.state.get('rendered')) {
8407              self.updateLayoutRect();
8408            }
8409          });
8410          return self._super();
8411        }
8412      });
8413  
8414      var Toolbar$1 = Container.extend({
8415        Defaults: {
8416          role: 'toolbar',
8417          layout: 'flow'
8418        },
8419        init: function (settings) {
8420          var self = this;
8421          self._super(settings);
8422          self.classes.add('toolbar');
8423        },
8424        postRender: function () {
8425          var self = this;
8426          self.items().each(function (ctrl) {
8427            ctrl.classes.add('toolbar-item');
8428          });
8429          return self._super();
8430        }
8431      });
8432  
8433      var MenuBar = Toolbar$1.extend({
8434        Defaults: {
8435          role: 'menubar',
8436          containerCls: 'menubar',
8437          ariaRoot: true,
8438          defaults: { type: 'menubutton' }
8439        }
8440      });
8441  
8442      function isChildOf$1(node, parent) {
8443        while (node) {
8444          if (parent === node) {
8445            return true;
8446          }
8447          node = node.parentNode;
8448        }
8449        return false;
8450      }
8451      var MenuButton = Button.extend({
8452        init: function (settings) {
8453          var self = this;
8454          self._renderOpen = true;
8455          self._super(settings);
8456          settings = self.settings;
8457          self.classes.add('menubtn');
8458          if (settings.fixedWidth) {
8459            self.classes.add('fixed-width');
8460          }
8461          self.aria('haspopup', true);
8462          self.state.set('menu', settings.menu || self.render());
8463        },
8464        showMenu: function (toggle) {
8465          var self = this;
8466          var menu;
8467          if (self.menu && self.menu.visible() && toggle !== false) {
8468            return self.hideMenu();
8469          }
8470          if (!self.menu) {
8471            menu = self.state.get('menu') || [];
8472            self.classes.add('opened');
8473            if (menu.length) {
8474              menu = {
8475                type: 'menu',
8476                animate: true,
8477                items: menu
8478              };
8479            } else {
8480              menu.type = menu.type || 'menu';
8481              menu.animate = true;
8482            }
8483            if (!menu.renderTo) {
8484              self.menu = global$b.create(menu).parent(self).renderTo();
8485            } else {
8486              self.menu = menu.parent(self).show().renderTo();
8487            }
8488            self.fire('createmenu');
8489            self.menu.reflow();
8490            self.menu.on('cancel', function (e) {
8491              if (e.control.parent() === self.menu) {
8492                e.stopPropagation();
8493                self.focus();
8494                self.hideMenu();
8495              }
8496            });
8497            self.menu.on('select', function () {
8498              self.focus();
8499            });
8500            self.menu.on('show hide', function (e) {
8501              if (e.type === 'hide' && e.control.parent() === self) {
8502                self.classes.remove('opened-under');
8503              }
8504              if (e.control === self.menu) {
8505                self.activeMenu(e.type === 'show');
8506                self.classes.toggle('opened', e.type === 'show');
8507              }
8508              self.aria('expanded', e.type === 'show');
8509            }).fire('show');
8510          }
8511          self.menu.show();
8512          self.menu.layoutRect({ w: self.layoutRect().w });
8513          self.menu.repaint();
8514          self.menu.moveRel(self.getEl(), self.isRtl() ? [
8515            'br-tr',
8516            'tr-br'
8517          ] : [
8518            'bl-tl',
8519            'tl-bl'
8520          ]);
8521          var menuLayoutRect = self.menu.layoutRect();
8522          var selfBottom = self.$el.offset().top + self.layoutRect().h;
8523          if (selfBottom > menuLayoutRect.y && selfBottom < menuLayoutRect.y + menuLayoutRect.h) {
8524            self.classes.add('opened-under');
8525          }
8526          self.fire('showmenu');
8527        },
8528        hideMenu: function () {
8529          var self = this;
8530          if (self.menu) {
8531            self.menu.items().each(function (item) {
8532              if (item.hideMenu) {
8533                item.hideMenu();
8534              }
8535            });
8536            self.menu.hide();
8537          }
8538        },
8539        activeMenu: function (state) {
8540          this.classes.toggle('active', state);
8541        },
8542        renderHtml: function () {
8543          var self = this, id = self._id, prefix = self.classPrefix;
8544          var icon = self.settings.icon, image;
8545          var text = self.state.get('text');
8546          var textHtml = '';
8547          image = self.settings.image;
8548          if (image) {
8549            icon = 'none';
8550            if (typeof image !== 'string') {
8551              image = domGlobals.window.getSelection ? image[0] : image[1];
8552            }
8553            image = ' style="background-image: url(\'' + image + '\')"';
8554          } else {
8555            image = '';
8556          }
8557          if (text) {
8558            self.classes.add('btn-has-text');
8559            textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>';
8560          }
8561          icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : '';
8562          self.aria('role', self.parent() instanceof MenuBar ? 'menuitem' : 'button');
8563          return '<div id="' + id + '" class="' + self.classes + '" tabindex="-1" aria-labelledby="' + id + '">' + '<button id="' + id + '-open" role="presentation" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + textHtml + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>';
8564        },
8565        postRender: function () {
8566          var self = this;
8567          self.on('click', function (e) {
8568            if (e.control === self && isChildOf$1(e.target, self.getEl())) {
8569              self.focus();
8570              self.showMenu(!e.aria);
8571              if (e.aria) {
8572                self.menu.items().filter(':visible')[0].focus();
8573              }
8574            }
8575          });
8576          self.on('mouseenter', function (e) {
8577            var overCtrl = e.control;
8578            var parent = self.parent();
8579            var hasVisibleSiblingMenu;
8580            if (overCtrl && parent && overCtrl instanceof MenuButton && overCtrl.parent() === parent) {
8581              parent.items().filter('MenuButton').each(function (ctrl) {
8582                if (ctrl.hideMenu && ctrl !== overCtrl) {
8583                  if (ctrl.menu && ctrl.menu.visible()) {
8584                    hasVisibleSiblingMenu = true;
8585                  }
8586                  ctrl.hideMenu();
8587                }
8588              });
8589              if (hasVisibleSiblingMenu) {
8590                overCtrl.focus();
8591                overCtrl.showMenu();
8592              }
8593            }
8594          });
8595          return self._super();
8596        },
8597        bindStates: function () {
8598          var self = this;
8599          self.state.on('change:menu', function () {
8600            if (self.menu) {
8601              self.menu.remove();
8602            }
8603            self.menu = null;
8604          });
8605          return self._super();
8606        },
8607        remove: function () {
8608          this._super();
8609          if (this.menu) {
8610            this.menu.remove();
8611          }
8612        }
8613      });
8614  
8615      function Throbber (elm, inline) {
8616        var self =