// ce-1.38.3824 68bd1c09d907ef391afaa49372311e7f4c84d359
// Copyright 2013-2016 Evernote Corp. All rights reserved.
// http://www.evernote.com

/* @preserve
 * The MIT License (MIT)
 * 
 * Copyright (c) 2013-2015 Petka Antonov
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 */
/**
 * bluebird build version 3.4.5
 * Features enabled: core, race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, using, timers, filter, any, each
*/
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof _dereq_=="function"&&_dereq_;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise) {
var SomePromiseArray = Promise._SomePromiseArray;
function any(promises) {
    var ret = new SomePromiseArray(promises);
    var promise = ret.promise();
    ret.setHowMany(1);
    ret.setUnwrap();
    ret.init();
    return promise;
}

Promise.any = function (promises) {
    return any(promises);
};

Promise.prototype.any = function () {
    return any(this);
};

};

},{}],2:[function(_dereq_,module,exports){
"use strict";
var firstLineError;
try {throw new Error(); } catch (e) {firstLineError = e;}
var schedule = _dereq_("./schedule");
var Queue = _dereq_("./queue");
var util = _dereq_("./util");

function Async() {
    this._customScheduler = false;
    this._isTickUsed = false;
    this._lateQueue = new Queue(16);
    this._normalQueue = new Queue(16);
    this._haveDrainedQueues = false;
    this._trampolineEnabled = true;
    var self = this;
    this.drainQueues = function () {
        self._drainQueues();
    };
    this._schedule = schedule;
}

Async.prototype.setScheduler = function(fn) {
    var prev = this._schedule;
    this._schedule = fn;
    this._customScheduler = true;
    return prev;
};

Async.prototype.hasCustomScheduler = function() {
    return this._customScheduler;
};

Async.prototype.enableTrampoline = function() {
    this._trampolineEnabled = true;
};

Async.prototype.disableTrampolineIfNecessary = function() {
    if (util.hasDevTools) {
        this._trampolineEnabled = false;
    }
};

Async.prototype.haveItemsQueued = function () {
    return this._isTickUsed || this._haveDrainedQueues;
};


Async.prototype.fatalError = function(e, isNode) {
    if (isNode) {
        process.stderr.write("Fatal " + (e instanceof Error ? e.stack : e) +
            "\n");
        process.exit(2);
    } else {
        this.throwLater(e);
    }
};

Async.prototype.throwLater = function(fn, arg) {
    if (arguments.length === 1) {
        arg = fn;
        fn = function () { throw arg; };
    }
    if (typeof setTimeout !== "undefined") {
        setTimeout(function() {
            fn(arg);
        }, 0);
    } else try {
        this._schedule(function() {
            fn(arg);
        });
    } catch (e) {
        throw new Error("No async scheduler available\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
};

function AsyncInvokeLater(fn, receiver, arg) {
    this._lateQueue.push(fn, receiver, arg);
    this._queueTick();
}

function AsyncInvoke(fn, receiver, arg) {
    this._normalQueue.push(fn, receiver, arg);
    this._queueTick();
}

function AsyncSettlePromises(promise) {
    this._normalQueue._pushOne(promise);
    this._queueTick();
}

if (!util.hasDevTools) {
    Async.prototype.invokeLater = AsyncInvokeLater;
    Async.prototype.invoke = AsyncInvoke;
    Async.prototype.settlePromises = AsyncSettlePromises;
} else {
    Async.prototype.invokeLater = function (fn, receiver, arg) {
        if (this._trampolineEnabled) {
            AsyncInvokeLater.call(this, fn, receiver, arg);
        } else {
            this._schedule(function() {
                setTimeout(function() {
                    fn.call(receiver, arg);
                }, 100);
            });
        }
    };

    Async.prototype.invoke = function (fn, receiver, arg) {
        if (this._trampolineEnabled) {
            AsyncInvoke.call(this, fn, receiver, arg);
        } else {
            this._schedule(function() {
                fn.call(receiver, arg);
            });
        }
    };

    Async.prototype.settlePromises = function(promise) {
        if (this._trampolineEnabled) {
            AsyncSettlePromises.call(this, promise);
        } else {
            this._schedule(function() {
                promise._settlePromises();
            });
        }
    };
}

Async.prototype.invokeFirst = function (fn, receiver, arg) {
    this._normalQueue.unshift(fn, receiver, arg);
    this._queueTick();
};

Async.prototype._drainQueue = function(queue) {
    while (queue.length() > 0) {
        var fn = queue.shift();
        if (typeof fn !== "function") {
            fn._settlePromises();
            continue;
        }
        var receiver = queue.shift();
        var arg = queue.shift();
        fn.call(receiver, arg);
    }
};

Async.prototype._drainQueues = function () {
    this._drainQueue(this._normalQueue);
    this._reset();
    this._haveDrainedQueues = true;
    this._drainQueue(this._lateQueue);
};

Async.prototype._queueTick = function () {
    if (!this._isTickUsed) {
        this._isTickUsed = true;
        this._schedule(this.drainQueues);
    }
};

Async.prototype._reset = function () {
    this._isTickUsed = false;
};

module.exports = Async;
module.exports.firstLineError = firstLineError;

},{"./queue":26,"./schedule":29,"./util":36}],3:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, INTERNAL, tryConvertToPromise, debug) {
var calledBind = false;
var rejectThis = function(_, e) {
    this._reject(e);
};

var targetRejected = function(e, context) {
    context.promiseRejectionQueued = true;
    context.bindingPromise._then(rejectThis, rejectThis, null, this, e);
};

var bindingResolved = function(thisArg, context) {
    if (((this._bitField & 50397184) === 0)) {
        this._resolveCallback(context.target);
    }
};

var bindingRejected = function(e, context) {
    if (!context.promiseRejectionQueued) this._reject(e);
};

Promise.prototype.bind = function (thisArg) {
    if (!calledBind) {
        calledBind = true;
        Promise.prototype._propagateFrom = debug.propagateFromFunction();
        Promise.prototype._boundValue = debug.boundValueFunction();
    }
    var maybePromise = tryConvertToPromise(thisArg);
    var ret = new Promise(INTERNAL);
    ret._propagateFrom(this, 1);
    var target = this._target();
    ret._setBoundTo(maybePromise);
    if (maybePromise instanceof Promise) {
        var context = {
            promiseRejectionQueued: false,
            promise: ret,
            target: target,
            bindingPromise: maybePromise
        };
        target._then(INTERNAL, targetRejected, undefined, ret, context);
        maybePromise._then(
            bindingResolved, bindingRejected, undefined, ret, context);
        ret._setOnCancel(maybePromise);
    } else {
        ret._resolveCallback(target);
    }
    return ret;
};

Promise.prototype._setBoundTo = function (obj) {
    if (obj !== undefined) {
        this._bitField = this._bitField | 2097152;
        this._boundTo = obj;
    } else {
        this._bitField = this._bitField & (~2097152);
    }
};

Promise.prototype._isBound = function () {
    return (this._bitField & 2097152) === 2097152;
};

Promise.bind = function (thisArg, value) {
    return Promise.resolve(value).bind(thisArg);
};
};

},{}],4:[function(_dereq_,module,exports){
"use strict";
var old;
if (typeof Promise !== "undefined") old = Promise;
function noConflict() {
    try { if (Promise === bluebird) Promise = old; }
    catch (e) {}
    return bluebird;
}
var bluebird = _dereq_("./promise")();
bluebird.noConflict = noConflict;
module.exports = bluebird;

},{"./promise":22}],5:[function(_dereq_,module,exports){
"use strict";
var cr = Object.create;
if (cr) {
    var callerCache = cr(null);
    var getterCache = cr(null);
    callerCache[" size"] = getterCache[" size"] = 0;
}

module.exports = function(Promise) {
var util = _dereq_("./util");
var canEvaluate = util.canEvaluate;
var isIdentifier = util.isIdentifier;

var getMethodCaller;
var getGetter;
if (!true) {
var makeMethodCaller = function (methodName) {
    return new Function("ensureMethod", "                                    \n\
        return function(obj) {                                               \n\
            'use strict'                                                     \n\
            var len = this.length;                                           \n\
            ensureMethod(obj, 'methodName');                                 \n\
            switch(len) {                                                    \n\
                case 1: return obj.methodName(this[0]);                      \n\
                case 2: return obj.methodName(this[0], this[1]);             \n\
                case 3: return obj.methodName(this[0], this[1], this[2]);    \n\
                case 0: return obj.methodName();                             \n\
                default:                                                     \n\
                    return obj.methodName.apply(obj, this);                  \n\
            }                                                                \n\
        };                                                                   \n\
        ".replace(/methodName/g, methodName))(ensureMethod);
};

var makeGetter = function (propertyName) {
    return new Function("obj", "                                             \n\
        'use strict';                                                        \n\
        return obj.propertyName;                                             \n\
        ".replace("propertyName", propertyName));
};

var getCompiled = function(name, compiler, cache) {
    var ret = cache[name];
    if (typeof ret !== "function") {
        if (!isIdentifier(name)) {
            return null;
        }
        ret = compiler(name);
        cache[name] = ret;
        cache[" size"]++;
        if (cache[" size"] > 512) {
            var keys = Object.keys(cache);
            for (var i = 0; i < 256; ++i) delete cache[keys[i]];
            cache[" size"] = keys.length - 256;
        }
    }
    return ret;
};

getMethodCaller = function(name) {
    return getCompiled(name, makeMethodCaller, callerCache);
};

getGetter = function(name) {
    return getCompiled(name, makeGetter, getterCache);
};
}

function ensureMethod(obj, methodName) {
    var fn;
    if (obj != null) fn = obj[methodName];
    if (typeof fn !== "function") {
        var message = "Object " + util.classString(obj) + " has no method '" +
            util.toString(methodName) + "'";
        throw new Promise.TypeError(message);
    }
    return fn;
}

function caller(obj) {
    var methodName = this.pop();
    var fn = ensureMethod(obj, methodName);
    return fn.apply(obj, this);
}
Promise.prototype.call = function (methodName) {
    var args = [].slice.call(arguments, 1);;
    if (!true) {
        if (canEvaluate) {
            var maybeCaller = getMethodCaller(methodName);
            if (maybeCaller !== null) {
                return this._then(
                    maybeCaller, undefined, undefined, args, undefined);
            }
        }
    }
    args.push(methodName);
    return this._then(caller, undefined, undefined, args, undefined);
};

function namedGetter(obj) {
    return obj[this];
}
function indexedGetter(obj) {
    var index = +this;
    if (index < 0) index = Math.max(0, index + obj.length);
    return obj[index];
}
Promise.prototype.get = function (propertyName) {
    var isIndex = (typeof propertyName === "number");
    var getter;
    if (!isIndex) {
        if (canEvaluate) {
            var maybeGetter = getGetter(propertyName);
            getter = maybeGetter !== null ? maybeGetter : namedGetter;
        } else {
            getter = namedGetter;
        }
    } else {
        getter = indexedGetter;
    }
    return this._then(getter, undefined, undefined, propertyName, undefined);
};
};

},{"./util":36}],6:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, PromiseArray, apiRejection, debug) {
var util = _dereq_("./util");
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;
var async = Promise._async;

Promise.prototype["break"] = Promise.prototype.cancel = function() {
    if (!debug.cancellation()) return this._warn("cancellation is disabled");

    var promise = this;
    var child = promise;
    while (promise._isCancellable()) {
        if (!promise._cancelBy(child)) {
            if (child._isFollowing()) {
                child._followee().cancel();
            } else {
                child._cancelBranched();
            }
            break;
        }

        var parent = promise._cancellationParent;
        if (parent == null || !parent._isCancellable()) {
            if (promise._isFollowing()) {
                promise._followee().cancel();
            } else {
                promise._cancelBranched();
            }
            break;
        } else {
            if (promise._isFollowing()) promise._followee().cancel();
            promise._setWillBeCancelled();
            child = promise;
            promise = parent;
        }
    }
};

Promise.prototype._branchHasCancelled = function() {
    this._branchesRemainingToCancel--;
};

Promise.prototype._enoughBranchesHaveCancelled = function() {
    return this._branchesRemainingToCancel === undefined ||
           this._branchesRemainingToCancel <= 0;
};

Promise.prototype._cancelBy = function(canceller) {
    if (canceller === this) {
        this._branchesRemainingToCancel = 0;
        this._invokeOnCancel();
        return true;
    } else {
        this._branchHasCancelled();
        if (this._enoughBranchesHaveCancelled()) {
            this._invokeOnCancel();
            return true;
        }
    }
    return false;
};

Promise.prototype._cancelBranched = function() {
    if (this._enoughBranchesHaveCancelled()) {
        this._cancel();
    }
};

Promise.prototype._cancel = function() {
    if (!this._isCancellable()) return;
    this._setCancelled();
    async.invoke(this._cancelPromises, this, undefined);
};

Promise.prototype._cancelPromises = function() {
    if (this._length() > 0) this._settlePromises();
};

Promise.prototype._unsetOnCancel = function() {
    this._onCancelField = undefined;
};

Promise.prototype._isCancellable = function() {
    return this.isPending() && !this._isCancelled();
};

Promise.prototype.isCancellable = function() {
    return this.isPending() && !this.isCancelled();
};

Promise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) {
    if (util.isArray(onCancelCallback)) {
        for (var i = 0; i < onCancelCallback.length; ++i) {
            this._doInvokeOnCancel(onCancelCallback[i], internalOnly);
        }
    } else if (onCancelCallback !== undefined) {
        if (typeof onCancelCallback === "function") {
            if (!internalOnly) {
                var e = tryCatch(onCancelCallback).call(this._boundValue());
                if (e === errorObj) {
                    this._attachExtraTrace(e.e);
                    async.throwLater(e.e);
                }
            }
        } else {
            onCancelCallback._resultCancelled(this);
        }
    }
};

Promise.prototype._invokeOnCancel = function() {
    var onCancelCallback = this._onCancel();
    this._unsetOnCancel();
    async.invoke(this._doInvokeOnCancel, this, onCancelCallback);
};

Promise.prototype._invokeInternalOnCancel = function() {
    if (this._isCancellable()) {
        this._doInvokeOnCancel(this._onCancel(), true);
        this._unsetOnCancel();
    }
};

Promise.prototype._resultCancelled = function() {
    this.cancel();
};

};

},{"./util":36}],7:[function(_dereq_,module,exports){
"use strict";
module.exports = function(NEXT_FILTER) {
var util = _dereq_("./util");
var getKeys = _dereq_("./es5").keys;
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;

function catchFilter(instances, cb, promise) {
    return function(e) {
        var boundTo = promise._boundValue();
        predicateLoop: for (var i = 0; i < instances.length; ++i) {
            var item = instances[i];

            if (item === Error ||
                (item != null && item.prototype instanceof Error)) {
                if (e instanceof item) {
                    return tryCatch(cb).call(boundTo, e);
                }
            } else if (typeof item === "function") {
                var matchesPredicate = tryCatch(item).call(boundTo, e);
                if (matchesPredicate === errorObj) {
                    return matchesPredicate;
                } else if (matchesPredicate) {
                    return tryCatch(cb).call(boundTo, e);
                }
            } else if (util.isObject(e)) {
                var keys = getKeys(item);
                for (var j = 0; j < keys.length; ++j) {
                    var key = keys[j];
                    if (item[key] != e[key]) {
                        continue predicateLoop;
                    }
                }
                return tryCatch(cb).call(boundTo, e);
            }
        }
        return NEXT_FILTER;
    };
}

return catchFilter;
};

},{"./es5":13,"./util":36}],8:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise) {
var longStackTraces = false;
var contextStack = [];

Promise.prototype._promiseCreated = function() {};
Promise.prototype._pushContext = function() {};
Promise.prototype._popContext = function() {return null;};
Promise._peekContext = Promise.prototype._peekContext = function() {};

function Context() {
    this._trace = new Context.CapturedTrace(peekContext());
}
Context.prototype._pushContext = function () {
    if (this._trace !== undefined) {
        this._trace._promiseCreated = null;
        contextStack.push(this._trace);
    }
};

Context.prototype._popContext = function () {
    if (this._trace !== undefined) {
        var trace = contextStack.pop();
        var ret = trace._promiseCreated;
        trace._promiseCreated = null;
        return ret;
    }
    return null;
};

function createContext() {
    if (longStackTraces) return new Context();
}

function peekContext() {
    var lastIndex = contextStack.length - 1;
    if (lastIndex >= 0) {
        return contextStack[lastIndex];
    }
    return undefined;
}
Context.CapturedTrace = null;
Context.create = createContext;
Context.deactivateLongStackTraces = function() {};
Context.activateLongStackTraces = function() {
    var Promise_pushContext = Promise.prototype._pushContext;
    var Promise_popContext = Promise.prototype._popContext;
    var Promise_PeekContext = Promise._peekContext;
    var Promise_peekContext = Promise.prototype._peekContext;
    var Promise_promiseCreated = Promise.prototype._promiseCreated;
    Context.deactivateLongStackTraces = function() {
        Promise.prototype._pushContext = Promise_pushContext;
        Promise.prototype._popContext = Promise_popContext;
        Promise._peekContext = Promise_PeekContext;
        Promise.prototype._peekContext = Promise_peekContext;
        Promise.prototype._promiseCreated = Promise_promiseCreated;
        longStackTraces = false;
    };
    longStackTraces = true;
    Promise.prototype._pushContext = Context.prototype._pushContext;
    Promise.prototype._popContext = Context.prototype._popContext;
    Promise._peekContext = Promise.prototype._peekContext = peekContext;
    Promise.prototype._promiseCreated = function() {
        var ctx = this._peekContext();
        if (ctx && ctx._promiseCreated == null) ctx._promiseCreated = this;
    };
};
return Context;
};

},{}],9:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, Context) {
var getDomain = Promise._getDomain;
var async = Promise._async;
var Warning = _dereq_("./errors").Warning;
var util = _dereq_("./util");
var canAttachTrace = util.canAttachTrace;
var unhandledRejectionHandled;
var possiblyUnhandledRejection;
var bluebirdFramePattern =
    /[\\\/]bluebird[\\\/]js[\\\/](release|debug|instrumented)/;
var nodeFramePattern = /\((?:timers\.js):\d+:\d+\)/;
var parseLinePattern = /[\/<\(](.+?):(\d+):(\d+)\)?\s*$/;
var stackFramePattern = null;
var formatStack = null;
var indentStackFrames = false;
var printWarning;
var debugging = !!(util.env("BLUEBIRD_DEBUG") != 0 &&
                        (true ||
                         util.env("BLUEBIRD_DEBUG") ||
                         util.env("NODE_ENV") === "development"));

var warnings = !!(util.env("BLUEBIRD_WARNINGS") != 0 &&
    (debugging || util.env("BLUEBIRD_WARNINGS")));

var longStackTraces = !!(util.env("BLUEBIRD_LONG_STACK_TRACES") != 0 &&
    (debugging || util.env("BLUEBIRD_LONG_STACK_TRACES")));

var wForgottenReturn = util.env("BLUEBIRD_W_FORGOTTEN_RETURN") != 0 &&
    (warnings || !!util.env("BLUEBIRD_W_FORGOTTEN_RETURN"));

Promise.prototype.suppressUnhandledRejections = function() {
    var target = this._target();
    target._bitField = ((target._bitField & (~1048576)) |
                      524288);
};

Promise.prototype._ensurePossibleRejectionHandled = function () {
    if ((this._bitField & 524288) !== 0) return;
    this._setRejectionIsUnhandled();
    async.invokeLater(this._notifyUnhandledRejection, this, undefined);
};

Promise.prototype._notifyUnhandledRejectionIsHandled = function () {
    fireRejectionEvent("rejectionHandled",
                                  unhandledRejectionHandled, undefined, this);
};

Promise.prototype._setReturnedNonUndefined = function() {
    this._bitField = this._bitField | 268435456;
};

Promise.prototype._returnedNonUndefined = function() {
    return (this._bitField & 268435456) !== 0;
};

Promise.prototype._notifyUnhandledRejection = function () {
    if (this._isRejectionUnhandled()) {
        var reason = this._settledValue();
        this._setUnhandledRejectionIsNotified();
        fireRejectionEvent("unhandledRejection",
                                      possiblyUnhandledRejection, reason, this);
    }
};

Promise.prototype._setUnhandledRejectionIsNotified = function () {
    this._bitField = this._bitField | 262144;
};

Promise.prototype._unsetUnhandledRejectionIsNotified = function () {
    this._bitField = this._bitField & (~262144);
};

Promise.prototype._isUnhandledRejectionNotified = function () {
    return (this._bitField & 262144) > 0;
};

Promise.prototype._setRejectionIsUnhandled = function () {
    this._bitField = this._bitField | 1048576;
};

Promise.prototype._unsetRejectionIsUnhandled = function () {
    this._bitField = this._bitField & (~1048576);
    if (this._isUnhandledRejectionNotified()) {
        this._unsetUnhandledRejectionIsNotified();
        this._notifyUnhandledRejectionIsHandled();
    }
};

Promise.prototype._isRejectionUnhandled = function () {
    return (this._bitField & 1048576) > 0;
};

Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) {
    return warn(message, shouldUseOwnTrace, promise || this);
};

Promise.onPossiblyUnhandledRejection = function (fn) {
    var domain = getDomain();
    possiblyUnhandledRejection =
        typeof fn === "function" ? (domain === null ?
                                            fn : util.domainBind(domain, fn))
                                 : undefined;
};

Promise.onUnhandledRejectionHandled = function (fn) {
    var domain = getDomain();
    unhandledRejectionHandled =
        typeof fn === "function" ? (domain === null ?
                                            fn : util.domainBind(domain, fn))
                                 : undefined;
};

var disableLongStackTraces = function() {};
Promise.longStackTraces = function () {
    if (async.haveItemsQueued() && !config.longStackTraces) {
        throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    if (!config.longStackTraces && longStackTracesIsSupported()) {
        var Promise_captureStackTrace = Promise.prototype._captureStackTrace;
        var Promise_attachExtraTrace = Promise.prototype._attachExtraTrace;
        config.longStackTraces = true;
        disableLongStackTraces = function() {
            if (async.haveItemsQueued() && !config.longStackTraces) {
                throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
            }
            Promise.prototype._captureStackTrace = Promise_captureStackTrace;
            Promise.prototype._attachExtraTrace = Promise_attachExtraTrace;
            Context.deactivateLongStackTraces();
            async.enableTrampoline();
            config.longStackTraces = false;
        };
        Promise.prototype._captureStackTrace = longStackTracesCaptureStackTrace;
        Promise.prototype._attachExtraTrace = longStackTracesAttachExtraTrace;
        Context.activateLongStackTraces();
        async.disableTrampolineIfNecessary();
    }
};

Promise.hasLongStackTraces = function () {
    return config.longStackTraces && longStackTracesIsSupported();
};

var fireDomEvent = (function() {
    try {
        if (typeof CustomEvent === "function") {
            var event = new CustomEvent("CustomEvent");
            util.global.dispatchEvent(event);
            return function(name, event) {
                var domEvent = new CustomEvent(name.toLowerCase(), {
                    detail: event,
                    cancelable: true
                });
                return !util.global.dispatchEvent(domEvent);
            };
        } else if (typeof Event === "function") {
            var event = new Event("CustomEvent");
            util.global.dispatchEvent(event);
            return function(name, event) {
                var domEvent = new Event(name.toLowerCase(), {
                    cancelable: true
                });
                domEvent.detail = event;
                return !util.global.dispatchEvent(domEvent);
            };
        } else {
            var event = document.createEvent("CustomEvent");
            event.initCustomEvent("testingtheevent", false, true, {});
            util.global.dispatchEvent(event);
            return function(name, event) {
                var domEvent = document.createEvent("CustomEvent");
                domEvent.initCustomEvent(name.toLowerCase(), false, true,
                    event);
                return !util.global.dispatchEvent(domEvent);
            };
        }
    } catch (e) {}
    return function() {
        return false;
    };
})();

var fireGlobalEvent = (function() {
    if (util.isNode) {
        return function() {
            return process.emit.apply(process, arguments);
        };
    } else {
        if (!util.global) {
            return function() {
                return false;
            };
        }
        return function(name) {
            var methodName = "on" + name.toLowerCase();
            var method = util.global[methodName];
            if (!method) return false;
            method.apply(util.global, [].slice.call(arguments, 1));
            return true;
        };
    }
})();

function generatePromiseLifecycleEventObject(name, promise) {
    return {promise: promise};
}

var eventToObjectGenerator = {
    promiseCreated: generatePromiseLifecycleEventObject,
    promiseFulfilled: generatePromiseLifecycleEventObject,
    promiseRejected: generatePromiseLifecycleEventObject,
    promiseResolved: generatePromiseLifecycleEventObject,
    promiseCancelled: generatePromiseLifecycleEventObject,
    promiseChained: function(name, promise, child) {
        return {promise: promise, child: child};
    },
    warning: function(name, warning) {
        return {warning: warning};
    },
    unhandledRejection: function (name, reason, promise) {
        return {reason: reason, promise: promise};
    },
    rejectionHandled: generatePromiseLifecycleEventObject
};

var activeFireEvent = function (name) {
    var globalEventFired = false;
    try {
        globalEventFired = fireGlobalEvent.apply(null, arguments);
    } catch (e) {
        async.throwLater(e);
        globalEventFired = true;
    }

    var domEventFired = false;
    try {
        domEventFired = fireDomEvent(name,
                    eventToObjectGenerator[name].apply(null, arguments));
    } catch (e) {
        async.throwLater(e);
        domEventFired = true;
    }

    return domEventFired || globalEventFired;
};

Promise.config = function(opts) {
    opts = Object(opts);
    if ("longStackTraces" in opts) {
        if (opts.longStackTraces) {
            Promise.longStackTraces();
        } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) {
            disableLongStackTraces();
        }
    }
    if ("warnings" in opts) {
        var warningsOption = opts.warnings;
        config.warnings = !!warningsOption;
        wForgottenReturn = config.warnings;

        if (util.isObject(warningsOption)) {
            if ("wForgottenReturn" in warningsOption) {
                wForgottenReturn = !!warningsOption.wForgottenReturn;
            }
        }
    }
    if ("cancellation" in opts && opts.cancellation && !config.cancellation) {
        if (async.haveItemsQueued()) {
            throw new Error(
                "cannot enable cancellation after promises are in use");
        }
        Promise.prototype._clearCancellationData =
            cancellationClearCancellationData;
        Promise.prototype._propagateFrom = cancellationPropagateFrom;
        Promise.prototype._onCancel = cancellationOnCancel;
        Promise.prototype._setOnCancel = cancellationSetOnCancel;
        Promise.prototype._attachCancellationCallback =
            cancellationAttachCancellationCallback;
        Promise.prototype._execute = cancellationExecute;
        propagateFromFunction = cancellationPropagateFrom;
        config.cancellation = true;
    }
    if ("monitoring" in opts) {
        if (opts.monitoring && !config.monitoring) {
            config.monitoring = true;
            Promise.prototype._fireEvent = activeFireEvent;
        } else if (!opts.monitoring && config.monitoring) {
            config.monitoring = false;
            Promise.prototype._fireEvent = defaultFireEvent;
        }
    }
};

function defaultFireEvent() { return false; }

Promise.prototype._fireEvent = defaultFireEvent;
Promise.prototype._execute = function(executor, resolve, reject) {
    try {
        executor(resolve, reject);
    } catch (e) {
        return e;
    }
};
Promise.prototype._onCancel = function () {};
Promise.prototype._setOnCancel = function (handler) { ; };
Promise.prototype._attachCancellationCallback = function(onCancel) {
    ;
};
Promise.prototype._captureStackTrace = function () {};
Promise.prototype._attachExtraTrace = function () {};
Promise.prototype._clearCancellationData = function() {};
Promise.prototype._propagateFrom = function (parent, flags) {
    ;
    ;
};

function cancellationExecute(executor, resolve, reject) {
    var promise = this;
    try {
        executor(resolve, reject, function(onCancel) {
            if (typeof onCancel !== "function") {
                throw new TypeError("onCancel must be a function, got: " +
                                    util.toString(onCancel));
            }
            promise._attachCancellationCallback(onCancel);
        });
    } catch (e) {
        return e;
    }
}

function cancellationAttachCancellationCallback(onCancel) {
    if (!this._isCancellable()) return this;

    var previousOnCancel = this._onCancel();
    if (previousOnCancel !== undefined) {
        if (util.isArray(previousOnCancel)) {
            previousOnCancel.push(onCancel);
        } else {
            this._setOnCancel([previousOnCancel, onCancel]);
        }
    } else {
        this._setOnCancel(onCancel);
    }
}

function cancellationOnCancel() {
    return this._onCancelField;
}

function cancellationSetOnCancel(onCancel) {
    this._onCancelField = onCancel;
}

function cancellationClearCancellationData() {
    this._cancellationParent = undefined;
    this._onCancelField = undefined;
}

function cancellationPropagateFrom(parent, flags) {
    if ((flags & 1) !== 0) {
        this._cancellationParent = parent;
        var branchesRemainingToCancel = parent._branchesRemainingToCancel;
        if (branchesRemainingToCancel === undefined) {
            branchesRemainingToCancel = 0;
        }
        parent._branchesRemainingToCancel = branchesRemainingToCancel + 1;
    }
    if ((flags & 2) !== 0 && parent._isBound()) {
        this._setBoundTo(parent._boundTo);
    }
}

function bindingPropagateFrom(parent, flags) {
    if ((flags & 2) !== 0 && parent._isBound()) {
        this._setBoundTo(parent._boundTo);
    }
}
var propagateFromFunction = bindingPropagateFrom;

function boundValueFunction() {
    var ret = this._boundTo;
    if (ret !== undefined) {
        if (ret instanceof Promise) {
            if (ret.isFulfilled()) {
                return ret.value();
            } else {
                return undefined;
            }
        }
    }
    return ret;
}

function longStackTracesCaptureStackTrace() {
    this._trace = new CapturedTrace(this._peekContext());
}

function longStackTracesAttachExtraTrace(error, ignoreSelf) {
    if (canAttachTrace(error)) {
        var trace = this._trace;
        if (trace !== undefined) {
            if (ignoreSelf) trace = trace._parent;
        }
        if (trace !== undefined) {
            trace.attachExtraTrace(error);
        } else if (!error.__stackCleaned__) {
            var parsed = parseStackAndMessage(error);
            util.notEnumerableProp(error, "stack",
                parsed.message + "\n" + parsed.stack.join("\n"));
            util.notEnumerableProp(error, "__stackCleaned__", true);
        }
    }
}

function checkForgottenReturns(returnValue, promiseCreated, name, promise,
                               parent) {
    if (returnValue === undefined && promiseCreated !== null &&
        wForgottenReturn) {
        if (parent !== undefined && parent._returnedNonUndefined()) return;
        if ((promise._bitField & 65535) === 0) return;

        if (name) name = name + " ";
        var handlerLine = "";
        var creatorLine = "";
        if (promiseCreated._trace) {
            var traceLines = promiseCreated._trace.stack.split("\n");
            var stack = cleanStack(traceLines);
            for (var i = stack.length - 1; i >= 0; --i) {
                var line = stack[i];
                if (!nodeFramePattern.test(line)) {
                    var lineMatches = line.match(parseLinePattern);
                    if (lineMatches) {
                        handlerLine  = "at " + lineMatches[1] +
                            ":" + lineMatches[2] + ":" + lineMatches[3] + " ";
                    }
                    break;
                }
            }

            if (stack.length > 0) {
                var firstUserLine = stack[0];
                for (var i = 0; i < traceLines.length; ++i) {

                    if (traceLines[i] === firstUserLine) {
                        if (i > 0) {
                            creatorLine = "\n" + traceLines[i - 1];
                        }
                        break;
                    }
                }

            }
        }
        var msg = "a promise was created in a " + name +
            "handler " + handlerLine + "but was not returned from it, " +
            "see http://goo.gl/rRqMUw" +
            creatorLine;
        promise._warn(msg, true, promiseCreated);
    }
}

function deprecated(name, replacement) {
    var message = name +
        " is deprecated and will be removed in a future version.";
    if (replacement) message += " Use " + replacement + " instead.";
    return warn(message);
}

function warn(message, shouldUseOwnTrace, promise) {
    if (!config.warnings) return;
    var warning = new Warning(message);
    var ctx;
    if (shouldUseOwnTrace) {
        promise._attachExtraTrace(warning);
    } else if (config.longStackTraces && (ctx = Promise._peekContext())) {
        ctx.attachExtraTrace(warning);
    } else {
        var parsed = parseStackAndMessage(warning);
        warning.stack = parsed.message + "\n" + parsed.stack.join("\n");
    }

    if (!activeFireEvent("warning", warning)) {
        formatAndLogError(warning, "", true);
    }
}

function reconstructStack(message, stacks) {
    for (var i = 0; i < stacks.length - 1; ++i) {
        stacks[i].push("From previous event:");
        stacks[i] = stacks[i].join("\n");
    }
    if (i < stacks.length) {
        stacks[i] = stacks[i].join("\n");
    }
    return message + "\n" + stacks.join("\n");
}

function removeDuplicateOrEmptyJumps(stacks) {
    for (var i = 0; i < stacks.length; ++i) {
        if (stacks[i].length === 0 ||
            ((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) {
            stacks.splice(i, 1);
            i--;
        }
    }
}

function removeCommonRoots(stacks) {
    var current = stacks[0];
    for (var i = 1; i < stacks.length; ++i) {
        var prev = stacks[i];
        var currentLastIndex = current.length - 1;
        var currentLastLine = current[currentLastIndex];
        var commonRootMeetPoint = -1;

        for (var j = prev.length - 1; j >= 0; --j) {
            if (prev[j] === currentLastLine) {
                commonRootMeetPoint = j;
                break;
            }
        }

        for (var j = commonRootMeetPoint; j >= 0; --j) {
            var line = prev[j];
            if (current[currentLastIndex] === line) {
                current.pop();
                currentLastIndex--;
            } else {
                break;
            }
        }
        current = prev;
    }
}

function cleanStack(stack) {
    var ret = [];
    for (var i = 0; i < stack.length; ++i) {
        var line = stack[i];
        var isTraceLine = "    (No stack trace)" === line ||
            stackFramePattern.test(line);
        var isInternalFrame = isTraceLine && shouldIgnore(line);
        if (isTraceLine && !isInternalFrame) {
            if (indentStackFrames && line.charAt(0) !== " ") {
                line = "    " + line;
            }
            ret.push(line);
        }
    }
    return ret;
}

function stackFramesAsArray(error) {
    var stack = error.stack.replace(/\s+$/g, "").split("\n");
    for (var i = 0; i < stack.length; ++i) {
        var line = stack[i];
        if ("    (No stack trace)" === line || stackFramePattern.test(line)) {
            break;
        }
    }
    if (i > 0) {
        stack = stack.slice(i);
    }
    return stack;
}

function parseStackAndMessage(error) {
    var stack = error.stack;
    var message = error.toString();
    stack = typeof stack === "string" && stack.length > 0
                ? stackFramesAsArray(error) : ["    (No stack trace)"];
    return {
        message: message,
        stack: cleanStack(stack)
    };
}

function formatAndLogError(error, title, isSoft) {
    if (typeof console !== "undefined") {
        var message;
        if (util.isObject(error)) {
            var stack = error.stack;
            message = title + formatStack(stack, error);
        } else {
            message = title + String(error);
        }
        if (typeof printWarning === "function") {
            printWarning(message, isSoft);
        } else if (typeof console.log === "function" ||
            typeof console.log === "object") {
            console.log(message);
        }
    }
}

function fireRejectionEvent(name, localHandler, reason, promise) {
    var localEventFired = false;
    try {
        if (typeof localHandler === "function") {
            localEventFired = true;
            if (name === "rejectionHandled") {
                localHandler(promise);
            } else {
                localHandler(reason, promise);
            }
        }
    } catch (e) {
        async.throwLater(e);
    }

    if (name === "unhandledRejection") {
        if (!activeFireEvent(name, reason, promise) && !localEventFired) {
            formatAndLogError(reason, "Unhandled rejection ");
        }
    } else {
        activeFireEvent(name, promise);
    }
}

function formatNonError(obj) {
    var str;
    if (typeof obj === "function") {
        str = "[function " +
            (obj.name || "anonymous") +
            "]";
    } else {
        str = obj && typeof obj.toString === "function"
            ? obj.toString() : util.toString(obj);
        var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/;
        if (ruselessToString.test(str)) {
            try {
                var newStr = JSON.stringify(obj);
                str = newStr;
            }
            catch(e) {

            }
        }
        if (str.length === 0) {
            str = "(empty array)";
        }
    }
    return ("(<" + snip(str) + ">, no stack trace)");
}

function snip(str) {
    var maxChars = 41;
    if (str.length < maxChars) {
        return str;
    }
    return str.substr(0, maxChars - 3) + "...";
}

function longStackTracesIsSupported() {
    return typeof captureStackTrace === "function";
}

var shouldIgnore = function() { return false; };
var parseLineInfoRegex = /[\/<\(]([^:\/]+):(\d+):(?:\d+)\)?\s*$/;
function parseLineInfo(line) {
    var matches = line.match(parseLineInfoRegex);
    if (matches) {
        return {
            fileName: matches[1],
            line: parseInt(matches[2], 10)
        };
    }
}

function setBounds(firstLineError, lastLineError) {
    if (!longStackTracesIsSupported()) return;
    var firstStackLines = firstLineError.stack.split("\n");
    var lastStackLines = lastLineError.stack.split("\n");
    var firstIndex = -1;
    var lastIndex = -1;
    var firstFileName;
    var lastFileName;
    for (var i = 0; i < firstStackLines.length; ++i) {
        var result = parseLineInfo(firstStackLines[i]);
        if (result) {
            firstFileName = result.fileName;
            firstIndex = result.line;
            break;
        }
    }
    for (var i = 0; i < lastStackLines.length; ++i) {
        var result = parseLineInfo(lastStackLines[i]);
        if (result) {
            lastFileName = result.fileName;
            lastIndex = result.line;
            break;
        }
    }
    if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName ||
        firstFileName !== lastFileName || firstIndex >= lastIndex) {
        return;
    }

    shouldIgnore = function(line) {
        if (bluebirdFramePattern.test(line)) return true;
        var info = parseLineInfo(line);
        if (info) {
            if (info.fileName === firstFileName &&
                (firstIndex <= info.line && info.line <= lastIndex)) {
                return true;
            }
        }
        return false;
    };
}

function CapturedTrace(parent) {
    this._parent = parent;
    this._promisesCreated = 0;
    var length = this._length = 1 + (parent === undefined ? 0 : parent._length);
    captureStackTrace(this, CapturedTrace);
    if (length > 32) this.uncycle();
}
util.inherits(CapturedTrace, Error);
Context.CapturedTrace = CapturedTrace;

CapturedTrace.prototype.uncycle = function() {
    var length = this._length;
    if (length < 2) return;
    var nodes = [];
    var stackToIndex = {};

    for (var i = 0, node = this; node !== undefined; ++i) {
        nodes.push(node);
        node = node._parent;
    }
    length = this._length = i;
    for (var i = length - 1; i >= 0; --i) {
        var stack = nodes[i].stack;
        if (stackToIndex[stack] === undefined) {
            stackToIndex[stack] = i;
        }
    }
    for (var i = 0; i < length; ++i) {
        var currentStack = nodes[i].stack;
        var index = stackToIndex[currentStack];
        if (index !== undefined && index !== i) {
            if (index > 0) {
                nodes[index - 1]._parent = undefined;
                nodes[index - 1]._length = 1;
            }
            nodes[i]._parent = undefined;
            nodes[i]._length = 1;
            var cycleEdgeNode = i > 0 ? nodes[i - 1] : this;

            if (index < length - 1) {
                cycleEdgeNode._parent = nodes[index + 1];
                cycleEdgeNode._parent.uncycle();
                cycleEdgeNode._length =
                    cycleEdgeNode._parent._length + 1;
            } else {
                cycleEdgeNode._parent = undefined;
                cycleEdgeNode._length = 1;
            }
            var currentChildLength = cycleEdgeNode._length + 1;
            for (var j = i - 2; j >= 0; --j) {
                nodes[j]._length = currentChildLength;
                currentChildLength++;
            }
            return;
        }
    }
};

CapturedTrace.prototype.attachExtraTrace = function(error) {
    if (error.__stackCleaned__) return;
    this.uncycle();
    var parsed = parseStackAndMessage(error);
    var message = parsed.message;
    var stacks = [parsed.stack];

    var trace = this;
    while (trace !== undefined) {
        stacks.push(cleanStack(trace.stack.split("\n")));
        trace = trace._parent;
    }
    removeCommonRoots(stacks);
    removeDuplicateOrEmptyJumps(stacks);
    util.notEnumerableProp(error, "stack", reconstructStack(message, stacks));
    util.notEnumerableProp(error, "__stackCleaned__", true);
};

var captureStackTrace = (function stackDetection() {
    var v8stackFramePattern = /^\s*at\s*/;
    var v8stackFormatter = function(stack, error) {
        if (typeof stack === "string") return stack;

        if (error.name !== undefined &&
            error.message !== undefined) {
            return error.toString();
        }
        return formatNonError(error);
    };

    if (typeof Error.stackTraceLimit === "number" &&
        typeof Error.captureStackTrace === "function") {
        Error.stackTraceLimit += 6;
        stackFramePattern = v8stackFramePattern;
        formatStack = v8stackFormatter;
        var captureStackTrace = Error.captureStackTrace;

        shouldIgnore = function(line) {
            return bluebirdFramePattern.test(line);
        };
        return function(receiver, ignoreUntil) {
            Error.stackTraceLimit += 6;
            captureStackTrace(receiver, ignoreUntil);
            Error.stackTraceLimit -= 6;
        };
    }
    var err = new Error();

    if (typeof err.stack === "string" &&
        err.stack.split("\n")[0].indexOf("stackDetection@") >= 0) {
        stackFramePattern = /@/;
        formatStack = v8stackFormatter;
        indentStackFrames = true;
        return function captureStackTrace(o) {
            o.stack = new Error().stack;
        };
    }

    var hasStackAfterThrow;
    try { throw new Error(); }
    catch(e) {
        hasStackAfterThrow = ("stack" in e);
    }
    if (!("stack" in err) && hasStackAfterThrow &&
        typeof Error.stackTraceLimit === "number") {
        stackFramePattern = v8stackFramePattern;
        formatStack = v8stackFormatter;
        return function captureStackTrace(o) {
            Error.stackTraceLimit += 6;
            try { throw new Error(); }
            catch(e) { o.stack = e.stack; }
            Error.stackTraceLimit -= 6;
        };
    }

    formatStack = function(stack, error) {
        if (typeof stack === "string") return stack;

        if ((typeof error === "object" ||
            typeof error === "function") &&
            error.name !== undefined &&
            error.message !== undefined) {
            return error.toString();
        }
        return formatNonError(error);
    };

    return null;

})([]);

if (typeof console !== "undefined" && typeof console.warn !== "undefined") {
    printWarning = function (message) {
        console.warn(message);
    };
    if (util.isNode && process.stderr.isTTY) {
        printWarning = function(message, isSoft) {
            var color = isSoft ? "\u001b[33m" : "\u001b[31m";
            console.warn(color + message + "\u001b[0m\n");
        };
    } else if (!util.isNode && typeof (new Error().stack) === "string") {
        printWarning = function(message, isSoft) {
            console.warn("%c" + message,
                        isSoft ? "color: darkorange" : "color: red");
        };
    }
}

var config = {
    warnings: warnings,
    longStackTraces: false,
    cancellation: false,
    monitoring: false
};

if (longStackTraces) Promise.longStackTraces();

return {
    longStackTraces: function() {
        return config.longStackTraces;
    },
    warnings: function() {
        return config.warnings;
    },
    cancellation: function() {
        return config.cancellation;
    },
    monitoring: function() {
        return config.monitoring;
    },
    propagateFromFunction: function() {
        return propagateFromFunction;
    },
    boundValueFunction: function() {
        return boundValueFunction;
    },
    checkForgottenReturns: checkForgottenReturns,
    setBounds: setBounds,
    warn: warn,
    deprecated: deprecated,
    CapturedTrace: CapturedTrace,
    fireDomEvent: fireDomEvent,
    fireGlobalEvent: fireGlobalEvent
};
};

},{"./errors":12,"./util":36}],10:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise) {
function returner() {
    return this.value;
}
function thrower() {
    throw this.reason;
}

Promise.prototype["return"] =
Promise.prototype.thenReturn = function (value) {
    if (value instanceof Promise) value.suppressUnhandledRejections();
    return this._then(
        returner, undefined, undefined, {value: value}, undefined);
};

Promise.prototype["throw"] =
Promise.prototype.thenThrow = function (reason) {
    return this._then(
        thrower, undefined, undefined, {reason: reason}, undefined);
};

Promise.prototype.catchThrow = function (reason) {
    if (arguments.length <= 1) {
        return this._then(
            undefined, thrower, undefined, {reason: reason}, undefined);
    } else {
        var _reason = arguments[1];
        var handler = function() {throw _reason;};
        return this.caught(reason, handler);
    }
};

Promise.prototype.catchReturn = function (value) {
    if (arguments.length <= 1) {
        if (value instanceof Promise) value.suppressUnhandledRejections();
        return this._then(
            undefined, returner, undefined, {value: value}, undefined);
    } else {
        var _value = arguments[1];
        if (_value instanceof Promise) _value.suppressUnhandledRejections();
        var handler = function() {return _value;};
        return this.caught(value, handler);
    }
};
};

},{}],11:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, INTERNAL) {
var PromiseReduce = Promise.reduce;
var PromiseAll = Promise.all;

function promiseAllThis() {
    return PromiseAll(this);
}

function PromiseMapSeries(promises, fn) {
    return PromiseReduce(promises, fn, INTERNAL, INTERNAL);
}

Promise.prototype.each = function (fn) {
    return PromiseReduce(this, fn, INTERNAL, 0)
              ._then(promiseAllThis, undefined, undefined, this, undefined);
};

Promise.prototype.mapSeries = function (fn) {
    return PromiseReduce(this, fn, INTERNAL, INTERNAL);
};

Promise.each = function (promises, fn) {
    return PromiseReduce(promises, fn, INTERNAL, 0)
              ._then(promiseAllThis, undefined, undefined, promises, undefined);
};

Promise.mapSeries = PromiseMapSeries;
};


},{}],12:[function(_dereq_,module,exports){
"use strict";
var es5 = _dereq_("./es5");
var Objectfreeze = es5.freeze;
var util = _dereq_("./util");
var inherits = util.inherits;
var notEnumerableProp = util.notEnumerableProp;

function subError(nameProperty, defaultMessage) {
    function SubError(message) {
        if (!(this instanceof SubError)) return new SubError(message);
        notEnumerableProp(this, "message",
            typeof message === "string" ? message : defaultMessage);
        notEnumerableProp(this, "name", nameProperty);
        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, this.constructor);
        } else {
            Error.call(this);
        }
    }
    inherits(SubError, Error);
    return SubError;
}

var _TypeError, _RangeError;
var Warning = subError("Warning", "warning");
var CancellationError = subError("CancellationError", "cancellation error");
var TimeoutError = subError("TimeoutError", "timeout error");
var AggregateError = subError("AggregateError", "aggregate error");
try {
    _TypeError = TypeError;
    _RangeError = RangeError;
} catch(e) {
    _TypeError = subError("TypeError", "type error");
    _RangeError = subError("RangeError", "range error");
}

var methods = ("join pop push shift unshift slice filter forEach some " +
    "every map indexOf lastIndexOf reduce reduceRight sort reverse").split(" ");

for (var i = 0; i < methods.length; ++i) {
    if (typeof Array.prototype[methods[i]] === "function") {
        AggregateError.prototype[methods[i]] = Array.prototype[methods[i]];
    }
}

es5.defineProperty(AggregateError.prototype, "length", {
    value: 0,
    configurable: false,
    writable: true,
    enumerable: true
});
AggregateError.prototype["isOperational"] = true;
var level = 0;
AggregateError.prototype.toString = function() {
    var indent = Array(level * 4 + 1).join(" ");
    var ret = "\n" + indent + "AggregateError of:" + "\n";
    level++;
    indent = Array(level * 4 + 1).join(" ");
    for (var i = 0; i < this.length; ++i) {
        var str = this[i] === this ? "[Circular AggregateError]" : this[i] + "";
        var lines = str.split("\n");
        for (var j = 0; j < lines.length; ++j) {
            lines[j] = indent + lines[j];
        }
        str = lines.join("\n");
        ret += str + "\n";
    }
    level--;
    return ret;
};

function OperationalError(message) {
    if (!(this instanceof OperationalError))
        return new OperationalError(message);
    notEnumerableProp(this, "name", "OperationalError");
    notEnumerableProp(this, "message", message);
    this.cause = message;
    this["isOperational"] = true;

    if (message instanceof Error) {
        notEnumerableProp(this, "message", message.message);
        notEnumerableProp(this, "stack", message.stack);
    } else if (Error.captureStackTrace) {
        Error.captureStackTrace(this, this.constructor);
    }

}
inherits(OperationalError, Error);

var errorTypes = Error["__BluebirdErrorTypes__"];
if (!errorTypes) {
    errorTypes = Objectfreeze({
        CancellationError: CancellationError,
        TimeoutError: TimeoutError,
        OperationalError: OperationalError,
        RejectionError: OperationalError,
        AggregateError: AggregateError
    });
    es5.defineProperty(Error, "__BluebirdErrorTypes__", {
        value: errorTypes,
        writable: false,
        enumerable: false,
        configurable: false
    });
}

module.exports = {
    Error: Error,
    TypeError: _TypeError,
    RangeError: _RangeError,
    CancellationError: errorTypes.CancellationError,
    OperationalError: errorTypes.OperationalError,
    TimeoutError: errorTypes.TimeoutError,
    AggregateError: errorTypes.AggregateError,
    Warning: Warning
};

},{"./es5":13,"./util":36}],13:[function(_dereq_,module,exports){
var isES5 = (function(){
    "use strict";
    return this === undefined;
})();

if (isES5) {
    module.exports = {
        freeze: Object.freeze,
        defineProperty: Object.defineProperty,
        getDescriptor: Object.getOwnPropertyDescriptor,
        keys: Object.keys,
        names: Object.getOwnPropertyNames,
        getPrototypeOf: Object.getPrototypeOf,
        isArray: Array.isArray,
        isES5: isES5,
        propertyIsWritable: function(obj, prop) {
            var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
            return !!(!descriptor || descriptor.writable || descriptor.set);
        }
    };
} else {
    var has = {}.hasOwnProperty;
    var str = {}.toString;
    var proto = {}.constructor.prototype;

    var ObjectKeys = function (o) {
        var ret = [];
        for (var key in o) {
            if (has.call(o, key)) {
                ret.push(key);
            }
        }
        return ret;
    };

    var ObjectGetDescriptor = function(o, key) {
        return {value: o[key]};
    };

    var ObjectDefineProperty = function (o, key, desc) {
        o[key] = desc.value;
        return o;
    };

    var ObjectFreeze = function (obj) {
        return obj;
    };

    var ObjectGetPrototypeOf = function (obj) {
        try {
            return Object(obj).constructor.prototype;
        }
        catch (e) {
            return proto;
        }
    };

    var ArrayIsArray = function (obj) {
        try {
            return str.call(obj) === "[object Array]";
        }
        catch(e) {
            return false;
        }
    };

    module.exports = {
        isArray: ArrayIsArray,
        keys: ObjectKeys,
        names: ObjectKeys,
        defineProperty: ObjectDefineProperty,
        getDescriptor: ObjectGetDescriptor,
        freeze: ObjectFreeze,
        getPrototypeOf: ObjectGetPrototypeOf,
        isES5: isES5,
        propertyIsWritable: function() {
            return true;
        }
    };
}

},{}],14:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, INTERNAL) {
var PromiseMap = Promise.map;

Promise.prototype.filter = function (fn, options) {
    return PromiseMap(this, fn, options, INTERNAL);
};

Promise.filter = function (promises, fn, options) {
    return PromiseMap(promises, fn, options, INTERNAL);
};
};

},{}],15:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, tryConvertToPromise) {
var util = _dereq_("./util");
var CancellationError = Promise.CancellationError;
var errorObj = util.errorObj;

function PassThroughHandlerContext(promise, type, handler) {
    this.promise = promise;
    this.type = type;
    this.handler = handler;
    this.called = false;
    this.cancelPromise = null;
}

PassThroughHandlerContext.prototype.isFinallyHandler = function() {
    return this.type === 0;
};

function FinallyHandlerCancelReaction(finallyHandler) {
    this.finallyHandler = finallyHandler;
}

FinallyHandlerCancelReaction.prototype._resultCancelled = function() {
    checkCancel(this.finallyHandler);
};

function checkCancel(ctx, reason) {
    if (ctx.cancelPromise != null) {
        if (arguments.length > 1) {
            ctx.cancelPromise._reject(reason);
        } else {
            ctx.cancelPromise._cancel();
        }
        ctx.cancelPromise = null;
        return true;
    }
    return false;
}

function succeed() {
    return finallyHandler.call(this, this.promise._target()._settledValue());
}
function fail(reason) {
    if (checkCancel(this, reason)) return;
    errorObj.e = reason;
    return errorObj;
}
function finallyHandler(reasonOrValue) {
    var promise = this.promise;
    var handler = this.handler;

    if (!this.called) {
        this.called = true;
        var ret = this.isFinallyHandler()
            ? handler.call(promise._boundValue())
            : handler.call(promise._boundValue(), reasonOrValue);
        if (ret !== undefined) {
            promise._setReturnedNonUndefined();
            var maybePromise = tryConvertToPromise(ret, promise);
            if (maybePromise instanceof Promise) {
                if (this.cancelPromise != null) {
                    if (maybePromise._isCancelled()) {
                        var reason =
                            new CancellationError("late cancellation observer");
                        promise._attachExtraTrace(reason);
                        errorObj.e = reason;
                        return errorObj;
                    } else if (maybePromise.isPending()) {
                        maybePromise._attachCancellationCallback(
                            new FinallyHandlerCancelReaction(this));
                    }
                }
                return maybePromise._then(
                    succeed, fail, undefined, this, undefined);
            }
        }
    }

    if (promise.isRejected()) {
        checkCancel(this);
        errorObj.e = reasonOrValue;
        return errorObj;
    } else {
        checkCancel(this);
        return reasonOrValue;
    }
}

Promise.prototype._passThrough = function(handler, type, success, fail) {
    if (typeof handler !== "function") return this.then();
    return this._then(success,
                      fail,
                      undefined,
                      new PassThroughHandlerContext(this, type, handler),
                      undefined);
};

Promise.prototype.lastly =
Promise.prototype["finally"] = function (handler) {
    return this._passThrough(handler,
                             0,
                             finallyHandler,
                             finallyHandler);
};

Promise.prototype.tap = function (handler) {
    return this._passThrough(handler, 1, finallyHandler);
};

return PassThroughHandlerContext;
};

},{"./util":36}],16:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise,
                          apiRejection,
                          INTERNAL,
                          tryConvertToPromise,
                          Proxyable,
                          debug) {
var errors = _dereq_("./errors");
var TypeError = errors.TypeError;
var util = _dereq_("./util");
var errorObj = util.errorObj;
var tryCatch = util.tryCatch;
var yieldHandlers = [];

function promiseFromYieldHandler(value, yieldHandlers, traceParent) {
    for (var i = 0; i < yieldHandlers.length; ++i) {
        traceParent._pushContext();
        var result = tryCatch(yieldHandlers[i])(value);
        traceParent._popContext();
        if (result === errorObj) {
            traceParent._pushContext();
            var ret = Promise.reject(errorObj.e);
            traceParent._popContext();
            return ret;
        }
        var maybePromise = tryConvertToPromise(result, traceParent);
        if (maybePromise instanceof Promise) return maybePromise;
    }
    return null;
}

function PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) {
    if (debug.cancellation()) {
        var internal = new Promise(INTERNAL);
        var _finallyPromise = this._finallyPromise = new Promise(INTERNAL);
        this._promise = internal.lastly(function() {
            return _finallyPromise;
        });
        internal._captureStackTrace();
        internal._setOnCancel(this);
    } else {
        var promise = this._promise = new Promise(INTERNAL);
        promise._captureStackTrace();
    }
    this._stack = stack;
    this._generatorFunction = generatorFunction;
    this._receiver = receiver;
    this._generator = undefined;
    this._yieldHandlers = typeof yieldHandler === "function"
        ? [yieldHandler].concat(yieldHandlers)
        : yieldHandlers;
    this._yieldedPromise = null;
    this._cancellationPhase = false;
}
util.inherits(PromiseSpawn, Proxyable);

PromiseSpawn.prototype._isResolved = function() {
    return this._promise === null;
};

PromiseSpawn.prototype._cleanup = function() {
    this._promise = this._generator = null;
    if (debug.cancellation() && this._finallyPromise !== null) {
        this._finallyPromise._fulfill();
        this._finallyPromise = null;
    }
};

PromiseSpawn.prototype._promiseCancelled = function() {
    if (this._isResolved()) return;
    var implementsReturn = typeof this._generator["return"] !== "undefined";

    var result;
    if (!implementsReturn) {
        var reason = new Promise.CancellationError(
            "generator .return() sentinel");
        Promise.coroutine.returnSentinel = reason;
        this._promise._attachExtraTrace(reason);
        this._promise._pushContext();
        result = tryCatch(this._generator["throw"]).call(this._generator,
                                                         reason);
        this._promise._popContext();
    } else {
        this._promise._pushContext();
        result = tryCatch(this._generator["return"]).call(this._generator,
                                                          undefined);
        this._promise._popContext();
    }
    this._cancellationPhase = true;
    this._yieldedPromise = null;
    this._continue(result);
};

PromiseSpawn.prototype._promiseFulfilled = function(value) {
    this._yieldedPromise = null;
    this._promise._pushContext();
    var result = tryCatch(this._generator.next).call(this._generator, value);
    this._promise._popContext();
    this._continue(result);
};

PromiseSpawn.prototype._promiseRejected = function(reason) {
    this._yieldedPromise = null;
    this._promise._attachExtraTrace(reason);
    this._promise._pushContext();
    var result = tryCatch(this._generator["throw"])
        .call(this._generator, reason);
    this._promise._popContext();
    this._continue(result);
};

PromiseSpawn.prototype._resultCancelled = function() {
    if (this._yieldedPromise instanceof Promise) {
        var promise = this._yieldedPromise;
        this._yieldedPromise = null;
        promise.cancel();
    }
};

PromiseSpawn.prototype.promise = function () {
    return this._promise;
};

PromiseSpawn.prototype._run = function () {
    this._generator = this._generatorFunction.call(this._receiver);
    this._receiver =
        this._generatorFunction = undefined;
    this._promiseFulfilled(undefined);
};

PromiseSpawn.prototype._continue = function (result) {
    var promise = this._promise;
    if (result === errorObj) {
        this._cleanup();
        if (this._cancellationPhase) {
            return promise.cancel();
        } else {
            return promise._rejectCallback(result.e, false);
        }
    }

    var value = result.value;
    if (result.done === true) {
        this._cleanup();
        if (this._cancellationPhase) {
            return promise.cancel();
        } else {
            return promise._resolveCallback(value);
        }
    } else {
        var maybePromise = tryConvertToPromise(value, this._promise);
        if (!(maybePromise instanceof Promise)) {
            maybePromise =
                promiseFromYieldHandler(maybePromise,
                                        this._yieldHandlers,
                                        this._promise);
            if (maybePromise === null) {
                this._promiseRejected(
                    new TypeError(
                        "A value %s was yielded that could not be treated as a promise\u000a\u000a    See http://goo.gl/MqrFmX\u000a\u000a".replace("%s", value) +
                        "From coroutine:\u000a" +
                        this._stack.split("\n").slice(1, -7).join("\n")
                    )
                );
                return;
            }
        }
        maybePromise = maybePromise._target();
        var bitField = maybePromise._bitField;
        ;
        if (((bitField & 50397184) === 0)) {
            this._yieldedPromise = maybePromise;
            maybePromise._proxy(this, null);
        } else if (((bitField & 33554432) !== 0)) {
            Promise._async.invoke(
                this._promiseFulfilled, this, maybePromise._value()
            );
        } else if (((bitField & 16777216) !== 0)) {
            Promise._async.invoke(
                this._promiseRejected, this, maybePromise._reason()
            );
        } else {
            this._promiseCancelled();
        }
    }
};

Promise.coroutine = function (generatorFunction, options) {
    if (typeof generatorFunction !== "function") {
        throw new TypeError("generatorFunction must be a function\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    var yieldHandler = Object(options).yieldHandler;
    var PromiseSpawn$ = PromiseSpawn;
    var stack = new Error().stack;
    return function () {
        var generator = generatorFunction.apply(this, arguments);
        var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler,
                                      stack);
        var ret = spawn.promise();
        spawn._generator = generator;
        spawn._promiseFulfilled(undefined);
        return ret;
    };
};

Promise.coroutine.addYieldHandler = function(fn) {
    if (typeof fn !== "function") {
        throw new TypeError("expecting a function but got " + util.classString(fn));
    }
    yieldHandlers.push(fn);
};

Promise.spawn = function (generatorFunction) {
    debug.deprecated("Promise.spawn()", "Promise.coroutine()");
    if (typeof generatorFunction !== "function") {
        return apiRejection("generatorFunction must be a function\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    var spawn = new PromiseSpawn(generatorFunction, this);
    var ret = spawn.promise();
    spawn._run(Promise.spawn);
    return ret;
};
};

},{"./errors":12,"./util":36}],17:[function(_dereq_,module,exports){
"use strict";
module.exports =
function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async,
         getDomain) {
var util = _dereq_("./util");
var canEvaluate = util.canEvaluate;
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;
var reject;

if (!true) {
if (canEvaluate) {
    var thenCallback = function(i) {
        return new Function("value", "holder", "                             \n\
            'use strict';                                                    \n\
            holder.pIndex = value;                                           \n\
            holder.checkFulfillment(this);                                   \n\
            ".replace(/Index/g, i));
    };

    var promiseSetter = function(i) {
        return new Function("promise", "holder", "                           \n\
            'use strict';                                                    \n\
            holder.pIndex = promise;                                         \n\
            ".replace(/Index/g, i));
    };

    var generateHolderClass = function(total) {
        var props = new Array(total);
        for (var i = 0; i < props.length; ++i) {
            props[i] = "this.p" + (i+1);
        }
        var assignment = props.join(" = ") + " = null;";
        var cancellationCode= "var promise;\n" + props.map(function(prop) {
            return "                                                         \n\
                promise = " + prop + ";                                      \n\
                if (promise instanceof Promise) {                            \n\
                    promise.cancel();                                        \n\
                }                                                            \n\
            ";
        }).join("\n");
        var passedArguments = props.join(", ");
        var name = "Holder$" + total;


        var code = "return function(tryCatch, errorObj, Promise, async) {    \n\
            'use strict';                                                    \n\
            function [TheName](fn) {                                         \n\
                [TheProperties]                                              \n\
                this.fn = fn;                                                \n\
                this.asyncNeeded = true;                                     \n\
                this.now = 0;                                                \n\
            }                                                                \n\
                                                                             \n\
            [TheName].prototype._callFunction = function(promise) {          \n\
                promise._pushContext();                                      \n\
                var ret = tryCatch(this.fn)([ThePassedArguments]);           \n\
                promise._popContext();                                       \n\
                if (ret === errorObj) {                                      \n\
                    promise._rejectCallback(ret.e, false);                   \n\
                } else {                                                     \n\
                    promise._resolveCallback(ret);                           \n\
                }                                                            \n\
            };                                                               \n\
                                                                             \n\
            [TheName].prototype.checkFulfillment = function(promise) {       \n\
                var now = ++this.now;                                        \n\
                if (now === [TheTotal]) {                                    \n\
                    if (this.asyncNeeded) {                                  \n\
                        async.invoke(this._callFunction, this, promise);     \n\
                    } else {                                                 \n\
                        this._callFunction(promise);                         \n\
                    }                                                        \n\
                                                                             \n\
                }                                                            \n\
            };                                                               \n\
                                                                             \n\
            [TheName].prototype._resultCancelled = function() {              \n\
                [CancellationCode]                                           \n\
            };                                                               \n\
                                                                             \n\
            return [TheName];                                                \n\
        }(tryCatch, errorObj, Promise, async);                               \n\
        ";

        code = code.replace(/\[TheName\]/g, name)
            .replace(/\[TheTotal\]/g, total)
            .replace(/\[ThePassedArguments\]/g, passedArguments)
            .replace(/\[TheProperties\]/g, assignment)
            .replace(/\[CancellationCode\]/g, cancellationCode);

        return new Function("tryCatch", "errorObj", "Promise", "async", code)
                           (tryCatch, errorObj, Promise, async);
    };

    var holderClasses = [];
    var thenCallbacks = [];
    var promiseSetters = [];

    for (var i = 0; i < 8; ++i) {
        holderClasses.push(generateHolderClass(i + 1));
        thenCallbacks.push(thenCallback(i + 1));
        promiseSetters.push(promiseSetter(i + 1));
    }

    reject = function (reason) {
        this._reject(reason);
    };
}}

Promise.join = function () {
    var last = arguments.length - 1;
    var fn;
    if (last > 0 && typeof arguments[last] === "function") {
        fn = arguments[last];
        if (!true) {
            if (last <= 8 && canEvaluate) {
                var ret = new Promise(INTERNAL);
                ret._captureStackTrace();
                var HolderClass = holderClasses[last - 1];
                var holder = new HolderClass(fn);
                var callbacks = thenCallbacks;

                for (var i = 0; i < last; ++i) {
                    var maybePromise = tryConvertToPromise(arguments[i], ret);
                    if (maybePromise instanceof Promise) {
                        maybePromise = maybePromise._target();
                        var bitField = maybePromise._bitField;
                        ;
                        if (((bitField & 50397184) === 0)) {
                            maybePromise._then(callbacks[i], reject,
                                               undefined, ret, holder);
                            promiseSetters[i](maybePromise, holder);
                            holder.asyncNeeded = false;
                        } else if (((bitField & 33554432) !== 0)) {
                            callbacks[i].call(ret,
                                              maybePromise._value(), holder);
                        } else if (((bitField & 16777216) !== 0)) {
                            ret._reject(maybePromise._reason());
                        } else {
                            ret._cancel();
                        }
                    } else {
                        callbacks[i].call(ret, maybePromise, holder);
                    }
                }

                if (!ret._isFateSealed()) {
                    if (holder.asyncNeeded) {
                        var domain = getDomain();
                        if (domain !== null) {
                            holder.fn = util.domainBind(domain, holder.fn);
                        }
                    }
                    ret._setAsyncGuaranteed();
                    ret._setOnCancel(holder);
                }
                return ret;
            }
        }
    }
    var args = [].slice.call(arguments);;
    if (fn) args.pop();
    var ret = new PromiseArray(args).promise();
    return fn !== undefined ? ret.spread(fn) : ret;
};

};

},{"./util":36}],18:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise,
                          PromiseArray,
                          apiRejection,
                          tryConvertToPromise,
                          INTERNAL,
                          debug) {
var getDomain = Promise._getDomain;
var util = _dereq_("./util");
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;

function MappingPromiseArray(promises, fn, limit, _filter) {
    this.constructor$(promises);
    this._promise._captureStackTrace();
    var domain = getDomain();
    this._callback = domain === null ? fn : util.domainBind(domain, fn);
    this._preservedValues = _filter === INTERNAL
        ? new Array(this.length())
        : null;
    this._limit = limit;
    this._inFlight = 0;
    this._queue = [];
    this._init$(undefined, -2);
}
util.inherits(MappingPromiseArray, PromiseArray);

MappingPromiseArray.prototype._init = function () {};

MappingPromiseArray.prototype._promiseFulfilled = function (value, index) {
    var values = this._values;
    var length = this.length();
    var preservedValues = this._preservedValues;
    var limit = this._limit;

    if (index < 0) {
        index = (index * -1) - 1;
        values[index] = value;
        if (limit >= 1) {
            this._inFlight--;
            this._drainQueue();
            if (this._isResolved()) return true;
        }
    } else {
        if (limit >= 1 && this._inFlight >= limit) {
            values[index] = value;
            this._queue.push(index);
            return false;
        }
        if (preservedValues !== null) preservedValues[index] = value;

        var promise = this._promise;
        var callback = this._callback;
        var receiver = promise._boundValue();
        promise._pushContext();
        var ret = tryCatch(callback).call(receiver, value, index, length);
        var promiseCreated = promise._popContext();
        debug.checkForgottenReturns(
            ret,
            promiseCreated,
            preservedValues !== null ? "Promise.filter" : "Promise.map",
            promise
        );
        if (ret === errorObj) {
            this._reject(ret.e);
            return true;
        }

        var maybePromise = tryConvertToPromise(ret, this._promise);
        if (maybePromise instanceof Promise) {
            maybePromise = maybePromise._target();
            var bitField = maybePromise._bitField;
            ;
            if (((bitField & 50397184) === 0)) {
                if (limit >= 1) this._inFlight++;
                values[index] = maybePromise;
                maybePromise._proxy(this, (index + 1) * -1);
                return false;
            } else if (((bitField & 33554432) !== 0)) {
                ret = maybePromise._value();
            } else if (((bitField & 16777216) !== 0)) {
                this._reject(maybePromise._reason());
                return true;
            } else {
                this._cancel();
                return true;
            }
        }
        values[index] = ret;
    }
    var totalResolved = ++this._totalResolved;
    if (totalResolved >= length) {
        if (preservedValues !== null) {
            this._filter(values, preservedValues);
        } else {
            this._resolve(values);
        }
        return true;
    }
    return false;
};

MappingPromiseArray.prototype._drainQueue = function () {
    var queue = this._queue;
    var limit = this._limit;
    var values = this._values;
    while (queue.length > 0 && this._inFlight < limit) {
        if (this._isResolved()) return;
        var index = queue.pop();
        this._promiseFulfilled(values[index], index);
    }
};

MappingPromiseArray.prototype._filter = function (booleans, values) {
    var len = values.length;
    var ret = new Array(len);
    var j = 0;
    for (var i = 0; i < len; ++i) {
        if (booleans[i]) ret[j++] = values[i];
    }
    ret.length = j;
    this._resolve(ret);
};

MappingPromiseArray.prototype.preservedValues = function () {
    return this._preservedValues;
};

function map(promises, fn, options, _filter) {
    if (typeof fn !== "function") {
        return apiRejection("expecting a function but got " + util.classString(fn));
    }

    var limit = 0;
    if (options !== undefined) {
        if (typeof options === "object" && options !== null) {
            if (typeof options.concurrency !== "number") {
                return Promise.reject(
                    new TypeError("'concurrency' must be a number but it is " +
                                    util.classString(options.concurrency)));
            }
            limit = options.concurrency;
        } else {
            return Promise.reject(new TypeError(
                            "options argument must be an object but it is " +
                             util.classString(options)));
        }
    }
    limit = typeof limit === "number" &&
        isFinite(limit) && limit >= 1 ? limit : 0;
    return new MappingPromiseArray(promises, fn, limit, _filter).promise();
}

Promise.prototype.map = function (fn, options) {
    return map(this, fn, options, null);
};

Promise.map = function (promises, fn, options, _filter) {
    return map(promises, fn, options, _filter);
};


};

},{"./util":36}],19:[function(_dereq_,module,exports){
"use strict";
module.exports =
function(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) {
var util = _dereq_("./util");
var tryCatch = util.tryCatch;

Promise.method = function (fn) {
    if (typeof fn !== "function") {
        throw new Promise.TypeError("expecting a function but got " + util.classString(fn));
    }
    return function () {
        var ret = new Promise(INTERNAL);
        ret._captureStackTrace();
        ret._pushContext();
        var value = tryCatch(fn).apply(this, arguments);
        var promiseCreated = ret._popContext();
        debug.checkForgottenReturns(
            value, promiseCreated, "Promise.method", ret);
        ret._resolveFromSyncValue(value);
        return ret;
    };
};

Promise.attempt = Promise["try"] = function (fn) {
    if (typeof fn !== "function") {
        return apiRejection("expecting a function but got " + util.classString(fn));
    }
    var ret = new Promise(INTERNAL);
    ret._captureStackTrace();
    ret._pushContext();
    var value;
    if (arguments.length > 1) {
        debug.deprecated("calling Promise.try with more than 1 argument");
        var arg = arguments[1];
        var ctx = arguments[2];
        value = util.isArray(arg) ? tryCatch(fn).apply(ctx, arg)
                                  : tryCatch(fn).call(ctx, arg);
    } else {
        value = tryCatch(fn)();
    }
    var promiseCreated = ret._popContext();
    debug.checkForgottenReturns(
        value, promiseCreated, "Promise.try", ret);
    ret._resolveFromSyncValue(value);
    return ret;
};

Promise.prototype._resolveFromSyncValue = function (value) {
    if (value === util.errorObj) {
        this._rejectCallback(value.e, false);
    } else {
        this._resolveCallback(value, true);
    }
};
};

},{"./util":36}],20:[function(_dereq_,module,exports){
"use strict";
var util = _dereq_("./util");
var maybeWrapAsError = util.maybeWrapAsError;
var errors = _dereq_("./errors");
var OperationalError = errors.OperationalError;
var es5 = _dereq_("./es5");

function isUntypedError(obj) {
    return obj instanceof Error &&
        es5.getPrototypeOf(obj) === Error.prototype;
}

var rErrorKey = /^(?:name|message|stack|cause)$/;
function wrapAsOperationalError(obj) {
    var ret;
    if (isUntypedError(obj)) {
        ret = new OperationalError(obj);
        ret.name = obj.name;
        ret.message = obj.message;
        ret.stack = obj.stack;
        var keys = es5.keys(obj);
        for (var i = 0; i < keys.length; ++i) {
            var key = keys[i];
            if (!rErrorKey.test(key)) {
                ret[key] = obj[key];
            }
        }
        return ret;
    }
    util.markAsOriginatingFromRejection(obj);
    return obj;
}

function nodebackForPromise(promise, multiArgs) {
    return function(err, value) {
        if (promise === null) return;
        if (err) {
            var wrapped = wrapAsOperationalError(maybeWrapAsError(err));
            promise._attachExtraTrace(wrapped);
            promise._reject(wrapped);
        } else if (!multiArgs) {
            promise._fulfill(value);
        } else {
            var args = [].slice.call(arguments, 1);;
            promise._fulfill(args);
        }
        promise = null;
    };
}

module.exports = nodebackForPromise;

},{"./errors":12,"./es5":13,"./util":36}],21:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise) {
var util = _dereq_("./util");
var async = Promise._async;
var tryCatch = util.tryCatch;
var errorObj = util.errorObj;

function spreadAdapter(val, nodeback) {
    var promise = this;
    if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback);
    var ret =
        tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val));
    if (ret === errorObj) {
        async.throwLater(ret.e);
    }
}

function successAdapter(val, nodeback) {
    var promise = this;
    var receiver = promise._boundValue();
    var ret = val === undefined
        ? tryCatch(nodeback).call(receiver, null)
        : tryCatch(nodeback).call(receiver, null, val);
    if (ret === errorObj) {
        async.throwLater(ret.e);
    }
}
function errorAdapter(reason, nodeback) {
    var promise = this;
    if (!reason) {
        var newReason = new Error(reason + "");
        newReason.cause = reason;
        reason = newReason;
    }
    var ret = tryCatch(nodeback).call(promise._boundValue(), reason);
    if (ret === errorObj) {
        async.throwLater(ret.e);
    }
}

Promise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback,
                                                                     options) {
    if (typeof nodeback == "function") {
        var adapter = successAdapter;
        if (options !== undefined && Object(options).spread) {
            adapter = spreadAdapter;
        }
        this._then(
            adapter,
            errorAdapter,
            undefined,
            this,
            nodeback
        );
    }
    return this;
};
};

},{"./util":36}],22:[function(_dereq_,module,exports){
"use strict";
module.exports = function() {
var makeSelfResolutionError = function () {
    return new TypeError("circular promise resolution chain\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
};
var reflectHandler = function() {
    return new Promise.PromiseInspection(this._target());
};
var apiRejection = function(msg) {
    return Promise.reject(new TypeError(msg));
};
function Proxyable() {}
var UNDEFINED_BINDING = {};
var util = _dereq_("./util");

var getDomain;
if (util.isNode) {
    getDomain = function() {
        var ret = process.domain;
        if (ret === undefined) ret = null;
        return ret;
    };
} else {
    getDomain = function() {
        return null;
    };
}
util.notEnumerableProp(Promise, "_getDomain", getDomain);

var es5 = _dereq_("./es5");
var Async = _dereq_("./async");
var async = new Async();
es5.defineProperty(Promise, "_async", {value: async});
var errors = _dereq_("./errors");
var TypeError = Promise.TypeError = errors.TypeError;
Promise.RangeError = errors.RangeError;
var CancellationError = Promise.CancellationError = errors.CancellationError;
Promise.TimeoutError = errors.TimeoutError;
Promise.OperationalError = errors.OperationalError;
Promise.RejectionError = errors.OperationalError;
Promise.AggregateError = errors.AggregateError;
var INTERNAL = function(){};
var APPLY = {};
var NEXT_FILTER = {};
var tryConvertToPromise = _dereq_("./thenables")(Promise, INTERNAL);
var PromiseArray =
    _dereq_("./promise_array")(Promise, INTERNAL,
                               tryConvertToPromise, apiRejection, Proxyable);
var Context = _dereq_("./context")(Promise);
 /*jshint unused:false*/
var createContext = Context.create;
var debug = _dereq_("./debuggability")(Promise, Context);
var CapturedTrace = debug.CapturedTrace;
var PassThroughHandlerContext =
    _dereq_("./finally")(Promise, tryConvertToPromise);
var catchFilter = _dereq_("./catch_filter")(NEXT_FILTER);
var nodebackForPromise = _dereq_("./nodeback");
var errorObj = util.errorObj;
var tryCatch = util.tryCatch;
function check(self, executor) {
    if (typeof executor !== "function") {
        throw new TypeError("expecting a function but got " + util.classString(executor));
    }
    if (self.constructor !== Promise) {
        throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
}

function Promise(executor) {
    this._bitField = 0;
    this._fulfillmentHandler0 = undefined;
    this._rejectionHandler0 = undefined;
    this._promise0 = undefined;
    this._receiver0 = undefined;
    if (executor !== INTERNAL) {
        check(this, executor);
        this._resolveFromExecutor(executor);
    }
    this._promiseCreated();
    this._fireEvent("promiseCreated", this);
}

Promise.prototype.toString = function () {
    return "[object Promise]";
};

Promise.prototype.caught = Promise.prototype["catch"] = function (fn) {
    var len = arguments.length;
    if (len > 1) {
        var catchInstances = new Array(len - 1),
            j = 0, i;
        for (i = 0; i < len - 1; ++i) {
            var item = arguments[i];
            if (util.isObject(item)) {
                catchInstances[j++] = item;
            } else {
                return apiRejection("expecting an object but got " +
                    "A catch statement predicate " + util.classString(item));
            }
        }
        catchInstances.length = j;
        fn = arguments[i];
        return this.then(undefined, catchFilter(catchInstances, fn, this));
    }
    return this.then(undefined, fn);
};

Promise.prototype.reflect = function () {
    return this._then(reflectHandler,
        reflectHandler, undefined, this, undefined);
};

Promise.prototype.then = function (didFulfill, didReject) {
    if (debug.warnings() && arguments.length > 0 &&
        typeof didFulfill !== "function" &&
        typeof didReject !== "function") {
        var msg = ".then() only accepts functions but was passed: " +
                util.classString(didFulfill);
        if (arguments.length > 1) {
            msg += ", " + util.classString(didReject);
        }
        this._warn(msg);
    }
    return this._then(didFulfill, didReject, undefined, undefined, undefined);
};

Promise.prototype.done = function (didFulfill, didReject) {
    var promise =
        this._then(didFulfill, didReject, undefined, undefined, undefined);
    promise._setIsFinal();
};

Promise.prototype.spread = function (fn) {
    if (typeof fn !== "function") {
        return apiRejection("expecting a function but got " + util.classString(fn));
    }
    return this.all()._then(fn, undefined, undefined, APPLY, undefined);
};

Promise.prototype.toJSON = function () {
    var ret = {
        isFulfilled: false,
        isRejected: false,
        fulfillmentValue: undefined,
        rejectionReason: undefined
    };
    if (this.isFulfilled()) {
        ret.fulfillmentValue = this.value();
        ret.isFulfilled = true;
    } else if (this.isRejected()) {
        ret.rejectionReason = this.reason();
        ret.isRejected = true;
    }
    return ret;
};

Promise.prototype.all = function () {
    if (arguments.length > 0) {
        this._warn(".all() was passed arguments but it does not take any");
    }
    return new PromiseArray(this).promise();
};

Promise.prototype.error = function (fn) {
    return this.caught(util.originatesFromRejection, fn);
};

Promise.getNewLibraryCopy = module.exports;

Promise.is = function (val) {
    return val instanceof Promise;
};

Promise.fromNode = Promise.fromCallback = function(fn) {
    var ret = new Promise(INTERNAL);
    ret._captureStackTrace();
    var multiArgs = arguments.length > 1 ? !!Object(arguments[1]).multiArgs
                                         : false;
    var result = tryCatch(fn)(nodebackForPromise(ret, multiArgs));
    if (result === errorObj) {
        ret._rejectCallback(result.e, true);
    }
    if (!ret._isFateSealed()) ret._setAsyncGuaranteed();
    return ret;
};

Promise.all = function (promises) {
    return new PromiseArray(promises).promise();
};

Promise.cast = function (obj) {
    var ret = tryConvertToPromise(obj);
    if (!(ret instanceof Promise)) {
        ret = new Promise(INTERNAL);
        ret._captureStackTrace();
        ret._setFulfilled();
        ret._rejectionHandler0 = obj;
    }
    return ret;
};

Promise.resolve = Promise.fulfilled = Promise.cast;

Promise.reject = Promise.rejected = function (reason) {
    var ret = new Promise(INTERNAL);
    ret._captureStackTrace();
    ret._rejectCallback(reason, true);
    return ret;
};

Promise.setScheduler = function(fn) {
    if (typeof fn !== "function") {
        throw new TypeError("expecting a function but got " + util.classString(fn));
    }
    return async.setScheduler(fn);
};

Promise.prototype._then = function (
    didFulfill,
    didReject,
    _,    receiver,
    internalData
) {
    var haveInternalData = internalData !== undefined;
    var promise = haveInternalData ? internalData : new Promise(INTERNAL);
    var target = this._target();
    var bitField = target._bitField;

    if (!haveInternalData) {
        promise._propagateFrom(this, 3);
        promise._captureStackTrace();
        if (receiver === undefined &&
            ((this._bitField & 2097152) !== 0)) {
            if (!((bitField & 50397184) === 0)) {
                receiver = this._boundValue();
            } else {
                receiver = target === this ? undefined : this._boundTo;
            }
        }
        this._fireEvent("promiseChained", this, promise);
    }

    var domain = getDomain();
    if (!((bitField & 50397184) === 0)) {
        var handler, value, settler = target._settlePromiseCtx;
        if (((bitField & 33554432) !== 0)) {
            value = target._rejectionHandler0;
            handler = didFulfill;
        } else if (((bitField & 16777216) !== 0)) {
            value = target._fulfillmentHandler0;
            handler = didReject;
            target._unsetRejectionIsUnhandled();
        } else {
            settler = target._settlePromiseLateCancellationObserver;
            value = new CancellationError("late cancellation observer");
            target._attachExtraTrace(value);
            handler = didReject;
        }

        async.invoke(settler, target, {
            handler: domain === null ? handler
                : (typeof handler === "function" &&
                    util.domainBind(domain, handler)),
            promise: promise,
            receiver: receiver,
            value: value
        });
    } else {
        target._addCallbacks(didFulfill, didReject, promise, receiver, domain);
    }

    return promise;
};

Promise.prototype._length = function () {
    return this._bitField & 65535;
};

Promise.prototype._isFateSealed = function () {
    return (this._bitField & 117506048) !== 0;
};

Promise.prototype._isFollowing = function () {
    return (this._bitField & 67108864) === 67108864;
};

Promise.prototype._setLength = function (len) {
    this._bitField = (this._bitField & -65536) |
        (len & 65535);
};

Promise.prototype._setFulfilled = function () {
    this._bitField = this._bitField | 33554432;
    this._fireEvent("promiseFulfilled", this);
};

Promise.prototype._setRejected = function () {
    this._bitField = this._bitField | 16777216;
    this._fireEvent("promiseRejected", this);
};

Promise.prototype._setFollowing = function () {
    this._bitField = this._bitField | 67108864;
    this._fireEvent("promiseResolved", this);
};

Promise.prototype._setIsFinal = function () {
    this._bitField = this._bitField | 4194304;
};

Promise.prototype._isFinal = function () {
    return (this._bitField & 4194304) > 0;
};

Promise.prototype._unsetCancelled = function() {
    this._bitField = this._bitField & (~65536);
};

Promise.prototype._setCancelled = function() {
    this._bitField = this._bitField | 65536;
    this._fireEvent("promiseCancelled", this);
};

Promise.prototype._setWillBeCancelled = function() {
    this._bitField = this._bitField | 8388608;
};

Promise.prototype._setAsyncGuaranteed = function() {
    if (async.hasCustomScheduler()) return;
    this._bitField = this._bitField | 134217728;
};

Promise.prototype._receiverAt = function (index) {
    var ret = index === 0 ? this._receiver0 : this[
            index * 4 - 4 + 3];
    if (ret === UNDEFINED_BINDING) {
        return undefined;
    } else if (ret === undefined && this._isBound()) {
        return this._boundValue();
    }
    return ret;
};

Promise.prototype._promiseAt = function (index) {
    return this[
            index * 4 - 4 + 2];
};

Promise.prototype._fulfillmentHandlerAt = function (index) {
    return this[
            index * 4 - 4 + 0];
};

Promise.prototype._rejectionHandlerAt = function (index) {
    return this[
            index * 4 - 4 + 1];
};

Promise.prototype._boundValue = function() {};

Promise.prototype._migrateCallback0 = function (follower) {
    var bitField = follower._bitField;
    var fulfill = follower._fulfillmentHandler0;
    var reject = follower._rejectionHandler0;
    var promise = follower._promise0;
    var receiver = follower._receiverAt(0);
    if (receiver === undefined) receiver = UNDEFINED_BINDING;
    this._addCallbacks(fulfill, reject, promise, receiver, null);
};

Promise.prototype._migrateCallbackAt = function (follower, index) {
    var fulfill = follower._fulfillmentHandlerAt(index);
    var reject = follower._rejectionHandlerAt(index);
    var promise = follower._promiseAt(index);
    var receiver = follower._receiverAt(index);
    if (receiver === undefined) receiver = UNDEFINED_BINDING;
    this._addCallbacks(fulfill, reject, promise, receiver, null);
};

Promise.prototype._addCallbacks = function (
    fulfill,
    reject,
    promise,
    receiver,
    domain
) {
    var index = this._length();

    if (index >= 65535 - 4) {
        index = 0;
        this._setLength(0);
    }

    if (index === 0) {
        this._promise0 = promise;
        this._receiver0 = receiver;
        if (typeof fulfill === "function") {
            this._fulfillmentHandler0 =
                domain === null ? fulfill : util.domainBind(domain, fulfill);
        }
        if (typeof reject === "function") {
            this._rejectionHandler0 =
                domain === null ? reject : util.domainBind(domain, reject);
        }
    } else {
        var base = index * 4 - 4;
        this[base + 2] = promise;
        this[base + 3] = receiver;
        if (typeof fulfill === "function") {
            this[base + 0] =
                domain === null ? fulfill : util.domainBind(domain, fulfill);
        }
        if (typeof reject === "function") {
            this[base + 1] =
                domain === null ? reject : util.domainBind(domain, reject);
        }
    }
    this._setLength(index + 1);
    return index;
};

Promise.prototype._proxy = function (proxyable, arg) {
    this._addCallbacks(undefined, undefined, arg, proxyable, null);
};

Promise.prototype._resolveCallback = function(value, shouldBind) {
    if (((this._bitField & 117506048) !== 0)) return;
    if (value === this)
        return this._rejectCallback(makeSelfResolutionError(), false);
    var maybePromise = tryConvertToPromise(value, this);
    if (!(maybePromise instanceof Promise)) return this._fulfill(value);

    if (shouldBind) this._propagateFrom(maybePromise, 2);

    var promise = maybePromise._target();

    if (promise === this) {
        this._reject(makeSelfResolutionError());
        return;
    }

    var bitField = promise._bitField;
    if (((bitField & 50397184) === 0)) {
        var len = this._length();
        if (len > 0) promise._migrateCallback0(this);
        for (var i = 1; i < len; ++i) {
            promise._migrateCallbackAt(this, i);
        }
        this._setFollowing();
        this._setLength(0);
        this._setFollowee(promise);
    } else if (((bitField & 33554432) !== 0)) {
        this._fulfill(promise._value());
    } else if (((bitField & 16777216) !== 0)) {
        this._reject(promise._reason());
    } else {
        var reason = new CancellationError("late cancellation observer");
        promise._attachExtraTrace(reason);
        this._reject(reason);
    }
};

Promise.prototype._rejectCallback =
function(reason, synchronous, ignoreNonErrorWarnings) {
    var trace = util.ensureErrorObject(reason);
    var hasStack = trace === reason;
    if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) {
        var message = "a promise was rejected with a non-error: " +
            util.classString(reason);
        this._warn(message, true);
    }
    this._attachExtraTrace(trace, synchronous ? hasStack : false);
    this._reject(reason);
};

Promise.prototype._resolveFromExecutor = function (executor) {
    var promise = this;
    this._captureStackTrace();
    this._pushContext();
    var synchronous = true;
    var r = this._execute(executor, function(value) {
        promise._resolveCallback(value);
    }, function (reason) {
        promise._rejectCallback(reason, synchronous);
    });
    synchronous = false;
    this._popContext();

    if (r !== undefined) {
        promise._rejectCallback(r, true);
    }
};

Promise.prototype._settlePromiseFromHandler = function (
    handler, receiver, value, promise
) {
    var bitField = promise._bitField;
    if (((bitField & 65536) !== 0)) return;
    promise._pushContext();
    var x;
    if (receiver === APPLY) {
        if (!value || typeof value.length !== "number") {
            x = errorObj;
            x.e = new TypeError("cannot .spread() a non-array: " +
                                    util.classString(value));
        } else {
            x = tryCatch(handler).apply(this._boundValue(), value);
        }
    } else {
        x = tryCatch(handler).call(receiver, value);
    }
    var promiseCreated = promise._popContext();
    bitField = promise._bitField;
    if (((bitField & 65536) !== 0)) return;

    if (x === NEXT_FILTER) {
        promise._reject(value);
    } else if (x === errorObj) {
        promise._rejectCallback(x.e, false);
    } else {
        debug.checkForgottenReturns(x, promiseCreated, "",  promise, this);
        promise._resolveCallback(x);
    }
};

Promise.prototype._target = function() {
    var ret = this;
    while (ret._isFollowing()) ret = ret._followee();
    return ret;
};

Promise.prototype._followee = function() {
    return this._rejectionHandler0;
};

Promise.prototype._setFollowee = function(promise) {
    this._rejectionHandler0 = promise;
};

Promise.prototype._settlePromise = function(promise, handler, receiver, value) {
    var isPromise = promise instanceof Promise;
    var bitField = this._bitField;
    var asyncGuaranteed = ((bitField & 134217728) !== 0);
    if (((bitField & 65536) !== 0)) {
        if (isPromise) promise._invokeInternalOnCancel();

        if (receiver instanceof PassThroughHandlerContext &&
            receiver.isFinallyHandler()) {
            receiver.cancelPromise = promise;
            if (tryCatch(handler).call(receiver, value) === errorObj) {
                promise._reject(errorObj.e);
            }
        } else if (handler === reflectHandler) {
            promise._fulfill(reflectHandler.call(receiver));
        } else if (receiver instanceof Proxyable) {
            receiver._promiseCancelled(promise);
        } else if (isPromise || promise instanceof PromiseArray) {
            promise._cancel();
        } else {
            receiver.cancel();
        }
    } else if (typeof handler === "function") {
        if (!isPromise) {
            handler.call(receiver, value, promise);
        } else {
            if (asyncGuaranteed) promise._setAsyncGuaranteed();
            this._settlePromiseFromHandler(handler, receiver, value, promise);
        }
    } else if (receiver instanceof Proxyable) {
        if (!receiver._isResolved()) {
            if (((bitField & 33554432) !== 0)) {
                receiver._promiseFulfilled(value, promise);
            } else {
                receiver._promiseRejected(value, promise);
            }
        }
    } else if (isPromise) {
        if (asyncGuaranteed) promise._setAsyncGuaranteed();
        if (((bitField & 33554432) !== 0)) {
            promise._fulfill(value);
        } else {
            promise._reject(value);
        }
    }
};

Promise.prototype._settlePromiseLateCancellationObserver = function(ctx) {
    var handler = ctx.handler;
    var promise = ctx.promise;
    var receiver = ctx.receiver;
    var value = ctx.value;
    if (typeof handler === "function") {
        if (!(promise instanceof Promise)) {
            handler.call(receiver, value, promise);
        } else {
            this._settlePromiseFromHandler(handler, receiver, value, promise);
        }
    } else if (promise instanceof Promise) {
        promise._reject(value);
    }
};

Promise.prototype._settlePromiseCtx = function(ctx) {
    this._settlePromise(ctx.promise, ctx.handler, ctx.receiver, ctx.value);
};

Promise.prototype._settlePromise0 = function(handler, value, bitField) {
    var promise = this._promise0;
    var receiver = this._receiverAt(0);
    this._promise0 = undefined;
    this._receiver0 = undefined;
    this._settlePromise(promise, handler, receiver, value);
};

Promise.prototype._clearCallbackDataAtIndex = function(index) {
    var base = index * 4 - 4;
    this[base + 2] =
    this[base + 3] =
    this[base + 0] =
    this[base + 1] = undefined;
};

Promise.prototype._fulfill = function (value) {
    var bitField = this._bitField;
    if (((bitField & 117506048) >>> 16)) return;
    if (value === this) {
        var err = makeSelfResolutionError();
        this._attachExtraTrace(err);
        return this._reject(err);
    }
    this._setFulfilled();
    this._rejectionHandler0 = value;

    if ((bitField & 65535) > 0) {
        if (((bitField & 134217728) !== 0)) {
            this._settlePromises();
        } else {
            async.settlePromises(this);
        }
    }
};

Promise.prototype._reject = function (reason) {
    var bitField = this._bitField;
    if (((bitField & 117506048) >>> 16)) return;
    this._setRejected();
    this._fulfillmentHandler0 = reason;

    if (this._isFinal()) {
        return async.fatalError(reason, util.isNode);
    }

    if ((bitField & 65535) > 0) {
        async.settlePromises(this);
    } else {
        this._ensurePossibleRejectionHandled();
    }
};

Promise.prototype._fulfillPromises = function (len, value) {
    for (var i = 1; i < len; i++) {
        var handler = this._fulfillmentHandlerAt(i);
        var promise = this._promiseAt(i);
        var receiver = this._receiverAt(i);
        this._clearCallbackDataAtIndex(i);
        this._settlePromise(promise, handler, receiver, value);
    }
};

Promise.prototype._rejectPromises = function (len, reason) {
    for (var i = 1; i < len; i++) {
        var handler = this._rejectionHandlerAt(i);
        var promise = this._promiseAt(i);
        var receiver = this._receiverAt(i);
        this._clearCallbackDataAtIndex(i);
        this._settlePromise(promise, handler, receiver, reason);
    }
};

Promise.prototype._settlePromises = function () {
    var bitField = this._bitField;
    var len = (bitField & 65535);

    if (len > 0) {
        if (((bitField & 16842752) !== 0)) {
            var reason = this._fulfillmentHandler0;
            this._settlePromise0(this._rejectionHandler0, reason, bitField);
            this._rejectPromises(len, reason);
        } else {
            var value = this._rejectionHandler0;
            this._settlePromise0(this._fulfillmentHandler0, value, bitField);
            this._fulfillPromises(len, value);
        }
        this._setLength(0);
    }
    this._clearCancellationData();
};

Promise.prototype._settledValue = function() {
    var bitField = this._bitField;
    if (((bitField & 33554432) !== 0)) {
        return this._rejectionHandler0;
    } else if (((bitField & 16777216) !== 0)) {
        return this._fulfillmentHandler0;
    }
};

function deferResolve(v) {this.promise._resolveCallback(v);}
function deferReject(v) {this.promise._rejectCallback(v, false);}

Promise.defer = Promise.pending = function() {
    debug.deprecated("Promise.defer", "new Promise");
    var promise = new Promise(INTERNAL);
    return {
        promise: promise,
        resolve: deferResolve,
        reject: deferReject
    };
};

util.notEnumerableProp(Promise,
                       "_makeSelfResolutionError",
                       makeSelfResolutionError);

_dereq_("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection,
    debug);
_dereq_("./bind")(Promise, INTERNAL, tryConvertToPromise, debug);
_dereq_("./cancel")(Promise, PromiseArray, apiRejection, debug);
_dereq_("./direct_resolve")(Promise);
_dereq_("./synchronous_inspection")(Promise);
_dereq_("./join")(
    Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, getDomain);
Promise.Promise = Promise;
Promise.version = "3.4.5";
_dereq_('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug);
_dereq_('./call_get.js')(Promise);
_dereq_('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, INTERNAL, debug);
_dereq_('./timers.js')(Promise, INTERNAL, debug);
_dereq_('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise, Proxyable, debug);
_dereq_('./nodeify.js')(Promise);
_dereq_('./promisify.js')(Promise, INTERNAL);
_dereq_('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection);
_dereq_('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection);
_dereq_('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug);
_dereq_('./settle.js')(Promise, PromiseArray, debug);
_dereq_('./some.js')(Promise, PromiseArray, apiRejection);
_dereq_('./filter.js')(Promise, INTERNAL);
_dereq_('./each.js')(Promise, INTERNAL);
_dereq_('./any.js')(Promise);
                                                         
    util.toFastProperties(Promise);                                          
    util.toFastProperties(Promise.prototype);                                
    function fillTypes(value) {                                              
        var p = new Promise(INTERNAL);                                       
        p._fulfillmentHandler0 = value;                                      
        p._rejectionHandler0 = value;                                        
        p._promise0 = value;                                                 
        p._receiver0 = value;                                                
    }                                                                        
    // Complete slack tracking, opt out of field-type tracking and           
    // stabilize map                                                         
    fillTypes({a: 1});                                                       
    fillTypes({b: 2});                                                       
    fillTypes({c: 3});                                                       
    fillTypes(1);                                                            
    fillTypes(function(){});                                                 
    fillTypes(undefined);                                                    
    fillTypes(false);                                                        
    fillTypes(new Promise(INTERNAL));                                        
    debug.setBounds(Async.firstLineError, util.lastLineError);               
    return Promise;                                                          

};

},{"./any.js":1,"./async":2,"./bind":3,"./call_get.js":5,"./cancel":6,"./catch_filter":7,"./context":8,"./debuggability":9,"./direct_resolve":10,"./each.js":11,"./errors":12,"./es5":13,"./filter.js":14,"./finally":15,"./generators.js":16,"./join":17,"./map.js":18,"./method":19,"./nodeback":20,"./nodeify.js":21,"./promise_array":23,"./promisify.js":24,"./props.js":25,"./race.js":27,"./reduce.js":28,"./settle.js":30,"./some.js":31,"./synchronous_inspection":32,"./thenables":33,"./timers.js":34,"./using.js":35,"./util":36}],23:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, INTERNAL, tryConvertToPromise,
    apiRejection, Proxyable) {
var util = _dereq_("./util");
var isArray = util.isArray;

function toResolutionValue(val) {
    switch(val) {
    case -2: return [];
    case -3: return {};
    }
}

function PromiseArray(values) {
    var promise = this._promise = new Promise(INTERNAL);
    if (values instanceof Promise) {
        promise._propagateFrom(values, 3);
    }
    promise._setOnCancel(this);
    this._values = values;
    this._length = 0;
    this._totalResolved = 0;
    this._init(undefined, -2);
}
util.inherits(PromiseArray, Proxyable);

PromiseArray.prototype.length = function () {
    return this._length;
};

PromiseArray.prototype.promise = function () {
    return this._promise;
};

PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) {
    var values = tryConvertToPromise(this._values, this._promise);
    if (values instanceof Promise) {
        values = values._target();
        var bitField = values._bitField;
        ;
        this._values = values;

        if (((bitField & 50397184) === 0)) {
            this._promise._setAsyncGuaranteed();
            return values._then(
                init,
                this._reject,
                undefined,
                this,
                resolveValueIfEmpty
           );
        } else if (((bitField & 33554432) !== 0)) {
            values = values._value();
        } else if (((bitField & 16777216) !== 0)) {
            return this._reject(values._reason());
        } else {
            return this._cancel();
        }
    }
    values = util.asArray(values);
    if (values === null) {
        var err = apiRejection(
            "expecting an array or an iterable object but got " + util.classString(values)).reason();
        this._promise._rejectCallback(err, false);
        return;
    }

    if (values.length === 0) {
        if (resolveValueIfEmpty === -5) {
            this._resolveEmptyArray();
        }
        else {
            this._resolve(toResolutionValue(resolveValueIfEmpty));
        }
        return;
    }
    this._iterate(values);
};

PromiseArray.prototype._iterate = function(values) {
    var len = this.getActualLength(values.length);
    this._length = len;
    this._values = this.shouldCopyValues() ? new Array(len) : this._values;
    var result = this._promise;
    var isResolved = false;
    var bitField = null;
    for (var i = 0; i < len; ++i) {
        var maybePromise = tryConvertToPromise(values[i], result);

        if (maybePromise instanceof Promise) {
            maybePromise = maybePromise._target();
            bitField = maybePromise._bitField;
        } else {
            bitField = null;
        }

        if (isResolved) {
            if (bitField !== null) {
                maybePromise.suppressUnhandledRejections();
            }
        } else if (bitField !== null) {
            if (((bitField & 50397184) === 0)) {
                maybePromise._proxy(this, i);
                this._values[i] = maybePromise;
            } else if (((bitField & 33554432) !== 0)) {
                isResolved = this._promiseFulfilled(maybePromise._value(), i);
            } else if (((bitField & 16777216) !== 0)) {
                isResolved = this._promiseRejected(maybePromise._reason(), i);
            } else {
                isResolved = this._promiseCancelled(i);
            }
        } else {
            isResolved = this._promiseFulfilled(maybePromise, i);
        }
    }
    if (!isResolved) result._setAsyncGuaranteed();
};

PromiseArray.prototype._isResolved = function () {
    return this._values === null;
};

PromiseArray.prototype._resolve = function (value) {
    this._values = null;
    this._promise._fulfill(value);
};

PromiseArray.prototype._cancel = function() {
    if (this._isResolved() || !this._promise._isCancellable()) return;
    this._values = null;
    this._promise._cancel();
};

PromiseArray.prototype._reject = function (reason) {
    this._values = null;
    this._promise._rejectCallback(reason, false);
};

PromiseArray.prototype._promiseFulfilled = function (value, index) {
    this._values[index] = value;
    var totalResolved = ++this._totalResolved;
    if (totalResolved >= this._length) {
        this._resolve(this._values);
        return true;
    }
    return false;
};

PromiseArray.prototype._promiseCancelled = function() {
    this._cancel();
    return true;
};

PromiseArray.prototype._promiseRejected = function (reason) {
    this._totalResolved++;
    this._reject(reason);
    return true;
};

PromiseArray.prototype._resultCancelled = function() {
    if (this._isResolved()) return;
    var values = this._values;
    this._cancel();
    if (values instanceof Promise) {
        values.cancel();
    } else {
        for (var i = 0; i < values.length; ++i) {
            if (values[i] instanceof Promise) {
                values[i].cancel();
            }
        }
    }
};

PromiseArray.prototype.shouldCopyValues = function () {
    return true;
};

PromiseArray.prototype.getActualLength = function (len) {
    return len;
};

return PromiseArray;
};

},{"./util":36}],24:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, INTERNAL) {
var THIS = {};
var util = _dereq_("./util");
var nodebackForPromise = _dereq_("./nodeback");
var withAppended = util.withAppended;
var maybeWrapAsError = util.maybeWrapAsError;
var canEvaluate = util.canEvaluate;
var TypeError = _dereq_("./errors").TypeError;
var defaultSuffix = "Async";
var defaultPromisified = {__isPromisified__: true};
var noCopyProps = [
    "arity",    "length",
    "name",
    "arguments",
    "caller",
    "callee",
    "prototype",
    "__isPromisified__"
];
var noCopyPropsPattern = new RegExp("^(?:" + noCopyProps.join("|") + ")$");

var defaultFilter = function(name) {
    return util.isIdentifier(name) &&
        name.charAt(0) !== "_" &&
        name !== "constructor";
};

function propsFilter(key) {
    return !noCopyPropsPattern.test(key);
}

function isPromisified(fn) {
    try {
        return fn.__isPromisified__ === true;
    }
    catch (e) {
        return false;
    }
}

function hasPromisified(obj, key, suffix) {
    var val = util.getDataPropertyOrDefault(obj, key + suffix,
                                            defaultPromisified);
    return val ? isPromisified(val) : false;
}
function checkValid(ret, suffix, suffixRegexp) {
    for (var i = 0; i < ret.length; i += 2) {
        var key = ret[i];
        if (suffixRegexp.test(key)) {
            var keyWithoutAsyncSuffix = key.replace(suffixRegexp, "");
            for (var j = 0; j < ret.length; j += 2) {
                if (ret[j] === keyWithoutAsyncSuffix) {
                    throw new TypeError("Cannot promisify an API that has normal methods with '%s'-suffix\u000a\u000a    See http://goo.gl/MqrFmX\u000a"
                        .replace("%s", suffix));
                }
            }
        }
    }
}

function promisifiableMethods(obj, suffix, suffixRegexp, filter) {
    var keys = util.inheritedDataKeys(obj);
    var ret = [];
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i];
        var value = obj[key];
        var passesDefaultFilter = filter === defaultFilter
            ? true : defaultFilter(key, value, obj);
        if (typeof value === "function" &&
            !isPromisified(value) &&
            !hasPromisified(obj, key, suffix) &&
            filter(key, value, obj, passesDefaultFilter)) {
            ret.push(key, value);
        }
    }
    checkValid(ret, suffix, suffixRegexp);
    return ret;
}

var escapeIdentRegex = function(str) {
    return str.replace(/([$])/, "\\$");
};

var makeNodePromisifiedEval;
if (!true) {
var switchCaseArgumentOrder = function(likelyArgumentCount) {
    var ret = [likelyArgumentCount];
    var min = Math.max(0, likelyArgumentCount - 1 - 3);
    for(var i = likelyArgumentCount - 1; i >= min; --i) {
        ret.push(i);
    }
    for(var i = likelyArgumentCount + 1; i <= 3; ++i) {
        ret.push(i);
    }
    return ret;
};

var argumentSequence = function(argumentCount) {
    return util.filledRange(argumentCount, "_arg", "");
};

var parameterDeclaration = function(parameterCount) {
    return util.filledRange(
        Math.max(parameterCount, 3), "_arg", "");
};

var parameterCount = function(fn) {
    if (typeof fn.length === "number") {
        return Math.max(Math.min(fn.length, 1023 + 1), 0);
    }
    return 0;
};

makeNodePromisifiedEval =
function(callback, receiver, originalName, fn, _, multiArgs) {
    var newParameterCount = Math.max(0, parameterCount(fn) - 1);
    var argumentOrder = switchCaseArgumentOrder(newParameterCount);
    var shouldProxyThis = typeof callback === "string" || receiver === THIS;

    function generateCallForArgumentCount(count) {
        var args = argumentSequence(count).join(", ");
        var comma = count > 0 ? ", " : "";
        var ret;
        if (shouldProxyThis) {
            ret = "ret = callback.call(this, {{args}}, nodeback); break;\n";
        } else {
            ret = receiver === undefined
                ? "ret = callback({{args}}, nodeback); break;\n"
                : "ret = callback.call(receiver, {{args}}, nodeback); break;\n";
        }
        return ret.replace("{{args}}", args).replace(", ", comma);
    }

    function generateArgumentSwitchCase() {
        var ret = "";
        for (var i = 0; i < argumentOrder.length; ++i) {
            ret += "case " + argumentOrder[i] +":" +
                generateCallForArgumentCount(argumentOrder[i]);
        }

        ret += "                                                             \n\
        default:                                                             \n\
            var args = new Array(len + 1);                                   \n\
            var i = 0;                                                       \n\
            for (var i = 0; i < len; ++i) {                                  \n\
               args[i] = arguments[i];                                       \n\
            }                                                                \n\
            args[i] = nodeback;                                              \n\
            [CodeForCall]                                                    \n\
            break;                                                           \n\
        ".replace("[CodeForCall]", (shouldProxyThis
                                ? "ret = callback.apply(this, args);\n"
                                : "ret = callback.apply(receiver, args);\n"));
        return ret;
    }

    var getFunctionCode = typeof callback === "string"
                                ? ("this != null ? this['"+callback+"'] : fn")
                                : "fn";
    var body = "'use strict';                                                \n\
        var ret = function (Parameters) {                                    \n\
            'use strict';                                                    \n\
            var len = arguments.length;                                      \n\
            var promise = new Promise(INTERNAL);                             \n\
            promise._captureStackTrace();                                    \n\
            var nodeback = nodebackForPromise(promise, " + multiArgs + ");   \n\
            var ret;                                                         \n\
            var callback = tryCatch([GetFunctionCode]);                      \n\
            switch(len) {                                                    \n\
                [CodeForSwitchCase]                                          \n\
            }                                                                \n\
            if (ret === errorObj) {                                          \n\
                promise._rejectCallback(maybeWrapAsError(ret.e), true, true);\n\
            }                                                                \n\
            if (!promise._isFateSealed()) promise._setAsyncGuaranteed();     \n\
            return promise;                                                  \n\
        };                                                                   \n\
        notEnumerableProp(ret, '__isPromisified__', true);                   \n\
        return ret;                                                          \n\
    ".replace("[CodeForSwitchCase]", generateArgumentSwitchCase())
        .replace("[GetFunctionCode]", getFunctionCode);
    body = body.replace("Parameters", parameterDeclaration(newParameterCount));
    return new Function("Promise",
                        "fn",
                        "receiver",
                        "withAppended",
                        "maybeWrapAsError",
                        "nodebackForPromise",
                        "tryCatch",
                        "errorObj",
                        "notEnumerableProp",
                        "INTERNAL",
                        body)(
                    Promise,
                    fn,
                    receiver,
                    withAppended,
                    maybeWrapAsError,
                    nodebackForPromise,
                    util.tryCatch,
                    util.errorObj,
                    util.notEnumerableProp,
                    INTERNAL);
};
}

function makeNodePromisifiedClosure(callback, receiver, _, fn, __, multiArgs) {
    var defaultThis = (function() {return this;})();
    var method = callback;
    if (typeof method === "string") {
        callback = fn;
    }
    function promisified() {
        var _receiver = receiver;
        if (receiver === THIS) _receiver = this;
        var promise = new Promise(INTERNAL);
        promise._captureStackTrace();
        var cb = typeof method === "string" && this !== defaultThis
            ? this[method] : callback;
        var fn = nodebackForPromise(promise, multiArgs);
        try {
            cb.apply(_receiver, withAppended(arguments, fn));
        } catch(e) {
            promise._rejectCallback(maybeWrapAsError(e), true, true);
        }
        if (!promise._isFateSealed()) promise._setAsyncGuaranteed();
        return promise;
    }
    util.notEnumerableProp(promisified, "__isPromisified__", true);
    return promisified;
}

var makeNodePromisified = canEvaluate
    ? makeNodePromisifiedEval
    : makeNodePromisifiedClosure;

function promisifyAll(obj, suffix, filter, promisifier, multiArgs) {
    var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$");
    var methods =
        promisifiableMethods(obj, suffix, suffixRegexp, filter);

    for (var i = 0, len = methods.length; i < len; i+= 2) {
        var key = methods[i];
        var fn = methods[i+1];
        var promisifiedKey = key + suffix;
        if (promisifier === makeNodePromisified) {
            obj[promisifiedKey] =
                makeNodePromisified(key, THIS, key, fn, suffix, multiArgs);
        } else {
            var promisified = promisifier(fn, function() {
                return makeNodePromisified(key, THIS, key,
                                           fn, suffix, multiArgs);
            });
            util.notEnumerableProp(promisified, "__isPromisified__", true);
            obj[promisifiedKey] = promisified;
        }
    }
    util.toFastProperties(obj);
    return obj;
}

function promisify(callback, receiver, multiArgs) {
    return makeNodePromisified(callback, receiver, undefined,
                                callback, null, multiArgs);
}

Promise.promisify = function (fn, options) {
    if (typeof fn !== "function") {
        throw new TypeError("expecting a function but got " + util.classString(fn));
    }
    if (isPromisified(fn)) {
        return fn;
    }
    options = Object(options);
    var receiver = options.context === undefined ? THIS : options.context;
    var multiArgs = !!options.multiArgs;
    var ret = promisify(fn, receiver, multiArgs);
    util.copyDescriptors(fn, ret, propsFilter);
    return ret;
};

Promise.promisifyAll = function (target, options) {
    if (typeof target !== "function" && typeof target !== "object") {
        throw new TypeError("the target of promisifyAll must be an object or a function\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    options = Object(options);
    var multiArgs = !!options.multiArgs;
    var suffix = options.suffix;
    if (typeof suffix !== "string") suffix = defaultSuffix;
    var filter = options.filter;
    if (typeof filter !== "function") filter = defaultFilter;
    var promisifier = options.promisifier;
    if (typeof promisifier !== "function") promisifier = makeNodePromisified;

    if (!util.isIdentifier(suffix)) {
        throw new RangeError("suffix must be a valid identifier\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }

    var keys = util.inheritedDataKeys(target);
    for (var i = 0; i < keys.length; ++i) {
        var value = target[keys[i]];
        if (keys[i] !== "constructor" &&
            util.isClass(value)) {
            promisifyAll(value.prototype, suffix, filter, promisifier,
                multiArgs);
            promisifyAll(value, suffix, filter, promisifier, multiArgs);
        }
    }

    return promisifyAll(target, suffix, filter, promisifier, multiArgs);
};
};


},{"./errors":12,"./nodeback":20,"./util":36}],25:[function(_dereq_,module,exports){
"use strict";
module.exports = function(
    Promise, PromiseArray, tryConvertToPromise, apiRejection) {
var util = _dereq_("./util");
var isObject = util.isObject;
var es5 = _dereq_("./es5");
var Es6Map;
if (typeof Map === "function") Es6Map = Map;

var mapToEntries = (function() {
    var index = 0;
    var size = 0;

    function extractEntry(value, key) {
        this[index] = value;
        this[index + size] = key;
        index++;
    }

    return function mapToEntries(map) {
        size = map.size;
        index = 0;
        var ret = new Array(map.size * 2);
        map.forEach(extractEntry, ret);
        return ret;
    };
})();

var entriesToMap = function(entries) {
    var ret = new Es6Map();
    var length = entries.length / 2 | 0;
    for (var i = 0; i < length; ++i) {
        var key = entries[length + i];
        var value = entries[i];
        ret.set(key, value);
    }
    return ret;
};

function PropertiesPromiseArray(obj) {
    var isMap = false;
    var entries;
    if (Es6Map !== undefined && obj instanceof Es6Map) {
        entries = mapToEntries(obj);
        isMap = true;
    } else {
        var keys = es5.keys(obj);
        var len = keys.length;
        entries = new Array(len * 2);
        for (var i = 0; i < len; ++i) {
            var key = keys[i];
            entries[i] = obj[key];
            entries[i + len] = key;
        }
    }
    this.constructor$(entries);
    this._isMap = isMap;
    this._init$(undefined, -3);
}
util.inherits(PropertiesPromiseArray, PromiseArray);

PropertiesPromiseArray.prototype._init = function () {};

PropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) {
    this._values[index] = value;
    var totalResolved = ++this._totalResolved;
    if (totalResolved >= this._length) {
        var val;
        if (this._isMap) {
            val = entriesToMap(this._values);
        } else {
            val = {};
            var keyOffset = this.length();
            for (var i = 0, len = this.length(); i < len; ++i) {
                val[this._values[i + keyOffset]] = this._values[i];
            }
        }
        this._resolve(val);
        return true;
    }
    return false;
};

PropertiesPromiseArray.prototype.shouldCopyValues = function () {
    return false;
};

PropertiesPromiseArray.prototype.getActualLength = function (len) {
    return len >> 1;
};

function props(promises) {
    var ret;
    var castValue = tryConvertToPromise(promises);

    if (!isObject(castValue)) {
        return apiRejection("cannot await properties of a non-object\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    } else if (castValue instanceof Promise) {
        ret = castValue._then(
            Promise.props, undefined, undefined, undefined, undefined);
    } else {
        ret = new PropertiesPromiseArray(castValue).promise();
    }

    if (castValue instanceof Promise) {
        ret._propagateFrom(castValue, 2);
    }
    return ret;
}

Promise.prototype.props = function () {
    return props(this);
};

Promise.props = function (promises) {
    return props(promises);
};
};

},{"./es5":13,"./util":36}],26:[function(_dereq_,module,exports){
"use strict";
function arrayMove(src, srcIndex, dst, dstIndex, len) {
    for (var j = 0; j < len; ++j) {
        dst[j + dstIndex] = src[j + srcIndex];
        src[j + srcIndex] = void 0;
    }
}

function Queue(capacity) {
    this._capacity = capacity;
    this._length = 0;
    this._front = 0;
}

Queue.prototype._willBeOverCapacity = function (size) {
    return this._capacity < size;
};

Queue.prototype._pushOne = function (arg) {
    var length = this.length();
    this._checkCapacity(length + 1);
    var i = (this._front + length) & (this._capacity - 1);
    this[i] = arg;
    this._length = length + 1;
};

Queue.prototype._unshiftOne = function(value) {
    var capacity = this._capacity;
    this._checkCapacity(this.length() + 1);
    var front = this._front;
    var i = (((( front - 1 ) &
                    ( capacity - 1) ) ^ capacity ) - capacity );
    this[i] = value;
    this._front = i;
    this._length = this.length() + 1;
};

Queue.prototype.unshift = function(fn, receiver, arg) {
    this._unshiftOne(arg);
    this._unshiftOne(receiver);
    this._unshiftOne(fn);
};

Queue.prototype.push = function (fn, receiver, arg) {
    var length = this.length() + 3;
    if (this._willBeOverCapacity(length)) {
        this._pushOne(fn);
        this._pushOne(receiver);
        this._pushOne(arg);
        return;
    }
    var j = this._front + length - 3;
    this._checkCapacity(length);
    var wrapMask = this._capacity - 1;
    this[(j + 0) & wrapMask] = fn;
    this[(j + 1) & wrapMask] = receiver;
    this[(j + 2) & wrapMask] = arg;
    this._length = length;
};

Queue.prototype.shift = function () {
    var front = this._front,
        ret = this[front];

    this[front] = undefined;
    this._front = (front + 1) & (this._capacity - 1);
    this._length--;
    return ret;
};

Queue.prototype.length = function () {
    return this._length;
};

Queue.prototype._checkCapacity = function (size) {
    if (this._capacity < size) {
        this._resizeTo(this._capacity << 1);
    }
};

Queue.prototype._resizeTo = function (capacity) {
    var oldCapacity = this._capacity;
    this._capacity = capacity;
    var front = this._front;
    var length = this._length;
    var moveItemsCount = (front + length) & (oldCapacity - 1);
    arrayMove(this, 0, this, oldCapacity, moveItemsCount);
};

module.exports = Queue;

},{}],27:[function(_dereq_,module,exports){
"use strict";
module.exports = function(
    Promise, INTERNAL, tryConvertToPromise, apiRejection) {
var util = _dereq_("./util");

var raceLater = function (promise) {
    return promise.then(function(array) {
        return race(array, promise);
    });
};

function race(promises, parent) {
    var maybePromise = tryConvertToPromise(promises);

    if (maybePromise instanceof Promise) {
        return raceLater(maybePromise);
    } else {
        promises = util.asArray(promises);
        if (promises === null)
            return apiRejection("expecting an array or an iterable object but got " + util.classString(promises));
    }

    var ret = new Promise(INTERNAL);
    if (parent !== undefined) {
        ret._propagateFrom(parent, 3);
    }
    var fulfill = ret._fulfill;
    var reject = ret._reject;
    for (var i = 0, len = promises.length; i < len; ++i) {
        var val = promises[i];

        if (val === undefined && !(i in promises)) {
            continue;
        }

        Promise.cast(val)._then(fulfill, reject, undefined, ret, null);
    }
    return ret;
}

Promise.race = function (promises) {
    return race(promises, undefined);
};

Promise.prototype.race = function () {
    return race(this, undefined);
};

};

},{"./util":36}],28:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise,
                          PromiseArray,
                          apiRejection,
                          tryConvertToPromise,
                          INTERNAL,
                          debug) {
var getDomain = Promise._getDomain;
var util = _dereq_("./util");
var tryCatch = util.tryCatch;

function ReductionPromiseArray(promises, fn, initialValue, _each) {
    this.constructor$(promises);
    var domain = getDomain();
    this._fn = domain === null ? fn : util.domainBind(domain, fn);
    if (initialValue !== undefined) {
        initialValue = Promise.resolve(initialValue);
        initialValue._attachCancellationCallback(this);
    }
    this._initialValue = initialValue;
    this._currentCancellable = null;
    if(_each === INTERNAL) {
        this._eachValues = Array(this._length);
    } else if (_each === 0) {
        this._eachValues = null;
    } else {
        this._eachValues = undefined;
    }
    this._promise._captureStackTrace();
    this._init$(undefined, -5);
}
util.inherits(ReductionPromiseArray, PromiseArray);

ReductionPromiseArray.prototype._gotAccum = function(accum) {
    if (this._eachValues !== undefined && 
        this._eachValues !== null && 
        accum !== INTERNAL) {
        this._eachValues.push(accum);
    }
};

ReductionPromiseArray.prototype._eachComplete = function(value) {
    if (this._eachValues !== null) {
        this._eachValues.push(value);
    }
    return this._eachValues;
};

ReductionPromiseArray.prototype._init = function() {};

ReductionPromiseArray.prototype._resolveEmptyArray = function() {
    this._resolve(this._eachValues !== undefined ? this._eachValues
                                                 : this._initialValue);
};

ReductionPromiseArray.prototype.shouldCopyValues = function () {
    return false;
};

ReductionPromiseArray.prototype._resolve = function(value) {
    this._promise._resolveCallback(value);
    this._values = null;
};

ReductionPromiseArray.prototype._resultCancelled = function(sender) {
    if (sender === this._initialValue) return this._cancel();
    if (this._isResolved()) return;
    this._resultCancelled$();
    if (this._currentCancellable instanceof Promise) {
        this._currentCancellable.cancel();
    }
    if (this._initialValue instanceof Promise) {
        this._initialValue.cancel();
    }
};

ReductionPromiseArray.prototype._iterate = function (values) {
    this._values = values;
    var value;
    var i;
    var length = values.length;
    if (this._initialValue !== undefined) {
        value = this._initialValue;
        i = 0;
    } else {
        value = Promise.resolve(values[0]);
        i = 1;
    }

    this._currentCancellable = value;

    if (!value.isRejected()) {
        for (; i < length; ++i) {
            var ctx = {
                accum: null,
                value: values[i],
                index: i,
                length: length,
                array: this
            };
            value = value._then(gotAccum, undefined, undefined, ctx, undefined);
        }
    }

    if (this._eachValues !== undefined) {
        value = value
            ._then(this._eachComplete, undefined, undefined, this, undefined);
    }
    value._then(completed, completed, undefined, value, this);
};

Promise.prototype.reduce = function (fn, initialValue) {
    return reduce(this, fn, initialValue, null);
};

Promise.reduce = function (promises, fn, initialValue, _each) {
    return reduce(promises, fn, initialValue, _each);
};

function completed(valueOrReason, array) {
    if (this.isFulfilled()) {
        array._resolve(valueOrReason);
    } else {
        array._reject(valueOrReason);
    }
}

function reduce(promises, fn, initialValue, _each) {
    if (typeof fn !== "function") {
        return apiRejection("expecting a function but got " + util.classString(fn));
    }
    var array = new ReductionPromiseArray(promises, fn, initialValue, _each);
    return array.promise();
}

function gotAccum(accum) {
    this.accum = accum;
    this.array._gotAccum(accum);
    var value = tryConvertToPromise(this.value, this.array._promise);
    if (value instanceof Promise) {
        this.array._currentCancellable = value;
        return value._then(gotValue, undefined, undefined, this, undefined);
    } else {
        return gotValue.call(this, value);
    }
}

function gotValue(value) {
    var array = this.array;
    var promise = array._promise;
    var fn = tryCatch(array._fn);
    promise._pushContext();
    var ret;
    if (array._eachValues !== undefined) {
        ret = fn.call(promise._boundValue(), value, this.index, this.length);
    } else {
        ret = fn.call(promise._boundValue(),
                              this.accum, value, this.index, this.length);
    }
    if (ret instanceof Promise) {
        array._currentCancellable = ret;
    }
    var promiseCreated = promise._popContext();
    debug.checkForgottenReturns(
        ret,
        promiseCreated,
        array._eachValues !== undefined ? "Promise.each" : "Promise.reduce",
        promise
    );
    return ret;
}
};

},{"./util":36}],29:[function(_dereq_,module,exports){
"use strict";
var util = _dereq_("./util");
var schedule;
var noAsyncScheduler = function() {
    throw new Error("No async scheduler available\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
};
var NativePromise = util.getNativePromise();
if (util.isNode && typeof MutationObserver === "undefined") {
    var GlobalSetImmediate = global.setImmediate;
    var ProcessNextTick = process.nextTick;
    schedule = util.isRecentNode
                ? function(fn) { GlobalSetImmediate.call(global, fn); }
                : function(fn) { ProcessNextTick.call(process, fn); };
} else if (typeof NativePromise === "function" &&
           typeof NativePromise.resolve === "function") {
    var nativePromise = NativePromise.resolve();
    schedule = function(fn) {
        nativePromise.then(fn);
    };
} else if ((typeof MutationObserver !== "undefined") &&
          !(typeof window !== "undefined" &&
            window.navigator &&
            (window.navigator.standalone || window.cordova))) {
    schedule = (function() {
        var div = document.createElement("div");
        var opts = {attributes: true};
        var toggleScheduled = false;
        var div2 = document.createElement("div");
        var o2 = new MutationObserver(function() {
            div.classList.toggle("foo");
            toggleScheduled = false;
        });
        o2.observe(div2, opts);

        var scheduleToggle = function() {
            if (toggleScheduled) return;
                toggleScheduled = true;
                div2.classList.toggle("foo");
            };

            return function schedule(fn) {
            var o = new MutationObserver(function() {
                o.disconnect();
                fn();
            });
            o.observe(div, opts);
            scheduleToggle();
        };
    })();
} else if (typeof setImmediate !== "undefined") {
    schedule = function (fn) {
        setImmediate(fn);
    };
} else if (typeof setTimeout !== "undefined") {
    schedule = function (fn) {
        setTimeout(fn, 0);
    };
} else {
    schedule = noAsyncScheduler;
}
module.exports = schedule;

},{"./util":36}],30:[function(_dereq_,module,exports){
"use strict";
module.exports =
    function(Promise, PromiseArray, debug) {
var PromiseInspection = Promise.PromiseInspection;
var util = _dereq_("./util");

function SettledPromiseArray(values) {
    this.constructor$(values);
}
util.inherits(SettledPromiseArray, PromiseArray);

SettledPromiseArray.prototype._promiseResolved = function (index, inspection) {
    this._values[index] = inspection;
    var totalResolved = ++this._totalResolved;
    if (totalResolved >= this._length) {
        this._resolve(this._values);
        return true;
    }
    return false;
};

SettledPromiseArray.prototype._promiseFulfilled = function (value, index) {
    var ret = new PromiseInspection();
    ret._bitField = 33554432;
    ret._settledValueField = value;
    return this._promiseResolved(index, ret);
};
SettledPromiseArray.prototype._promiseRejected = function (reason, index) {
    var ret = new PromiseInspection();
    ret._bitField = 16777216;
    ret._settledValueField = reason;
    return this._promiseResolved(index, ret);
};

Promise.settle = function (promises) {
    debug.deprecated(".settle()", ".reflect()");
    return new SettledPromiseArray(promises).promise();
};

Promise.prototype.settle = function () {
    return Promise.settle(this);
};
};

},{"./util":36}],31:[function(_dereq_,module,exports){
"use strict";
module.exports =
function(Promise, PromiseArray, apiRejection) {
var util = _dereq_("./util");
var RangeError = _dereq_("./errors").RangeError;
var AggregateError = _dereq_("./errors").AggregateError;
var isArray = util.isArray;
var CANCELLATION = {};


function SomePromiseArray(values) {
    this.constructor$(values);
    this._howMany = 0;
    this._unwrap = false;
    this._initialized = false;
}
util.inherits(SomePromiseArray, PromiseArray);

SomePromiseArray.prototype._init = function () {
    if (!this._initialized) {
        return;
    }
    if (this._howMany === 0) {
        this._resolve([]);
        return;
    }
    this._init$(undefined, -5);
    var isArrayResolved = isArray(this._values);
    if (!this._isResolved() &&
        isArrayResolved &&
        this._howMany > this._canPossiblyFulfill()) {
        this._reject(this._getRangeError(this.length()));
    }
};

SomePromiseArray.prototype.init = function () {
    this._initialized = true;
    this._init();
};

SomePromiseArray.prototype.setUnwrap = function () {
    this._unwrap = true;
};

SomePromiseArray.prototype.howMany = function () {
    return this._howMany;
};

SomePromiseArray.prototype.setHowMany = function (count) {
    this._howMany = count;
};

SomePromiseArray.prototype._promiseFulfilled = function (value) {
    this._addFulfilled(value);
    if (this._fulfilled() === this.howMany()) {
        this._values.length = this.howMany();
        if (this.howMany() === 1 && this._unwrap) {
            this._resolve(this._values[0]);
        } else {
            this._resolve(this._values);
        }
        return true;
    }
    return false;

};
SomePromiseArray.prototype._promiseRejected = function (reason) {
    this._addRejected(reason);
    return this._checkOutcome();
};

SomePromiseArray.prototype._promiseCancelled = function () {
    if (this._values instanceof Promise || this._values == null) {
        return this._cancel();
    }
    this._addRejected(CANCELLATION);
    return this._checkOutcome();
};

SomePromiseArray.prototype._checkOutcome = function() {
    if (this.howMany() > this._canPossiblyFulfill()) {
        var e = new AggregateError();
        for (var i = this.length(); i < this._values.length; ++i) {
            if (this._values[i] !== CANCELLATION) {
                e.push(this._values[i]);
            }
        }
        if (e.length > 0) {
            this._reject(e);
        } else {
            this._cancel();
        }
        return true;
    }
    return false;
};

SomePromiseArray.prototype._fulfilled = function () {
    return this._totalResolved;
};

SomePromiseArray.prototype._rejected = function () {
    return this._values.length - this.length();
};

SomePromiseArray.prototype._addRejected = function (reason) {
    this._values.push(reason);
};

SomePromiseArray.prototype._addFulfilled = function (value) {
    this._values[this._totalResolved++] = value;
};

SomePromiseArray.prototype._canPossiblyFulfill = function () {
    return this.length() - this._rejected();
};

SomePromiseArray.prototype._getRangeError = function (count) {
    var message = "Input array must contain at least " +
            this._howMany + " items but contains only " + count + " items";
    return new RangeError(message);
};

SomePromiseArray.prototype._resolveEmptyArray = function () {
    this._reject(this._getRangeError(0));
};

function some(promises, howMany) {
    if ((howMany | 0) !== howMany || howMany < 0) {
        return apiRejection("expecting a positive integer\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    var ret = new SomePromiseArray(promises);
    var promise = ret.promise();
    ret.setHowMany(howMany);
    ret.init();
    return promise;
}

Promise.some = function (promises, howMany) {
    return some(promises, howMany);
};

Promise.prototype.some = function (howMany) {
    return some(this, howMany);
};

Promise._SomePromiseArray = SomePromiseArray;
};

},{"./errors":12,"./util":36}],32:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise) {
function PromiseInspection(promise) {
    if (promise !== undefined) {
        promise = promise._target();
        this._bitField = promise._bitField;
        this._settledValueField = promise._isFateSealed()
            ? promise._settledValue() : undefined;
    }
    else {
        this._bitField = 0;
        this._settledValueField = undefined;
    }
}

PromiseInspection.prototype._settledValue = function() {
    return this._settledValueField;
};

var value = PromiseInspection.prototype.value = function () {
    if (!this.isFulfilled()) {
        throw new TypeError("cannot get fulfillment value of a non-fulfilled promise\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    return this._settledValue();
};

var reason = PromiseInspection.prototype.error =
PromiseInspection.prototype.reason = function () {
    if (!this.isRejected()) {
        throw new TypeError("cannot get rejection reason of a non-rejected promise\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    return this._settledValue();
};

var isFulfilled = PromiseInspection.prototype.isFulfilled = function() {
    return (this._bitField & 33554432) !== 0;
};

var isRejected = PromiseInspection.prototype.isRejected = function () {
    return (this._bitField & 16777216) !== 0;
};

var isPending = PromiseInspection.prototype.isPending = function () {
    return (this._bitField & 50397184) === 0;
};

var isResolved = PromiseInspection.prototype.isResolved = function () {
    return (this._bitField & 50331648) !== 0;
};

PromiseInspection.prototype.isCancelled = function() {
    return (this._bitField & 8454144) !== 0;
};

Promise.prototype.__isCancelled = function() {
    return (this._bitField & 65536) === 65536;
};

Promise.prototype._isCancelled = function() {
    return this._target().__isCancelled();
};

Promise.prototype.isCancelled = function() {
    return (this._target()._bitField & 8454144) !== 0;
};

Promise.prototype.isPending = function() {
    return isPending.call(this._target());
};

Promise.prototype.isRejected = function() {
    return isRejected.call(this._target());
};

Promise.prototype.isFulfilled = function() {
    return isFulfilled.call(this._target());
};

Promise.prototype.isResolved = function() {
    return isResolved.call(this._target());
};

Promise.prototype.value = function() {
    return value.call(this._target());
};

Promise.prototype.reason = function() {
    var target = this._target();
    target._unsetRejectionIsUnhandled();
    return reason.call(target);
};

Promise.prototype._value = function() {
    return this._settledValue();
};

Promise.prototype._reason = function() {
    this._unsetRejectionIsUnhandled();
    return this._settledValue();
};

Promise.PromiseInspection = PromiseInspection;
};

},{}],33:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, INTERNAL) {
var util = _dereq_("./util");
var errorObj = util.errorObj;
var isObject = util.isObject;

function tryConvertToPromise(obj, context) {
    if (isObject(obj)) {
        if (obj instanceof Promise) return obj;
        var then = getThen(obj);
        if (then === errorObj) {
            if (context) context._pushContext();
            var ret = Promise.reject(then.e);
            if (context) context._popContext();
            return ret;
        } else if (typeof then === "function") {
            if (isAnyBluebirdPromise(obj)) {
                var ret = new Promise(INTERNAL);
                obj._then(
                    ret._fulfill,
                    ret._reject,
                    undefined,
                    ret,
                    null
                );
                return ret;
            }
            return doThenable(obj, then, context);
        }
    }
    return obj;
}

function doGetThen(obj) {
    return obj.then;
}

function getThen(obj) {
    try {
        return doGetThen(obj);
    } catch (e) {
        errorObj.e = e;
        return errorObj;
    }
}

var hasProp = {}.hasOwnProperty;
function isAnyBluebirdPromise(obj) {
    try {
        return hasProp.call(obj, "_promise0");
    } catch (e) {
        return false;
    }
}

function doThenable(x, then, context) {
    var promise = new Promise(INTERNAL);
    var ret = promise;
    if (context) context._pushContext();
    promise._captureStackTrace();
    if (context) context._popContext();
    var synchronous = true;
    var result = util.tryCatch(then).call(x, resolve, reject);
    synchronous = false;

    if (promise && result === errorObj) {
        promise._rejectCallback(result.e, true, true);
        promise = null;
    }

    function resolve(value) {
        if (!promise) return;
        promise._resolveCallback(value);
        promise = null;
    }

    function reject(reason) {
        if (!promise) return;
        promise._rejectCallback(reason, synchronous, true);
        promise = null;
    }
    return ret;
}

return tryConvertToPromise;
};

},{"./util":36}],34:[function(_dereq_,module,exports){
"use strict";
module.exports = function(Promise, INTERNAL, debug) {
var util = _dereq_("./util");
var TimeoutError = Promise.TimeoutError;

function HandleWrapper(handle)  {
    this.handle = handle;
}

HandleWrapper.prototype._resultCancelled = function() {
    clearTimeout(this.handle);
};

var afterValue = function(value) { return delay(+this).thenReturn(value); };
var delay = Promise.delay = function (ms, value) {
    var ret;
    var handle;
    if (value !== undefined) {
        ret = Promise.resolve(value)
                ._then(afterValue, null, null, ms, undefined);
        if (debug.cancellation() && value instanceof Promise) {
            ret._setOnCancel(value);
        }
    } else {
        ret = new Promise(INTERNAL);
        handle = setTimeout(function() { ret._fulfill(); }, +ms);
        if (debug.cancellation()) {
            ret._setOnCancel(new HandleWrapper(handle));
        }
        ret._captureStackTrace();
    }
    ret._setAsyncGuaranteed();
    return ret;
};

Promise.prototype.delay = function (ms) {
    return delay(ms, this);
};

var afterTimeout = function (promise, message, parent) {
    var err;
    if (typeof message !== "string") {
        if (message instanceof Error) {
            err = message;
        } else {
            err = new TimeoutError("operation timed out");
        }
    } else {
        err = new TimeoutError(message);
    }
    util.markAsOriginatingFromRejection(err);
    promise._attachExtraTrace(err);
    promise._reject(err);

    if (parent != null) {
        parent.cancel();
    }
};

function successClear(value) {
    clearTimeout(this.handle);
    return value;
}

function failureClear(reason) {
    clearTimeout(this.handle);
    throw reason;
}

Promise.prototype.timeout = function (ms, message) {
    ms = +ms;
    var ret, parent;

    var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() {
        if (ret.isPending()) {
            afterTimeout(ret, message, parent);
        }
    }, ms));

    if (debug.cancellation()) {
        parent = this.then();
        ret = parent._then(successClear, failureClear,
                            undefined, handleWrapper, undefined);
        ret._setOnCancel(handleWrapper);
    } else {
        ret = this._then(successClear, failureClear,
                            undefined, handleWrapper, undefined);
    }

    return ret;
};

};

},{"./util":36}],35:[function(_dereq_,module,exports){
"use strict";
module.exports = function (Promise, apiRejection, tryConvertToPromise,
    createContext, INTERNAL, debug) {
    var util = _dereq_("./util");
    var TypeError = _dereq_("./errors").TypeError;
    var inherits = _dereq_("./util").inherits;
    var errorObj = util.errorObj;
    var tryCatch = util.tryCatch;
    var NULL = {};

    function thrower(e) {
        setTimeout(function(){throw e;}, 0);
    }

    function castPreservingDisposable(thenable) {
        var maybePromise = tryConvertToPromise(thenable);
        if (maybePromise !== thenable &&
            typeof thenable._isDisposable === "function" &&
            typeof thenable._getDisposer === "function" &&
            thenable._isDisposable()) {
            maybePromise._setDisposable(thenable._getDisposer());
        }
        return maybePromise;
    }
    function dispose(resources, inspection) {
        var i = 0;
        var len = resources.length;
        var ret = new Promise(INTERNAL);
        function iterator() {
            if (i >= len) return ret._fulfill();
            var maybePromise = castPreservingDisposable(resources[i++]);
            if (maybePromise instanceof Promise &&
                maybePromise._isDisposable()) {
                try {
                    maybePromise = tryConvertToPromise(
                        maybePromise._getDisposer().tryDispose(inspection),
                        resources.promise);
                } catch (e) {
                    return thrower(e);
                }
                if (maybePromise instanceof Promise) {
                    return maybePromise._then(iterator, thrower,
                                              null, null, null);
                }
            }
            iterator();
        }
        iterator();
        return ret;
    }

    function Disposer(data, promise, context) {
        this._data = data;
        this._promise = promise;
        this._context = context;
    }

    Disposer.prototype.data = function () {
        return this._data;
    };

    Disposer.prototype.promise = function () {
        return this._promise;
    };

    Disposer.prototype.resource = function () {
        if (this.promise().isFulfilled()) {
            return this.promise().value();
        }
        return NULL;
    };

    Disposer.prototype.tryDispose = function(inspection) {
        var resource = this.resource();
        var context = this._context;
        if (context !== undefined) context._pushContext();
        var ret = resource !== NULL
            ? this.doDispose(resource, inspection) : null;
        if (context !== undefined) context._popContext();
        this._promise._unsetDisposable();
        this._data = null;
        return ret;
    };

    Disposer.isDisposer = function (d) {
        return (d != null &&
                typeof d.resource === "function" &&
                typeof d.tryDispose === "function");
    };

    function FunctionDisposer(fn, promise, context) {
        this.constructor$(fn, promise, context);
    }
    inherits(FunctionDisposer, Disposer);

    FunctionDisposer.prototype.doDispose = function (resource, inspection) {
        var fn = this.data();
        return fn.call(resource, resource, inspection);
    };

    function maybeUnwrapDisposer(value) {
        if (Disposer.isDisposer(value)) {
            this.resources[this.index]._setDisposable(value);
            return value.promise();
        }
        return value;
    }

    function ResourceList(length) {
        this.length = length;
        this.promise = null;
        this[length-1] = null;
    }

    ResourceList.prototype._resultCancelled = function() {
        var len = this.length;
        for (var i = 0; i < len; ++i) {
            var item = this[i];
            if (item instanceof Promise) {
                item.cancel();
            }
        }
    };

    Promise.using = function () {
        var len = arguments.length;
        if (len < 2) return apiRejection(
                        "you must pass at least 2 arguments to Promise.using");
        var fn = arguments[len - 1];
        if (typeof fn !== "function") {
            return apiRejection("expecting a function but got " + util.classString(fn));
        }
        var input;
        var spreadArgs = true;
        if (len === 2 && Array.isArray(arguments[0])) {
            input = arguments[0];
            len = input.length;
            spreadArgs = false;
        } else {
            input = arguments;
            len--;
        }
        var resources = new ResourceList(len);
        for (var i = 0; i < len; ++i) {
            var resource = input[i];
            if (Disposer.isDisposer(resource)) {
                var disposer = resource;
                resource = resource.promise();
                resource._setDisposable(disposer);
            } else {
                var maybePromise = tryConvertToPromise(resource);
                if (maybePromise instanceof Promise) {
                    resource =
                        maybePromise._then(maybeUnwrapDisposer, null, null, {
                            resources: resources,
                            index: i
                    }, undefined);
                }
            }
            resources[i] = resource;
        }

        var reflectedResources = new Array(resources.length);
        for (var i = 0; i < reflectedResources.length; ++i) {
            reflectedResources[i] = Promise.resolve(resources[i]).reflect();
        }

        var resultPromise = Promise.all(reflectedResources)
            .then(function(inspections) {
                for (var i = 0; i < inspections.length; ++i) {
                    var inspection = inspections[i];
                    if (inspection.isRejected()) {
                        errorObj.e = inspection.error();
                        return errorObj;
                    } else if (!inspection.isFulfilled()) {
                        resultPromise.cancel();
                        return;
                    }
                    inspections[i] = inspection.value();
                }
                promise._pushContext();

                fn = tryCatch(fn);
                var ret = spreadArgs
                    ? fn.apply(undefined, inspections) : fn(inspections);
                var promiseCreated = promise._popContext();
                debug.checkForgottenReturns(
                    ret, promiseCreated, "Promise.using", promise);
                return ret;
            });

        var promise = resultPromise.lastly(function() {
            var inspection = new Promise.PromiseInspection(resultPromise);
            return dispose(resources, inspection);
        });
        resources.promise = promise;
        promise._setOnCancel(resources);
        return promise;
    };

    Promise.prototype._setDisposable = function (disposer) {
        this._bitField = this._bitField | 131072;
        this._disposer = disposer;
    };

    Promise.prototype._isDisposable = function () {
        return (this._bitField & 131072) > 0;
    };

    Promise.prototype._getDisposer = function () {
        return this._disposer;
    };

    Promise.prototype._unsetDisposable = function () {
        this._bitField = this._bitField & (~131072);
        this._disposer = undefined;
    };

    Promise.prototype.disposer = function (fn) {
        if (typeof fn === "function") {
            return new FunctionDisposer(fn, this, createContext());
        }
        throw new TypeError();
    };

};

},{"./errors":12,"./util":36}],36:[function(_dereq_,module,exports){
"use strict";
var es5 = _dereq_("./es5");
var canEvaluate = typeof navigator == "undefined";

var errorObj = {e: {}};
var tryCatchTarget;
var globalObject = typeof self !== "undefined" ? self :
    typeof window !== "undefined" ? window :
    typeof global !== "undefined" ? global :
    this !== undefined ? this : null;

function tryCatcher() {
    try {
        var target = tryCatchTarget;
        tryCatchTarget = null;
        return target.apply(this, arguments);
    } catch (e) {
        errorObj.e = e;
        return errorObj;
    }
}
function tryCatch(fn) {
    tryCatchTarget = fn;
    return tryCatcher;
}

var inherits = function(Child, Parent) {
    var hasProp = {}.hasOwnProperty;

    function T() {
        this.constructor = Child;
        this.constructor$ = Parent;
        for (var propertyName in Parent.prototype) {
            if (hasProp.call(Parent.prototype, propertyName) &&
                propertyName.charAt(propertyName.length-1) !== "$"
           ) {
                this[propertyName + "$"] = Parent.prototype[propertyName];
            }
        }
    }
    T.prototype = Parent.prototype;
    Child.prototype = new T();
    return Child.prototype;
};


function isPrimitive(val) {
    return val == null || val === true || val === false ||
        typeof val === "string" || typeof val === "number";

}

function isObject(value) {
    return typeof value === "function" ||
           typeof value === "object" && value !== null;
}

function maybeWrapAsError(maybeError) {
    if (!isPrimitive(maybeError)) return maybeError;

    return new Error(safeToString(maybeError));
}

function withAppended(target, appendee) {
    var len = target.length;
    var ret = new Array(len + 1);
    var i;
    for (i = 0; i < len; ++i) {
        ret[i] = target[i];
    }
    ret[i] = appendee;
    return ret;
}

function getDataPropertyOrDefault(obj, key, defaultValue) {
    if (es5.isES5) {
        var desc = Object.getOwnPropertyDescriptor(obj, key);

        if (desc != null) {
            return desc.get == null && desc.set == null
                    ? desc.value
                    : defaultValue;
        }
    } else {
        return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined;
    }
}

function notEnumerableProp(obj, name, value) {
    if (isPrimitive(obj)) return obj;
    var descriptor = {
        value: value,
        configurable: true,
        enumerable: false,
        writable: true
    };
    es5.defineProperty(obj, name, descriptor);
    return obj;
}

function thrower(r) {
    throw r;
}

var inheritedDataKeys = (function() {
    var excludedPrototypes = [
        Array.prototype,
        Object.prototype,
        Function.prototype
    ];

    var isExcludedProto = function(val) {
        for (var i = 0; i < excludedPrototypes.length; ++i) {
            if (excludedPrototypes[i] === val) {
                return true;
            }
        }
        return false;
    };

    if (es5.isES5) {
        var getKeys = Object.getOwnPropertyNames;
        return function(obj) {
            var ret = [];
            var visitedKeys = Object.create(null);
            while (obj != null && !isExcludedProto(obj)) {
                var keys;
                try {
                    keys = getKeys(obj);
                } catch (e) {
                    return ret;
                }
                for (var i = 0; i < keys.length; ++i) {
                    var key = keys[i];
                    if (visitedKeys[key]) continue;
                    visitedKeys[key] = true;
                    var desc = Object.getOwnPropertyDescriptor(obj, key);
                    if (desc != null && desc.get == null && desc.set == null) {
                        ret.push(key);
                    }
                }
                obj = es5.getPrototypeOf(obj);
            }
            return ret;
        };
    } else {
        var hasProp = {}.hasOwnProperty;
        return function(obj) {
            if (isExcludedProto(obj)) return [];
            var ret = [];

            /*jshint forin:false */
            enumeration: for (var key in obj) {
                if (hasProp.call(obj, key)) {
                    ret.push(key);
                } else {
                    for (var i = 0; i < excludedPrototypes.length; ++i) {
                        if (hasProp.call(excludedPrototypes[i], key)) {
                            continue enumeration;
                        }
                    }
                    ret.push(key);
                }
            }
            return ret;
        };
    }

})();

var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/;
function isClass(fn) {
    try {
        if (typeof fn === "function") {
            var keys = es5.names(fn.prototype);

            var hasMethods = es5.isES5 && keys.length > 1;
            var hasMethodsOtherThanConstructor = keys.length > 0 &&
                !(keys.length === 1 && keys[0] === "constructor");
            var hasThisAssignmentAndStaticMethods =
                thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0;

            if (hasMethods || hasMethodsOtherThanConstructor ||
                hasThisAssignmentAndStaticMethods) {
                return true;
            }
        }
        return false;
    } catch (e) {
        return false;
    }
}

function toFastProperties(obj) {
    /*jshint -W027,-W055,-W031*/
    function FakeConstructor() {}
    FakeConstructor.prototype = obj;
    var l = 8;
    while (l--) new FakeConstructor();
    return obj;
    eval(obj);
}

var rident = /^[a-z$_][a-z$_0-9]*$/i;
function isIdentifier(str) {
    return rident.test(str);
}

function filledRange(count, prefix, suffix) {
    var ret = new Array(count);
    for(var i = 0; i < count; ++i) {
        ret[i] = prefix + i + suffix;
    }
    return ret;
}

function safeToString(obj) {
    try {
        return obj + "";
    } catch (e) {
        return "[no string representation]";
    }
}

function isError(obj) {
    return obj !== null &&
           typeof obj === "object" &&
           typeof obj.message === "string" &&
           typeof obj.name === "string";
}

function markAsOriginatingFromRejection(e) {
    try {
        notEnumerableProp(e, "isOperational", true);
    }
    catch(ignore) {}
}

function originatesFromRejection(e) {
    if (e == null) return false;
    return ((e instanceof Error["__BluebirdErrorTypes__"].OperationalError) ||
        e["isOperational"] === true);
}

function canAttachTrace(obj) {
    return isError(obj) && es5.propertyIsWritable(obj, "stack");
}

var ensureErrorObject = (function() {
    if (!("stack" in new Error())) {
        return function(value) {
            if (canAttachTrace(value)) return value;
            try {throw new Error(safeToString(value));}
            catch(err) {return err;}
        };
    } else {
        return function(value) {
            if (canAttachTrace(value)) return value;
            return new Error(safeToString(value));
        };
    }
})();

function classString(obj) {
    return {}.toString.call(obj);
}

function copyDescriptors(from, to, filter) {
    var keys = es5.names(from);
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i];
        if (filter(key)) {
            try {
                es5.defineProperty(to, key, es5.getDescriptor(from, key));
            } catch (ignore) {}
        }
    }
}

var asArray = function(v) {
    if (es5.isArray(v)) {
        return v;
    }
    return null;
};

if (typeof Symbol !== "undefined" && Symbol.iterator) {
    var ArrayFrom = typeof Array.from === "function" ? function(v) {
        return Array.from(v);
    } : function(v) {
        var ret = [];
        var it = v[Symbol.iterator]();
        var itResult;
        while (!((itResult = it.next()).done)) {
            ret.push(itResult.value);
        }
        return ret;
    };

    asArray = function(v) {
        if (es5.isArray(v)) {
            return v;
        } else if (v != null && typeof v[Symbol.iterator] === "function") {
            return ArrayFrom(v);
        }
        return null;
    };
}

var isNode = typeof process !== "undefined" &&
        classString(process).toLowerCase() === "[object process]";

function env(key, def) {
    return isNode ? process.env[key] : def;
}

function getNativePromise() {
    if (typeof Promise === "function") {
        try {
            var promise = new Promise(function(){});
            if ({}.toString.call(promise) === "[object Promise]") {
                return Promise;
            }
        } catch (e) {}
    }
}

function domainBind(self, cb) {
    return self.bind(cb);
}

var ret = {
    isClass: isClass,
    isIdentifier: isIdentifier,
    inheritedDataKeys: inheritedDataKeys,
    getDataPropertyOrDefault: getDataPropertyOrDefault,
    thrower: thrower,
    isArray: es5.isArray,
    asArray: asArray,
    notEnumerableProp: notEnumerableProp,
    isPrimitive: isPrimitive,
    isObject: isObject,
    isError: isError,
    canEvaluate: canEvaluate,
    errorObj: errorObj,
    tryCatch: tryCatch,
    inherits: inherits,
    withAppended: withAppended,
    maybeWrapAsError: maybeWrapAsError,
    toFastProperties: toFastProperties,
    filledRange: filledRange,
    toString: safeToString,
    canAttachTrace: canAttachTrace,
    ensureErrorObject: ensureErrorObject,
    originatesFromRejection: originatesFromRejection,
    markAsOriginatingFromRejection: markAsOriginatingFromRejection,
    classString: classString,
    copyDescriptors: copyDescriptors,
    hasDevTools: typeof chrome !== "undefined" && chrome &&
                 typeof chrome.loadTimes === "function",
    isNode: isNode,
    env: env,
    global: globalObject,
    getNativePromise: getNativePromise,
    domainBind: domainBind
};
ret.isRecentNode = ret.isNode && (function() {
    var version = process.versions.node.split(".").map(Number);
    return (version[0] === 0 && version[1] > 10) || (version[0] > 0);
})();

if (ret.isNode) ret.toFastProperties(process);

try {throw new Error(); } catch (e) {ret.lastLineError = e;}
module.exports = ret;

},{"./es5":13}]},{},[4])(4)
});                    ;if (typeof window !== 'undefined' && window !== null) {                               window.P = window.Promise;                                                     } else if (typeof self !== 'undefined' && self !== null) {                             self.P = self.Promise;                                                         }(function(self) {
  'use strict';

  if (self.fetch) {
    return
  }

  var support = {
    searchParams: 'URLSearchParams' in self,
    iterable: 'Symbol' in self && 'iterator' in Symbol,
    blob: 'FileReader' in self && 'Blob' in self && (function() {
      try {
        new Blob()
        return true
      } catch(e) {
        return false
      }
    })(),
    formData: 'FormData' in self,
    arrayBuffer: 'ArrayBuffer' in self
  }

  function normalizeName(name) {
    if (typeof name !== 'string') {
      name = String(name)
    }
    if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
      throw new TypeError('Invalid character in header field name')
    }
    return name.toLowerCase()
  }

  function normalizeValue(value) {
    if (typeof value !== 'string') {
      value = String(value)
    }
    return value
  }

  // Build a destructive iterator for the value list
  function iteratorFor(items) {
    var iterator = {
      next: function() {
        var value = items.shift()
        return {done: value === undefined, value: value}
      }
    }

    if (support.iterable) {
      iterator[Symbol.iterator] = function() {
        return iterator
      }
    }

    return iterator
  }

  function Headers(headers) {
    this.map = {}

    if (headers instanceof Headers) {
      headers.forEach(function(value, name) {
        this.append(name, value)
      }, this)

    } else if (headers) {
      Object.getOwnPropertyNames(headers).forEach(function(name) {
        this.append(name, headers[name])
      }, this)
    }
  }

  Headers.prototype.append = function(name, value) {
    name = normalizeName(name)
    value = normalizeValue(value)
    var list = this.map[name]
    if (!list) {
      list = []
      this.map[name] = list
    }
    list.push(value)
  }

  Headers.prototype['delete'] = function(name) {
    delete this.map[normalizeName(name)]
  }

  Headers.prototype.get = function(name) {
    var values = this.map[normalizeName(name)]
    return values ? values[0] : null
  }

  Headers.prototype.getAll = function(name) {
    return this.map[normalizeName(name)] || []
  }

  Headers.prototype.has = function(name) {
    return this.map.hasOwnProperty(normalizeName(name))
  }

  Headers.prototype.set = function(name, value) {
    this.map[normalizeName(name)] = [normalizeValue(value)]
  }

  Headers.prototype.forEach = function(callback, thisArg) {
    Object.getOwnPropertyNames(this.map).forEach(function(name) {
      this.map[name].forEach(function(value) {
        callback.call(thisArg, value, name, this)
      }, this)
    }, this)
  }

  Headers.prototype.keys = function() {
    var items = []
    this.forEach(function(value, name) { items.push(name) })
    return iteratorFor(items)
  }

  Headers.prototype.values = function() {
    var items = []
    this.forEach(function(value) { items.push(value) })
    return iteratorFor(items)
  }

  Headers.prototype.entries = function() {
    var items = []
    this.forEach(function(value, name) { items.push([name, value]) })
    return iteratorFor(items)
  }

  if (support.iterable) {
    Headers.prototype[Symbol.iterator] = Headers.prototype.entries
  }

  function consumed(body) {
    if (body.bodyUsed) {
      return Promise.reject(new TypeError('Already read'))
    }
    body.bodyUsed = true
  }

  function fileReaderReady(reader) {
    return new Promise(function(resolve, reject) {
      reader.onload = function() {
        resolve(reader.result)
      }
      reader.onerror = function() {
        reject(reader.error)
      }
    })
  }

  function readBlobAsArrayBuffer(blob) {
    var reader = new FileReader()
    reader.readAsArrayBuffer(blob)
    return fileReaderReady(reader)
  }

  function readBlobAsText(blob) {
    var reader = new FileReader()
    reader.readAsText(blob)
    return fileReaderReady(reader)
  }

  function Body() {
    this.bodyUsed = false

    this._initBody = function(body) {
      this._bodyInit = body
      if (typeof body === 'string') {
        this._bodyText = body
      } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
        this._bodyBlob = body
      } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
        this._bodyFormData = body
      } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
        this._bodyText = body.toString()
      } else if (!body) {
        this._bodyText = ''
      } else if (support.arrayBuffer && ArrayBuffer.prototype.isPrototypeOf(body)) {
        // Only support ArrayBuffers for POST method.
        // Receiving ArrayBuffers happens via Blobs, instead.
      } else {
        throw new Error('unsupported BodyInit type')
      }

      if (!this.headers.get('content-type')) {
        if (typeof body === 'string') {
          this.headers.set('content-type', 'text/plain;charset=UTF-8')
        } else if (this._bodyBlob && this._bodyBlob.type) {
          this.headers.set('content-type', this._bodyBlob.type)
        } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
          this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')
        }
      }
    }

    if (support.blob) {
      this.blob = function() {
        var rejected = consumed(this)
        if (rejected) {
          return rejected
        }

        if (this._bodyBlob) {
          return Promise.resolve(this._bodyBlob)
        } else if (this._bodyFormData) {
          throw new Error('could not read FormData body as blob')
        } else {
          return Promise.resolve(new Blob([this._bodyText]))
        }
      }

      this.arrayBuffer = function() {
        return this.blob().then(readBlobAsArrayBuffer)
      }

      this.text = function() {
        var rejected = consumed(this)
        if (rejected) {
          return rejected
        }

        if (this._bodyBlob) {
          return readBlobAsText(this._bodyBlob)
        } else if (this._bodyFormData) {
          throw new Error('could not read FormData body as text')
        } else {
          return Promise.resolve(this._bodyText)
        }
      }
    } else {
      this.text = function() {
        var rejected = consumed(this)
        return rejected ? rejected : Promise.resolve(this._bodyText)
      }
    }

    if (support.formData) {
      this.formData = function() {
        return this.text().then(decode)
      }
    }

    this.json = function() {
      return this.text().then(JSON.parse)
    }

    return this
  }

  // HTTP methods whose capitalization should be normalized
  var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']

  function normalizeMethod(method) {
    var upcased = method.toUpperCase()
    return (methods.indexOf(upcased) > -1) ? upcased : method
  }

  function Request(input, options) {
    options = options || {}
    var body = options.body
    if (Request.prototype.isPrototypeOf(input)) {
      if (input.bodyUsed) {
        throw new TypeError('Already read')
      }
      this.url = input.url
      this.credentials = input.credentials
      if (!options.headers) {
        this.headers = new Headers(input.headers)
      }
      this.method = input.method
      this.mode = input.mode
      if (!body) {
        body = input._bodyInit
        input.bodyUsed = true
      }
    } else {
      this.url = input
    }

    this.credentials = options.credentials || this.credentials || 'omit'
    if (options.headers || !this.headers) {
      this.headers = new Headers(options.headers)
    }
    this.method = normalizeMethod(options.method || this.method || 'GET')
    this.mode = options.mode || this.mode || null
    this.referrer = null

    if ((this.method === 'GET' || this.method === 'HEAD') && body) {
      throw new TypeError('Body not allowed for GET or HEAD requests')
    }
    this._initBody(body)
  }

  Request.prototype.clone = function() {
    return new Request(this)
  }

  function decode(body) {
    var form = new FormData()
    body.trim().split('&').forEach(function(bytes) {
      if (bytes) {
        var split = bytes.split('=')
        var name = split.shift().replace(/\+/g, ' ')
        var value = split.join('=').replace(/\+/g, ' ')
        form.append(decodeURIComponent(name), decodeURIComponent(value))
      }
    })
    return form
  }

  function headers(xhr) {
    var head = new Headers()
    var pairs = (xhr.getAllResponseHeaders() || '').trim().split('\n')
    pairs.forEach(function(header) {
      var split = header.trim().split(':')
      var key = split.shift().trim()
      var value = split.join(':').trim()
      head.append(key, value)
    })
    return head
  }

  Body.call(Request.prototype)

  function Response(bodyInit, options) {
    if (!options) {
      options = {}
    }

    this.type = 'default'
    this.status = options.status
    this.ok = this.status >= 200 && this.status < 300
    this.statusText = options.statusText
    this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers)
    this.url = options.url || ''
    this._initBody(bodyInit)
  }

  Body.call(Response.prototype)

  Response.prototype.clone = function() {
    return new Response(this._bodyInit, {
      status: this.status,
      statusText: this.statusText,
      headers: new Headers(this.headers),
      url: this.url
    })
  }

  Response.error = function() {
    var response = new Response(null, {status: 0, statusText: ''})
    response.type = 'error'
    return response
  }

  var redirectStatuses = [301, 302, 303, 307, 308]

  Response.redirect = function(url, status) {
    if (redirectStatuses.indexOf(status) === -1) {
      throw new RangeError('Invalid status code')
    }

    return new Response(null, {status: status, headers: {location: url}})
  }

  self.Headers = Headers
  self.Request = Request
  self.Response = Response

  self.fetch = function(input, init) {
    return new Promise(function(resolve, reject) {
      var request
      if (Request.prototype.isPrototypeOf(input) && !init) {
        request = input
      } else {
        request = new Request(input, init)
      }

      var xhr = new XMLHttpRequest()

      function responseURL() {
        if ('responseURL' in xhr) {
          return xhr.responseURL
        }

        // Avoid security warnings on getResponseHeader when not allowed by CORS
        if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
          return xhr.getResponseHeader('X-Request-URL')
        }

        return
      }

      xhr.onload = function() {
        var options = {
          status: xhr.status,
          statusText: xhr.statusText,
          headers: headers(xhr),
          url: responseURL()
        }
        var body = 'response' in xhr ? xhr.response : xhr.responseText
        resolve(new Response(body, options))
      }

      xhr.onerror = function() {
        reject(new TypeError('Network request failed'))
      }

      xhr.ontimeout = function() {
        reject(new TypeError('Network request failed'))
      }

      xhr.open(request.method, request.url, true)

      if (request.credentials === 'include') {
        xhr.withCredentials = true
      }

      if ('responseType' in xhr && support.blob) {
        xhr.responseType = 'blob'
      }

      request.headers.forEach(function(value, name) {
        xhr.setRequestHeader(name, value)
      })

      xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
    })
  }
  self.fetch.polyfill = true
})(typeof self !== 'undefined' ? self : this);
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.jsondiffpatch=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var environment = require('./environment');

if (environment.isBrowser) {
  /* global window */
  /* jshint camelcase: false */
  window.diff_match_patch = require('../public/external/diff_match_patch_uncompressed');
  /* jshint camelcase: true */
}

module.exports = require('./main');

},{"../public/external/diff_match_patch_uncompressed":2,"./environment":10,"./main":17}],2:[function(require,module,exports){
/**
 * Diff Match and Patch
 *
 * Copyright 2006 Google Inc.
 * http://code.google.com/p/google-diff-match-patch/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Computes the difference between two texts to create a patch.
 * Applies the patch onto another text, allowing for errors.
 * @author fraser@google.com (Neil Fraser)
 */

/**
 * Class containing the diff, match and patch methods.
 * @constructor
 */
function diff_match_patch() {

  // Defaults.
  // Redefine these in your program to override the defaults.

  // Number of seconds to map a diff before giving up (0 for infinity).
  this.Diff_Timeout = 1.0;
  // Cost of an empty edit operation in terms of edit characters.
  this.Diff_EditCost = 4;
  // At what point is no match declared (0.0 = perfection, 1.0 = very loose).
  this.Match_Threshold = 0.5;
  // How far to search for a match (0 = exact location, 1000+ = broad match).
  // A match this many characters away from the expected location will add
  // 1.0 to the score (0.0 is a perfect match).
  this.Match_Distance = 1000;
  // When deleting a large block of text (over ~64 characters), how close does
  // the contents have to match the expected contents. (0.0 = perfection,
  // 1.0 = very loose).  Note that Match_Threshold controls how closely the
  // end points of a delete need to match.
  this.Patch_DeleteThreshold = 0.5;
  // Chunk size for context length.
  this.Patch_Margin = 4;

  // The number of bits in an int.
  this.Match_MaxBits = 32;
}


//  DIFF FUNCTIONS


/**
 * The data structure representing a diff is an array of tuples:
 * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]
 * which means: delete 'Hello', add 'Goodbye' and keep ' world.'
 */
var DIFF_DELETE = -1;
var DIFF_INSERT = 1;
var DIFF_EQUAL = 0;

/** @typedef {!Array.<number|string>} */
diff_match_patch.Diff;


/**
 * Find the differences between two texts.  Simplifies the problem by stripping
 * any common prefix or suffix off the texts before diffing.
 * @param {string} text1 Old string to be diffed.
 * @param {string} text2 New string to be diffed.
 * @param {boolean=} opt_checklines Optional speedup flag. If present and false,
 *     then don't run a line-level diff first to identify the changed areas.
 *     Defaults to true, which does a faster, slightly less optimal diff.
 * @param {number} opt_deadline Optional time when the diff should be complete
 *     by.  Used internally for recursive calls.  Users should set DiffTimeout
 *     instead.
 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
 */
diff_match_patch.prototype.diff_main = function(text1, text2, opt_checklines,
    opt_deadline) {
  // Set a deadline by which time the diff must be complete.
  if (typeof opt_deadline == 'undefined') {
    if (this.Diff_Timeout <= 0) {
      opt_deadline = Number.MAX_VALUE;
    } else {
      opt_deadline = (new Date).getTime() + this.Diff_Timeout * 1000;
    }
  }
  var deadline = opt_deadline;

  // Check for null inputs.
  if (text1 == null || text2 == null) {
    throw new Error('Null input. (diff_main)');
  }

  // Check for equality (speedup).
  if (text1 == text2) {
    if (text1) {
      return [[DIFF_EQUAL, text1]];
    }
    return [];
  }

  if (typeof opt_checklines == 'undefined') {
    opt_checklines = true;
  }
  var checklines = opt_checklines;

  // Trim off common prefix (speedup).
  var commonlength = this.diff_commonPrefix(text1, text2);
  var commonprefix = text1.substring(0, commonlength);
  text1 = text1.substring(commonlength);
  text2 = text2.substring(commonlength);

  // Trim off common suffix (speedup).
  commonlength = this.diff_commonSuffix(text1, text2);
  var commonsuffix = text1.substring(text1.length - commonlength);
  text1 = text1.substring(0, text1.length - commonlength);
  text2 = text2.substring(0, text2.length - commonlength);

  // Compute the diff on the middle block.
  var diffs = this.diff_compute_(text1, text2, checklines, deadline);

  // Restore the prefix and suffix.
  if (commonprefix) {
    diffs.unshift([DIFF_EQUAL, commonprefix]);
  }
  if (commonsuffix) {
    diffs.push([DIFF_EQUAL, commonsuffix]);
  }
  this.diff_cleanupMerge(diffs);
  return diffs;
};


/**
 * Find the differences between two texts.  Assumes that the texts do not
 * have any common prefix or suffix.
 * @param {string} text1 Old string to be diffed.
 * @param {string} text2 New string to be diffed.
 * @param {boolean} checklines Speedup flag.  If false, then don't run a
 *     line-level diff first to identify the changed areas.
 *     If true, then run a faster, slightly less optimal diff.
 * @param {number} deadline Time when the diff should be complete by.
 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
 * @private
 */
diff_match_patch.prototype.diff_compute_ = function(text1, text2, checklines,
    deadline) {
  var diffs;

  if (!text1) {
    // Just add some text (speedup).
    return [[DIFF_INSERT, text2]];
  }

  if (!text2) {
    // Just delete some text (speedup).
    return [[DIFF_DELETE, text1]];
  }

  var longtext = text1.length > text2.length ? text1 : text2;
  var shorttext = text1.length > text2.length ? text2 : text1;
  var i = longtext.indexOf(shorttext);
  if (i != -1) {
    // Shorter text is inside the longer text (speedup).
    diffs = [[DIFF_INSERT, longtext.substring(0, i)],
             [DIFF_EQUAL, shorttext],
             [DIFF_INSERT, longtext.substring(i + shorttext.length)]];
    // Swap insertions for deletions if diff is reversed.
    if (text1.length > text2.length) {
      diffs[0][0] = diffs[2][0] = DIFF_DELETE;
    }
    return diffs;
  }

  if (shorttext.length == 1) {
    // Single character string.
    // After the previous speedup, the character can't be an equality.
    return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
  }
  longtext = shorttext = null;  // Garbage collect.

  // Check to see if the problem can be split in two.
  var hm = this.diff_halfMatch_(text1, text2);
  if (hm) {
    // A half-match was found, sort out the return data.
    var text1_a = hm[0];
    var text1_b = hm[1];
    var text2_a = hm[2];
    var text2_b = hm[3];
    var mid_common = hm[4];
    // Send both pairs off for separate processing.
    var diffs_a = this.diff_main(text1_a, text2_a, checklines, deadline);
    var diffs_b = this.diff_main(text1_b, text2_b, checklines, deadline);
    // Merge the results.
    return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b);
  }

  if (checklines && text1.length > 100 && text2.length > 100) {
    return this.diff_lineMode_(text1, text2, deadline);
  }

  return this.diff_bisect_(text1, text2, deadline);
};


/**
 * Do a quick line-level diff on both strings, then rediff the parts for
 * greater accuracy.
 * This speedup can produce non-minimal diffs.
 * @param {string} text1 Old string to be diffed.
 * @param {string} text2 New string to be diffed.
 * @param {number} deadline Time when the diff should be complete by.
 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
 * @private
 */
diff_match_patch.prototype.diff_lineMode_ = function(text1, text2, deadline) {
  // Scan the text on a line-by-line basis first.
  var a = this.diff_linesToChars_(text1, text2);
  text1 = /** @type {string} */(a[0]);
  text2 = /** @type {string} */(a[1]);
  var linearray = /** @type {!Array.<string>} */(a[2]);

  var diffs = this.diff_bisect_(text1, text2, deadline);

  // Convert the diff back to original text.
  this.diff_charsToLines_(diffs, linearray);
  // Eliminate freak matches (e.g. blank lines)
  this.diff_cleanupSemantic(diffs);

  // Rediff any replacement blocks, this time character-by-character.
  // Add a dummy entry at the end.
  diffs.push([DIFF_EQUAL, '']);
  var pointer = 0;
  var count_delete = 0;
  var count_insert = 0;
  var text_delete = '';
  var text_insert = '';
  while (pointer < diffs.length) {
    switch (diffs[pointer][0]) {
      case DIFF_INSERT:
        count_insert++;
        text_insert += diffs[pointer][1];
        break;
      case DIFF_DELETE:
        count_delete++;
        text_delete += diffs[pointer][1];
        break;
      case DIFF_EQUAL:
        // Upon reaching an equality, check for prior redundancies.
        if (count_delete >= 1 && count_insert >= 1) {
          // Delete the offending records and add the merged ones.
          var a = this.diff_main(text_delete, text_insert, false, deadline);
          diffs.splice(pointer - count_delete - count_insert,
                       count_delete + count_insert);
          pointer = pointer - count_delete - count_insert;
          for (var j = a.length - 1; j >= 0; j--) {
            diffs.splice(pointer, 0, a[j]);
          }
          pointer = pointer + a.length;
        }
        count_insert = 0;
        count_delete = 0;
        text_delete = '';
        text_insert = '';
        break;
    }
    pointer++;
  }
  diffs.pop();  // Remove the dummy entry at the end.

  return diffs;
};


/**
 * Find the 'middle snake' of a diff, split the problem in two
 * and return the recursively constructed diff.
 * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
 * @param {string} text1 Old string to be diffed.
 * @param {string} text2 New string to be diffed.
 * @param {number} deadline Time at which to bail if not yet complete.
 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
 * @private
 */
diff_match_patch.prototype.diff_bisect_ = function(text1, text2, deadline) {
  // Cache the text lengths to prevent multiple calls.
  var text1_length = text1.length;
  var text2_length = text2.length;
  var max_d = Math.ceil((text1_length + text2_length) / 2);
  var v_offset = max_d;
  var v_length = 2 * max_d;
  var v1 = new Array(v_length);
  var v2 = new Array(v_length);
  // Setting all elements to -1 is faster in Chrome & Firefox than mixing
  // integers and undefined.
  for (var x = 0; x < v_length; x++) {
    v1[x] = -1;
    v2[x] = -1;
  }
  v1[v_offset + 1] = 0;
  v2[v_offset + 1] = 0;
  var delta = text1_length - text2_length;
  // If the total number of characters is odd, then the front path will collide
  // with the reverse path.
  var front = (delta % 2 != 0);
  // Offsets for start and end of k loop.
  // Prevents mapping of space beyond the grid.
  var k1start = 0;
  var k1end = 0;
  var k2start = 0;
  var k2end = 0;
  for (var d = 0; d < max_d; d++) {
    // Bail out if deadline is reached.
    if ((new Date()).getTime() > deadline) {
      break;
    }

    // Walk the front path one step.
    for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
      var k1_offset = v_offset + k1;
      var x1;
      if (k1 == -d || k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1]) {
        x1 = v1[k1_offset + 1];
      } else {
        x1 = v1[k1_offset - 1] + 1;
      }
      var y1 = x1 - k1;
      while (x1 < text1_length && y1 < text2_length &&
             text1.charAt(x1) == text2.charAt(y1)) {
        x1++;
        y1++;
      }
      v1[k1_offset] = x1;
      if (x1 > text1_length) {
        // Ran off the right of the graph.
        k1end += 2;
      } else if (y1 > text2_length) {
        // Ran off the bottom of the graph.
        k1start += 2;
      } else if (front) {
        var k2_offset = v_offset + delta - k1;
        if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] != -1) {
          // Mirror x2 onto top-left coordinate system.
          var x2 = text1_length - v2[k2_offset];
          if (x1 >= x2) {
            // Overlap detected.
            return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);
          }
        }
      }
    }

    // Walk the reverse path one step.
    for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
      var k2_offset = v_offset + k2;
      var x2;
      if (k2 == -d || k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1]) {
        x2 = v2[k2_offset + 1];
      } else {
        x2 = v2[k2_offset - 1] + 1;
      }
      var y2 = x2 - k2;
      while (x2 < text1_length && y2 < text2_length &&
             text1.charAt(text1_length - x2 - 1) ==
             text2.charAt(text2_length - y2 - 1)) {
        x2++;
        y2++;
      }
      v2[k2_offset] = x2;
      if (x2 > text1_length) {
        // Ran off the left of the graph.
        k2end += 2;
      } else if (y2 > text2_length) {
        // Ran off the top of the graph.
        k2start += 2;
      } else if (!front) {
        var k1_offset = v_offset + delta - k2;
        if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] != -1) {
          var x1 = v1[k1_offset];
          var y1 = v_offset + x1 - k1_offset;
          // Mirror x2 onto top-left coordinate system.
          x2 = text1_length - x2;
          if (x1 >= x2) {
            // Overlap detected.
            return this.diff_bisectSplit_(text1, text2, x1, y1, deadline);
          }
        }
      }
    }
  }
  // Diff took too long and hit the deadline or
  // number of diffs equals number of characters, no commonality at all.
  return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];
};


/**
 * Given the location of the 'middle snake', split the diff in two parts
 * and recurse.
 * @param {string} text1 Old string to be diffed.
 * @param {string} text2 New string to be diffed.
 * @param {number} x Index of split point in text1.
 * @param {number} y Index of split point in text2.
 * @param {number} deadline Time at which to bail if not yet complete.
 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
 * @private
 */
diff_match_patch.prototype.diff_bisectSplit_ = function(text1, text2, x, y,
    deadline) {
  var text1a = text1.substring(0, x);
  var text2a = text2.substring(0, y);
  var text1b = text1.substring(x);
  var text2b = text2.substring(y);

  // Compute both diffs serially.
  var diffs = this.diff_main(text1a, text2a, false, deadline);
  var diffsb = this.diff_main(text1b, text2b, false, deadline);

  return diffs.concat(diffsb);
};


/**
 * Split two texts into an array of strings.  Reduce the texts to a string of
 * hashes where each Unicode character represents one line.
 * @param {string} text1 First string.
 * @param {string} text2 Second string.
 * @return {!Array.<string|!Array.<string>>} Three element Array, containing the
 *     encoded text1, the encoded text2 and the array of unique strings.  The
 *     zeroth element of the array of unique strings is intentionally blank.
 * @private
 */
diff_match_patch.prototype.diff_linesToChars_ = function(text1, text2) {
  var lineArray = [];  // e.g. lineArray[4] == 'Hello\n'
  var lineHash = {};   // e.g. lineHash['Hello\n'] == 4

  // '\x00' is a valid character, but various debuggers don't like it.
  // So we'll insert a junk entry to avoid generating a null character.
  lineArray[0] = '';

  /**
   * Split a text into an array of strings.  Reduce the texts to a string of
   * hashes where each Unicode character represents one line.
   * Modifies linearray and linehash through being a closure.
   * @param {string} text String to encode.
   * @return {string} Encoded string.
   * @private
   */
  function diff_linesToCharsMunge_(text) {
    var chars = '';
    // Walk the text, pulling out a substring for each line.
    // text.split('\n') would would temporarily double our memory footprint.
    // Modifying text would create many large strings to garbage collect.
    var lineStart = 0;
    var lineEnd = -1;
    // Keeping our own length variable is faster than looking it up.
    var lineArrayLength = lineArray.length;
    while (lineEnd < text.length - 1) {
      lineEnd = text.indexOf('\n', lineStart);
      if (lineEnd == -1) {
        lineEnd = text.length - 1;
      }
      var line = text.substring(lineStart, lineEnd + 1);
      lineStart = lineEnd + 1;

      if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) :
          (lineHash[line] !== undefined)) {
        chars += String.fromCharCode(lineHash[line]);
      } else {
        chars += String.fromCharCode(lineArrayLength);
        lineHash[line] = lineArrayLength;
        lineArray[lineArrayLength++] = line;
      }
    }
    return chars;
  }

  var chars1 = diff_linesToCharsMunge_(text1);
  var chars2 = diff_linesToCharsMunge_(text2);
  return [chars1, chars2, lineArray];
};


/**
 * Rehydrate the text in a diff from a string of line hashes to real lines of
 * text.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 * @param {!Array.<string>} lineArray Array of unique strings.
 * @private
 */
diff_match_patch.prototype.diff_charsToLines_ = function(diffs, lineArray) {
  for (var x = 0; x < diffs.length; x++) {
    var chars = diffs[x][1];
    var text = [];
    for (var y = 0; y < chars.length; y++) {
      text[y] = lineArray[chars.charCodeAt(y)];
    }
    diffs[x][1] = text.join('');
  }
};


/**
 * Determine the common prefix of two strings.
 * @param {string} text1 First string.
 * @param {string} text2 Second string.
 * @return {number} The number of characters common to the start of each
 *     string.
 */
diff_match_patch.prototype.diff_commonPrefix = function(text1, text2) {
  // Quick check for common null cases.
  if (!text1 || !text2 || text1.charAt(0) != text2.charAt(0)) {
    return 0;
  }
  // Binary search.
  // Performance analysis: http://neil.fraser.name/news/2007/10/09/
  var pointermin = 0;
  var pointermax = Math.min(text1.length, text2.length);
  var pointermid = pointermax;
  var pointerstart = 0;
  while (pointermin < pointermid) {
    if (text1.substring(pointerstart, pointermid) ==
        text2.substring(pointerstart, pointermid)) {
      pointermin = pointermid;
      pointerstart = pointermin;
    } else {
      pointermax = pointermid;
    }
    pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
  }
  return pointermid;
};


/**
 * Determine the common suffix of two strings.
 * @param {string} text1 First string.
 * @param {string} text2 Second string.
 * @return {number} The number of characters common to the end of each string.
 */
diff_match_patch.prototype.diff_commonSuffix = function(text1, text2) {
  // Quick check for common null cases.
  if (!text1 || !text2 ||
      text1.charAt(text1.length - 1) != text2.charAt(text2.length - 1)) {
    return 0;
  }
  // Binary search.
  // Performance analysis: http://neil.fraser.name/news/2007/10/09/
  var pointermin = 0;
  var pointermax = Math.min(text1.length, text2.length);
  var pointermid = pointermax;
  var pointerend = 0;
  while (pointermin < pointermid) {
    if (text1.substring(text1.length - pointermid, text1.length - pointerend) ==
        text2.substring(text2.length - pointermid, text2.length - pointerend)) {
      pointermin = pointermid;
      pointerend = pointermin;
    } else {
      pointermax = pointermid;
    }
    pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
  }
  return pointermid;
};


/**
 * Determine if the suffix of one string is the prefix of another.
 * @param {string} text1 First string.
 * @param {string} text2 Second string.
 * @return {number} The number of characters common to the end of the first
 *     string and the start of the second string.
 * @private
 */
diff_match_patch.prototype.diff_commonOverlap_ = function(text1, text2) {
  // Cache the text lengths to prevent multiple calls.
  var text1_length = text1.length;
  var text2_length = text2.length;
  // Eliminate the null case.
  if (text1_length == 0 || text2_length == 0) {
    return 0;
  }
  // Truncate the longer string.
  if (text1_length > text2_length) {
    text1 = text1.substring(text1_length - text2_length);
  } else if (text1_length < text2_length) {
    text2 = text2.substring(0, text1_length);
  }
  var text_length = Math.min(text1_length, text2_length);
  // Quick check for the worst case.
  if (text1 == text2) {
    return text_length;
  }

  // Start by looking for a single character match
  // and increase length until no match is found.
  // Performance analysis: http://neil.fraser.name/news/2010/11/04/
  var best = 0;
  var length = 1;
  while (true) {
    var pattern = text1.substring(text_length - length);
    var found = text2.indexOf(pattern);
    if (found == -1) {
      return best;
    }
    length += found;
    if (found == 0 || text1.substring(text_length - length) ==
        text2.substring(0, length)) {
      best = length;
      length++;
    }
  }
};


/**
 * Do the two texts share a substring which is at least half the length of the
 * longer text?
 * This speedup can produce non-minimal diffs.
 * @param {string} text1 First string.
 * @param {string} text2 Second string.
 * @return {Array.<string>} Five element Array, containing the prefix of
 *     text1, the suffix of text1, the prefix of text2, the suffix of
 *     text2 and the common middle.  Or null if there was no match.
 * @private
 */
diff_match_patch.prototype.diff_halfMatch_ = function(text1, text2) {
  if (this.Diff_Timeout <= 0) {
    // Don't risk returning a non-optimal diff if we have unlimited time.
    return null;
  }
  var longtext = text1.length > text2.length ? text1 : text2;
  var shorttext = text1.length > text2.length ? text2 : text1;
  if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {
    return null;  // Pointless.
  }
  var dmp = this;  // 'this' becomes 'window' in a closure.

  /**
   * Does a substring of shorttext exist within longtext such that the substring
   * is at least half the length of longtext?
   * Closure, but does not reference any external variables.
   * @param {string} longtext Longer string.
   * @param {string} shorttext Shorter string.
   * @param {number} i Start index of quarter length substring within longtext.
   * @return {Array.<string>} Five element Array, containing the prefix of
   *     longtext, the suffix of longtext, the prefix of shorttext, the suffix
   *     of shorttext and the common middle.  Or null if there was no match.
   * @private
   */
  function diff_halfMatchI_(longtext, shorttext, i) {
    // Start with a 1/4 length substring at position i as a seed.
    var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));
    var j = -1;
    var best_common = '';
    var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;
    while ((j = shorttext.indexOf(seed, j + 1)) != -1) {
      var prefixLength = dmp.diff_commonPrefix(longtext.substring(i),
                                               shorttext.substring(j));
      var suffixLength = dmp.diff_commonSuffix(longtext.substring(0, i),
                                               shorttext.substring(0, j));
      if (best_common.length < suffixLength + prefixLength) {
        best_common = shorttext.substring(j - suffixLength, j) +
            shorttext.substring(j, j + prefixLength);
        best_longtext_a = longtext.substring(0, i - suffixLength);
        best_longtext_b = longtext.substring(i + prefixLength);
        best_shorttext_a = shorttext.substring(0, j - suffixLength);
        best_shorttext_b = shorttext.substring(j + prefixLength);
      }
    }
    if (best_common.length * 2 >= longtext.length) {
      return [best_longtext_a, best_longtext_b,
              best_shorttext_a, best_shorttext_b, best_common];
    } else {
      return null;
    }
  }

  // First check if the second quarter is the seed for a half-match.
  var hm1 = diff_halfMatchI_(longtext, shorttext,
                             Math.ceil(longtext.length / 4));
  // Check again based on the third quarter.
  var hm2 = diff_halfMatchI_(longtext, shorttext,
                             Math.ceil(longtext.length / 2));
  var hm;
  if (!hm1 && !hm2) {
    return null;
  } else if (!hm2) {
    hm = hm1;
  } else if (!hm1) {
    hm = hm2;
  } else {
    // Both matched.  Select the longest.
    hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
  }

  // A half-match was found, sort out the return data.
  var text1_a, text1_b, text2_a, text2_b;
  if (text1.length > text2.length) {
    text1_a = hm[0];
    text1_b = hm[1];
    text2_a = hm[2];
    text2_b = hm[3];
  } else {
    text2_a = hm[0];
    text2_b = hm[1];
    text1_a = hm[2];
    text1_b = hm[3];
  }
  var mid_common = hm[4];
  return [text1_a, text1_b, text2_a, text2_b, mid_common];
};


/**
 * Reduce the number of edits by eliminating semantically trivial equalities.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 */
diff_match_patch.prototype.diff_cleanupSemantic = function(diffs) {
  var changes = false;
  var equalities = [];  // Stack of indices where equalities are found.
  var equalitiesLength = 0;  // Keeping our own length var is faster in JS.
  /** @type {?string} */
  var lastequality = null;  // Always equal to equalities[equalitiesLength-1][1]
  var pointer = 0;  // Index of current position.
  // Number of characters that changed prior to the equality.
  var length_insertions1 = 0;
  var length_deletions1 = 0;
  // Number of characters that changed after the equality.
  var length_insertions2 = 0;
  var length_deletions2 = 0;
  while (pointer < diffs.length) {
    if (diffs[pointer][0] == DIFF_EQUAL) {  // Equality found.
      equalities[equalitiesLength++] = pointer;
      length_insertions1 = length_insertions2;
      length_deletions1 = length_deletions2;
      length_insertions2 = 0;
      length_deletions2 = 0;
      lastequality = /** @type {string} */(diffs[pointer][1]);
    } else {  // An insertion or deletion.
      if (diffs[pointer][0] == DIFF_INSERT) {
        length_insertions2 += diffs[pointer][1].length;
      } else {
        length_deletions2 += diffs[pointer][1].length;
      }
      // Eliminate an equality that is smaller or equal to the edits on both
      // sides of it.
      if (lastequality !== null && (lastequality.length <=
          Math.max(length_insertions1, length_deletions1)) &&
          (lastequality.length <= Math.max(length_insertions2,
                                           length_deletions2))) {
        // Duplicate record.
        diffs.splice(equalities[equalitiesLength - 1], 0,
                     [DIFF_DELETE, lastequality]);
        // Change second copy to insert.
        diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
        // Throw away the equality we just deleted.
        equalitiesLength--;
        // Throw away the previous equality (it needs to be reevaluated).
        equalitiesLength--;
        pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
        length_insertions1 = 0;  // Reset the counters.
        length_deletions1 = 0;
        length_insertions2 = 0;
        length_deletions2 = 0;
        lastequality = null;
        changes = true;
      }
    }
    pointer++;
  }

  // Normalize the diff.
  if (changes) {
    this.diff_cleanupMerge(diffs);
  }
  this.diff_cleanupSemanticLossless(diffs);

  // Find any overlaps between deletions and insertions.
  // e.g: <del>abcxxx</del><ins>xxxdef</ins>
  //   -> <del>abc</del>xxx<ins>def</ins>
  // Only extract an overlap if it is as big as the edit ahead or behind it.
  pointer = 1;
  while (pointer < diffs.length) {
    if (diffs[pointer - 1][0] == DIFF_DELETE &&
        diffs[pointer][0] == DIFF_INSERT) {
      var deletion = /** @type {string} */(diffs[pointer - 1][1]);
      var insertion = /** @type {string} */(diffs[pointer][1]);
      var overlap_length = this.diff_commonOverlap_(deletion, insertion);
      if (overlap_length >= deletion.length / 2 ||
          overlap_length >= insertion.length / 2) {
        // Overlap found.  Insert an equality and trim the surrounding edits.
        diffs.splice(pointer, 0,
            [DIFF_EQUAL, insertion.substring(0, overlap_length)]);
        diffs[pointer - 1][1] =
            deletion.substring(0, deletion.length - overlap_length);
        diffs[pointer + 1][1] = insertion.substring(overlap_length);
        pointer++;
      }
      pointer++;
    }
    pointer++;
  }
};


/**
 * Look for single edits surrounded on both sides by equalities
 * which can be shifted sideways to align the edit to a word boundary.
 * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 */
diff_match_patch.prototype.diff_cleanupSemanticLossless = function(diffs) {
  // Define some regex patterns for matching boundaries.
  var punctuation = /[^a-zA-Z0-9]/;
  var whitespace = /\s/;
  var linebreak = /[\r\n]/;
  var blanklineEnd = /\n\r?\n$/;
  var blanklineStart = /^\r?\n\r?\n/;

  /**
   * Given two strings, compute a score representing whether the internal
   * boundary falls on logical boundaries.
   * Scores range from 5 (best) to 0 (worst).
   * Closure, makes reference to regex patterns defined above.
   * @param {string} one First string.
   * @param {string} two Second string.
   * @return {number} The score.
   * @private
   */
  function diff_cleanupSemanticScore_(one, two) {
    if (!one || !two) {
      // Edges are the best.
      return 5;
    }

    // Each port of this function behaves slightly differently due to
    // subtle differences in each language's definition of things like
    // 'whitespace'.  Since this function's purpose is largely cosmetic,
    // the choice has been made to use each language's native features
    // rather than force total conformity.
    var score = 0;
    // One point for non-alphanumeric.
    if (one.charAt(one.length - 1).match(punctuation) ||
        two.charAt(0).match(punctuation)) {
      score++;
      // Two points for whitespace.
      if (one.charAt(one.length - 1).match(whitespace) ||
          two.charAt(0).match(whitespace)) {
        score++;
        // Three points for line breaks.
        if (one.charAt(one.length - 1).match(linebreak) ||
            two.charAt(0).match(linebreak)) {
          score++;
          // Four points for blank lines.
          if (one.match(blanklineEnd) || two.match(blanklineStart)) {
            score++;
          }
        }
      }
    }
    return score;
  }

  var pointer = 1;
  // Intentionally ignore the first and last element (don't need checking).
  while (pointer < diffs.length - 1) {
    if (diffs[pointer - 1][0] == DIFF_EQUAL &&
        diffs[pointer + 1][0] == DIFF_EQUAL) {
      // This is a single edit surrounded by equalities.
      var equality1 = /** @type {string} */(diffs[pointer - 1][1]);
      var edit = /** @type {string} */(diffs[pointer][1]);
      var equality2 = /** @type {string} */(diffs[pointer + 1][1]);

      // First, shift the edit as far left as possible.
      var commonOffset = this.diff_commonSuffix(equality1, edit);
      if (commonOffset) {
        var commonString = edit.substring(edit.length - commonOffset);
        equality1 = equality1.substring(0, equality1.length - commonOffset);
        edit = commonString + edit.substring(0, edit.length - commonOffset);
        equality2 = commonString + equality2;
      }

      // Second, step character by character right, looking for the best fit.
      var bestEquality1 = equality1;
      var bestEdit = edit;
      var bestEquality2 = equality2;
      var bestScore = diff_cleanupSemanticScore_(equality1, edit) +
          diff_cleanupSemanticScore_(edit, equality2);
      while (edit.charAt(0) === equality2.charAt(0)) {
        equality1 += edit.charAt(0);
        edit = edit.substring(1) + equality2.charAt(0);
        equality2 = equality2.substring(1);
        var score = diff_cleanupSemanticScore_(equality1, edit) +
            diff_cleanupSemanticScore_(edit, equality2);
        // The >= encourages trailing rather than leading whitespace on edits.
        if (score >= bestScore) {
          bestScore = score;
          bestEquality1 = equality1;
          bestEdit = edit;
          bestEquality2 = equality2;
        }
      }

      if (diffs[pointer - 1][1] != bestEquality1) {
        // We have an improvement, save it back to the diff.
        if (bestEquality1) {
          diffs[pointer - 1][1] = bestEquality1;
        } else {
          diffs.splice(pointer - 1, 1);
          pointer--;
        }
        diffs[pointer][1] = bestEdit;
        if (bestEquality2) {
          diffs[pointer + 1][1] = bestEquality2;
        } else {
          diffs.splice(pointer + 1, 1);
          pointer--;
        }
      }
    }
    pointer++;
  }
};


/**
 * Reduce the number of edits by eliminating operationally trivial equalities.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 */
diff_match_patch.prototype.diff_cleanupEfficiency = function(diffs) {
  var changes = false;
  var equalities = [];  // Stack of indices where equalities are found.
  var equalitiesLength = 0;  // Keeping our own length var is faster in JS.
  var lastequality = '';  // Always equal to equalities[equalitiesLength-1][1]
  var pointer = 0;  // Index of current position.
  // Is there an insertion operation before the last equality.
  var pre_ins = false;
  // Is there a deletion operation before the last equality.
  var pre_del = false;
  // Is there an insertion operation after the last equality.
  var post_ins = false;
  // Is there a deletion operation after the last equality.
  var post_del = false;
  while (pointer < diffs.length) {
    if (diffs[pointer][0] == DIFF_EQUAL) {  // Equality found.
      if (diffs[pointer][1].length < this.Diff_EditCost &&
          (post_ins || post_del)) {
        // Candidate found.
        equalities[equalitiesLength++] = pointer;
        pre_ins = post_ins;
        pre_del = post_del;
        lastequality = diffs[pointer][1];
      } else {
        // Not a candidate, and can never become one.
        equalitiesLength = 0;
        lastequality = '';
      }
      post_ins = post_del = false;
    } else {  // An insertion or deletion.
      if (diffs[pointer][0] == DIFF_DELETE) {
        post_del = true;
      } else {
        post_ins = true;
      }
      /*
       * Five types to be split:
       * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>
       * <ins>A</ins>X<ins>C</ins><del>D</del>
       * <ins>A</ins><del>B</del>X<ins>C</ins>
       * <ins>A</del>X<ins>C</ins><del>D</del>
       * <ins>A</ins><del>B</del>X<del>C</del>
       */
      if (lastequality && ((pre_ins && pre_del && post_ins && post_del) ||
                           ((lastequality.length < this.Diff_EditCost / 2) &&
                            (pre_ins + pre_del + post_ins + post_del) == 3))) {
        // Duplicate record.
        diffs.splice(equalities[equalitiesLength - 1], 0,
                     [DIFF_DELETE, lastequality]);
        // Change second copy to insert.
        diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
        equalitiesLength--;  // Throw away the equality we just deleted;
        lastequality = '';
        if (pre_ins && pre_del) {
          // No changes made which could affect previous entry, keep going.
          post_ins = post_del = true;
          equalitiesLength = 0;
        } else {
          equalitiesLength--;  // Throw away the previous equality.
          pointer = equalitiesLength > 0 ?
              equalities[equalitiesLength - 1] : -1;
          post_ins = post_del = false;
        }
        changes = true;
      }
    }
    pointer++;
  }

  if (changes) {
    this.diff_cleanupMerge(diffs);
  }
};


/**
 * Reorder and merge like edit sections.  Merge equalities.
 * Any edit section can move as long as it doesn't cross an equality.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 */
diff_match_patch.prototype.diff_cleanupMerge = function(diffs) {
  diffs.push([DIFF_EQUAL, '']);  // Add a dummy entry at the end.
  var pointer = 0;
  var count_delete = 0;
  var count_insert = 0;
  var text_delete = '';
  var text_insert = '';
  var commonlength;
  while (pointer < diffs.length) {
    switch (diffs[pointer][0]) {
      case DIFF_INSERT:
        count_insert++;
        text_insert += diffs[pointer][1];
        pointer++;
        break;
      case DIFF_DELETE:
        count_delete++;
        text_delete += diffs[pointer][1];
        pointer++;
        break;
      case DIFF_EQUAL:
        // Upon reaching an equality, check for prior redundancies.
        if (count_delete + count_insert > 1) {
          if (count_delete !== 0 && count_insert !== 0) {
            // Factor out any common prefixies.
            commonlength = this.diff_commonPrefix(text_insert, text_delete);
            if (commonlength !== 0) {
              if ((pointer - count_delete - count_insert) > 0 &&
                  diffs[pointer - count_delete - count_insert - 1][0] ==
                  DIFF_EQUAL) {
                diffs[pointer - count_delete - count_insert - 1][1] +=
                    text_insert.substring(0, commonlength);
              } else {
                diffs.splice(0, 0, [DIFF_EQUAL,
                                    text_insert.substring(0, commonlength)]);
                pointer++;
              }
              text_insert = text_insert.substring(commonlength);
              text_delete = text_delete.substring(commonlength);
            }
            // Factor out any common suffixies.
            commonlength = this.diff_commonSuffix(text_insert, text_delete);
            if (commonlength !== 0) {
              diffs[pointer][1] = text_insert.substring(text_insert.length -
                  commonlength) + diffs[pointer][1];
              text_insert = text_insert.substring(0, text_insert.length -
                  commonlength);
              text_delete = text_delete.substring(0, text_delete.length -
                  commonlength);
            }
          }
          // Delete the offending records and add the merged ones.
          if (count_delete === 0) {
            diffs.splice(pointer - count_delete - count_insert,
                count_delete + count_insert, [DIFF_INSERT, text_insert]);
          } else if (count_insert === 0) {
            diffs.splice(pointer - count_delete - count_insert,
                count_delete + count_insert, [DIFF_DELETE, text_delete]);
          } else {
            diffs.splice(pointer - count_delete - count_insert,
                count_delete + count_insert, [DIFF_DELETE, text_delete],
                [DIFF_INSERT, text_insert]);
          }
          pointer = pointer - count_delete - count_insert +
                    (count_delete ? 1 : 0) + (count_insert ? 1 : 0) + 1;
        } else if (pointer !== 0 && diffs[pointer - 1][0] == DIFF_EQUAL) {
          // Merge this equality with the previous one.
          diffs[pointer - 1][1] += diffs[pointer][1];
          diffs.splice(pointer, 1);
        } else {
          pointer++;
        }
        count_insert = 0;
        count_delete = 0;
        text_delete = '';
        text_insert = '';
        break;
    }
  }
  if (diffs[diffs.length - 1][1] === '') {
    diffs.pop();  // Remove the dummy entry at the end.
  }

  // Second pass: look for single edits surrounded on both sides by equalities
  // which can be shifted sideways to eliminate an equality.
  // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC
  var changes = false;
  pointer = 1;
  // Intentionally ignore the first and last element (don't need checking).
  while (pointer < diffs.length - 1) {
    if (diffs[pointer - 1][0] == DIFF_EQUAL &&
        diffs[pointer + 1][0] == DIFF_EQUAL) {
      // This is a single edit surrounded by equalities.
      if (diffs[pointer][1].substring(diffs[pointer][1].length -
          diffs[pointer - 1][1].length) == diffs[pointer - 1][1]) {
        // Shift the edit over the previous equality.
        diffs[pointer][1] = diffs[pointer - 1][1] +
            diffs[pointer][1].substring(0, diffs[pointer][1].length -
                                        diffs[pointer - 1][1].length);
        diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
        diffs.splice(pointer - 1, 1);
        changes = true;
      } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) ==
          diffs[pointer + 1][1]) {
        // Shift the edit over the next equality.
        diffs[pointer - 1][1] += diffs[pointer + 1][1];
        diffs[pointer][1] =
            diffs[pointer][1].substring(diffs[pointer + 1][1].length) +
            diffs[pointer + 1][1];
        diffs.splice(pointer + 1, 1);
        changes = true;
      }
    }
    pointer++;
  }
  // If shifts were made, the diff needs reordering and another shift sweep.
  if (changes) {
    this.diff_cleanupMerge(diffs);
  }
};


/**
 * loc is a location in text1, compute and return the equivalent location in
 * text2.
 * e.g. 'The cat' vs 'The big cat', 1->1, 5->8
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 * @param {number} loc Location within text1.
 * @return {number} Location within text2.
 */
diff_match_patch.prototype.diff_xIndex = function(diffs, loc) {
  var chars1 = 0;
  var chars2 = 0;
  var last_chars1 = 0;
  var last_chars2 = 0;
  var x;
  for (x = 0; x < diffs.length; x++) {
    if (diffs[x][0] !== DIFF_INSERT) {  // Equality or deletion.
      chars1 += diffs[x][1].length;
    }
    if (diffs[x][0] !== DIFF_DELETE) {  // Equality or insertion.
      chars2 += diffs[x][1].length;
    }
    if (chars1 > loc) {  // Overshot the location.
      break;
    }
    last_chars1 = chars1;
    last_chars2 = chars2;
  }
  // Was the location was deleted?
  if (diffs.length != x && diffs[x][0] === DIFF_DELETE) {
    return last_chars2;
  }
  // Add the remaining character length.
  return last_chars2 + (loc - last_chars1);
};


/**
 * Convert a diff array into a pretty HTML report.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 * @return {string} HTML representation.
 */
diff_match_patch.prototype.diff_prettyHtml = function(diffs) {
  var html = [];
  var i = 0;
  var pattern_amp = /&/g;
  var pattern_lt = /</g;
  var pattern_gt = />/g;
  var pattern_para = /\n/g;
  for (var x = 0; x < diffs.length; x++) {
    var op = diffs[x][0];    // Operation (insert, delete, equal)
    var data = diffs[x][1];  // Text of change.
    var text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;')
        .replace(pattern_gt, '&gt;').replace(pattern_para, '&para;<br>');
    switch (op) {
      case DIFF_INSERT:
        html[x] = '<ins style="background:#e6ffe6;">' + text + '</ins>';
        break;
      case DIFF_DELETE:
        html[x] = '<del style="background:#ffe6e6;">' + text + '</del>';
        break;
      case DIFF_EQUAL:
        html[x] = '<span>' + text + '</span>';
        break;
    }
    if (op !== DIFF_DELETE) {
      i += data.length;
    }
  }
  return html.join('');
};


/**
 * Compute and return the source text (all equalities and deletions).
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 * @return {string} Source text.
 */
diff_match_patch.prototype.diff_text1 = function(diffs) {
  var text = [];
  for (var x = 0; x < diffs.length; x++) {
    if (diffs[x][0] !== DIFF_INSERT) {
      text[x] = diffs[x][1];
    }
  }
  return text.join('');
};


/**
 * Compute and return the destination text (all equalities and insertions).
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 * @return {string} Destination text.
 */
diff_match_patch.prototype.diff_text2 = function(diffs) {
  var text = [];
  for (var x = 0; x < diffs.length; x++) {
    if (diffs[x][0] !== DIFF_DELETE) {
      text[x] = diffs[x][1];
    }
  }
  return text.join('');
};


/**
 * Compute the Levenshtein distance; the number of inserted, deleted or
 * substituted characters.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 * @return {number} Number of changes.
 */
diff_match_patch.prototype.diff_levenshtein = function(diffs) {
  var levenshtein = 0;
  var insertions = 0;
  var deletions = 0;
  for (var x = 0; x < diffs.length; x++) {
    var op = diffs[x][0];
    var data = diffs[x][1];
    switch (op) {
      case DIFF_INSERT:
        insertions += data.length;
        break;
      case DIFF_DELETE:
        deletions += data.length;
        break;
      case DIFF_EQUAL:
        // A deletion and an insertion is one substitution.
        levenshtein += Math.max(insertions, deletions);
        insertions = 0;
        deletions = 0;
        break;
    }
  }
  levenshtein += Math.max(insertions, deletions);
  return levenshtein;
};


/**
 * Crush the diff into an encoded string which describes the operations
 * required to transform text1 into text2.
 * E.g. =3\t-2\t+ing  -> Keep 3 chars, delete 2 chars, insert 'ing'.
 * Operations are tab-separated.  Inserted text is escaped using %xx notation.
 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
 * @return {string} Delta text.
 */
diff_match_patch.prototype.diff_toDelta = function(diffs) {
  var text = [];
  for (var x = 0; x < diffs.length; x++) {
    switch (diffs[x][0]) {
      case DIFF_INSERT:
        text[x] = '+' + encodeURI(diffs[x][1]);
        break;
      case DIFF_DELETE:
        text[x] = '-' + diffs[x][1].length;
        break;
      case DIFF_EQUAL:
        text[x] = '=' + diffs[x][1].length;
        break;
    }
  }
  return text.join('\t').replace(/%20/g, ' ');
};


/**
 * Given the original text1, and an encoded string which describes the
 * operations required to transform text1 into text2, compute the full diff.
 * @param {string} text1 Source string for the diff.
 * @param {string} delta Delta text.
 * @return {!Array.<!diff_match_patch.Diff>} Array of diff tuples.
 * @throws {!Error} If invalid input.
 */
diff_match_patch.prototype.diff_fromDelta = function(text1, delta) {
  var diffs = [];
  var diffsLength = 0;  // Keeping our own length var is faster in JS.
  var pointer = 0;  // Cursor in text1
  var tokens = delta.split(/\t/g);
  for (var x = 0; x < tokens.length; x++) {
    // Each token begins with a one character parameter which specifies the
    // operation of this token (delete, insert, equality).
    var param = tokens[x].substring(1);
    switch (tokens[x].charAt(0)) {
      case '+':
        try {
          diffs[diffsLength++] = [DIFF_INSERT, decodeURI(param)];
        } catch (ex) {
          // Malformed URI sequence.
          throw new Error('Illegal escape in diff_fromDelta: ' + param);
        }
        break;
      case '-':
        // Fall through.
      case '=':
        var n = parseInt(param, 10);
        if (isNaN(n) || n < 0) {
          throw new Error('Invalid number in diff_fromDelta: ' + param);
        }
        var text = text1.substring(pointer, pointer += n);
        if (tokens[x].charAt(0) == '=') {
          diffs[diffsLength++] = [DIFF_EQUAL, text];
        } else {
          diffs[diffsLength++] = [DIFF_DELETE, text];
        }
        break;
      default:
        // Blank tokens are ok (from a trailing \t).
        // Anything else is an error.
        if (tokens[x]) {
          throw new Error('Invalid diff operation in diff_fromDelta: ' +
                          tokens[x]);
        }
    }
  }
  if (pointer != text1.length) {
    throw new Error('Delta length (' + pointer +
        ') does not equal source text length (' + text1.length + ').');
  }
  return diffs;
};


//  MATCH FUNCTIONS


/**
 * Locate the best instance of 'pattern' in 'text' near 'loc'.
 * @param {string} text The text to search.
 * @param {string} pattern The pattern to search for.
 * @param {number} loc The location to search around.
 * @return {number} Best match index or -1.
 */
diff_match_patch.prototype.match_main = function(text, pattern, loc) {
  // Check for null inputs.
  if (text == null || pattern == null || loc == null) {
    throw new Error('Null input. (match_main)');
  }

  loc = Math.max(0, Math.min(loc, text.length));
  if (text == pattern) {
    // Shortcut (potentially not guaranteed by the algorithm)
    return 0;
  } else if (!text.length) {
    // Nothing to match.
    return -1;
  } else if (text.substring(loc, loc + pattern.length) == pattern) {
    // Perfect match at the perfect spot!  (Includes case of null pattern)
    return loc;
  } else {
    // Do a fuzzy compare.
    return this.match_bitap_(text, pattern, loc);
  }
};


/**
 * Locate the best instance of 'pattern' in 'text' near 'loc' using the
 * Bitap algorithm.
 * @param {string} text The text to search.
 * @param {string} pattern The pattern to search for.
 * @param {number} loc The location to search around.
 * @return {number} Best match index or -1.
 * @private
 */
diff_match_patch.prototype.match_bitap_ = function(text, pattern, loc) {
  if (pattern.length > this.Match_MaxBits) {
    throw new Error('Pattern too long for this browser.');
  }

  // Initialise the alphabet.
  var s = this.match_alphabet_(pattern);

  var dmp = this;  // 'this' becomes 'window' in a closure.

  /**
   * Compute and return the score for a match with e errors and x location.
   * Accesses loc and pattern through being a closure.
   * @param {number} e Number of errors in match.
   * @param {number} x Location of match.
   * @return {number} Overall score for match (0.0 = good, 1.0 = bad).
   * @private
   */
  function match_bitapScore_(e, x) {
    var accuracy = e / pattern.length;
    var proximity = Math.abs(loc - x);
    if (!dmp.Match_Distance) {
      // Dodge divide by zero error.
      return proximity ? 1.0 : accuracy;
    }
    return accuracy + (proximity / dmp.Match_Distance);
  }

  // Highest score beyond which we give up.
  var score_threshold = this.Match_Threshold;
  // Is there a nearby exact match? (speedup)
  var best_loc = text.indexOf(pattern, loc);
  if (best_loc != -1) {
    score_threshold = Math.min(match_bitapScore_(0, best_loc), score_threshold);
    // What about in the other direction? (speedup)
    best_loc = text.lastIndexOf(pattern, loc + pattern.length);
    if (best_loc != -1) {
      score_threshold =
          Math.min(match_bitapScore_(0, best_loc), score_threshold);
    }
  }

  // Initialise the bit arrays.
  var matchmask = 1 << (pattern.length - 1);
  best_loc = -1;

  var bin_min, bin_mid;
  var bin_max = pattern.length + text.length;
  var last_rd;
  for (var d = 0; d < pattern.length; d++) {
    // Scan for the best match; each iteration allows for one more error.
    // Run a binary search to determine how far from 'loc' we can stray at this
    // error level.
    bin_min = 0;
    bin_mid = bin_max;
    while (bin_min < bin_mid) {
      if (match_bitapScore_(d, loc + bin_mid) <= score_threshold) {
        bin_min = bin_mid;
      } else {
        bin_max = bin_mid;
      }
      bin_mid = Math.floor((bin_max - bin_min) / 2 + bin_min);
    }
    // Use the result from this iteration as the maximum for the next.
    bin_max = bin_mid;
    var start = Math.max(1, loc - bin_mid + 1);
    var finish = Math.min(loc + bin_mid, text.length) + pattern.length;

    var rd = Array(finish + 2);
    rd[finish + 1] = (1 << d) - 1;
    for (var j = finish; j >= start; j--) {
      // The alphabet (s) is a sparse hash, so the following line generates
      // warnings.
      var charMatch = s[text.charAt(j - 1)];
      if (d === 0) {  // First pass: exact match.
        rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;
      } else {  // Subsequent passes: fuzzy match.
        rd[j] = ((rd[j + 1] << 1) | 1) & charMatch |
                (((last_rd[j + 1] | last_rd[j]) << 1) | 1) |
                last_rd[j + 1];
      }
      if (rd[j] & matchmask) {
        var score = match_bitapScore_(d, j - 1);
        // This match will almost certainly be better than any existing match.
        // But check anyway.
        if (score <= score_threshold) {
          // Told you so.
          score_threshold = score;
          best_loc = j - 1;
          if (best_loc > loc) {
            // When passing loc, don't exceed our current distance from loc.
            start = Math.max(1, 2 * loc - best_loc);
          } else {
            // Already passed loc, downhill from here on in.
            break;
          }
        }
      }
    }
    // No hope for a (better) match at greater error levels.
    if (match_bitapScore_(d + 1, loc) > score_threshold) {
      break;
    }
    last_rd = rd;
  }
  return best_loc;
};


/**
 * Initialise the alphabet for the Bitap algorithm.
 * @param {string} pattern The text to encode.
 * @return {!Object} Hash of character locations.
 * @private
 */
diff_match_patch.prototype.match_alphabet_ = function(pattern) {
  var s = {};
  for (var i = 0; i < pattern.length; i++) {
    s[pattern.charAt(i)] = 0;
  }
  for (var i = 0; i < pattern.length; i++) {
    s[pattern.charAt(i)] |= 1 << (pattern.length - i - 1);
  }
  return s;
};


//  PATCH FUNCTIONS


/**
 * Increase the context until it is unique,
 * but don't let the pattern expand beyond Match_MaxBits.
 * @param {!diff_match_patch.patch_obj} patch The patch to grow.
 * @param {string} text Source text.
 * @private
 */
diff_match_patch.prototype.patch_addContext_ = function(patch, text) {
  if (text.length == 0) {
    return;
  }
  var pattern = text.substring(patch.start2, patch.start2 + patch.length1);
  var padding = 0;

  // Look for the first and last matches of pattern in text.  If two different
  // matches are found, increase the pattern length.
  while (text.indexOf(pattern) != text.lastIndexOf(pattern) &&
         pattern.length < this.Match_MaxBits - this.Patch_Margin -
         this.Patch_Margin) {
    padding += this.Patch_Margin;
    pattern = text.substring(patch.start2 - padding,
                             patch.start2 + patch.length1 + padding);
  }
  // Add one chunk for good luck.
  padding += this.Patch_Margin;

  // Add the prefix.
  var prefix = text.substring(patch.start2 - padding, patch.start2);
  if (prefix) {
    patch.diffs.unshift([DIFF_EQUAL, prefix]);
  }
  // Add the suffix.
  var suffix = text.substring(patch.start2 + patch.length1,
                              patch.start2 + patch.length1 + padding);
  if (suffix) {
    patch.diffs.push([DIFF_EQUAL, suffix]);
  }

  // Roll back the start points.
  patch.start1 -= prefix.length;
  patch.start2 -= prefix.length;
  // Extend the lengths.
  patch.length1 += prefix.length + suffix.length;
  patch.length2 += prefix.length + suffix.length;
};


/**
 * Compute a list of patches to turn text1 into text2.
 * Use diffs if provided, otherwise compute it ourselves.
 * There are four ways to call this function, depending on what data is
 * available to the caller:
 * Method 1:
 * a = text1, b = text2
 * Method 2:
 * a = diffs
 * Method 3 (optimal):
 * a = text1, b = diffs
 * Method 4 (deprecated, use method 3):
 * a = text1, b = text2, c = diffs
 *
 * @param {string|!Array.<!diff_match_patch.Diff>} a text1 (methods 1,3,4) or
 * Array of diff tuples for text1 to text2 (method 2).
 * @param {string|!Array.<!diff_match_patch.Diff>} opt_b text2 (methods 1,4) or
 * Array of diff tuples for text1 to text2 (method 3) or undefined (method 2).
 * @param {string|!Array.<!diff_match_patch.Diff>} opt_c Array of diff tuples
 * for text1 to text2 (method 4) or undefined (methods 1,2,3).
 * @return {!Array.<!diff_match_patch.patch_obj>} Array of patch objects.
 */
diff_match_patch.prototype.patch_make = function(a, opt_b, opt_c) {
  var text1, diffs;
  if (typeof a == 'string' && typeof opt_b == 'string' &&
      typeof opt_c == 'undefined') {
    // Method 1: text1, text2
    // Compute diffs from text1 and text2.
    text1 = /** @type {string} */(a);
    diffs = this.diff_main(text1, /** @type {string} */(opt_b), true);
    if (diffs.length > 2) {
      this.diff_cleanupSemantic(diffs);
      this.diff_cleanupEfficiency(diffs);
    }
  } else if (a && typeof a == 'object' && typeof opt_b == 'undefined' &&
      typeof opt_c == 'undefined') {
    // Method 2: diffs
    // Compute text1 from diffs.
    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(a);
    text1 = this.diff_text1(diffs);
  } else if (typeof a == 'string' && opt_b && typeof opt_b == 'object' &&
      typeof opt_c == 'undefined') {
    // Method 3: text1, diffs
    text1 = /** @type {string} */(a);
    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_b);
  } else if (typeof a == 'string' && typeof opt_b == 'string' &&
      opt_c && typeof opt_c == 'object') {
    // Method 4: text1, text2, diffs
    // text2 is not used.
    text1 = /** @type {string} */(a);
    diffs = /** @type {!Array.<!diff_match_patch.Diff>} */(opt_c);
  } else {
    throw new Error('Unknown call format to patch_make.');
  }

  if (diffs.length === 0) {
    return [];  // Get rid of the null case.
  }
  var patches = [];
  var patch = new diff_match_patch.patch_obj();
  var patchDiffLength = 0;  // Keeping our own length var is faster in JS.
  var char_count1 = 0;  // Number of characters into the text1 string.
  var char_count2 = 0;  // Number of characters into the text2 string.
  // Start with text1 (prepatch_text) and apply the diffs until we arrive at
  // text2 (postpatch_text).  We recreate the patches one by one to determine
  // context info.
  var prepatch_text = text1;
  var postpatch_text = text1;
  for (var x = 0; x < diffs.length; x++) {
    var diff_type = diffs[x][0];
    var diff_text = diffs[x][1];

    if (!patchDiffLength && diff_type !== DIFF_EQUAL) {
      // A new patch starts here.
      patch.start1 = char_count1;
      patch.start2 = char_count2;
    }

    switch (diff_type) {
      case DIFF_INSERT:
        patch.diffs[patchDiffLength++] = diffs[x];
        patch.length2 += diff_text.length;
        postpatch_text = postpatch_text.substring(0, char_count2) + diff_text +
                         postpatch_text.substring(char_count2);
        break;
      case DIFF_DELETE:
        patch.length1 += diff_text.length;
        patch.diffs[patchDiffLength++] = diffs[x];
        postpatch_text = postpatch_text.substring(0, char_count2) +
                         postpatch_text.substring(char_count2 +
                             diff_text.length);
        break;
      case DIFF_EQUAL:
        if (diff_text.length <= 2 * this.Patch_Margin &&
            patchDiffLength && diffs.length != x + 1) {
          // Small equality inside a patch.
          patch.diffs[patchDiffLength++] = diffs[x];
          patch.length1 += diff_text.length;
          patch.length2 += diff_text.length;
        } else if (diff_text.length >= 2 * this.Patch_Margin) {
          // Time for a new patch.
          if (patchDiffLength) {
            this.patch_addContext_(patch, prepatch_text);
            patches.push(patch);
            patch = new diff_match_patch.patch_obj();
            patchDiffLength = 0;
            // Unlike Unidiff, our patch lists have a rolling context.
            // http://code.google.com/p/google-diff-match-patch/wiki/Unidiff
            // Update prepatch text & pos to reflect the application of the
            // just completed patch.
            prepatch_text = postpatch_text;
            char_count1 = char_count2;
          }
        }
        break;
    }

    // Update the current character count.
    if (diff_type !== DIFF_INSERT) {
      char_count1 += diff_text.length;
    }
    if (diff_type !== DIFF_DELETE) {
      char_count2 += diff_text.length;
    }
  }
  // Pick up the leftover patch if not empty.
  if (patchDiffLength) {
    this.patch_addContext_(patch, prepatch_text);
    patches.push(patch);
  }

  return patches;
};


/**
 * Given an array of patches, return another array that is identical.
 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
 * @return {!Array.<!diff_match_patch.patch_obj>} Array of patch objects.
 */
diff_match_patch.prototype.patch_deepCopy = function(patches) {
  // Making deep copies is hard in JavaScript.
  var patchesCopy = [];
  for (var x = 0; x < patches.length; x++) {
    var patch = patches[x];
    var patchCopy = new diff_match_patch.patch_obj();
    patchCopy.diffs = [];
    for (var y = 0; y < patch.diffs.length; y++) {
      patchCopy.diffs[y] = patch.diffs[y].slice();
    }
    patchCopy.start1 = patch.start1;
    patchCopy.start2 = patch.start2;
    patchCopy.length1 = patch.length1;
    patchCopy.length2 = patch.length2;
    patchesCopy[x] = patchCopy;
  }
  return patchesCopy;
};


/**
 * Merge a set of patches onto the text.  Return a patched text, as well
 * as a list of true/false values indicating which patches were applied.
 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
 * @param {string} text Old text.
 * @return {!Array.<string|!Array.<boolean>>} Two element Array, containing the
 *      new text and an array of boolean values.
 */
diff_match_patch.prototype.patch_apply = function(patches, text) {
  if (patches.length == 0) {
    return [text, []];
  }

  // Deep copy the patches so that no changes are made to originals.
  patches = this.patch_deepCopy(patches);

  var nullPadding = this.patch_addPadding(patches);
  text = nullPadding + text + nullPadding;

  this.patch_splitMax(patches);
  // delta keeps track of the offset between the expected and actual location
  // of the previous patch.  If there are patches expected at positions 10 and
  // 20, but the first patch was found at 12, delta is 2 and the second patch
  // has an effective expected position of 22.
  var delta = 0;
  var results = [];
  for (var x = 0; x < patches.length; x++) {
    var expected_loc = patches[x].start2 + delta;
    var text1 = this.diff_text1(patches[x].diffs);
    var start_loc;
    var end_loc = -1;
    if (text1.length > this.Match_MaxBits) {
      // patch_splitMax will only provide an oversized pattern in the case of
      // a monster delete.
      start_loc = this.match_main(text, text1.substring(0, this.Match_MaxBits),
                                  expected_loc);
      if (start_loc != -1) {
        end_loc = this.match_main(text,
            text1.substring(text1.length - this.Match_MaxBits),
            expected_loc + text1.length - this.Match_MaxBits);
        if (end_loc == -1 || start_loc >= end_loc) {
          // Can't find valid trailing context.  Drop this patch.
          start_loc = -1;
        }
      }
    } else {
      start_loc = this.match_main(text, text1, expected_loc);
    }
    if (start_loc == -1) {
      // No match found.  :(
      results[x] = false;
      // Subtract the delta for this failed patch from subsequent patches.
      delta -= patches[x].length2 - patches[x].length1;
    } else {
      // Found a match.  :)
      results[x] = true;
      delta = start_loc - expected_loc;
      var text2;
      if (end_loc == -1) {
        text2 = text.substring(start_loc, start_loc + text1.length);
      } else {
        text2 = text.substring(start_loc, end_loc + this.Match_MaxBits);
      }
      if (text1 == text2) {
        // Perfect match, just shove the replacement text in.
        text = text.substring(0, start_loc) +
               this.diff_text2(patches[x].diffs) +
               text.substring(start_loc + text1.length);
      } else {
        // Imperfect match.  Run a diff to get a framework of equivalent
        // indices.
        var diffs = this.diff_main(text1, text2, false);
        if (text1.length > this.Match_MaxBits &&
            this.diff_levenshtein(diffs) / text1.length >
            this.Patch_DeleteThreshold) {
          // The end points match, but the content is unacceptably bad.
          results[x] = false;
        } else {
          this.diff_cleanupSemanticLossless(diffs);
          var index1 = 0;
          var index2;
          for (var y = 0; y < patches[x].diffs.length; y++) {
            var mod = patches[x].diffs[y];
            if (mod[0] !== DIFF_EQUAL) {
              index2 = this.diff_xIndex(diffs, index1);
            }
            if (mod[0] === DIFF_INSERT) {  // Insertion
              text = text.substring(0, start_loc + index2) + mod[1] +
                     text.substring(start_loc + index2);
            } else if (mod[0] === DIFF_DELETE) {  // Deletion
              text = text.substring(0, start_loc + index2) +
                     text.substring(start_loc + this.diff_xIndex(diffs,
                         index1 + mod[1].length));
            }
            if (mod[0] !== DIFF_DELETE) {
              index1 += mod[1].length;
            }
          }
        }
      }
    }
  }
  // Strip the padding off.
  text = text.substring(nullPadding.length, text.length - nullPadding.length);
  return [text, results];
};


/**
 * Add some padding on text start and end so that edges can match something.
 * Intended to be called only from within patch_apply.
 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
 * @return {string} The padding string added to each side.
 */
diff_match_patch.prototype.patch_addPadding = function(patches) {
  var paddingLength = this.Patch_Margin;
  var nullPadding = '';
  for (var x = 1; x <= paddingLength; x++) {
    nullPadding += String.fromCharCode(x);
  }

  // Bump all the patches forward.
  for (var x = 0; x < patches.length; x++) {
    patches[x].start1 += paddingLength;
    patches[x].start2 += paddingLength;
  }

  // Add some padding on start of first diff.
  var patch = patches[0];
  var diffs = patch.diffs;
  if (diffs.length == 0 || diffs[0][0] != DIFF_EQUAL) {
    // Add nullPadding equality.
    diffs.unshift([DIFF_EQUAL, nullPadding]);
    patch.start1 -= paddingLength;  // Should be 0.
    patch.start2 -= paddingLength;  // Should be 0.
    patch.length1 += paddingLength;
    patch.length2 += paddingLength;
  } else if (paddingLength > diffs[0][1].length) {
    // Grow first equality.
    var extraLength = paddingLength - diffs[0][1].length;
    diffs[0][1] = nullPadding.substring(diffs[0][1].length) + diffs[0][1];
    patch.start1 -= extraLength;
    patch.start2 -= extraLength;
    patch.length1 += extraLength;
    patch.length2 += extraLength;
  }

  // Add some padding on end of last diff.
  patch = patches[patches.length - 1];
  diffs = patch.diffs;
  if (diffs.length == 0 || diffs[diffs.length - 1][0] != DIFF_EQUAL) {
    // Add nullPadding equality.
    diffs.push([DIFF_EQUAL, nullPadding]);
    patch.length1 += paddingLength;
    patch.length2 += paddingLength;
  } else if (paddingLength > diffs[diffs.length - 1][1].length) {
    // Grow last equality.
    var extraLength = paddingLength - diffs[diffs.length - 1][1].length;
    diffs[diffs.length - 1][1] += nullPadding.substring(0, extraLength);
    patch.length1 += extraLength;
    patch.length2 += extraLength;
  }

  return nullPadding;
};


/**
 * Look through the patches and break up any which are longer than the maximum
 * limit of the match algorithm.
 * Intended to be called only from within patch_apply.
 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
 */
diff_match_patch.prototype.patch_splitMax = function(patches) {
  var patch_size = this.Match_MaxBits;
  for (var x = 0; x < patches.length; x++) {
    if (patches[x].length1 > patch_size) {
      var bigpatch = patches[x];
      // Remove the big old patch.
      patches.splice(x--, 1);
      var start1 = bigpatch.start1;
      var start2 = bigpatch.start2;
      var precontext = '';
      while (bigpatch.diffs.length !== 0) {
        // Create one of several smaller patches.
        var patch = new diff_match_patch.patch_obj();
        var empty = true;
        patch.start1 = start1 - precontext.length;
        patch.start2 = start2 - precontext.length;
        if (precontext !== '') {
          patch.length1 = patch.length2 = precontext.length;
          patch.diffs.push([DIFF_EQUAL, precontext]);
        }
        while (bigpatch.diffs.length !== 0 &&
               patch.length1 < patch_size - this.Patch_Margin) {
          var diff_type = bigpatch.diffs[0][0];
          var diff_text = bigpatch.diffs[0][1];
          if (diff_type === DIFF_INSERT) {
            // Insertions are harmless.
            patch.length2 += diff_text.length;
            start2 += diff_text.length;
            patch.diffs.push(bigpatch.diffs.shift());
            empty = false;
          } else if (diff_type === DIFF_DELETE && patch.diffs.length == 1 &&
                     patch.diffs[0][0] == DIFF_EQUAL &&
                     diff_text.length > 2 * patch_size) {
            // This is a large deletion.  Let it pass in one chunk.
            patch.length1 += diff_text.length;
            start1 += diff_text.length;
            empty = false;
            patch.diffs.push([diff_type, diff_text]);
            bigpatch.diffs.shift();
          } else {
            // Deletion or equality.  Only take as much as we can stomach.
            diff_text = diff_text.substring(0,
                patch_size - patch.length1 - this.Patch_Margin);
            patch.length1 += diff_text.length;
            start1 += diff_text.length;
            if (diff_type === DIFF_EQUAL) {
              patch.length2 += diff_text.length;
              start2 += diff_text.length;
            } else {
              empty = false;
            }
            patch.diffs.push([diff_type, diff_text]);
            if (diff_text == bigpatch.diffs[0][1]) {
              bigpatch.diffs.shift();
            } else {
              bigpatch.diffs[0][1] =
                  bigpatch.diffs[0][1].substring(diff_text.length);
            }
          }
        }
        // Compute the head context for the next patch.
        precontext = this.diff_text2(patch.diffs);
        precontext =
            precontext.substring(precontext.length - this.Patch_Margin);
        // Append the end context for this patch.
        var postcontext = this.diff_text1(bigpatch.diffs)
                              .substring(0, this.Patch_Margin);
        if (postcontext !== '') {
          patch.length1 += postcontext.length;
          patch.length2 += postcontext.length;
          if (patch.diffs.length !== 0 &&
              patch.diffs[patch.diffs.length - 1][0] === DIFF_EQUAL) {
            patch.diffs[patch.diffs.length - 1][1] += postcontext;
          } else {
            patch.diffs.push([DIFF_EQUAL, postcontext]);
          }
        }
        if (!empty) {
          patches.splice(++x, 0, patch);
        }
      }
    }
  }
};


/**
 * Take a list of patches and return a textual representation.
 * @param {!Array.<!diff_match_patch.patch_obj>} patches Array of patch objects.
 * @return {string} Text representation of patches.
 */
diff_match_patch.prototype.patch_toText = function(patches) {
  var text = [];
  for (var x = 0; x < patches.length; x++) {
    text[x] = patches[x];
  }
  return text.join('');
};


/**
 * Parse a textual representation of patches and return a list of patch objects.
 * @param {string} textline Text representation of patches.
 * @return {!Array.<!diff_match_patch.patch_obj>} Array of patch objects.
 * @throws {!Error} If invalid input.
 */
diff_match_patch.prototype.patch_fromText = function(textline) {
  var patches = [];
  if (!textline) {
    return patches;
  }
  var text = textline.split('\n');
  var textPointer = 0;
  var patchHeader = /^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;
  while (textPointer < text.length) {
    var m = text[textPointer].match(patchHeader);
    if (!m) {
      throw new Error('Invalid patch string: ' + text[textPointer]);
    }
    var patch = new diff_match_patch.patch_obj();
    patches.push(patch);
    patch.start1 = parseInt(m[1], 10);
    if (m[2] === '') {
      patch.start1--;
      patch.length1 = 1;
    } else if (m[2] == '0') {
      patch.length1 = 0;
    } else {
      patch.start1--;
      patch.length1 = parseInt(m[2], 10);
    }

    patch.start2 = parseInt(m[3], 10);
    if (m[4] === '') {
      patch.start2--;
      patch.length2 = 1;
    } else if (m[4] == '0') {
      patch.length2 = 0;
    } else {
      patch.start2--;
      patch.length2 = parseInt(m[4], 10);
    }
    textPointer++;

    while (textPointer < text.length) {
      var sign = text[textPointer].charAt(0);
      try {
        var line = decodeURI(text[textPointer].substring(1));
      } catch (ex) {
        // Malformed URI sequence.
        throw new Error('Illegal escape in patch_fromText: ' + line);
      }
      if (sign == '-') {
        // Deletion.
        patch.diffs.push([DIFF_DELETE, line]);
      } else if (sign == '+') {
        // Insertion.
        patch.diffs.push([DIFF_INSERT, line]);
      } else if (sign == ' ') {
        // Minor equality.
        patch.diffs.push([DIFF_EQUAL, line]);
      } else if (sign == '@') {
        // Start of next patch.
        break;
      } else if (sign === '') {
        // Blank line?  Whatever.
      } else {
        // WTF?
        throw new Error('Invalid patch mode "' + sign + '" in: ' + line);
      }
      textPointer++;
    }
  }
  return patches;
};


/**
 * Class representing one patch operation.
 * @constructor
 */
diff_match_patch.patch_obj = function() {
  /** @type {!Array.<!diff_match_patch.Diff>} */
  this.diffs = [];
  /** @type {?number} */
  this.start1 = null;
  /** @type {?number} */
  this.start2 = null;
  /** @type {number} */
  this.length1 = 0;
  /** @type {number} */
  this.length2 = 0;
};


/**
 * Emmulate GNU diff's format.
 * Header: @@ -382,8 +481,9 @@
 * Indicies are printed as 1-based, not 0-based.
 * @return {string} The GNU diff string.
 */
diff_match_patch.patch_obj.prototype.toString = function() {
  var coords1, coords2;
  if (this.length1 === 0) {
    coords1 = this.start1 + ',0';
  } else if (this.length1 == 1) {
    coords1 = this.start1 + 1;
  } else {
    coords1 = (this.start1 + 1) + ',' + this.length1;
  }
  if (this.length2 === 0) {
    coords2 = this.start2 + ',0';
  } else if (this.length2 == 1) {
    coords2 = this.start2 + 1;
  } else {
    coords2 = (this.start2 + 1) + ',' + this.length2;
  }
  var text = ['@@ -' + coords1 + ' +' + coords2 + ' @@\n'];
  var op;
  // Escape the body of the patch with %xx notation.
  for (var x = 0; x < this.diffs.length; x++) {
    switch (this.diffs[x][0]) {
      case DIFF_INSERT:
        op = '+';
        break;
      case DIFF_DELETE:
        op = '-';
        break;
      case DIFF_EQUAL:
        op = ' ';
        break;
    }
    text[x + 1] = op + encodeURI(this.diffs[x][1]) + '\n';
  }
  return text.join('').replace(/%20/g, ' ');
};


// Export these global variables so that they survive Google's JS compiler.
// In a browser, 'this' will be 'window'.
// In node.js 'this' will be a global object.
this['diff_match_patch'] = diff_match_patch;
this['DIFF_DELETE'] = DIFF_DELETE;
this['DIFF_INSERT'] = DIFF_INSERT;
this['DIFF_EQUAL'] = DIFF_EQUAL;


},{}],3:[function(require,module,exports){

var isArray = (typeof Array.isArray === 'function') ?
  // use native function
  Array.isArray :
  // use instanceof operator
  function(a) {
    return a instanceof Array;
  };

function cloneRegExp(re) {
  var regexMatch = /^\/(.*)\/([gimyu]*)$/.exec(re.toString());
  return new RegExp(regexMatch[1], regexMatch[2]);
}

function clone(arg) {
  if (typeof arg !== 'object') {
    return arg;
  }
  if (arg === null) {
    return null;
  }
  if (isArray(arg)) {
    return arg.map(clone);
  }
  if (arg instanceof Date) {
    return new Date(arg.getTime());
  }
  if (arg instanceof RegExp) {
    return cloneRegExp(arg);
  }
  var cloned = {};
  for (var name in arg) {
    if (Object.prototype.hasOwnProperty.call(arg, name)) {
      cloned[name] = clone(arg[name]);
    }
  }
  return cloned;
}

module.exports = clone;

},{}],4:[function(require,module,exports){

var Pipe = require('../pipe').Pipe;

var Context = function Context(){
};

Context.prototype.setResult = function(result) {
	this.result = result;
	this.hasResult = true;
	return this;
};

Context.prototype.exit = function() {
	this.exiting = true;
	return this;
};

Context.prototype.switchTo = function(next, pipe) {
	if (typeof next === 'string' || next instanceof Pipe) {
		this.nextPipe = next;
	} else {
		this.next = next;
		if (pipe) {
			this.nextPipe = pipe;
		}
	}
	return this;
};

Context.prototype.push = function(child, name) {
	child.parent = this;
	if (typeof name !== 'undefined') {
		child.childName = name;
	}
	child.root = this.root || this;
	child.options = child.options || this.options;
	if (!this.children) {
		this.children = [child];
		this.nextAfterChildren = this.next || null;
		this.next = child;
	} else {
		this.children[this.children.length - 1].next = child;
		this.children.push(child);
	}
	child.next = this;
	return this;
};

exports.Context = Context;

},{"../pipe":18}],5:[function(require,module,exports){
var Context = require('./context').Context;
var defaultClone = require('../clone');

var DiffContext = function DiffContext(left, right) {
  this.left = left;
  this.right = right;
  this.pipe = 'diff';
};

DiffContext.prototype = new Context();

DiffContext.prototype.setResult = function(result) {
  if (this.options.cloneDiffValues && typeof result === 'object') {
    var clone = typeof this.options.cloneDiffValues === 'function' ?
      this.options.cloneDiffValues : defaultClone;
    if (typeof result[0] === 'object') {
      result[0] = clone(result[0]);
    }
    if (typeof result[1] === 'object') {
      result[1] = clone(result[1]);
    }
  }
  return Context.prototype.setResult.apply(this, arguments);
};

exports.DiffContext = DiffContext;

},{"../clone":3,"./context":4}],6:[function(require,module,exports){
var Context = require('./context').Context;

var PatchContext = function PatchContext(left, delta) {
  this.left = left;
  this.delta = delta;
  this.pipe = 'patch';
};

PatchContext.prototype = new Context();

exports.PatchContext = PatchContext;

},{"./context":4}],7:[function(require,module,exports){
var Context = require('./context').Context;

var ReverseContext = function ReverseContext(delta) {
  this.delta = delta;
  this.pipe = 'reverse';
};

ReverseContext.prototype = new Context();

exports.ReverseContext = ReverseContext;

},{"./context":4}],8:[function(require,module,exports){
// use as 2nd parameter for JSON.parse to revive Date instances
module.exports = function dateReviver(key, value) {
  var parts;
  if (typeof value === 'string') {
    parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d*))?(Z|([+\-])(\d{2}):(\d{2}))$/.exec(value);
    if (parts) {
      return new Date(Date.UTC(+parts[1], +parts[2] - 1, +parts[3], +parts[4], +parts[5], +parts[6], +(parts[7] || 0)));
    }
  }
  return value;
};

},{}],9:[function(require,module,exports){
var Processor = require('./processor').Processor;
var Pipe = require('./pipe').Pipe;
var DiffContext = require('./contexts/diff').DiffContext;
var PatchContext = require('./contexts/patch').PatchContext;
var ReverseContext = require('./contexts/reverse').ReverseContext;

var clone = require('./clone');

var trivial = require('./filters/trivial');
var nested = require('./filters/nested');
var arrays = require('./filters/arrays');
var dates = require('./filters/dates');
var texts = require('./filters/texts');

var DiffPatcher = function DiffPatcher(options) {
  this.processor = new Processor(options);
  this.processor.pipe(new Pipe('diff').append(
    nested.collectChildrenDiffFilter,
    trivial.diffFilter,
    dates.diffFilter,
    texts.diffFilter,
    nested.objectsDiffFilter,
    arrays.diffFilter
  ).shouldHaveResult());
  this.processor.pipe(new Pipe('patch').append(
    nested.collectChildrenPatchFilter,
    arrays.collectChildrenPatchFilter,
    trivial.patchFilter,
    texts.patchFilter,
    nested.patchFilter,
    arrays.patchFilter
  ).shouldHaveResult());
  this.processor.pipe(new Pipe('reverse').append(
    nested.collectChildrenReverseFilter,
    arrays.collectChildrenReverseFilter,
    trivial.reverseFilter,
    texts.reverseFilter,
    nested.reverseFilter,
    arrays.reverseFilter
  ).shouldHaveResult());
};

DiffPatcher.prototype.options = function() {
  return this.processor.options.apply(this.processor, arguments);
};

DiffPatcher.prototype.diff = function(left, right) {
  return this.processor.process(new DiffContext(left, right));
};

DiffPatcher.prototype.patch = function(left, delta) {
  return this.processor.process(new PatchContext(left, delta));
};

DiffPatcher.prototype.reverse = function(delta) {
  return this.processor.process(new ReverseContext(delta));
};

DiffPatcher.prototype.unpatch = function(right, delta) {
  return this.patch(right, this.reverse(delta));
};

DiffPatcher.prototype.clone = function(value) {
  return clone(value);
};

exports.DiffPatcher = DiffPatcher;

},{"./clone":3,"./contexts/diff":5,"./contexts/patch":6,"./contexts/reverse":7,"./filters/arrays":11,"./filters/dates":12,"./filters/nested":14,"./filters/texts":15,"./filters/trivial":16,"./pipe":18,"./processor":19}],10:[function(require,module,exports){

exports.isBrowser = typeof window !== 'undefined';

},{}],11:[function(require,module,exports){
var DiffContext = require('../contexts/diff').DiffContext;
var PatchContext = require('../contexts/patch').PatchContext;
var ReverseContext = require('../contexts/reverse').ReverseContext;

var lcs = require('./lcs');

var ARRAY_MOVE = 3;

var isArray = (typeof Array.isArray === 'function') ?
  // use native function
  Array.isArray :
  // use instanceof operator
  function(a) {
    return a instanceof Array;
  };

var arrayIndexOf = typeof Array.prototype.indexOf === 'function' ?
  function(array, item) {
    return array.indexOf(item);
  } : function(array, item) {
    var length = array.length;
    for (var i = 0; i < length; i++) {
      if (array[i] === item) {
        return i;
      }
    }
    return -1;
  };

function arraysHaveMatchByRef(array1, array2, len1, len2) {
  for (var index1 = 0; index1 < len1; index1++) {
    var val1 = array1[index1];
    for (var index2 = 0; index2 < len2; index2++) {
      var val2 = array2[index2];
      if (index1 !== index2 && val1 === val2) {
        return true;
      }
    }
  }
}

function matchItems(array1, array2, index1, index2, context) {
  var value1 = array1[index1];
  var value2 = array2[index2];
  if (value1 === value2) {
    return true;
  }
  if (typeof value1 !== 'object' || typeof value2 !== 'object') {
    return false;
  }
  var objectHash = context.objectHash;
  if (!objectHash) {
    // no way to match objects was provided, try match by position
    return context.matchByPosition && index1 === index2;
  }
  var hash1;
  var hash2;
  if (typeof index1 === 'number') {
    context.hashCache1 = context.hashCache1 || [];
    hash1 = context.hashCache1[index1];
    if (typeof hash1 === 'undefined') {
      context.hashCache1[index1] = hash1 = objectHash(value1, index1);
    }
  } else {
    hash1 = objectHash(value1);
  }
  if (typeof hash1 === 'undefined') {
    return false;
  }
  if (typeof index2 === 'number') {
    context.hashCache2 = context.hashCache2 || [];
    hash2 = context.hashCache2[index2];
    if (typeof hash2 === 'undefined') {
      context.hashCache2[index2] = hash2 = objectHash(value2, index2);
    }
  } else {
    hash2 = objectHash(value2);
  }
  if (typeof hash2 === 'undefined') {
    return false;
  }
  return hash1 === hash2;
}

var diffFilter = function arraysDiffFilter(context) {
  if (!context.leftIsArray) {
    return;
  }

  var matchContext = {
    objectHash: context.options && context.options.objectHash,
    matchByPosition: context.options && context.options.matchByPosition
  };
  var commonHead = 0;
  var commonTail = 0;
  var index;
  var index1;
  var index2;
  var array1 = context.left;
  var array2 = context.right;
  var len1 = array1.length;
  var len2 = array2.length;

  var child;

  if (len1 > 0 && len2 > 0 && !matchContext.objectHash &&
    typeof matchContext.matchByPosition !== 'boolean') {
    matchContext.matchByPosition = !arraysHaveMatchByRef(array1, array2, len1, len2);
  }

  // separate common head
  while (commonHead < len1 && commonHead < len2 &&
    matchItems(array1, array2, commonHead, commonHead, matchContext)) {
    index = commonHead;
    child = new DiffContext(context.left[index], context.right[index]);
    context.push(child, index);
    commonHead++;
  }
  // separate common tail
  while (commonTail + commonHead < len1 && commonTail + commonHead < len2 &&
    matchItems(array1, array2, len1 - 1 - commonTail, len2 - 1 - commonTail, matchContext)) {
    index1 = len1 - 1 - commonTail;
    index2 = len2 - 1 - commonTail;
    child = new DiffContext(context.left[index1], context.right[index2]);
    context.push(child, index2);
    commonTail++;
  }
  var result;
  if (commonHead + commonTail === len1) {
    if (len1 === len2) {
      // arrays are identical
      context.setResult(undefined).exit();
      return;
    }
    // trivial case, a block (1 or more consecutive items) was added
    result = result || {
      _t: 'a'
    };
    for (index = commonHead; index < len2 - commonTail; index++) {
      result[index] = [array2[index]];
    }
    context.setResult(result).exit();
    return;
  }
  if (commonHead + commonTail === len2) {
    // trivial case, a block (1 or more consecutive items) was removed
    result = result || {
      _t: 'a'
    };
    for (index = commonHead; index < len1 - commonTail; index++) {
      result['_' + index] = [array1[index], 0, 0];
    }
    context.setResult(result).exit();
    return;
  }
  // reset hash cache
  delete matchContext.hashCache1;
  delete matchContext.hashCache2;

  // diff is not trivial, find the LCS (Longest Common Subsequence)
  var trimmed1 = array1.slice(commonHead, len1 - commonTail);
  var trimmed2 = array2.slice(commonHead, len2 - commonTail);
  var seq = lcs.get(
    trimmed1, trimmed2,
    matchItems,
    matchContext
  );
  var removedItems = [];
  result = result || {
    _t: 'a'
  };
  for (index = commonHead; index < len1 - commonTail; index++) {
    if (arrayIndexOf(seq.indices1, index - commonHead) < 0) {
      // removed
      result['_' + index] = [array1[index], 0, 0];
      removedItems.push(index);
    }
  }

  var detectMove = true;
  if (context.options && context.options.arrays && context.options.arrays.detectMove === false) {
    detectMove = false;
  }
  var includeValueOnMove = false;
  if (context.options && context.options.arrays && context.options.arrays.includeValueOnMove) {
    includeValueOnMove = true;
  }

  var removedItemsLength = removedItems.length;
  for (index = commonHead; index < len2 - commonTail; index++) {
    var indexOnArray2 = arrayIndexOf(seq.indices2, index - commonHead);
    if (indexOnArray2 < 0) {
      // added, try to match with a removed item and register as position move
      var isMove = false;
      if (detectMove && removedItemsLength > 0) {
        for (var removeItemIndex1 = 0; removeItemIndex1 < removedItemsLength; removeItemIndex1++) {
          index1 = removedItems[removeItemIndex1];
          if (matchItems(trimmed1, trimmed2, index1 - commonHead,
            index - commonHead, matchContext)) {
            // store position move as: [originalValue, newPosition, ARRAY_MOVE]
            result['_' + index1].splice(1, 2, index, ARRAY_MOVE);
            if (!includeValueOnMove) {
              // don't include moved value on diff, to save bytes
              result['_' + index1][0] = '';
            }

            index2 = index;
            child = new DiffContext(context.left[index1], context.right[index2]);
            context.push(child, index2);
            removedItems.splice(removeItemIndex1, 1);
            isMove = true;
            break;
          }
        }
      }
      if (!isMove) {
        // added
        result[index] = [array2[index]];
      }
    } else {
      // match, do inner diff
      index1 = seq.indices1[indexOnArray2] + commonHead;
      index2 = seq.indices2[indexOnArray2] + commonHead;
      child = new DiffContext(context.left[index1], context.right[index2]);
      context.push(child, index2);
    }
  }

  context.setResult(result).exit();

};
diffFilter.filterName = 'arrays';

var compare = {
  numerically: function(a, b) {
    return a - b;
  },
  numericallyBy: function(name) {
    return function(a, b) {
      return a[name] - b[name];
    };
  }
};

var patchFilter = function nestedPatchFilter(context) {
  if (!context.nested) {
    return;
  }
  if (context.delta._t !== 'a') {
    return;
  }
  var index, index1;

  var delta = context.delta;
  var array = context.left;

  // first, separate removals, insertions and modifications
  var toRemove = [];
  var toInsert = [];
  var toModify = [];
  for (index in delta) {
    if (index !== '_t') {
      if (index[0] === '_') {
        // removed item from original array
        if (delta[index][2] === 0 || delta[index][2] === ARRAY_MOVE) {
          toRemove.push(parseInt(index.slice(1), 10));
        } else {
          throw new Error('only removal or move can be applied at original array indices' +
            ', invalid diff type: ' + delta[index][2]);
        }
      } else {
        if (delta[index].length === 1) {
          // added item at new array
          toInsert.push({
            index: parseInt(index, 10),
            value: delta[index][0]
          });
        } else {
          // modified item at new array
          toModify.push({
            index: parseInt(index, 10),
            delta: delta[index]
          });
        }
      }
    }
  }

  // remove items, in reverse order to avoid sawing our own floor
  toRemove = toRemove.sort(compare.numerically);
  for (index = toRemove.length - 1; index >= 0; index--) {
    index1 = toRemove[index];
    var indexDiff = delta['_' + index1];
    var removedValue = array.splice(index1, 1)[0];
    if (indexDiff[2] === ARRAY_MOVE) {
      // reinsert later
      toInsert.push({
        index: indexDiff[1],
        value: removedValue
      });
    }
  }

  // insert items, in reverse order to avoid moving our own floor
  toInsert = toInsert.sort(compare.numericallyBy('index'));
  var toInsertLength = toInsert.length;
  for (index = 0; index < toInsertLength; index++) {
    var insertion = toInsert[index];
    array.splice(insertion.index, 0, insertion.value);
  }

  // apply modifications
  var toModifyLength = toModify.length;
  var child;
  if (toModifyLength > 0) {
    for (index = 0; index < toModifyLength; index++) {
      var modification = toModify[index];
      child = new PatchContext(context.left[modification.index], modification.delta);
      context.push(child, modification.index);
    }
  }

  if (!context.children) {
    context.setResult(context.left).exit();
    return;
  }
  context.exit();
};
patchFilter.filterName = 'arrays';

var collectChildrenPatchFilter = function collectChildrenPatchFilter(context) {
  if (!context || !context.children) {
    return;
  }
  if (context.delta._t !== 'a') {
    return;
  }
  var length = context.children.length;
  var child;
  for (var index = 0; index < length; index++) {
    child = context.children[index];
    context.left[child.childName] = child.result;
  }
  context.setResult(context.left).exit();
};
collectChildrenPatchFilter.filterName = 'arraysCollectChildren';

var reverseFilter = function arraysReverseFilter(context) {
  if (!context.nested) {
    if (context.delta[2] === ARRAY_MOVE) {
      context.newName = '_' + context.delta[1];
      context.setResult([context.delta[0], parseInt(context.childName.substr(1), 10), ARRAY_MOVE]).exit();
    }
    return;
  }
  if (context.delta._t !== 'a') {
    return;
  }
  var name, child;
  for (name in context.delta) {
    if (name === '_t') {
      continue;
    }
    child = new ReverseContext(context.delta[name]);
    context.push(child, name);
  }
  context.exit();
};
reverseFilter.filterName = 'arrays';

var reverseArrayDeltaIndex = function(delta, index, itemDelta) {
  if (typeof index === 'string' && index[0] === '_') {
    return parseInt(index.substr(1), 10);
  } else if (isArray(itemDelta) && itemDelta[2] === 0) {
    return '_' + index;
  }

  var reverseIndex = +index;
  for (var deltaIndex in delta) {
    var deltaItem = delta[deltaIndex];
    if (isArray(deltaItem)) {
      if (deltaItem[2] === ARRAY_MOVE) {
        var moveFromIndex = parseInt(deltaIndex.substr(1), 10);
        var moveToIndex = deltaItem[1];
        if (moveToIndex === +index) {
          return moveFromIndex;
        }
        if (moveFromIndex <= reverseIndex && moveToIndex > reverseIndex) {
          reverseIndex++;
        } else if (moveFromIndex >= reverseIndex && moveToIndex < reverseIndex) {
          reverseIndex--;
        }
      } else if (deltaItem[2] === 0) {
        var deleteIndex = parseInt(deltaIndex.substr(1), 10);
        if (deleteIndex <= reverseIndex) {
          reverseIndex++;
        }
      } else if (deltaItem.length === 1 && deltaIndex <= reverseIndex) {
        reverseIndex--;
      }
    }
  }

  return reverseIndex;
};

var collectChildrenReverseFilter = function collectChildrenReverseFilter(context) {
  if (!context || !context.children) {
    return;
  }
  if (context.delta._t !== 'a') {
    return;
  }
  var length = context.children.length;
  var child;
  var delta = {
    _t: 'a'
  };

  for (var index = 0; index < length; index++) {
    child = context.children[index];
    var name = child.newName;
    if (typeof name === 'undefined') {
      name = reverseArrayDeltaIndex(context.delta, child.childName, child.result);
    }
    if (delta[name] !== child.result) {
      delta[name] = child.result;
    }
  }
  context.setResult(delta).exit();
};
collectChildrenReverseFilter.filterName = 'arraysCollectChildren';

exports.diffFilter = diffFilter;
exports.patchFilter = patchFilter;
exports.collectChildrenPatchFilter = collectChildrenPatchFilter;
exports.reverseFilter = reverseFilter;
exports.collectChildrenReverseFilter = collectChildrenReverseFilter;

},{"../contexts/diff":5,"../contexts/patch":6,"../contexts/reverse":7,"./lcs":13}],12:[function(require,module,exports){
var diffFilter = function datesDiffFilter(context) {
  if (context.left instanceof Date) {
    if (context.right instanceof Date) {
      if (context.left.getTime() !== context.right.getTime()) {
        context.setResult([context.left, context.right]);
      } else {
        context.setResult(undefined);
      }
    } else {
      context.setResult([context.left, context.right]);
    }
    context.exit();
  } else if (context.right instanceof Date) {
    context.setResult([context.left, context.right]).exit();
  }
};
diffFilter.filterName = 'dates';

exports.diffFilter = diffFilter;

},{}],13:[function(require,module,exports){
/*

LCS implementation that supports arrays or strings

reference: http://en.wikipedia.org/wiki/Longest_common_subsequence_problem

*/

var defaultMatch = function(array1, array2, index1, index2) {
  return array1[index1] === array2[index2];
};

var lengthMatrix = function(array1, array2, match, context) {
  var len1 = array1.length;
  var len2 = array2.length;
  var x, y;

  // initialize empty matrix of len1+1 x len2+1
  var matrix = [len1 + 1];
  for (x = 0; x < len1 + 1; x++) {
    matrix[x] = [len2 + 1];
    for (y = 0; y < len2 + 1; y++) {
      matrix[x][y] = 0;
    }
  }
  matrix.match = match;
  // save sequence lengths for each coordinate
  for (x = 1; x < len1 + 1; x++) {
    for (y = 1; y < len2 + 1; y++) {
      if (match(array1, array2, x - 1, y - 1, context)) {
        matrix[x][y] = matrix[x - 1][y - 1] + 1;
      } else {
        matrix[x][y] = Math.max(matrix[x - 1][y], matrix[x][y - 1]);
      }
    }
  }
  return matrix;
};

var backtrack = function(matrix, array1, array2, index1, index2, context) {
  if (index1 === 0 || index2 === 0) {
    return {
      sequence: [],
      indices1: [],
      indices2: []
    };
  }

  if (matrix.match(array1, array2, index1 - 1, index2 - 1, context)) {
    var subsequence = backtrack(matrix, array1, array2, index1 - 1, index2 - 1, context);
    subsequence.sequence.push(array1[index1 - 1]);
    subsequence.indices1.push(index1 - 1);
    subsequence.indices2.push(index2 - 1);
    return subsequence;
  }

  if (matrix[index1][index2 - 1] > matrix[index1 - 1][index2]) {
    return backtrack(matrix, array1, array2, index1, index2 - 1, context);
  } else {
    return backtrack(matrix, array1, array2, index1 - 1, index2, context);
  }
};

var get = function(array1, array2, match, context) {
  context = context || {};
  var matrix = lengthMatrix(array1, array2, match || defaultMatch, context);
  var result = backtrack(matrix, array1, array2, array1.length, array2.length, context);
  if (typeof array1 === 'string' && typeof array2 === 'string') {
    result.sequence = result.sequence.join('');
  }
  return result;
};

exports.get = get;

},{}],14:[function(require,module,exports){
var DiffContext = require('../contexts/diff').DiffContext;
var PatchContext = require('../contexts/patch').PatchContext;
var ReverseContext = require('../contexts/reverse').ReverseContext;

var collectChildrenDiffFilter = function collectChildrenDiffFilter(context) {
  if (!context || !context.children) {
    return;
  }
  var length = context.children.length;
  var child;
  var result = context.result;
  for (var index = 0; index < length; index++) {
    child = context.children[index];
    if (typeof child.result === 'undefined') {
      continue;
    }
    result = result || {};
    result[child.childName] = child.result;
  }
  if (result && context.leftIsArray) {
    result._t = 'a';
  }
  context.setResult(result).exit();
};
collectChildrenDiffFilter.filterName = 'collectChildren';

var objectsDiffFilter = function objectsDiffFilter(context) {
  if (context.leftIsArray || context.leftType !== 'object') {
    return;
  }

  var name, child, propertyFilter = context.options.propertyFilter;
  for (name in context.left) {
    if (!Object.prototype.hasOwnProperty.call(context.left, name)) {
      continue;
    }
    if (propertyFilter && !propertyFilter(name, context)) {
      continue;
    }
    child = new DiffContext(context.left[name], context.right[name]);
    context.push(child, name);
  }
  for (name in context.right) {
    if (!Object.prototype.hasOwnProperty.call(context.right, name)) {
      continue;
    }
    if (propertyFilter && !propertyFilter(name, context)) {
      continue;
    }
    if (typeof context.left[name] === 'undefined') {
      child = new DiffContext(undefined, context.right[name]);
      context.push(child, name);
    }
  }

  if (!context.children || context.children.length === 0) {
    context.setResult(undefined).exit();
    return;
  }
  context.exit();
};
objectsDiffFilter.filterName = 'objects';

var patchFilter = function nestedPatchFilter(context) {
  if (!context.nested) {
    return;
  }
  if (context.delta._t) {
    return;
  }
  var name, child;
  for (name in context.delta) {
    child = new PatchContext(context.left[name], context.delta[name]);
    context.push(child, name);
  }
  context.exit();
};
patchFilter.filterName = 'objects';

var collectChildrenPatchFilter = function collectChildrenPatchFilter(context) {
  if (!context || !context.children) {
    return;
  }
  if (context.delta._t) {
    return;
  }
  var length = context.children.length;
  var child;
  for (var index = 0; index < length; index++) {
    child = context.children[index];
    if (Object.prototype.hasOwnProperty.call(context.left, child.childName) && child.result === undefined) {
      delete context.left[child.childName];
    } else if (context.left[child.childName] !== child.result) {
      context.left[child.childName] = child.result;
    }
  }
  context.setResult(context.left).exit();
};
collectChildrenPatchFilter.filterName = 'collectChildren';

var reverseFilter = function nestedReverseFilter(context) {
  if (!context.nested) {
    return;
  }
  if (context.delta._t) {
    return;
  }
  var name, child;
  for (name in context.delta) {
    child = new ReverseContext(context.delta[name]);
    context.push(child, name);
  }
  context.exit();
};
reverseFilter.filterName = 'objects';

var collectChildrenReverseFilter = function collectChildrenReverseFilter(context) {
  if (!context || !context.children) {
    return;
  }
  if (context.delta._t) {
    return;
  }
  var length = context.children.length;
  var child;
  var delta = {};
  for (var index = 0; index < length; index++) {
    child = context.children[index];
    if (delta[child.childName] !== child.result) {
      delta[child.childName] = child.result;
    }
  }
  context.setResult(delta).exit();
};
collectChildrenReverseFilter.filterName = 'collectChildren';

exports.collectChildrenDiffFilter = collectChildrenDiffFilter;
exports.objectsDiffFilter = objectsDiffFilter;
exports.patchFilter = patchFilter;
exports.collectChildrenPatchFilter = collectChildrenPatchFilter;
exports.reverseFilter = reverseFilter;
exports.collectChildrenReverseFilter = collectChildrenReverseFilter;

},{"../contexts/diff":5,"../contexts/patch":6,"../contexts/reverse":7}],15:[function(require,module,exports){
/* global diff_match_patch */
var TEXT_DIFF = 2;
var DEFAULT_MIN_LENGTH = 60;
var cachedDiffPatch = null;

var getDiffMatchPatch = function(required) {
  /*jshint camelcase: false */

  if (!cachedDiffPatch) {
    var instance;
    if (typeof diff_match_patch !== 'undefined') {
      // already loaded, probably a browser
      instance = typeof diff_match_patch === 'function' ?
        new diff_match_patch() : new diff_match_patch.diff_match_patch();
    } else if (typeof require === 'function') {
      try {
        var dmpModuleName = 'diff_match_patch_uncompressed';
        var dmp = require('../../public/external/' + dmpModuleName);
        instance = new dmp.diff_match_patch();
      } catch (err) {
        instance = null;
      }
    }
    if (!instance) {
      if (!required) {
        return null;
      }
      var error = new Error('text diff_match_patch library not found');
      error.diff_match_patch_not_found = true;
      throw error;
    }
    cachedDiffPatch = {
      diff: function(txt1, txt2) {
        return instance.patch_toText(instance.patch_make(txt1, txt2));
      },
      patch: function(txt1, patch) {
        var results = instance.patch_apply(instance.patch_fromText(patch), txt1);
        for (var i = 0; i < results[1].length; i++) {
          if (!results[1][i]) {
            var error = new Error('text patch failed');
            error.textPatchFailed = true;
          }
        }
        return results[0];
      }
    };
  }
  return cachedDiffPatch;
};

var diffFilter = function textsDiffFilter(context) {
  if (context.leftType !== 'string') {
    return;
  }
  var minLength = (context.options && context.options.textDiff &&
    context.options.textDiff.minLength) || DEFAULT_MIN_LENGTH;
  if (context.left.length < minLength ||
    context.right.length < minLength) {
    context.setResult([context.left, context.right]).exit();
    return;
  }
  // large text, try to use a text-diff algorithm
  var diffMatchPatch = getDiffMatchPatch();
  if (!diffMatchPatch) {
    // diff-match-patch library not available, fallback to regular string replace
    context.setResult([context.left, context.right]).exit();
    return;
  }
  var diff = diffMatchPatch.diff;
  context.setResult([diff(context.left, context.right), 0, TEXT_DIFF]).exit();
};
diffFilter.filterName = 'texts';

var patchFilter = function textsPatchFilter(context) {
  if (context.nested) {
    return;
  }
  if (context.delta[2] !== TEXT_DIFF) {
    return;
  }

  // text-diff, use a text-patch algorithm
  var patch = getDiffMatchPatch(true).patch;
  context.setResult(patch(context.left, context.delta[0])).exit();
};
patchFilter.filterName = 'texts';

var textDeltaReverse = function(delta) {
  var i, l, lines, line, lineTmp, header = null,
    headerRegex = /^@@ +\-(\d+),(\d+) +\+(\d+),(\d+) +@@$/,
    lineHeader, lineAdd, lineRemove;
  lines = delta.split('\n');
  for (i = 0, l = lines.length; i < l; i++) {
    line = lines[i];
    var lineStart = line.slice(0, 1);
    if (lineStart === '@') {
      header = headerRegex.exec(line);
      lineHeader = i;
      lineAdd = null;
      lineRemove = null;

      // fix header
      lines[lineHeader] = '@@ -' + header[3] + ',' + header[4] + ' +' + header[1] + ',' + header[2] + ' @@';
    } else if (lineStart === '+') {
      lineAdd = i;
      lines[i] = '-' + lines[i].slice(1);
      if (lines[i - 1].slice(0, 1) === '+') {
        // swap lines to keep default order (-+)
        lineTmp = lines[i];
        lines[i] = lines[i - 1];
        lines[i - 1] = lineTmp;
      }
    } else if (lineStart === '-') {
      lineRemove = i;
      lines[i] = '+' + lines[i].slice(1);
    }
  }
  return lines.join('\n');
};

var reverseFilter = function textsReverseFilter(context) {
  if (context.nested) {
    return;
  }
  if (context.delta[2] !== TEXT_DIFF) {
    return;
  }

  // text-diff, use a text-diff algorithm
  context.setResult([textDeltaReverse(context.delta[0]), 0, TEXT_DIFF]).exit();
};
reverseFilter.filterName = 'texts';

exports.diffFilter = diffFilter;
exports.patchFilter = patchFilter;
exports.reverseFilter = reverseFilter;

},{}],16:[function(require,module,exports){
var isArray = (typeof Array.isArray === 'function') ?
  // use native function
  Array.isArray :
  // use instanceof operator
  function(a) {
    return a instanceof Array;
  };

var diffFilter = function trivialMatchesDiffFilter(context) {
  if (context.left === context.right) {
    context.setResult(undefined).exit();
    return;
  }
  if (typeof context.left === 'undefined') {
    if (typeof context.right === 'function') {
      throw new Error('functions are not supported');
    }
    context.setResult([context.right]).exit();
    return;
  }
  if (typeof context.right === 'undefined') {
    context.setResult([context.left, 0, 0]).exit();
    return;
  }
  if (typeof context.left === 'function' || typeof context.right === 'function') {
    throw new Error('functions are not supported');
  }
  context.leftType = context.left === null ? 'null' : typeof context.left;
  context.rightType = context.right === null ? 'null' : typeof context.right;
  if (context.leftType !== context.rightType) {
    context.setResult([context.left, context.right]).exit();
    return;
  }
  if (context.leftType === 'boolean' || context.leftType === 'number') {
    context.setResult([context.left, context.right]).exit();
    return;
  }
  if (context.leftType === 'object') {
    context.leftIsArray = isArray(context.left);
  }
  if (context.rightType === 'object') {
    context.rightIsArray = isArray(context.right);
  }
  if (context.leftIsArray !== context.rightIsArray) {
    context.setResult([context.left, context.right]).exit();
    return;
  }

  if (context.left instanceof RegExp) {
    if (context.right instanceof RegExp) {
      context.setResult([context.left.toString(), context.right.toString()]).exit();
    } else {
      context.setResult([context.left, context.right]).exit();
      return;
    }
  }
};
diffFilter.filterName = 'trivial';

var patchFilter = function trivialMatchesPatchFilter(context) {
  if (typeof context.delta === 'undefined') {
    context.setResult(context.left).exit();
    return;
  }
  context.nested = !isArray(context.delta);
  if (context.nested) {
    return;
  }
  if (context.delta.length === 1) {
    context.setResult(context.delta[0]).exit();
    return;
  }
  if (context.delta.length === 2) {
    if (context.left instanceof RegExp) {
      var regexArgs = /^\/(.*)\/([gimyu]+)$/.exec(context.delta[1]);
      if (regexArgs) {
        context.setResult(new RegExp(regexArgs[1], regexArgs[2])).exit();
        return;
      }
    }
    context.setResult(context.delta[1]).exit();
    return;
  }
  if (context.delta.length === 3 && context.delta[2] === 0) {
    context.setResult(undefined).exit();
    return;
  }
};
patchFilter.filterName = 'trivial';

var reverseFilter = function trivialReferseFilter(context) {
  if (typeof context.delta === 'undefined') {
    context.setResult(context.delta).exit();
    return;
  }
  context.nested = !isArray(context.delta);
  if (context.nested) {
    return;
  }
  if (context.delta.length === 1) {
    context.setResult([context.delta[0], 0, 0]).exit();
    return;
  }
  if (context.delta.length === 2) {
    context.setResult([context.delta[1], context.delta[0]]).exit();
    return;
  }
  if (context.delta.length === 3 && context.delta[2] === 0) {
    context.setResult([context.delta[0]]).exit();
    return;
  }
};
reverseFilter.filterName = 'trivial';

exports.diffFilter = diffFilter;
exports.patchFilter = patchFilter;
exports.reverseFilter = reverseFilter;

},{}],17:[function(require,module,exports){

var environment = require('./environment');

var DiffPatcher = require('./diffpatcher').DiffPatcher;
exports.DiffPatcher = DiffPatcher;

exports.create = function(options){
  return new DiffPatcher(options);
};

exports.dateReviver = require('./date-reviver');

var defaultInstance;

exports.diff = function() {
  if (!defaultInstance) {
    defaultInstance = new DiffPatcher();
  }
  return defaultInstance.diff.apply(defaultInstance, arguments);
};

exports.patch = function() {
  if (!defaultInstance) {
    defaultInstance = new DiffPatcher();
  }
  return defaultInstance.patch.apply(defaultInstance, arguments);
};

exports.unpatch = function() {
  if (!defaultInstance) {
    defaultInstance = new DiffPatcher();
  }
  return defaultInstance.unpatch.apply(defaultInstance, arguments);
};

exports.reverse = function() {
  if (!defaultInstance) {
    defaultInstance = new DiffPatcher();
  }
  return defaultInstance.reverse.apply(defaultInstance, arguments);
};

exports.clone = function() {
  if (!defaultInstance) {
    defaultInstance = new DiffPatcher();
  }
  return defaultInstance.clone.apply(defaultInstance, arguments);
};


if (environment.isBrowser) {
  exports.homepage = 'https://github.com/benjamine/jsondiffpatch';
  exports.version = '0.2.3';
} else {
  var packageInfoModuleName = '../package.json';
  var packageInfo = require(packageInfoModuleName);
  exports.homepage = packageInfo.homepage;
  exports.version = packageInfo.version;

  var formatterModuleName = './formatters';
  var formatters = require(formatterModuleName);
  exports.formatters = formatters;
  // shortcut for console
  exports.console = formatters.console;
}

},{"./date-reviver":8,"./diffpatcher":9,"./environment":10}],18:[function(require,module,exports){
var Pipe = function Pipe(name) {
  this.name = name;
  this.filters = [];
};

Pipe.prototype.process = function(input) {
  if (!this.processor) {
    throw new Error('add this pipe to a processor before using it');
  }
  var debug = this.debug;
  var length = this.filters.length;
  var context = input;
  for (var index = 0; index < length; index++) {
    var filter = this.filters[index];
    if (debug) {
      this.log('filter: ' + filter.filterName);
    }
    filter(context);
    if (typeof context === 'object' && context.exiting) {
      context.exiting = false;
      break;
    }
  }
  if (!context.next && this.resultCheck) {
    this.resultCheck(context);
  }
};

Pipe.prototype.log = function(msg) {
  console.log('[jsondiffpatch] ' + this.name + ' pipe, ' + msg);
};

Pipe.prototype.append = function() {
  this.filters.push.apply(this.filters, arguments);
  return this;
};

Pipe.prototype.prepend = function() {
  this.filters.unshift.apply(this.filters, arguments);
  return this;
};

Pipe.prototype.indexOf = function(filterName) {
  if (!filterName) {
    throw new Error('a filter name is required');
  }
  for (var index = 0; index < this.filters.length; index++) {
    var filter = this.filters[index];
    if (filter.filterName === filterName) {
      return index;
    }
  }
  throw new Error('filter not found: ' + filterName);
};

Pipe.prototype.list = function() {
  var names = [];
  for (var index = 0; index < this.filters.length; index++) {
    var filter = this.filters[index];
    names.push(filter.filterName);
  }
  return names;
};

Pipe.prototype.after = function(filterName) {
  var index = this.indexOf(filterName);
  var params = Array.prototype.slice.call(arguments, 1);
  if (!params.length) {
    throw new Error('a filter is required');
  }
  params.unshift(index + 1, 0);
  Array.prototype.splice.apply(this.filters, params);
  return this;
};

Pipe.prototype.before = function(filterName) {
  var index = this.indexOf(filterName);
  var params = Array.prototype.slice.call(arguments, 1);
  if (!params.length) {
    throw new Error('a filter is required');
  }
  params.unshift(index, 0);
  Array.prototype.splice.apply(this.filters, params);
  return this;
};

Pipe.prototype.clear = function() {
  this.filters.length = 0;
  return this;
};

Pipe.prototype.shouldHaveResult = function(should) {
  if (should === false) {
    this.resultCheck = null;
    return;
  }
  if (this.resultCheck) {
    return;
  }
  var pipe = this;
  this.resultCheck = function(context) {
    if (!context.hasResult) {
      console.log(context);
      var error = new Error(pipe.name + ' failed');
      error.noResult = true;
      throw error;
    }
  };
  return this;
};

exports.Pipe = Pipe;

},{}],19:[function(require,module,exports){

var Processor = function Processor(options){
  this.selfOptions = options || {};
  this.pipes = {};
};

Processor.prototype.options = function(options) {
  if (options) {
    this.selfOptions = options;
  }
  return this.selfOptions;
};

Processor.prototype.pipe = function(name, pipe) {
  if (typeof name === 'string') {
    if (typeof pipe === 'undefined') {
      return this.pipes[name];
    } else {
      this.pipes[name] = pipe;
    }
  }
  if (name && name.name) {
    pipe = name;
    if (pipe.processor === this) { return pipe; }
    this.pipes[pipe.name] = pipe;
  }
  pipe.processor = this;
  return pipe;
};

Processor.prototype.process = function(input, pipe) {
  var context = input;
  context.options = this.options();
  var nextPipe = pipe || input.pipe || 'default';
  var lastPipe, lastContext;
  while (nextPipe) {
    if (typeof context.nextAfterChildren !== 'undefined') {
      // children processed and coming back to parent
      context.next = context.nextAfterChildren;
      context.nextAfterChildren = null;
    }

    if (typeof nextPipe === 'string') {
      nextPipe = this.pipe(nextPipe);
    }
    nextPipe.process(context);
    lastContext = context;
    lastPipe = nextPipe;
    nextPipe = null;
    if (context) {
      if (context.next) {
        context = context.next;
        nextPipe = lastContext.nextPipe || context.pipe || lastPipe;
      }
    }
  }
  return context.hasResult ? context.result : undefined;
};

exports.Processor = Processor;

},{}]},{},[1])(1)
});
//# sourceMappingURL=data:application/json;base64, 
/**
 * yjs - A framework for real-time p2p shared editing on any data
 * @version v13.0.0-42
 * @license MIT
 */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Y=e()}(this,function(){"use strict";function t(t,e){return e={exports:{}},t(e,e.exports),e.exports}function e(t,e){var n=e._id;if(void 0===n)e._integrate(t);else{if(t.ss.getState(n.user)>n.clock)return;e._integrate(t);var r=t._missingStructs.get(n.user);if(null!=r)for(var i=n.clock,o=i+e._length;i<o;i++){var s=r.get(i);void 0!==s&&(s.forEach(function(e){if(0===--e.missing){var n=e.decoder,r=n.pos,i=e.struct._fromBinary(t,n);n.pos=r,0===i.length&&t._readyToIntegrate.push(e.struct)}}),r.delete(i))}}}function n(t,e,n){for(var r=e.readUint32(),i=0;i<r;i++){var o=e.readVarUint(),s=z(o),a=new s,l=a._fromBinary(t,e),u="  "+a._logString();l.length>0&&(u+=" .. missing: "+l.map(g).join(", ")),n.push(u)}}function r(t,n,r){for(var i=t.readUint32(),o=0;o<i;o++){var s=t.readVarUint(),a=z(s),l=new a,u=t.pos,h=l._fromBinary(r,t);if(0===h.length)for(;null!=l;)e(r,l),l=r._readyToIntegrate.shift();else{var c=new vt(t.uint8arr);c.pos=u;for(var f=new gt(c,h,l),d=r._missingStructs,_=h.length-1;_>=0;_--){var v=h[_];d.has(v.user)||d.set(v.user,new Map);var g=d.get(v.user);g.has(v.clock)||g.set(v.clock,[]);(g=g.get(v.clock)).push(f)}}}}function i(t){for(var e=new Map,n=t.readUint32(),r=0;r<n;r++){var i=t.readVarUint(),o=t.readVarUint();e.set(i,o)}return e}function o(t,e){var n=e.pos,r=0;e.writeUint32(0);var i=!0,o=!1,s=void 0;try{for(var a,l=t.ss.state[Symbol.iterator]();!(i=(a=l.next()).done);i=!0){var u=lt(a.value,2),h=u[0],c=u[1];e.writeVarUint(h),e.writeVarUint(c),r++}}catch(t){o=!0,s=t}finally{try{!i&&l.return&&l.return()}finally{if(o)throw s}}e.setUint32(n,r)}function s(t,e){var n=null,r=void 0,i=void 0,o=0,s=e.pos;e.writeUint32(0),t.ds.iterate(null,null,function(t){var s=t._id.user,a=t._id.clock,l=t.len,u=t.gc;n!==s&&(o++,null!==n&&e.setUint32(i,r),n=s,e.writeVarUint(s),i=e.pos,e.writeUint32(0),r=0),e.writeVarUint(a),e.writeVarUint(l),e.writeUint8(u?1:0),r++}),null!==n&&e.setUint32(i,r),e.setUint32(s,o)}function a(t,e){for(var n=e.readUint32(),r=0;r<n;r++)!function(n){for(var r=e.readVarUint(),i=[],o=e.readUint32(),s=0;s<o;s++){var a=e.readVarUint(),l=e.readVarUint(),u=1===e.readUint8();i.push([a,l,u])}if(o>0){var h=0,c=i[h],f=[];t.ds.iterate(new ct(r,0),new ct(r,Number.MAX_VALUE),function(t){for(;null!=c;){var e=0;if(t._id.clock+t.len<=c[0])break;c[0]<t._id.clock?(e=Math.min(t._id.clock-c[0],c[1]),f.push([r,c[0],e])):(e=t._id.clock+t.len-c[0],c[2]&&!t.gc&&f.push([r,c[0],Math.min(e,c[1])])),c[1]<=e?c=i[++h]:(c[0]=c[0]+e,c[1]=c[1]-e)}});for(var d=f.length-1;d>=0;d--){var _=f[d];p(t,_[0],_[1],_[2])}for(;h<i.length;h++)c=i[h],p(t,r,c[0],c[1])}}()}function l(t,e,n){var r=e.readVarString(),i=e.readVarUint();n.push('  - auth: "'+r+'"'),n.push("  - protocolVersion: "+i);for(var o=[],s=e.readUint32(),a=0;a<s;a++){var l=e.readVarUint(),u=e.readVarUint();o.push("("+l+":"+u+")")}n.push("  == SS: "+o.join(","))}function u(t,e){var n=new pt;n.writeVarString(t.y.room),n.writeVarString("sync step 1"),n.writeVarString(t.authInfo||""),n.writeVarUint(t.protocolVersion),o(t.y,n),t.send(e,n.createBuffer())}function h(t,e,n,r){var i=t.pos;t.writeUint32(0);var o=0,s=!0,a=!1,l=void 0;try{for(var u,h=n.ss.state.keys()[Symbol.iterator]();!(s=(u=h.next()).done);s=!0){var c=u.value,f=r.get(c)||0;c!==Tt&&n.os.iterate(new ct(c,f),new ct(c,Number.MAX_VALUE),function(e){e._toBinary(t),o++})}}catch(t){a=!0,l=t}finally{try{!s&&h.return&&h.return()}finally{if(a)throw l}}t.setUint32(i,o)}function c(t,e,n,r,o){var a=t.readVarUint();a!==n.connector.protocolVersion&&(console.warn("You tried to sync with a Yjs instance that has a different protocol version\n      (You: "+a+", Client: "+a+").\n      "),n.destroy()),e.writeVarString("sync step 2"),e.writeVarString(n.connector.authInfo||""),h(e,t,n,i(t)),s(n,e),n.connector.send(r.uid,e.createBuffer()),r.receivedSyncStep2=!0,"slave"===n.connector.role&&u(n.connector,o)}function f(t,e,r){r.push("     - auth: "+e.readVarString()),r.push("  == OS:"),n(t,e,r),r.push("  == DS:");for(var i=e.readUint32(),o=0;o<i;o++){var s=e.readVarUint();r.push("    User: "+s+": ");for(var a=e.readUint32(),l=0;l<a;l++){var u=e.readVarUint(),h=e.readVarUint(),c=1===e.readUint8();r.push("["+u+", "+h+", "+c+"]")}}}function d(t,e,n,i,o){r(t,e,n),a(n,t),n.connector._setSyncedWith(o)}function _(t){var e=lt(t,2),r=e[0],i=e[1],o=new vt(i);o.readVarString();var s=o.readVarString(),a=[];return a.push("\n === "+s+" ==="),"update"===s?n(r,o,a):"sync step 1"===s?l(r,o,a):"sync step 2"===s?f(r,o,a):a.push("-- Unknown message type - probably an encoding issue!!!"),a.join("\n")}function v(t){var e=new vt(t);return e.readVarString(),e.readVarString()}function g(t){if(null!==t&&null!=t._id&&(t=t._id),null===t)return"()";if(t instanceof ct)return"("+t.user+","+t.clock+")";if(t instanceof Nt)return"("+t.name+","+t.type+")";if(t.constructor===Y)return"y";throw new Error("This is not a valid ID!")}function p(t,e,n,r){var i=t.connector._forwardAppliedStructs,o=t.os.getItemCleanStart(new ct(e,n));if(null!==o){o._deleted||(o._splitAt(t,r),o._delete(t,i));var s=o._length;if(r-=s,n+=s,r>0)for(var a=t.os.findNode(new ct(e,n));null!==a&&r>0&&a.val._id.equals(new ct(e,n));){var l=a.val;l._deleted||(l._splitAt(t,r),l._delete(t,i));var u=l._length;r-=u,n+=u,a=a.next()}}}function y(t,e,n){if(e!==t&&!e._deleted&&!t._transaction.newTypes.has(e)){var r=t._transaction.changedTypes,i=r.get(e);void 0===i&&(i=new Set,r.set(e,i)),i.add(n)}}function m(t,e,n,r){var i=e._id;n._id=new ct(i.user,i.clock+r),n._origin=e,n._left=e,n._right=e._right,null!==n._right&&(n._right._left=n),n._right_origin=e._right_origin,e._right=n,n._parent=e._parent,n._parentSub=e._parentSub,n._deleted=e._deleted;var o=new Set;o.add(e);for(var s=n._right;null!==s&&o.has(s._origin);)s._origin===e&&(s._origin=n),o.add(s),s=s._right;t.os.put(n)}function b(t,e){var n=void 0;do{n=e._right,e._right=null,e._right_origin=null,e._origin=e._left,e._integrate(t),e=n}while(null!==n)}function k(t,e){return e}function w(t){for(;null!==t&&t._deleted;)t=t._right;return t}function S(t,e,n){var r=t.insertDomElementsAfter(e,[n]);return r.length>0?r[0]:e}function E(t){var e=t._yxml;if(e.constructor!==YXmlHook){var n=e._y,r=new Set(Array.prototype.map.call(t.childNodes,function(t){return t._yxml}).filter(function(t){return void 0!==t}));e.forEach(function(t,e){r.has(t)||t._delete(n)});for(var i=t.childNodes,o=i.length,s=null,a=w(e._start),l=0;l<o;l++){var u=i[l],h=u._yxml;if(null!=h){if(!1===h)continue;null!==a?a!==h?(h._parent!==this?u._yxml=null:h._delete(n),s=S(e,s,u)):(s=a,a=w(a._right)):s=S(e,s,u)}else s=S(e,s,u)}}}function O(t,e){this._mutualExclude(function(){t.forEach(function(t){var n=t.target,r=n._dom;if(null!=r)if(n.constructor===YXmlText)n._dom.nodeValue=n.toString();else if(void 0!==t.attributesChanged&&(t.attributesChanged.forEach(function(t){var e=n.getAttribute(t);void 0===e?r.removeAttribute(t):r.setAttribute(t,e)}),t.childListChanged&&n.constructor!==YXmlHook)){var i=r.firstChild;for(n.forEach(function(t){var n=t.getDom(e);if(n.parentNode===r){for(;i!==n;){var o=i;i=i.nextSibling,r.removeChild(o)}i=i.nextSibling}else r.insertBefore(n,i)});null!==i;){var o=i.nextSibling;r.removeChild(i),i=o}}})})}function A(t,e){if(0===e)return["startof",t._id.user,t._id.clock||null,t._id.name||null,t._id.type||null];for(var n=t._start;null!==n;){if(!1===n._deleted){if(n._length>=e)return[n._id.user,n._id.clock+e-1];if(null===n._right)return[n._id.user,n._id.clock+n._length-1];e-=n._length}n=n._right}return null}function U(t,e){if("startof"===e[0]){var n=void 0;return n=null===e[3]?new ct(e[1],e[2]):new Nt(e[3],e[4]),{type:t.os.get(n),offset:0}}var r=0,i=t.os.findNodeWithUpperBound(new ct(e[0],e[1])).val,o=i._parent;if(o._deleted)return null;for(i._deleted||(r=e[1]-i._id.clock+1),i=i._left;null!==i;)i._deleted||(r+=i._length),i=i._left;return{type:o,offset:r}}function B(t,e,n){if(null!==kt&&n){var r=kt.to,i=kt.from,o=kt.fromY,s=kt.toY,a=!1,l=bt.anchorNode,u=bt.anchorOffset,h=bt.focusNode,c=bt.focusOffset;if(null!==i){var f=U(o,i);if(null!==f){var d=f.type.getDom(),_=f.offset;d===l&&_===u||(l=d,u=_,a=!0)}}if(null!==r){var v=U(s,r);if(null!==v){var g=v.type.getDom(),p=v.offset;g===h&&p===c||(h=g,c=p,a=!0)}}a&&bt.setBaseAndExtent(l,u,h,c)}}function x(t,e,n){if(t==e)return t?[[Ot,t]]:[];(n<0||t.length<n)&&(n=null);var r=N(t,e),i=t.substring(0,r);t=t.substring(r),e=e.substring(r),r=L(t,e);var o=t.substring(t.length-r);t=t.substring(0,t.length-r),e=e.substring(0,e.length-r);var s=D(t,e);return i&&s.unshift([Ot,i]),o&&s.push([Ot,o]),P(s),null!=n&&(s=j(s,n)),s=M(s)}function D(t,e){var n;if(!t)return[[Et,e]];if(!e)return[[St,t]];var r=t.length>e.length?t:e,i=t.length>e.length?e:t,o=r.indexOf(i);if(-1!=o)return n=[[Et,r.substring(0,o)],[Ot,i],[Et,r.substring(o+i.length)]],t.length>e.length&&(n[0][0]=n[2][0]=St),n;if(1==i.length)return[[St,t],[Et,e]];var s=V(t,e);if(s){var a=s[0],l=s[1],u=s[2],h=s[3],c=s[4],f=x(a,u),d=x(l,h);return f.concat([[Ot,c]],d)}return I(t,e)}function I(t,e){for(var n=t.length,r=e.length,i=Math.ceil((n+r)/2),o=i,s=2*i,a=new Array(s),l=new Array(s),u=0;u<s;u++)a[u]=-1,l[u]=-1;a[o+1]=0,l[o+1]=0;for(var h=n-r,c=h%2!=0,f=0,d=0,_=0,v=0,g=0;g<i;g++){for(var p=-g+f;p<=g-d;p+=2){var y,m=o+p;y=p==-g||p!=g&&a[m-1]<a[m+1]?a[m+1]:a[m-1]+1;for(var b=y-p;y<n&&b<r&&t.charAt(y)==e.charAt(b);)y++,b++;if(a[m]=y,y>n)d+=2;else if(b>r)f+=2;else if(c){var k=o+h-p;if(k>=0&&k<s&&-1!=l[k]){var w=n-l[k];if(y>=w)return T(t,e,y,b)}}}for(var S=-g+_;S<=g-v;S+=2){var w,k=o+S;w=S==-g||S!=g&&l[k-1]<l[k+1]?l[k+1]:l[k-1]+1;for(var E=w-S;w<n&&E<r&&t.charAt(n-w-1)==e.charAt(r-E-1);)w++,E++;if(l[k]=w,w>n)v+=2;else if(E>r)_+=2;else if(!c){var m=o+h-S;if(m>=0&&m<s&&-1!=a[m]){var y=a[m],b=o+y-m;if(w=n-w,y>=w)return T(t,e,y,b)}}}}return[[St,t],[Et,e]]}function T(t,e,n,r){var i=t.substring(0,n),o=e.substring(0,r),s=t.substring(n),a=e.substring(r),l=x(i,o),u=x(s,a);return l.concat(u)}function N(t,e){if(!t||!e||t.charAt(0)!=e.charAt(0))return 0;for(var n=0,r=Math.min(t.length,e.length),i=r,o=0;n<i;)t.substring(o,i)==e.substring(o,i)?(n=i,o=n):r=i,i=Math.floor((r-n)/2+n);return i}function L(t,e){if(!t||!e||t.charAt(t.length-1)!=e.charAt(e.length-1))return 0;for(var n=0,r=Math.min(t.length,e.length),i=r,o=0;n<i;)t.substring(t.length-i,t.length-o)==e.substring(e.length-i,e.length-o)?(n=i,o=n):r=i,i=Math.floor((r-n)/2+n);return i}function V(t,e){function n(t,e,n){for(var r,i,o,s,a=t.substring(n,n+Math.floor(t.length/4)),l=-1,u="";-1!=(l=e.indexOf(a,l+1));){var h=N(t.substring(n),e.substring(l)),c=L(t.substring(0,n),e.substring(0,l));u.length<c+h&&(u=e.substring(l-c,l)+e.substring(l,l+h),r=t.substring(0,n-c),i=t.substring(n+h),o=e.substring(0,l-c),s=e.substring(l+h))}return 2*u.length>=t.length?[r,i,o,s,u]:null}var r=t.length>e.length?t:e,i=t.length>e.length?e:t;if(r.length<4||2*i.length<r.length)return null;var o,s=n(r,i,Math.ceil(r.length/4)),a=n(r,i,Math.ceil(r.length/2));if(!s&&!a)return null;o=a?s&&s[4].length>a[4].length?s:a:s;var l,u,h,c;return t.length>e.length?(l=o[0],u=o[1],h=o[2],c=o[3]):(h=o[0],c=o[1],l=o[2],u=o[3]),[l,u,h,c,o[4]]}function P(t){t.push([Ot,""]);for(var e,n=0,r=0,i=0,o="",s="";n<t.length;)switch(t[n][0]){case Et:i++,s+=t[n][1],n++;break;case St:r++,o+=t[n][1],n++;break;case Ot:r+i>1?(0!==r&&0!==i&&(e=N(s,o),0!==e&&(n-r-i>0&&t[n-r-i-1][0]==Ot?t[n-r-i-1][1]+=s.substring(0,e):(t.splice(0,0,[Ot,s.substring(0,e)]),n++),s=s.substring(e),o=o.substring(e)),0!==(e=L(s,o))&&(t[n][1]=s.substring(s.length-e)+t[n][1],s=s.substring(0,s.length-e),o=o.substring(0,o.length-e))),0===r?t.splice(n-i,r+i,[Et,s]):0===i?t.splice(n-r,r+i,[St,o]):t.splice(n-r-i,r+i,[St,o],[Et,s]),n=n-r-i+(r?1:0)+(i?1:0)+1):0!==n&&t[n-1][0]==Ot?(t[n-1][1]+=t[n][1],t.splice(n,1)):n++,i=0,r=0,o="",s=""}""===t[t.length-1][1]&&t.pop();var a=!1;for(n=1;n<t.length-1;)t[n-1][0]==Ot&&t[n+1][0]==Ot&&(t[n][1].substring(t[n][1].length-t[n-1][1].length)==t[n-1][1]?(t[n][1]=t[n-1][1]+t[n][1].substring(0,t[n][1].length-t[n-1][1].length),t[n+1][1]=t[n-1][1]+t[n+1][1],t.splice(n-1,1),a=!0):t[n][1].substring(0,t[n+1][1].length)==t[n+1][1]&&(t[n-1][1]+=t[n+1][1],t[n][1]=t[n][1].substring(t[n+1][1].length)+t[n+1][1],t.splice(n+1,1),a=!0)),n++;a&&P(t)}function C(t,e){if(0===e)return[Ot,t];for(var n=0,r=0;r<t.length;r++){var i=t[r];if(i[0]===St||i[0]===Ot){var o=n+i[1].length;if(e===o)return[r+1,t];if(e<o){t=t.slice();var s=e-n,a=[i[0],i[1].slice(0,s)],l=[i[0],i[1].slice(s)];return t.splice(r,1,a,l),[r+1,t]}n=o}}throw new Error("cursor_pos is out of bounds!")}function j(t,e){var n=C(t,e),r=n[1],i=n[0],o=r[i],s=r[i+1];if(null==o)return t;if(o[0]!==Ot)return t;if(null!=s&&o[1]+s[1]===s[1]+o[1])return r.splice(i,2,s,o),F(r,i,2);if(null!=s&&0===s[1].indexOf(o[1])){r.splice(i,2,[s[0],o[1]],[0,o[1]]);var a=s[1].slice(o[1].length);return a.length>0&&r.splice(i+2,0,[s[0],a]),F(r,i,3)}return t}function M(t){for(var e=!1,n=function(t){return t.charCodeAt(0)>=56320&&t.charCodeAt(0)<=57343},r=2;r<t.length;r+=1)t[r-2][0]===Ot&&function(t){return t.charCodeAt(t.length-1)>=55296&&t.charCodeAt(t.length-1)<=56319}(t[r-2][1])&&t[r-1][0]===St&&n(t[r-1][1])&&t[r][0]===Et&&n(t[r][1])&&(e=!0,t[r-1][1]=t[r-2][1].slice(-1)+t[r-1][1],t[r][1]=t[r-2][1].slice(-1)+t[r][1],t[r-2][1]=t[r-2][1].slice(0,-1));if(!e)return t;for(var i=[],r=0;r<t.length;r+=1)t[r][1].length>0&&i.push(t[r]);return i}function F(t,e,n){for(var r=e+n-1;r>=0&&r>=e-1;r--)if(r+1<t.length){var i=t[r],o=t[r+1];i[0]===o[1]&&t.splice(r,2,[i[0],i[1]+o[1]])}return t}function R(t,e,n){var r=[];return e.forEach(function(e){if(null!=e._yxml&&!1!==e._yxml&&e._yxml._unbindFromDom(),null!==t._domFilter(e.nodeName,new Map)){var i=void 0,o=e._yjsHook||(null!=e.dataset?e.dataset.yjsHook:void 0);if(void 0!==o)i=new YXmlHook(o,e);else if(e.nodeType===e.TEXT_NODE)i=new YXmlText(e);else{if(e.nodeType!==e.ELEMENT_NODE)throw new Error("Unsupported node!");i=new YXmlFragment._YXmlElement(e,t._domFilter,n)}r.push(i)}else e._yxml=!1}),r}function H(t,e){xt[t]=e}function J(t){var e=xt[t];if(void 0===e)throw new Error('The hook "'+t+'" is not specified! You must not access this hook!');return e}function W(t,e){Dt.set(t,e),It.set(e,t)}function z(t){return Dt.get(t)}function X(t){return It.get(t)}function q(){if("undefined"!=typeof crypto&&null!=crypto.getRandomValue){var t=new Uint32Array(1);return crypto.getRandomValues(t),t[0]}if("undefined"!=typeof crypto&&null!=crypto.randomBytes){var e=crypto.randomBytes(4);return new Uint32Array(e.buffer)[0]}return Math.ceil(4294967295*Math.random())}function $(t,e,n){for(;e!==t;){if(e===n)return!0;e=e._parent}return!1}function Q(t,e,n){var r=!1;return t.transact(function(){for(;!r&&n.length>0;){var i=n.pop();t.os.getItemCleanStart(i.fromState),t.os.getItemCleanEnd(i.toState),t.os.iterate(i.fromState,i.toState,function(n){!n._deleted&&$(t,n,e)&&(r=!0,n._delete(t))});var o=!0,s=!1,a=void 0;try{for(var l,u=i.deletedStructs[Symbol.iterator]();!(o=(l=u.next()).done);o=!0){var h=l.value;$(t,h,e)&&h._parent!==t&&!h._parent._deleted&&(h._parent._id.user!==t.userID||h._parent._id.clock<i.fromState.clock||h._parent._id.clock>i.fromState.clock)&&(r=!0,h=h._copy(i.deletedStructs),h._integrate(t))}}catch(t){s=!0,a=t}finally{try{!o&&u.return&&u.return()}finally{if(s)throw a}}}}),r}function Z(t){if(t=String(t),!(t.length>100)){var e=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(t);if(e){var n=parseFloat(e[1]);switch((e[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return n*Ht;case"days":case"day":case"d":return n*Yt;case"hours":case"hour":case"hrs":case"hr":case"h":return n*Rt;case"minutes":case"minute":case"mins":case"min":case"m":return n*Ft;case"seconds":case"second":case"secs":case"sec":case"s":return n*Mt;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function G(t){return t>=Yt?Math.round(t/Yt)+"d":t>=Rt?Math.round(t/Rt)+"h":t>=Ft?Math.round(t/Ft)+"m":t>=Mt?Math.round(t/Mt)+"s":t+"ms"}function K(t){return tt(t,Yt,"day")||tt(t,Rt,"hour")||tt(t,Ft,"minute")||tt(t,Mt,"second")||t+" ms"}function tt(t,e,n){if(!(t<e))return t<1.5*e?Math.floor(t/e)+" "+n:Math.ceil(t/e)+" "+n+"s"}function et(Y){var t=function(){function t(e,n){rt(this,t),this.y=e,this.opts=n,this.saveOperationsBuffer=[],this.log=Y.debug("y:persistence")}return it(t,[{key:"saveToMessageQueue",value:function(t){this.log("Room %s: Save message to message queue",this.y.options.connector.room)}},{key:"saveOperations",value:function(t){t=t.map(function(t){return Y.Struct[t.struct].encode(t)}),0===this.saveOperationsBuffer.length?this.saveOperationsBuffer=t:this.saveOperationsBuffer=this.saveOperationsBuffer.concat(t)}}]),t}();Y.AbstractPersistence=t}var nt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},rt=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},it=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),ot=function t(e,n,r){null===e&&(e=Function.prototype);var i=Object.getOwnPropertyDescriptor(e,n);if(void 0===i){var o=Object.getPrototypeOf(e);return null===o?void 0:t(o,n,r)}if("value"in i)return i.value;var s=i.get;if(void 0!==s)return s.call(r)},st=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},at=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},lt=function(){function t(t,e){var n=[],r=!0,i=!1,o=void 0;try{for(var s,a=t[Symbol.iterator]();!(r=(s=a.next()).done)&&(n.push(s.value),!e||n.length!==e);r=!0);}catch(t){i=!0,o=t}finally{try{!r&&a.return&&a.return()}finally{if(i)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),ut=function(){function t(e){rt(this,t),this.val=e,this.color=!0,this._left=null,this._right=null,this._parent=null}return it(t,[{key:"isRed",value:function(){return this.color}},{key:"isBlack",value:function(){return!this.color}},{key:"redden",value:function(){return this.color=!0,this}},{key:"blacken",value:function(){return this.color=!1,this}},{key:"rotateLeft",value:function(t){var e=this.parent,n=this.right,r=this.right.left;if(n.left=this,this.right=r,null===e)t.root=n,n._parent=null;else if(e.left===this)e.left=n;else{if(e.right!==this)throw new Error("The elements are wrongly connected!");e.right=n}}},{key:"next",value:function(){if(null!==this.right){for(var t=this.right;null!==t.left;)t=t.left;return t}for(var e=this;null!==e.parent&&e!==e.parent.left;)e=e.parent;return e.parent}},{key:"prev",value:function(){if(null!==this.left){for(var t=this.left;null!==t.right;)t=t.right;return t}for(var e=this;null!==e.parent&&e!==e.parent.right;)e=e.parent;return e.parent}},{key:"rotateRight",value:function(t){var e=this.parent,n=this.left,r=this.left.right;if(n.right=this,this.left=r,null===e)t.root=n,n._parent=null;else if(e.left===this)e.left=n;else{if(e.right!==this)throw new Error("The elements are wrongly connected!");e.right=n}}},{key:"getUncle",value:function(){return this.parent===this.parent.parent.left?this.parent.parent.right:this.parent.parent.left}},{key:"grandparent",get:function(){return this.parent.parent}},{key:"parent",get:function(){return this._parent}},{key:"sibling",get:function(){return this===this.parent.left?this.parent.right:this.parent.left}},{key:"left",get:function(){return this._left},set:function(t){null!==t&&(t._parent=this),this._left=t}},{key:"right",get:function(){return this._right},set:function(t){null!==t&&(t._parent=this),this._right=t}}]),t}(),ht=function(){function t(){rt(this,t),this.root=null,this.length=0}return it(t,[{key:"findNext",value:function(t){var e=t.clone();return e.clock+=1,this.findWithLowerBound(e)}},{key:"findPrev",value:function(t){var e=t.clone();return e.clock-=1,this.findWithUpperBound(e)}},{key:"findNodeWithLowerBound",value:function(t){var e=this.root;if(null===e)return null;for(;;)if(null===t||t.lessThan(e.val._id)&&null!==e.left)e=e.left;else{if(null===t||!e.val._id.lessThan(t))return e;if(null===e.right)return e.next();e=e.right}}},{key:"findNodeWithUpperBound",value:function(t){if(void 0===t)throw new Error("You must define from!");var e=this.root;if(null===e)return null;for(;;)if(null!==t&&!e.val._id.lessThan(t)||null===e.right){if(null===t||!t.lessThan(e.val._id))return e;if(null===e.left)return e.prev();e=e.left}else e=e.right}},{key:"findSmallestNode",value:function(){for(var t=this.root;null!=t&&null!=t.left;)t=t.left;return t}},{key:"findWithLowerBound",value:function(t){var e=this.findNodeWithLowerBound(t);return null==e?null:e.val}},{key:"findWithUpperBound",value:function(t){var e=this.findNodeWithUpperBound(t);return null==e?null:e.val}},{key:"iterate",value:function(t,e,n){var r;for(r=null===t?this.findSmallestNode():this.findNodeWithLowerBound(t);null!==r&&(null===e||r.val._id.lessThan(e)||r.val._id.equals(e));)n(r.val),r=r.next()}},{key:"find",value:function(t){var e=this.findNode(t);return null!==e?e.val:null}},{key:"findNode",value:function(t){var e=this.root;if(null===e)return null;for(;;){if(null===e)return null;if(t.lessThan(e.val._id))e=e.left;else{if(!e.val._id.lessThan(t))return e;e=e.right}}}},{key:"delete",value:function(t){var e=this.findNode(t);if(null!=e){if(this.length--,null!==e.left&&null!==e.right){for(var n=e.left;null!==n.right;)n=n.right;e.val=n.val,e=n}var r,i=e.left||e.right;if(null===i?(r=!0,i=new ut(null),i.blacken(),e.right=i):r=!1,null===e.parent)return void(r?this.root=null:(this.root=i,i.blacken(),i._parent=null));if(e.parent.left===e)e.parent.left=i;else{if(e.parent.right!==e)throw new Error("Impossible!");e.parent.right=i}if(e.isBlack()&&(i.isRed()?i.blacken():this._fixDelete(i)),this.root.blacken(),r)if(i.parent.left===i)i.parent.left=null;else{if(i.parent.right!==i)throw new Error("Impossible #3");i.parent.right=null}}}},{key:"_fixDelete",value:function(t){function e(t){return null===t||t.isBlack()}function n(t){return null!==t&&t.isRed()}if(null!==t.parent){var r=t.sibling;if(n(r)){if(t.parent.redden(),r.blacken(),t===t.parent.left)t.parent.rotateLeft(this);else{if(t!==t.parent.right)throw new Error("Impossible #2");t.parent.rotateRight(this)}r=t.sibling}t.parent.isBlack()&&r.isBlack()&&e(r.left)&&e(r.right)?(r.redden(),this._fixDelete(t.parent)):t.parent.isRed()&&r.isBlack()&&e(r.left)&&e(r.right)?(r.redden(),t.parent.blacken()):(t===t.parent.left&&r.isBlack()&&n(r.left)&&e(r.right)?(r.redden(),r.left.blacken(),r.rotateRight(this),r=t.sibling):t===t.parent.right&&r.isBlack()&&n(r.right)&&e(r.left)&&(r.redden(),r.right.blacken(),r.rotateLeft(this),r=t.sibling),r.color=t.parent.color,t.parent.blacken(),t===t.parent.left?(r.right.blacken(),t.parent.rotateLeft(this)):(r.left.blacken(),t.parent.rotateRight(this)))}}},{key:"put",value:function(t){var e=new ut(t);if(null!==this.root){for(var n=this.root;;)if(e.val._id.lessThan(n.val._id)){if(null===n.left){n.left=e;break}n=n.left}else{if(!n.val._id.lessThan(e.val._id))return n.val=e.val,n;if(null===n.right){n.right=e;break}n=n.right}this._fixInsert(e)}else this.root=e;return this.length++,this.root.blacken(),e}},{key:"_fixInsert",value:function(t){if(null===t.parent)return void t.blacken();if(!t.parent.isBlack()){var e=t.getUncle();null!==e&&e.isRed()?(t.parent.blacken(),e.blacken(),t.grandparent.redden(),this._fixInsert(t.grandparent)):(t===t.parent.right&&t.parent===t.grandparent.left?(t.parent.rotateLeft(this),t=t.left):t===t.parent.left&&t.parent===t.grandparent.right&&(t.parent.rotateRight(this),t=t.right),t.parent.blacken(),t.grandparent.redden(),t===t.parent.left?t.grandparent.rotateRight(this):t.grandparent.rotateLeft(this))}}},{key:"flush",value:function(){}}]),t}(),ct=function(){function t(e,n){rt(this,t),this.user=e,this.clock=n}return it(t,[{key:"clone",value:function(){return new t(this.user,this.clock)}},{key:"equals",value:function(t){return null!==t&&t.user===this.user&&t.clock===this.clock}},{key:"lessThan",value:function(t){return this.user<t.user||this.user===t.user&&this.clock<t.clock}}]),t}(),ft=function(){function t(e,n,r){rt(this,t),this._id=e,this.len=n,this.gc=r}return it(t,[{key:"clone",value:function(){return new t(this._id,this.len,this.gc)}}]),t}(),dt=function(t){function e(){return rt(this,e),at(this,(e.__proto__||Object.getPrototypeOf(e)).apply(this,arguments))}return st(e,t),it(e,[{key:"logTable",value:function(){var t=[];this.iterate(null,null,function(e){t.push({user:e._id.user,clock:e._id.clock,len:e.len,gc:e.gc})}),console.table(t)}},{key:"isDeleted",value:function(t){var e=this.findWithUpperBound(t);return null!==e&&e._id.user===t.user&&t.clock<e._id.clock+e.len}},{key:"markDeleted",value:function(t,e){if(null==e)throw new Error("length must be defined");var n=this.findWithUpperBound(t);if(null!=n&&n._id.user===t.user)if(n._id.clock<=t.clock&&t.clock<=n._id.clock+n.len){var r=t.clock+e-(n._id.clock+n.len);if(!(r>0))return n;if(n.gc){if(!((r=n._id.clock+n.len-t.clock)<e))throw new Error("DS reached an inconsistent state. Please report this issue!");var i=t.clone();i.clock+=r,n=new ft(i,e-r,!1),this.put(n)}else n.len+=r}else n=new ft(t,e,!1),this.put(n);else n=new ft(t,e,!1),this.put(n);var o=this.findNext(n._id);if(null!=o&&n._id.user===o._id.user&&n._id.clock+n.len>=o._id.clock)for(r=n._id.clock+n.len-o._id.clock;r>=0;){if(o.gc){n.len-=r,r>=o.len&&(r-=o.len)>0&&(this.put(n),this.markDeleted(new ct(o._id.user,o._id.clock+o.len),r));break}if(!(r>o.len)){n.len+=o.len-r,this.delete(o._id);break}var s=this.findNext(o._id);if(this.delete(o._id),null==s||n._id.user!==s._id.user)break;o=s,r=n._id.clock+n.len-o._id.clock}return this.put(n),n}}]),e}(ht);String.fromCodePoint||function(){var t=function(){try{var t={},e=Object.defineProperty,n=e(t,t,t)&&e}catch(t){}return n}(),e=String.fromCharCode,n=Math.floor,r=function(t){var r,i,o=[],s=-1,a=arguments.length;if(!a)return"";for(var l="";++s<a;){var u=Number(arguments[s]);if(!isFinite(u)||u<0||u>1114111||n(u)!=u)throw RangeError("Invalid code point: "+u);u<=65535?o.push(u):(u-=65536,r=55296+(u>>10),i=u%1024+56320,o.push(r,i)),(s+1==a||o.length>16384)&&(l+=e.apply(null,o),o.length=0)}return l};t?t(String,"fromCodePoint",{value:r,configurable:!0,writable:!0}):String.fromCodePoint=r}(),String.prototype.codePointAt||function(){var t=function(){try{var t={},e=Object.defineProperty,n=e(t,t,t)&&e}catch(t){}return n}(),e=function(t){if(null==this)throw TypeError();var e=String(this),n=e.length,r=t?Number(t):0;if(r!=r&&(r=0),!(r<0||r>=n)){var i,o=e.charCodeAt(r);return o>=55296&&o<=56319&&n>r+1&&(i=e.charCodeAt(r+1))>=56320&&i<=57343?1024*(o-55296)+i-56320+65536:o}};t?t(String.prototype,"codePointAt",{value:e,configurable:!0,writable:!0}):String.prototype.codePointAt=e}();var _t=t(function(t){t.require;var e={isNotUTF8:function(t,n,r){try{e.getStringFromBytes(t,n,r,!0)}catch(t){return!0}return!1},getCharLength:function(t){return 240==(240&t)?4:224==(224&t)?3:192==(192&t)?2:t==(127&t)?1:0},getCharCode:function(t,n,r){var i=0,o="";if(n=n||0,0==(r=r||e.getCharLength(t[n])))throw new Error(t[n].toString(2)+" is not a significative byte (offset:"+n+").");if(1===r)return t[n];if(o="00000000".slice(0,r)+1+"00000000".slice(r+1),t[n]&parseInt(o,2))throw Error("Index "+n+": A "+r+" bytes encoded char cannot encode the "+(r+1)+"th rank bit to 1.");for(o="0000".slice(0,r+1)+"11111111".slice(r+1),i+=(t[n]&parseInt(o,2))<<6*--r;r;){if(128!=(128&t[n+1])||64==(64&t[n+1]))throw Error("Index "+(n+1)+': Next bytes of encoded char must begin with a "10" bit sequence.');i+=(63&t[++n])<<6*--r}return i},getStringFromBytes:function(t,n,r,i){var o,s=[];for(n|=0,r="number"==typeof r?r:t.byteLength||t.length;n<r;n++){if(o=e.getCharLength(t[n]),n+o>r){if(i)throw Error("Index "+n+": Found a "+o+" bytes encoded char declaration but only "+(r-n)+" bytes are available.")}else s.push(String.fromCodePoint(e.getCharCode(t,n,o,i)));n+=o-1}return s.join("")},getBytesForCharCode:function(t){if(t<128)return 1;if(t<2048)return 2;if(t<65536)return 3;if(t<2097152)return 4;throw new Error("CharCode "+t+" cannot be encoded with UTF8.")},setBytesFromCharCode:function(t,n,r,i){if(t|=0,n=n||[],r|=0,1==(i=i||e.getBytesForCharCode(t)))n[r]=t;else for(n[r++]=(parseInt("1111".slice(0,i),2)<<8-i)+(t>>>6*--i);i>0;)n[r++]=t>>>6*--i&63|128;return n},setBytesFromString:function(t,n,r,i,o){t=t||"",n=n||[],r|=0,i="number"==typeof i?i:n.byteLength||1/0;for(var s=0,a=t.length;s<a;s++){var l=e.getBytesForCharCode(t[s].codePointAt(0));if(o&&r+l>i)throw new Error('Not enought bytes to encode the char "'+t[s]+'" at the offset "'+r+'".');e.setBytesFromCharCode(t[s].codePointAt(0),n,r,l,o),r+=l}return n}};t.exports=e}),vt=function(){function t(e){if(rt(this,t),e instanceof ArrayBuffer)this.uint8arr=new Uint8Array(e);else{if(!(e instanceof Uint8Array||"undefined"!=typeof Buffer&&e instanceof Buffer))throw new Error("Expected an ArrayBuffer or Uint8Array!");this.uint8arr=e}this.pos=0}return it(t,[{key:"clone",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.pos,n=new t(this.uint8arr);return n.pos=e,n}},{key:"skip8",value:function(){this.pos++}},{key:"readUint8",value:function(){return this.uint8arr[this.pos++]}},{key:"readUint32",value:function(){var t=this.uint8arr[this.pos]+(this.uint8arr[this.pos+1]<<8)+(this.uint8arr[this.pos+2]<<16)+(this.uint8arr[this.pos+3]<<24);return this.pos+=4,t}},{key:"peekUint8",value:function(){return this.uint8arr[this.pos]}},{key:"readVarUint",value:function(){for(var t=0,e=0;;){var n=this.uint8arr[this.pos++];if(t|=(127&n)<<e,e+=7,n<128)return t>>>0;if(e>35)throw new Error("Integer out of range!")}}},{key:"readVarString",value:function(){for(var t=this.readVarUint(),e=new Array(t),n=0;n<t;n++)e[n]=this.uint8arr[this.pos++];return _t.getStringFromBytes(e)}},{key:"peekVarString",value:function(){var t=this.pos,e=this.readVarString();return this.pos=t,e}},{key:"readID",value:function(){var t=this.readVarUint();if(t===Tt){var e=new Nt(this.readVarString(),null);return e.type=this.readVarUint(),e}return new ct(t,this.readVarUint())}},{key:"length",get:function(){return this.uint8arr.length}}]),t}(),gt=function t(e,n,r){rt(this,t),this.decoder=e,this.missing=n.length,this.struct=r},pt=function(){function t(){rt(this,t),this.data=[]}return it(t,[{key:"createBuffer",value:function(){return Uint8Array.from(this.data).buffer}},{key:"writeUint8",value:function(t){this.data.push(255&t)}},{key:"setUint8",value:function(t,e){this.data[t]=255&e}},{key:"writeUint16",value:function(t){this.data.push(255&t,t>>>8&255)}},{key:"setUint16",value:function(t,e){this.data[t]=255&e,this.data[t+1]=e>>>8&255}},{key:"writeUint32",value:function(t){for(var e=0;e<4;e++)this.data.push(255&t),t>>>=8}},{key:"setUint32",value:function(t,e){for(var n=0;n<4;n++)this.data[t+n]=255&e,e>>>=8}},{key:"writeVarUint",value:function(t){for(;t>=128;)this.data.push(128|127&t),t>>>=7;this.data.push(127&t)}},{key:"writeVarString",value:function(t){var e=_t.setBytesFromString(t),n=e.length;this.writeVarUint(n);for(var r=0;r<n;r++)this.data.push(e[r])}},{key:"writeID",value:function(t){var e=t.user;this.writeVarUint(e),e!==Tt?this.writeVarUint(t.clock):(this.writeVarString(t.name),this.writeVarUint(t.type))}},{key:"length",get:function(){return this.data.length}},{key:"pos",get:function(){
return this.data.length}}]),t}(),Delete=function(){function Delete(){rt(this,Delete),this._target=null,this._length=null}return it(Delete,[{key:"_fromBinary",value:function(t,e){var n=e.readID();return this._targetID=n,this._length=e.readVarUint(),null===t.os.getItem(n)?[n]:[]}},{key:"_toBinary",value:function(t){t.writeUint8(X(this.constructor)),t.writeID(this._targetID),t.writeVarUint(this._length)}},{key:"_integrate",value:function(t){if(arguments.length>1&&void 0!==arguments[1]&&arguments[1])t.connector.broadcastStruct(this);else{var e=this._targetID;p(t,e.user,e.clock,this._length)}null!==t.persistence&&t.persistence.saveOperations(this)}},{key:"_logString",value:function(){return"Delete - target: "+g(this._targetID)+", len: "+this._length}}]),Delete}(),yt=function t(e){rt(this,t),this.y=e,this.newTypes=new Set,this.changedTypes=new Map,this.deletedStructs=new Set,this.beforeState=new Map,this.changedParentTypes=new Map},Item=function(){function Item(){rt(this,Item),this._id=null,this._origin=null,this._left=null,this._right=null,this._right_origin=null,this._parent=null,this._parentSub=null,this._deleted=!1}return it(Item,[{key:"_copy",value:function(){var t=new this.constructor;return t._origin=this._left,t._left=this._left,t._right=this,t._right_origin=this,t._parent=this._parent,t._parentSub=this._parentSub,t}},{key:"_splitAt",value:function(t,e){return 0===e?this:this._right}},{key:"_delete",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(this._deleted=!0,t.ds.markDeleted(this._id,this._length),e){var n=new Delete;n._targetID=this._id,n._length=this._length,n._integrate(t,!0)}y(t,this._parent,this._parentSub),t._transaction.deletedStructs.add(this)}},{key:"_beforeChange",value:function(){}},{key:"_integrate",value:function(t){var e=this._parent,n=this._id,r=null===n?0:t.ss.getState(n.user);if(null===n)this._id=t.ss.getNextID(this._length);else if(n.user===Tt);else{if(n.clock<r)return[];if(n.clock!==r)throw new Error("Can not apply yet!");t.ss.setState(n.user,r+this._length)}e._deleted||t._transaction.changedTypes.has(e)||t._transaction.newTypes.has(e)||this._parent._beforeChange();var i=void 0;i=null!==this._left?this._left._right:null!==this._parentSub?this._parent._map.get(this._parentSub)||null:this._parent._start;for(var o=new Set,s=new Set;null!==i&&i!==this._right;){if(s.add(i),o.add(i),this._origin===i._origin)i._id.user<this._id.user&&(this._left=i,o.clear());else{if(!s.has(i._origin))break;o.has(i._origin)||(this._left=i,o.clear())}i=i._right}var a=this._parentSub;if(null===this._left){var l=void 0;if(null!==a){var u=e._map;l=u.get(a)||null,u.set(a,this)}else l=e._start,e._start=this;this._right=l,null!==l&&(l._left=this)}else{var h=this._left,c=h._right;this._right=c,h._right=this,null!==c&&(c._left=this)}e._deleted&&this._delete(t,!1),t.os.put(this),y(t,e,a),this._id.user!==Tt&&((t.connector._forwardAppliedStructs||this._id.user===t.userID)&&t.connector.broadcastStruct(this),null!==t.persistence&&t.persistence.saveOperations(this))}},{key:"_toBinary",value:function(t){t.writeUint8(X(this.constructor));var e=0;null!==this._origin&&(e+=1),null!==this._right_origin&&(e+=4),null!==this._parentSub&&(e+=8),t.writeUint8(e),t.writeID(this._id),1&e&&t.writeID(this._origin._lastId),4&e&&t.writeID(this._right_origin._id),0==(5&e)&&t.writeID(this._parent._id),8&e&&t.writeVarString(JSON.stringify(this._parentSub))}},{key:"_fromBinary",value:function(t,e){var n=[],r=e.readUint8(),i=e.readID();if(this._id=i,1&r){var o=e.readID(),s=t.os.getItemCleanEnd(o);null===s?n.push(o):(this._origin=s,this._left=this._origin)}if(4&r){var a=e.readID(),l=t.os.getItemCleanStart(a);null===l?n.push(a):(this._right=l,this._right_origin=l)}if(0==(5&r)){var u=e.readID();if(null===this._parent){var h=t.os.get(u);null===h?n.push(u):this._parent=h}}else null===this._parent&&(null!==this._origin?this._parent=this._origin._parent:null!==this._right_origin&&(this._parent=this._right_origin._parent));return 8&r&&(this._parentSub=JSON.parse(e.readVarString())),t.ss.getState(i.user)<i.clock&&n.push(new ct(i.user,i.clock-1)),n}},{key:"_lastId",get:function(){return new ct(this._id.user,this._id.clock+this._length-1)}},{key:"_length",get:function(){return 1}}]),Item}(),mt=function(){function t(){rt(this,t),this.eventListeners=[]}return it(t,[{key:"destroy",value:function(){this.eventListeners=null}},{key:"addEventListener",value:function(t){this.eventListeners.push(t)}},{key:"removeEventListener",value:function(t){this.eventListeners=this.eventListeners.filter(function(e){return t!==e})}},{key:"removeAllEventListeners",value:function(){this.eventListeners=[]}},{key:"callEventListeners",value:function(t,e){for(var n=0;n<this.eventListeners.length;n++)try{(0,this.eventListeners[n])(e)}catch(t){console.error(t)}}}]),t}(),Type=function(t){function Type(){rt(this,Type);var t=at(this,(Type.__proto__||Object.getPrototypeOf(Type)).call(this));return t._map=new Map,t._start=null,t._y=null,t._eventHandler=new mt,t._deepEventHandler=new mt,t}return st(Type,t),it(Type,[{key:"getPathTo",value:function(t){if(t===this)return[];for(var e=[],n=this._y;t._parent!==this&&this._parent!==n;){var r=t._parent;if(null!==t._parentSub)e.push(t._parentSub);else{var i=!0,o=!1,s=void 0;try{for(var a,l=r[Symbol.iterator]();!(i=(a=l.next()).done);i=!0){var u=lt(a.value,2),h=u[0];if(u[1]===t){e.push(h);break}}}catch(t){o=!0,s=t}finally{try{!i&&l.return&&l.return()}finally{if(o)throw s}}}t=r}if(this._parent!==this)throw new Error("The type is not a child of this node");return e}},{key:"_callEventHandler",value:function(t,e){var n=t.changedParentTypes;this._eventHandler.callEventListeners(t,e);for(var r=this;r!==this._y;){var i=n.get(r);void 0===i&&(i=[],n.set(r,i)),i.push(e),r=r._parent}}},{key:"_copy",value:function(t){var e=ot(Type.prototype.__proto__||Object.getPrototypeOf(Type.prototype),"_copy",this).call(this),n=new Map;e._map=n;var r=!0,i=!1,o=void 0;try{for(var s,a=this._map[Symbol.iterator]();!(r=(s=a.next()).done);r=!0){var l=lt(s.value,2),u=l[0],h=l[1];if(t.has(h)||!h.deleted){h._copy(t)._parent=e,n.set(u,h._copy(t))}}}catch(t){i=!0,o=t}finally{try{!r&&a.return&&a.return()}finally{if(i)throw o}}var c=null;e._start=null;for(var f=this._start;null!==f;){if(t.has(f)||!f.deleted){var d=f._copy(t);d._left=c,d._origin=c,d._right=null,d._right_origin=null,d._parent=e,null===c?e._start=d:c._right=d,c=d}f=f._right}return e}},{key:"_transact",value:function(t){var e=this._y;null!==e?e.transact(t):t(e)}},{key:"observe",value:function(t){this._eventHandler.addEventListener(t)}},{key:"observeDeep",value:function(t){this._deepEventHandler.addEventListener(t)}},{key:"unobserve",value:function(t){this._eventHandler.removeEventListener(t)}},{key:"unobserveDeep",value:function(t){this._deepEventHandler.removeEventListener(t)}},{key:"_integrate",value:function(t){t._transaction.newTypes.add(this),ot(Type.prototype.__proto__||Object.getPrototypeOf(Type.prototype),"_integrate",this).call(this,t),this._y=t;var e=this._start;null!==e&&(this._start=null,b(t,e));var n=this._map;this._map=new Map;var r=!0,i=!1,o=void 0;try{for(var s,a=n.values()[Symbol.iterator]();!(r=(s=a.next()).done);r=!0){b(t,s.value)}}catch(t){i=!0,o=t}finally{try{!r&&a.return&&a.return()}finally{if(i)throw o}}}},{key:"_delete",value:function(t,e){ot(Type.prototype.__proto__||Object.getPrototypeOf(Type.prototype),"_delete",this).call(this,t,e),t._transaction.changedTypes.delete(this);var n=!0,r=!1,i=void 0;try{for(var o,s=this._map.values()[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var a=o.value;a instanceof Item&&!a._deleted&&a._delete(t,!1)}}catch(t){r=!0,i=t}finally{try{!n&&s.return&&s.return()}finally{if(r)throw i}}for(var l=this._start;null!==l;)l._deleted||l._delete(t,!1),l=l._right}}]),Type}(Item),ItemJSON=function(t){function ItemJSON(){rt(this,ItemJSON);var t=at(this,(ItemJSON.__proto__||Object.getPrototypeOf(ItemJSON)).call(this));return t._content=null,t}return st(ItemJSON,t),it(ItemJSON,[{key:"_copy",value:function(){var t=ot(ItemJSON.prototype.__proto__||Object.getPrototypeOf(ItemJSON.prototype),"_copy",this).call(this);return t._content=this._content,t}},{key:"_fromBinary",value:function(t,e){var n=ot(ItemJSON.prototype.__proto__||Object.getPrototypeOf(ItemJSON.prototype),"_fromBinary",this).call(this,t,e),r=e.readVarUint();this._content=new Array(r);for(var i=0;i<r;i++){var o=e.readVarString(),s=void 0;s="undefined"===o?void 0:JSON.parse(o),this._content[i]=s}return n}},{key:"_toBinary",value:function(t){ot(ItemJSON.prototype.__proto__||Object.getPrototypeOf(ItemJSON.prototype),"_toBinary",this).call(this,t);var e=this._content.length;t.writeVarUint(e);for(var n=0;n<e;n++){var r=void 0,i=this._content[n];r=void 0===i?"undefined":JSON.stringify(i),t.writeVarString(r)}}},{key:"_logString",value:function(){var t=null!==this._left?this._left._lastId:null,e=null!==this._origin?this._origin._lastId:null;return"ItemJSON(id:"+g(this._id)+",content:"+JSON.stringify(this._content)+",left:"+g(t)+",origin:"+g(e)+",right:"+g(this._right)+",parent:"+g(this._parent)+",parentSub:"+this._parentSub+")"}},{key:"_splitAt",value:function(t,e){if(0===e)return this;if(e>=this._length)return this._right;var n=new ItemJSON;return n._content=this._content.splice(e),m(t,this,n,e),n}},{key:"_length",get:function(){return this._content.length}}]),ItemJSON}(Item),ItemString=function(t){function ItemString(){rt(this,ItemString);var t=at(this,(ItemString.__proto__||Object.getPrototypeOf(ItemString)).call(this));return t._content=null,t}return st(ItemString,t),it(ItemString,[{key:"_copy",value:function(){var t=ot(ItemString.prototype.__proto__||Object.getPrototypeOf(ItemString.prototype),"_copy",this).call(this);return t._content=this._content,t}},{key:"_fromBinary",value:function(t,e){var n=ot(ItemString.prototype.__proto__||Object.getPrototypeOf(ItemString.prototype),"_fromBinary",this).call(this,t,e);return this._content=e.readVarString(),n}},{key:"_toBinary",value:function(t){ot(ItemString.prototype.__proto__||Object.getPrototypeOf(ItemString.prototype),"_toBinary",this).call(this,t),t.writeVarString(this._content)}},{key:"_logString",value:function(){var t=null!==this._left?this._left._lastId:null,e=null!==this._origin?this._origin._lastId:null;return"ItemJSON(id:"+g(this._id)+",content:"+JSON.stringify(this._content)+",left:"+g(t)+",origin:"+g(e)+",right:"+g(this._right)+",parent:"+g(this._parent)+",parentSub:"+this._parentSub+")"}},{key:"_splitAt",value:function(t,e){if(0===e)return this;if(e>=this._length)return this._right;var n=new ItemString;return n._content=this._content.slice(e),this._content=this._content.slice(0,e),m(t,this,n,e),n}},{key:"_length",get:function(){return this._content.length}}]),ItemString}(Item),YEvent=function(){function YEvent(t){rt(this,YEvent),this.target=t,this.currentTarget=t}return it(YEvent,[{key:"path",get:function(){for(var t=[],e=this.target,n=e._y;e!==this.currentTarget&&e!==n;){var r=e._parent;if(null!==e._parentSub)t.unshift(e._parentSub);else{var i=!0,o=!1,s=void 0;try{for(var a,l=r[Symbol.iterator]();!(i=(a=l.next()).done);i=!0){var u=lt(a.value,2),h=u[0];if(u[1]===e){t.unshift(h);break}}}catch(t){o=!0,s=t}finally{try{!i&&l.return&&l.return()}finally{if(o)throw s}}}e=r}return t}}]),YEvent}(),YArrayEvent=function(t){function YArrayEvent(t,e,n){rt(this,YArrayEvent);var r=at(this,(YArrayEvent.__proto__||Object.getPrototypeOf(YArrayEvent)).call(this,t));return r.remote=e,r._transaction=n,r}return st(YArrayEvent,t),it(YArrayEvent,[{key:"addedElements",get:function(){var t=this.target,e=this._transaction,n=new Set;return e.newTypes.forEach(function(r){r._parent!==t||e.deletedStructs.has(r)||n.add(r)}),n}},{key:"removedElements",get:function(){var t=this.target,e=this._transaction,n=new Set;return e.deletedStructs.forEach(function(r){r._parent!==t||e.newTypes.has(r)||n.add(r)}),n}}]),YArrayEvent}(YEvent),YArray=function(t){function YArray(){return rt(this,YArray),at(this,(YArray.__proto__||Object.getPrototypeOf(YArray)).apply(this,arguments))}return st(YArray,t),it(YArray,[{key:"_callObserver",value:function(t,e,n){this._callEventHandler(t,new YArrayEvent(this,n,t))}},{key:"get",value:function(t){for(var e=this._start;null!==e;){if(!e._deleted){if(t<e._length)return e.constructor===ItemJSON||e.constructor===ItemString?e._content[t]:e;t-=e._length}e=e._right}}},{key:"toArray",value:function(){return this.map(function(t){return t})}},{key:"toJSON",value:function(){return this.map(function(t){return t instanceof Type?null!==t.toJSON?t.toJSON():t.toString():t})}},{key:"map",value:function(t){var e=this,n=[];return this.forEach(function(r,i){n.push(t(r,i,e))}),n}},{key:"forEach",value:function(t){for(var e=0,n=this._start;null!==n;){if(!n._deleted)if(n instanceof Type)t(n,e++,this);else for(var r=n._content,i=r.length,o=0;o<i;o++)e++,t(r[o],e,this);n=n._right}}},{key:Symbol.iterator,value:function(){return{next:function(){for(;null!==this._item&&(this._item._deleted||this._item._length<=this._itemElement);)this._item=this._item._right,this._itemElement=0;if(null===this._item)return{done:!0};var t=void 0;return t=this._item instanceof Type?this._item:this._item._content[this._itemElement++],{value:[this._count,t],done:!1}},_item:this._start,_itemElement:0,_count:0}}},{key:"delete",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;if(this._y.transact(function(){for(var r=e._start,i=0;null!==r&&n>0;){if(!r._deleted)if(i<=t&&t<i+r._length){var o=t-i;r=r._splitAt(e._y,o),r._splitAt(e._y,n),n-=r._length,r._delete(e._y),i+=o}else i+=r._length;r=r._right}}),n>0)throw new Error("Delete exceeds the range of the YArray")}},{key:"insertAfter",value:function(t,e){var n=this;this._transact(function(r){var i=void 0;i=null===t?n._start:t._right;for(var o=null,s=0;s<e.length;s++){var a=e[s];"function"==typeof a&&(a=new a),a instanceof Type?(null!==o&&(null!==r&&o._integrate(r),t=o,o=null),a._origin=t,a._left=t,a._right=i,a._right_origin=i,a._parent=n,null!==r?a._integrate(r):null===t?n._start=a:t._right=a,t=a):(null===o&&(o=new ItemJSON,o._origin=t,o._left=t,o._right=i,o._right_origin=i,o._parent=n,o._content=[]),o._content.push(a))}null!==o&&(null!==r?o._integrate(r):null===o._left&&(n._start=o))})}},{key:"insert",value:function(t,e){for(var n=null,r=this._start,i=0,o=this._y;null!==r;){var s=r._deleted?0:r._length-1;if(i<=t&&t<=i+s){var a=t-i;r=r._splitAt(o,a),n=r._left,i+=a;break}r._deleted||(i+=r._length),n=r,r=r._right}if(t>i)throw new Error("Position exceeds array range!");this.insertAfter(n,e)}},{key:"push",value:function(t){for(var e=this._start,n=null;null!==e;)e._deleted||(n=e),e=e._right;this.insertAfter(n,t)}},{key:"_logString",value:function(){var t=null!==this._left?this._left._lastId:null,e=null!==this._origin?this._origin._lastId:null;return"YArray(id:"+g(this._id)+",start:"+g(this._start)+",left:"+g(t)+",origin:"+g(e)+",right:"+g(this._right)+",parent:"+g(this._parent)+",parentSub:"+this._parentSub+")"}},{key:"length",get:function(){for(var t=0,e=this._start;null!==e;)e._deleted||(t+=e._length),e=e._right;return t}}]),YArray}(Type),YMapEvent=function(t){function YMapEvent(t,e,n){rt(this,YMapEvent);var r=at(this,(YMapEvent.__proto__||Object.getPrototypeOf(YMapEvent)).call(this,t));return r.keysChanged=e,r.remote=n,r}return st(YMapEvent,t),YMapEvent}(YEvent),YMap=function(t){function YMap(){return rt(this,YMap),at(this,(YMap.__proto__||Object.getPrototypeOf(YMap)).apply(this,arguments))}return st(YMap,t),it(YMap,[{key:"_callObserver",value:function(t,e,n){this._callEventHandler(t,new YMapEvent(this,e,n))}},{key:"toJSON",value:function(){var t={},e=!0,n=!1,r=void 0;try{for(var i,o=this._map[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){var s=lt(i.value,2),a=s[0],l=s[1];if(!l._deleted){var u=void 0;u=l instanceof Type?void 0!==l.toJSON?l.toJSON():l.toString():l._content[0],t[a]=u}}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}return t}},{key:"keys",value:function(){var t=[],e=!0,n=!1,r=void 0;try{for(var i,o=this._map[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){var s=lt(i.value,2),a=s[0];s[1]._deleted||t.push(a)}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}return t}},{key:"delete",value:function(t){var e=this;this._transact(function(n){var r=e._map.get(t);null!==n&&void 0!==r&&r._delete(n)})}},{key:"set",value:function(t,e){var n=this;return this._transact(function(r){var i=n._map.get(t)||null;if(null!==i){if(i instanceof ItemJSON&&i._content[0]===e)return e;null!==r&&i._delete(r)}var o=void 0;"function"==typeof e?(o=new e,e=o):e instanceof Item?o=e:(o=new ItemJSON,o._content=[e]),o._right=i,o._right_origin=i,o._parent=n,o._parentSub=t,null!==r?o._integrate(r):n._map.set(t,o)}),e}},{key:"get",value:function(t){var e=this._map.get(t);if(void 0!==e&&!e._deleted)return e instanceof Type?e:e._content[e._content.length-1]}},{key:"has",value:function(t){var e=this._map.get(t);return void 0!==e&&!e._deleted}},{key:"_logString",value:function(){var t=null!==this._left?this._left._lastId:null,e=null!==this._origin?this._origin._lastId:null;return"YMap(id:"+g(this._id)+",mapSize:"+this._map.size+",left:"+g(t)+",origin:"+g(e)+",right:"+g(this._right)+",parent:"+g(this._parent)+",parentSub:"+this._parentSub+")"}}]),YMap}(Type),YText=function(t){function YText(t){rt(this,YText);var e=at(this,(YText.__proto__||Object.getPrototypeOf(YText)).call(this));if("string"==typeof t){var n=new ItemString;n._parent=e,n._content=t,e._start=n}return e}return st(YText,t),it(YText,[{key:"toString",value:function(){for(var t=[],e=this._start;null!==e;)e._deleted||t.push(e._content),e=e._right;return t.join("")}},{key:"insert",value:function(t,e){var n=this;this._transact(function(r){for(var i=null,o=n._start,s=0;null!==o;){var a=o._deleted?0:o._length-1;if(s<=t&&t<=s+a){var l=t-s;o=o._splitAt(n._y,l),i=o._left,s+=l;break}o._deleted||(s+=o._length),i=o,o=o._right}if(t>s)throw new Error("Position exceeds array range!");var u=new ItemString;u._origin=i,u._left=i,u._right=o,u._right_origin=o,u._parent=n,u._content=e,null!==r?u._integrate(n._y):null===i?n._start=u:i._right=u})}},{key:"_logString",value:function(){var t=null!==this._left?this._left._lastId:null,e=null!==this._origin?this._origin._lastId:null;return"YText(id:"+g(this._id)+",start:"+g(this._start)+",left:"+g(t)+",origin:"+g(e)+",right:"+g(this._right)+",parent:"+g(this._parent)+",parentSub:"+this._parentSub+")"}}]),YText}(YArray),bt=null,kt=null,wt=void 0;wt="undefined"!=typeof getSelection?function(t,e,n){if(n){kt={from:null,to:null,fromY:null,toY:null},bt=getSelection();var r=bt.anchorNode;if(null!==r&&null!=r._yxml){var i=r._yxml;kt.from=A(i,bt.anchorOffset),kt.fromY=i._y}var o=bt.focusNode;if(null!==o&&null!=o._yxml){var s=o._yxml;kt.to=A(s,bt.focusOffset),kt.toY=s._y}}}:function(){};var YXmlEvent=function(t){function YXmlEvent(t,e,n){rt(this,YXmlEvent);var r=at(this,(YXmlEvent.__proto__||Object.getPrototypeOf(YXmlEvent)).call(this,t));return r.childListChanged=!1,r.attributesChanged=new Set,r.remote=n,e.forEach(function(t){null===t?r.childListChanged=!0:r.attributesChanged.add(t)}),r}return st(YXmlEvent,t),YXmlEvent}(YEvent),St=-1,Et=1,Ot=0,At=x;At.INSERT=Et,At.DELETE=St,At.EQUAL=Ot;var Ut=At,Bt=function(){function t(e,n){rt(this,t),this._filter=n||function(){return!0},this._root=e,this._currentNode=e,this._firstCall=!0}return it(t,[{key:Symbol.iterator,value:function(){return this}},{key:"next",value:function(){var t=this._currentNode;if(this._firstCall&&(this._firstCall=!1,!t._deleted&&this._filter(t)))return{value:t,done:!1};do{if(t._deleted||t.constructor!==YXmlFragment._YXmlElement&&t.constructor!==YXmlFragment||null===t._start){for(;t!==this._root;){if(null!==t._right){t=t._right;break}t=t._parent}t===this._root&&(t=null)}else t=t._start;if(t===this._root)break}while(null!==t&&(t._deleted||!this._filter(t)));return this._currentNode=t,null===t?{done:!0}:{value:t,done:!1}}}]),t}(),YXmlFragment=function(t){function YXmlFragment(){rt(this,YXmlFragment);var t=at(this,(YXmlFragment.__proto__||Object.getPrototypeOf(YXmlFragment)).call(this));t._dom=null,t._domFilter=k,t._domObserver=null;var e=!0;return t._mutualExclude=function(n){if(e){e=!1;try{n()}catch(t){console.error(t)}null!==t._domObserver&&t._domObserver.takeRecords(),e=!0}},t}return st(YXmlFragment,t),it(YXmlFragment,[{key:"createTreeWalker",value:function(t){return new Bt(this,t)}},{key:"querySelector",value:function(t){t=t.toUpperCase();var e=new Bt(this,function(e){return e.nodeName===t}),n=e.next();return n.done?null:n.value}},{key:"querySelectorAll",value:function(t){return t=t.toUpperCase(),Array.from(new Bt(this,function(e){return e.nodeName===t}))}},{key:"enableSmartScrolling",value:function(t){this._scrollElement=t,this.forEach(function(e){e.enableSmartScrolling(t)})}},{key:"setDomFilter",value:function(t){this._domFilter=t,this.forEach(function(e){e.setDomFilter(t)})}},{key:"_callObserver",value:function(t,e,n){this._callEventHandler(t,new YXmlEvent(this,e,n))}},{key:"toString",value:function(){return this.map(function(t){return t.toString()}).join("")}},{key:"_delete",value:function(t,e){this._unbindFromDom(),ot(YXmlFragment.prototype.__proto__||Object.getPrototypeOf(YXmlFragment.prototype),"_delete",this).call(this,t,e)}},{key:"_unbindFromDom",value:function(){null!=this._domObserver&&(this._domObserver.disconnect(),this._domObserver=null),null!=this._dom&&(this._dom._yxml=null,this._dom=null)}},{key:"insertDomElementsAfter",value:function(t,e,n){var r=R(this,e,n);return this.insertAfter(t,r),r}},{key:"insertDomElements",value:function(t,e,n){var r=R(this,e,n);return this.insert(t,r),r}},{key:"getDom",value:function(){return this._dom}},{key:"bindToDom",value:function(t,e){null!=this._dom&&this._unbindFromDom(),null!=t._yxml&&t._yxml._unbindFromDom(),t.innerHTML="",this.forEach(function(n){t.insertBefore(n.getDom(e),null)}),this._bindToDom(t,e)}},{key:"_bindToDom",value:function(t,e){var n=this;if(e=e||document,this._dom=t,t._yxml=this,(this.constructor===YXmlFragment||this._parent===this._y)&&null!==this._parent){this._y.on("beforeTransaction",wt),this._y.on("afterTransaction",B);var r=function(t){if(!t._deleted){for(var e=!1,r=t;r!==n._y;){if(r===n){e=!0;break}r=r._parent}if(e){var i=new Map;if(void 0!==t.getAttributes){var o=t.getAttributes();for(var s in o)i.set(s,o[s])}var a=n._domFilter(t.nodeName,new Map(i));null===a?t._delete(n._y):i.forEach(function(e,n){a.has(n)||t.removeAttribute(n)})}}};return this._y.on("beforeObserverCalls",function(t,e){e.changedTypes.forEach(function(t,e){(t.size>1||!t.has(null))&&r(e)}),e.newTypes.forEach(r)}),this.observeDeep(function(t){O.call(n,t,e)}),"undefined"!=typeof MutationObserver&&(this._y.on("beforeTransaction",function(){n._domObserverListener(n._domObserver.takeRecords())}),this._domObserverListener=function(t){n._mutualExclude(function(){n._y.transact(function(){var e=new Set;t.forEach(function(t){var r=t.target,i=r._yxml;if(null!=i&&i.constructor!==YXmlHook)switch(t.type){case"characterData":for(var o=Ut(i.toString(),r.nodeValue),s=0,a=0;a<o.length;a++){var l=o[a];0===l[0]?s+=l[1].length:-1===l[0]?i.delete(s,l[1].length):(i.insert(s,l[1]),s+=l[1].length)}break;case"attributes":if(i.constructor===YXmlFragment)break;var u=t.attributeName,h=r.getAttribute(u),c=new Map;c.set(u,h),n._domFilter(r.nodeName,c).size>0&&i.constructor!==YXmlFragment&&i.getAttribute(u)!==h&&(null==h?i.removeAttribute(u):i.setAttribute(u,h));break;case"childList":e.add(t.target)}});var r=!0,i=!1,o=void 0;try{for(var s,a=e[Symbol.iterator]();!(r=(s=a.next()).done);r=!0){var l=s.value;null!=l._yxml&&!1!==l._yxml&&E(l)}}catch(t){i=!0,o=t}finally{try{!r&&a.return&&a.return()}finally{if(i)throw o}}})})},this._domObserver=new MutationObserver(this._domObserverListener),this._domObserver.observe(t,{childList:!0,attributes:!0,characterData:!0,subtree:!0})),t}}},{key:"_logString",value:function(){var t=null!==this._left?this._left._lastId:null,e=null!==this._origin?this._origin._lastId:null;return"YXml(id:"+g(this._id)+",left:"+g(t)+",origin:"+g(e)+",right:"+this._right+",parent:"+g(this._parent)+",parentSub:"+this._parentSub+")"}}]),YXmlFragment}(YArray),YXmlElement=function(t){function YXmlElement(t,e,n){rt(this,YXmlElement);var r=at(this,(YXmlElement.__proto__||Object.getPrototypeOf(YXmlElement)).call(this));return r.nodeName=null,r._scrollElement=null,"string"==typeof t?r.nodeName=t.toUpperCase():null!=t&&null!=t.nodeType&&t.nodeType===t.ELEMENT_NODE?(r.nodeName=t.nodeName,r._setDom(t,n)):r.nodeName="UNDEFINED","function"==typeof e&&(r._domFilter=e),r}return st(YXmlElement,t),it(YXmlElement,[{key:"_copy",value:function(t){var e=ot(YXmlElement.prototype.__proto__||Object.getPrototypeOf(YXmlElement.prototype),"_copy",this).call(this,t);return e.nodeName=this.nodeName,e}},{key:"_setDom",value:function(t,e){var n=this;if(null!=this._dom)throw new Error("Only call this method if you know what you are doing ;)");if(null!=t._yxml)throw new Error("Already bound to an YXml type");for(var r=new Map,i=0;i<t.attributes.length;i++){var o=t.attributes[i];r.set(o.name,o.value)}return r=this._domFilter(t,r),r.forEach(function(t,e){n.setAttribute(e,t)}),this.insertDomElements(0,Array.prototype.slice.call(t.childNodes),e),this._bindToDom(t,e),t}},{key:"_fromBinary",value:function(t,e){var n=ot(YXmlElement.prototype.__proto__||Object.getPrototypeOf(YXmlElement.prototype),"_fromBinary",this).call(this,t,e);return this.nodeName=e.readVarString(),n}},{key:"_toBinary",value:function(t){ot(YXmlElement.prototype.__proto__||Object.getPrototypeOf(YXmlElement.prototype),"_toBinary",this).call(this,t),t.writeVarString(this.nodeName)}},{key:"_integrate",value:function(t){if(null===this.nodeName)throw new Error("nodeName must be defined!");this._domFilter===k&&void 0!==this._parent._domFilter&&(this._domFilter=this._parent._domFilter),ot(YXmlElement.prototype.__proto__||Object.getPrototypeOf(YXmlElement.prototype),"_integrate",this).call(this,t)}},{key:"toString",value:function(){var t=this.getAttributes(),e=[],n=[];for(var r in t)n.push(r);n.sort();for(var i=n.length,o=0;o<i;o++){var s=n[o];e.push(s+'="'+t[s]+'"')}var a=this.nodeName.toLocaleLowerCase();return"<"+a+(e.length>0?" "+e.join(" "):"")+">"+ot(YXmlElement.prototype.__proto__||Object.getPrototypeOf(YXmlElement.prototype),"toString",this).call(this)+"</"+a+">"}},{key:"removeAttribute",value:function(){return YMap.prototype.delete.apply(this,arguments)}},{key:"setAttribute",value:function(){return YMap.prototype.set.apply(this,arguments)}},{key:"getAttribute",value:function(){return YMap.prototype.get.apply(this,arguments)}},{key:"getAttributes",value:function(){var t={},e=!0,n=!1,r=void 0;try{for(var i,o=this._map[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){var s=lt(i.value,2),a=s[0],l=s[1];l._deleted||(t[a]=l._content[0])}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}return t}},{key:"getDom",value:function(t){t=t||document;var e=this._dom;if(null==e){e=t.createElement(this.nodeName),e._yxml=this;var n=this.getAttributes();for(var r in n)e.setAttribute(r,n[r]);this.forEach(function(n){e.appendChild(n.getDom(t))}),this._bindToDom(e,t)}return e}}]),YXmlElement}(YXmlFragment),xt={},YXmlHook=function(t){function YXmlHook(t,e){rt(this,YXmlHook);var n=at(this,(YXmlHook.__proto__||Object.getPrototypeOf(YXmlHook)).call(this));return n._dom=null,n.hookName=null,void 0!==t&&(n.hookName=t,n._dom=e,e._yjsHook=t,e._yxml=n,J(t).fillType(e,n)),n}return st(YXmlHook,t),it(YXmlHook,[{key:"getDom",value:function(t){if(t=t||document,null===this._dom){var e=J(this.hookName).createDom(this);this._dom=e,e._yxml=this,e._yjsHook=this.hookName}return this._dom}},{key:"_unbindFromDom",value:function(){this._dom._yxml=null,this._yxml=null}},{key:"_fromBinary",value:function(t,e){var n=ot(YXmlHook.prototype.__proto__||Object.getPrototypeOf(YXmlHook.prototype),"_fromBinary",this).call(this,t,e);return this.hookName=e.readVarString(),n}},{key:"_toBinary",value:function(t){ot(YXmlHook.prototype.__proto__||Object.getPrototypeOf(YXmlHook.prototype),"_toBinary",this).call(this,t),t.writeVarString(this.hookName)}},{key:"_integrate",value:function(t){if(null===this.hookName)throw new Error("hookName must be defined!");ot(YXmlHook.prototype.__proto__||Object.getPrototypeOf(YXmlHook.prototype),"_integrate",this).call(this,t)}},{key:"setDomFilter",value:function(){}},{key:"enableSmartScrolling",value:function(){}}]),YXmlHook}(YMap);YXmlHook.addHook=H;var YXmlText=function(t){function YXmlText(t){rt(this,YXmlText);var e=null,n=null;null!=t&&(null!=t.nodeType&&t.nodeType===t.TEXT_NODE?(e=t,n=e.nodeValue):"string"==typeof t&&(n=t));var r=at(this,(YXmlText.__proto__||Object.getPrototypeOf(YXmlText)).call(this,n));return r._dom=null,r._domObserver=null,r._domObserverListener=null,r._scrollElement=null,null!==e&&r._setDom(t),r}return st(YXmlText,t),it(YXmlText,[{key:"setDomFilter",value:function(){}},{key:"enableSmartScrolling",value:function(t){this._scrollElement=t}},{key:"_setDom",value:function(t){null!=this._dom&&this._unbindFromDom(),null!=t._yxml&&t._yxml._unbindFromDom(),this._dom=t,t._yxml=this}},{key:"getDom",value:function(t){if(t=t||document,null===this._dom){var e=t.createTextNode(this.toString());return this._setDom(e),e}return this._dom}},{key:"_delete",value:function(t,e){this._unbindFromDom(),ot(YXmlText.prototype.__proto__||Object.getPrototypeOf(YXmlText.prototype),"_delete",this).call(this,t,e)}},{key:"_unbindFromDom",value:function(){null!=this._domObserver&&(this._domObserver.disconnect(),this._domObserver=null),null!=this._dom&&(this._dom._yxml=null,this._dom=null)}}]),YXmlText}(YText);YXmlFragment._YXmlElement=YXmlElement,YXmlFragment._YXmlHook=YXmlHook;var Dt=new Map,It=new Map;W(0,ItemJSON),W(1,ItemString),W(2,Delete),W(3,YArray),W(4,YMap),W(5,YText),W(6,YXmlFragment),W(7,YXmlElement),W(8,YXmlText),W(9,YXmlHook);var Tt=16777215,Nt=function(){function t(e,n){rt(this,t),this.user=Tt,this.name=e,this.type=X(n)}return it(t,[{key:"equals",value:function(t){return null!==t&&t.user===this.user&&t.name===this.name&&t.type===this.type}},{key:"lessThan",value:function(t){return this.user<t.user||this.user===t.user&&(this.name<t.name||this.name===t.name&&this.type<t.type)}}]),t}(),Lt=function(t){function e(t){rt(this,e);var n=at(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return n.y=t,n}return st(e,t),it(e,[{key:"logTable",value:function(){var t=[];this.iterate(null,null,function(e){t.push({id:g(e),origin:g(null===e._origin?null:e._origin._lastId),left:g(null===e._left?null:e._left._lastId),right:g(e._right),right_origin:g(e._right_origin),parent:g(e._parent),parentSub:e._parentSub,deleted:e._deleted,content:JSON.stringify(e._content)})}),console.table(t)}},{key:"get",value:function(t){var e=this.find(t);if(null===e&&t instanceof Nt){var n=z(t.type),r=this.y;e=new n,e._id=t,e._parent=r,r.transact(function(){e._integrate(r)}),this.put(e)}return e}},{key:"getItem",value:function(t){var e=this.findWithUpperBound(t);if(null===e)return null;var n=e._id;return t.user===n.user&&t.clock<n.clock+e._length?e:null}},{key:"getItemCleanStart",value:function(t){var e=this.getItem(t);if(null===e||1===e._length)return e;var n=e._id;return n.clock===t.clock?e:e._splitAt(this.y,t.clock-n.clock)}},{key:"getItemCleanEnd",value:function(t){var e=this.getItem(t);if(null===e||1===e._length)return e;var n=e._id;return n.clock+e._length-1===t.clock?e:(e._splitAt(this.y,t.clock-n.clock+1),e)}}]),e}(ht),Vt=function(){function t(e){rt(this,t),this.y=e,this.state=new Map}return it(t,[{key:"logTable",value:function(){var t=[],e=!0,n=!1,r=void 0;try{for(var i,o=this.state[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){var s=lt(i.value,2),a=s[0],l=s[1];t.push({user:a,state:l})}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}console.table(t)}},{key:"getNextID",value:function(t){var e=this.y.userID,n=this.getState(e);return this.setState(e,n+t),
new ct(e,n)}},{key:"updateRemoteState",value:function(t){for(var e=t._id.user,n=this.state.get(e);null!==t&&t._id.clock===n;)n+=t._length,t=this.y.os.get(new ct(e,n));this.state.set(e,n)}},{key:"getState",value:function(t){var e=this.state.get(t);return null==e?0:e}},{key:"setState",value:function(t,e){var n=this.y._transaction.beforeState;n.has(t)||n.set(t,this.getState(t)),this.state.set(t,e)}}]),t}(),Pt=function(){function t(){rt(this,t),this._eventListener=new Map}return it(t,[{key:"_getListener",value:function(t){var e=this._eventListener.get(t);return void 0===e&&(e={once:new Set,on:new Set},this._eventListener.set(t,e)),e}},{key:"once",value:function(t,e){this._getListener(t).once.add(e)}},{key:"on",value:function(t,e){this._getListener(t).on.add(e)}},{key:"off",value:function(t,e){if(null==t||null==e)throw new Error("You must specify event name and function!");var n=this._eventListener.get(t);void 0!==n&&n.remove(e)}},{key:"emit",value:function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),r=1;r<e;r++)n[r-1]=arguments[r];var i=this._eventListener.get(t);void 0!==i?(i.on.forEach(function(t){return t.apply(null,n)}),i.once.forEach(function(t){return t.apply(null,n)}),i.once=new Set):"error"===t&&console.error(n[0])}},{key:"destroy",value:function(){this._eventListener=null}}]),t}(),Ct=function t(e,n){rt(this,t),this.created=new Date;var r=n.beforeState;this.toState=new ct(e.userID,e.ss.getState(e.userID)-1),r.has(e.userID)?this.fromState=new ct(e.userID,r.get(e.userID)):this.fromState=this.toState,this.deletedStructs=n.deletedStructs},jt=function(){function t(e){var n=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};rt(this,t),this.options=r,r.captureTimeout=null==r.captureTimeout?500:r.captureTimeout,this._undoBuffer=[],this._redoBuffer=[],this._scope=e,this._undoing=!1,this._redoing=!1;var i=e._y;this.y=i,i.on("afterTransaction",function(t,i,o){if(!o&&i.changedParentTypes.has(e)){var s=new Ct(t,i);if(n._undoing)n._redoBuffer.push(s);else{var a=n._undoBuffer.length>0?n._undoBuffer[n._undoBuffer.length-1]:null;null!==a&&s.created-a.created<=r.captureTimeout?(a.created=s.created,a.toState=s.toState,s.deletedStructs.forEach(a.deletedStructs.add,a.deletedStructs)):n._undoBuffer.push(s),n._redoing||(n._redoBuffer=[])}}})}return it(t,[{key:"undo",value:function(){this._undoing=!0;var t=Q(this.y,this._scope,this._undoBuffer);return this._undoing=!1,t}},{key:"redo",value:function(){this._redoing=!0;var t=Q(this.y,this._scope,this._redoBuffer);return this._redoing=!1,t}}]),t}(),Mt=1e3,Ft=60*Mt,Rt=60*Ft,Yt=24*Rt,Ht=365.25*Yt,Jt=function(t,e){e=e||{};var n=void 0===t?"undefined":nt(t);if("string"===n&&t.length>0)return Z(t);if("number"===n&&!1===isNaN(t))return e.long?K(t):G(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))},Wt=t(function(t,e){function n(t){var n,r=0;for(n in t)r=(r<<5)-r+t.charCodeAt(n),r|=0;return e.colors[Math.abs(r)%e.colors.length]}function r(t){function r(){if(r.enabled){var t=r,n=+new Date,i=n-(l||n);t.diff=i,t.prev=l,t.curr=n,l=n;for(var o=new Array(arguments.length),s=0;s<o.length;s++)o[s]=arguments[s];o[0]=e.coerce(o[0]),"string"!=typeof o[0]&&o.unshift("%O");var a=0;o[0]=o[0].replace(/%([a-zA-Z%])/g,function(n,r){if("%%"===n)return n;a++;var i=e.formatters[r];if("function"==typeof i){var s=o[a];n=i.call(t,s),o.splice(a,1),a--}return n}),e.formatArgs.call(t,o);(r.log||e.log||console.log.bind(console)).apply(t,o)}}return r.namespace=t,r.enabled=e.enabled(t),r.useColors=e.useColors(),r.color=n(t),"function"==typeof e.init&&e.init(r),r}function i(t){e.save(t),e.names=[],e.skips=[];for(var n=("string"==typeof t?t:"").split(/[\s,]+/),r=n.length,i=0;i<r;i++)n[i]&&(t=n[i].replace(/\*/g,".*?"),"-"===t[0]?e.skips.push(new RegExp("^"+t.substr(1)+"$")):e.names.push(new RegExp("^"+t+"$")))}function o(){e.enable("")}function s(t){var n,r;for(n=0,r=e.skips.length;n<r;n++)if(e.skips[n].test(t))return!1;for(n=0,r=e.names.length;n<r;n++)if(e.names[n].test(t))return!0;return!1}function a(t){return t instanceof Error?t.stack||t.message:t}e=t.exports=r.debug=r.default=r,e.coerce=a,e.disable=o,e.enable=i,e.enabled=s,e.humanize=Jt,e.names=[],e.skips=[],e.formatters={};var l}),zt=(Wt.coerce,Wt.disable,Wt.enable,Wt.enabled,Wt.humanize,Wt.names,Wt.skips,Wt.formatters,t(function(t,e){function n(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function r(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+t[0]+(n?"%c ":" ")+"+"+e.humanize(this.diff),n){var r="color: "+this.color;t.splice(1,0,r,"color: inherit");var i=0,o=0;t[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(i++,"%c"===t&&(o=i))}),t.splice(o,0,r)}}function i(){return"object"===("undefined"==typeof console?"undefined":nt(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function o(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=t}catch(t){}}function s(){var t;try{t=e.storage.debug}catch(t){}return!t&&"undefined"!=typeof process&&"env"in process&&(t=process.env.DEBUG),t}e=t.exports=Wt,e.log=i,e.formatArgs=r,e.save=o,e.load=s,e.useColors=n,e.storage="undefined"!=typeof chrome&&void 0!==chrome.storage?chrome.storage.local:function(){try{return window.localStorage}catch(t){}}(),e.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],e.formatters.j=function(t){try{return JSON.stringify(t)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}},e.enable(s())})),Xt=(zt.log,zt.formatArgs,zt.save,zt.load,zt.useColors,zt.storage,zt.colors,function(){function t(e,n){if(rt(this,t),this.y=e,this.opts=n,null==n.role||"master"===n.role)this.role="master";else{if("slave"!==n.role)throw new Error("Role must be either 'master' or 'slave'!");this.role="slave"}this.log=zt("y:connector"),this.logMessage=zt("y:connector-message"),this._forwardAppliedStructs=n.forwardAppliedOperations||!1,this.role=n.role,this.connections=new Map,this.isSynced=!1,this.userEventListeners=[],this.whenSyncedListeners=[],this.currentSyncTarget=null,this.debug=!0===n.debug,this.broadcastBuffer=new pt,this.broadcastBufferSize=0,this.protocolVersion=11,this.authInfo=n.auth||null,this.checkAuth=n.checkAuth||function(){return Promise.resolve("write")},null==n.maxBufferLength?this.maxBufferLength=-1:this.maxBufferLength=n.maxBufferLength}return it(t,[{key:"reconnect",value:function(){this.log("reconnecting..")}},{key:"disconnect",value:function(){return this.log("discronnecting.."),this.connections=new Map,this.isSynced=!1,this.currentSyncTarget=null,this.whenSyncedListeners=[],Promise.resolve()}},{key:"onUserEvent",value:function(t){this.userEventListeners.push(t)}},{key:"removeUserEventListener",value:function(t){this.userEventListeners=this.userEventListeners.filter(function(e){return t!==e})}},{key:"userLeft",value:function(t){if(this.connections.has(t)){this.log("%s: User left %s",this.y.userID,t),this.connections.delete(t),this._setSyncedWith(null);var e=!0,n=!1,r=void 0;try{for(var i,o=this.userEventListeners[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){(0,i.value)({action:"userLeft",user:t})}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}}}},{key:"userJoined",value:function(t,e,n){if(null==e)throw new Error("You must specify the role of the joined user!");if(this.connections.has(t))throw new Error("This user already joined!");this.log("%s: User joined %s",this.y.userID,t),this.connections.set(t,{uid:t,isSynced:!1,role:e,processAfterAuth:[],processAfterSync:[],auth:n||null,receivedSyncStep2:!1});var r={};r.promise=new Promise(function(t){r.resolve=t}),this.connections.get(t).syncStep2=r;var i=!0,o=!1,s=void 0;try{for(var a,l=this.userEventListeners[Symbol.iterator]();!(i=(a=l.next()).done);i=!0){(0,a.value)({action:"userJoined",user:t,role:e})}}catch(t){o=!0,s=t}finally{try{!i&&l.return&&l.return()}finally{if(o)throw s}}this._syncWithUser(t)}},{key:"whenSynced",value:function(t){this.isSynced?t():this.whenSyncedListeners.push(t)}},{key:"_syncWithUser",value:function(t){"slave"!==this.role&&u(this,t)}},{key:"_fireIsSyncedListeners",value:function(){if(!this.isSynced){this.isSynced=!0;var t=!0,e=!1,n=void 0;try{for(var r,i=this.whenSyncedListeners[Symbol.iterator]();!(t=(r=i.next()).done);t=!0){(0,r.value)()}}catch(t){e=!0,n=t}finally{try{!t&&i.return&&i.return()}finally{if(e)throw n}}this.whenSyncedListeners=[],this.y.emit("synced")}}},{key:"send",value:function(t,e){var n=this.y;if(!(e instanceof ArrayBuffer||e instanceof Uint8Array))throw new Error("Expected Message to be an ArrayBuffer or Uint8Array - don't use this method to send custom messages");this.log("User%s to User%s: Send '%y'",n.userID,t,e),this.logMessage("User%s to User%s: Send %Y",n.userID,t,[n,e])}},{key:"broadcast",value:function(t){var e=this.y;if(!(t instanceof ArrayBuffer||t instanceof Uint8Array))throw new Error("Expected Message to be an ArrayBuffer or Uint8Array - don't use this method to send custom messages");this.log("User%s: Broadcast '%y'",e.userID,t),this.logMessage("User%s: Broadcast: %Y",e.userID,[e,t])}},{key:"broadcastStruct",value:function(t){var e=this,n=0===this.broadcastBuffer.length;if(n&&(this.broadcastBuffer.writeVarString(this.y.room),this.broadcastBuffer.writeVarString("update"),this.broadcastBufferSize=0,this.broadcastBufferSizePos=this.broadcastBuffer.pos,this.broadcastBuffer.writeUint32(0)),this.broadcastBufferSize++,t._toBinary(this.broadcastBuffer),this.maxBufferLength>0&&this.broadcastBuffer.length>this.maxBufferLength){var r=this.broadcastBuffer;r.setUint32(this.broadcastBufferSizePos,this.broadcastBufferSize),this.broadcastBuffer=new pt,this.whenRemoteResponsive().then(function(){e.broadcast(r.createBuffer())})}else n&&setTimeout(function(){if(e.broadcastBuffer.length>0){var t=e.broadcastBuffer;t.setUint32(e.broadcastBufferSizePos,e.broadcastBufferSize),e.broadcast(t.createBuffer()),e.broadcastBuffer=new pt}},0)}},{key:"whenRemoteResponsive",value:function(){return new Promise(function(t){setTimeout(t,100)})}},{key:"receiveMessage",value:function(t,e,n){var r=this,i=this.y,o=i.userID;if(n=n||!1,!(e instanceof ArrayBuffer||e instanceof Uint8Array))return Promise.reject(new Error("Expected Message to be an ArrayBuffer or Uint8Array!"));if(t===o)return Promise.resolve();var s=new vt(e),a=new pt,l=s.readVarString();a.writeVarString(l);var u=s.readVarString(),h=this.connections.get(t);if(this.log("User%s from User%s: Receive '%s'",o,t,u),this.logMessage("User%s from User%s: Receive %Y",o,t,[i,e]),null==h&&!n)throw new Error("Received message from unknown peer!");if("sync step 1"===u||"sync step 2"===u){var c=s.readVarUint();if(null==h.auth)return h.processAfterAuth.push([u,h,s,a,t]),this.checkAuth(c,i,t).then(function(t){null==h.auth&&(h.auth=t,i.emit("userAuthenticated",{user:h.uid,auth:t}));var e=h.processAfterAuth;h.processAfterAuth=[],e.forEach(function(t){return r.computeMessage(t[0],t[1],t[2],t[3],t[4])})})}!n&&null==h.auth||"update"===u&&!h.isSynced?h.processAfterSync.push([u,h,s,a,t,!1]):this.computeMessage(u,h,s,a,t,n)}},{key:"computeMessage",value:function(t,e,n,i,o,s){if("sync step 1"!==t||"write"!==e.auth&&"read"!==e.auth){var a=this.y;a.transact(function(){if("sync step 2"===t&&"write"===e.auth)d(n,i,a,e,o);else{if("update"!==t||!s&&"write"!==e.auth)throw new Error("Unable to receive message");r(n,i,a,e,o)}},!0)}else c(n,i,this.y,e,o)}},{key:"_setSyncedWith",value:function(t){var e=this;if(null!=t){var n=this.connections.get(t);n.isSynced=!0;var r=n.processAfterSync;n.processAfterSync=[],r.forEach(function(t){e.computeMessage(t[0],t[1],t[2],t[3],t[4])})}var i=Array.from(this.connections.values());i.length>0&&i.every(function(t){return t.isSynced})&&this._fireIsSyncedListeners()}}]),t}()),Y=function(t){function Y(t){rt(this,Y);var e=at(this,(Y.__proto__||Object.getPrototypeOf(Y)).call(this));return e._opts=t,e.userID=null!=t._userID?t._userID:q(),e.share={},e.ds=new dt(e),e.os=new Lt(e),e.ss=new Vt(e),e.connector=new Y[t.connector.name](e,t.connector),null!=t.persistence?(e.persistence=new Y[t.persistence.name](e,t.persistence),e.persistence.retrieveContent()):e.persistence=null,e.connected=!0,e._missingStructs=new Map,e._readyToIntegrate=[],e._transaction=null,e}return st(Y,t),it(Y,[{key:"_beforeChange",value:function(){}},{key:"transact",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=null===this._transaction;n&&(this._transaction=new yt(this),this.emit("beforeTransaction",this,this._transaction,e));try{t(this)}catch(t){console.error(t)}if(n){this.emit("beforeObserverCalls",this,this._transaction,e);var r=this._transaction;this._transaction=null,r.changedTypes.forEach(function(t,n){n._deleted||n._callObserver(r,t,e)}),r.changedParentTypes.forEach(function(t,e){e._deleted||(t=t.filter(function(t){return!t.target._deleted}),t.forEach(function(t){t.currentTarget=e}),e._deepEventHandler.callEventListeners(r,t))}),this.emit("afterTransaction",this,r,e)}}},{key:"define",value:function(t,e){var n=new Nt(t,e),r=this.os.get(n);if(void 0===this.share[t])this.share[t]=r;else if(this.share[t]!==r)throw new Error("Type is already defined with a different constructor");return r}},{key:"get",value:function(t){return this.share[t]}},{key:"disconnect",value:function(){return this.connected?(this.connected=!1,this.connector.disconnect()):Promise.resolve()}},{key:"reconnect",value:function(){return this.connected?Promise.resolve():(this.connected=!0,this.connector.reconnect())}},{key:"destroy",value:function(){this.share=null,null!=this.connector.destroy?this.connector.destroy():this.connector.disconnect(),this.os=null,this.ds=null,this.ss=null}},{key:"whenSynced",value:function(){var t=this;return new Promise(function(e){t.once("synced",function(){e()})})}},{key:"_start",get:function(){return null},set:function(t){return null}},{key:"room",get:function(){return this._opts.connector.room}}]),Y}(Pt);return Y.extend=function(){for(var t=0;t<arguments.length;t++){var e=arguments[t];if("function"!=typeof e)throw new Error("Expected a function!");e(Y)}},Y.AbstractConnector=Xt,Y.Persisence=et,Y.Array=YArray,Y.Map=YMap,Y.Text=YText,Y.XmlElement=YXmlElement,Y.XmlFragment=YXmlFragment,Y.XmlText=YXmlText,Y.XmlHook=YXmlHook,Y.utils={BinaryDecoder:vt,UndoManager:jt,getRelativePosition:A,fromRelativePosition:U,addType:W},Y.debug=zt,zt.formatters.Y=_,zt.formatters.y=v,Y});
//# sourceMappingURL=y.js.map
/**
 * en-y-websockets-client - Websockets connector for Yjs (browser/node client)
 * @version v10.0.10
 * @license MIT
 */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.yWebsocketsClient=e()}(this,function(){"use strict";function t(t,e){return e={exports:{}},t(e,e.exports),e.exports}function e(t){if(t=String(t),!(t.length>100)){var e=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(t);if(e){var n=parseFloat(e[1]);switch((e[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return n*$;case"days":case"day":case"d":return n*K;case"hours":case"hour":case"hrs":case"hr":case"h":return n*J;case"minutes":case"minute":case"mins":case"min":case"m":return n*W;case"seconds":case"second":case"secs":case"sec":case"s":return n*F;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function n(t){return t>=K?Math.round(t/K)+"d":t>=J?Math.round(t/J)+"h":t>=W?Math.round(t/W)+"m":t>=F?Math.round(t/F)+"s":t+"ms"}function o(t){return r(t,K,"day")||r(t,J,"hour")||r(t,W,"minute")||r(t,F,"second")||t+" ms"}function r(t,e,n){if(!(t<e))return t<1.5*e?Math.floor(t/e)+" "+n:Math.ceil(t/e)+" "+n+"s"}function i(t,e){var n=t;e=e||P.location,null==t&&(t=e.protocol+"//"+e.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?e.protocol+t:e.host+t),/^(https?|wss?):\/\//.test(t)||(tt("protocol-less url %s",t),t=void 0!==e?e.protocol+"//"+t:"https://"+t),tt("parse %s",t),n=U(t)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";var o=-1!==n.host.indexOf(":"),r=o?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+r+":"+n.port,n.href=n.protocol+"://"+r+(e&&e.port===n.port?"":":"+n.port),n}function s(t){if(!t||"object"!==(void 0===t?"undefined":L(t)))return!1;if(rt(t)){for(var e=0,n=t.length;e<n;e++)if(s(t[e]))return!0;return!1}if("function"==typeof P.Buffer&&P.Buffer.isBuffer&&P.Buffer.isBuffer(t)||"function"==typeof P.ArrayBuffer&&t instanceof ArrayBuffer||st&&t instanceof Blob||at&&t instanceof File)return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return s(t.toJSON(),!0);for(var o in t)if(Object.prototype.hasOwnProperty.call(t,o)&&s(t[o]))return!0;return!1}function a(t){return P.Buffer&&P.Buffer.isBuffer(t)||P.ArrayBuffer&&t instanceof ArrayBuffer}function c(t,e){if(!t)return t;if(pt(t)){var n={_placeholder:!0,num:e.length};return e.push(t),n}if(ut(t)){for(var o=new Array(t.length),r=0;r<t.length;r++)o[r]=c(t[r],e);return o}if("object"===(void 0===t?"undefined":L(t))&&!(t instanceof Date)){var o={};for(var i in t)o[i]=c(t[i],e);return o}return t}function h(t,e){if(!t)return t;if(t&&t._placeholder)return e[t.num];if(ut(t))for(var n=0;n<t.length;n++)t[n]=h(t[n],e);else if("object"===(void 0===t?"undefined":L(t)))for(var o in t)t[o]=h(t[o],e);return t}function u(t,e,n){function o(t,i){if(o.count<=0)throw new Error("after called too many times");--o.count,t?(r=!0,e(t),e=n):0!==o.count||r||e(null,i)}var r=!1;return n=n||p,o.count=t,0===t?e():o}function p(){}function f(t){for(var e=0;e<t.length;e++){var n=t[e];if(n.buffer instanceof ArrayBuffer){var o=n.buffer;if(n.byteLength!==o.byteLength){var r=new Uint8Array(n.byteLength);r.set(new Uint8Array(o,n.byteOffset,n.byteLength)),o=r.buffer}t[e]=o}}}function l(t,e){e=e||{};var n=new Tt;f(t);for(var o=0;o<t.length;o++)n.append(t[o]);return e.type?n.getBlob(e.type):n.getBlob()}function d(t,e){return f(t),new Blob(t,e||{})}function y(t){this.path=t.path,this.hostname=t.hostname,this.port=t.port,this.secure=t.secure,this.query=t.query,this.timestampParam=t.timestampParam,this.timestampRequests=t.timestampRequests,this.readyState="",this.agent=t.agent||!1,this.socket=t.socket,this.enablesXDR=t.enablesXDR,this.pfx=t.pfx,this.key=t.key,this.passphrase=t.passphrase,this.cert=t.cert,this.ca=t.ca,this.ciphers=t.ciphers,this.rejectUnauthorized=t.rejectUnauthorized,this.forceNode=t.forceNode,this.extraHeaders=t.extraHeaders,this.localAddress=t.localAddress}function m(t){var e="";do{e=Lt[t%qt]+e,t=Math.floor(t/qt)}while(t>0);return e}function g(t){var e=0;for(zt=0;zt<t.length;zt++)e=e*qt+Mt[t.charAt(zt)];return e}function v(){var t=m(+new Date);return t!==Dt?(Vt=0,Dt=t):t+"."+m(Vt++)}function b(t){var e=t&&t.forceBase64;Yt&&!e||(this.supportsBinary=!1),Rt.call(this,t)}function k(){}function w(t){if(Wt.call(this,t),this.requestTimeout=t.requestTimeout,this.extraHeaders=t.extraHeaders,P.location){var e="https:"===location.protocol,n=location.port;n||(n=e?443:80),this.xd=t.hostname!==P.location.hostname||n!==t.port,this.xs=t.secure!==e}}function E(t){this.method=t.method||"GET",this.uri=t.uri,this.xd=!!t.xd,this.xs=!!t.xs,this.async=!1!==t.async,this.data=void 0!==t.data?t.data:null,this.agent=t.agent,this.isBinary=t.isBinary,this.supportsBinary=t.supportsBinary,this.enablesXDR=t.enablesXDR,this.requestTimeout=t.requestTimeout,this.pfx=t.pfx,this.key=t.key,this.passphrase=t.passphrase,this.cert=t.cert,this.ca=t.ca,this.ciphers=t.ciphers,this.rejectUnauthorized=t.rejectUnauthorized,this.extraHeaders=t.extraHeaders,this.create()}function A(){for(var t in E.requests)E.requests.hasOwnProperty(t)&&E.requests[t].abort()}function _(){}function C(t){Wt.call(this,t),this.query=this.query||{},Qt||(P.___eio||(P.___eio=[]),Qt=P.___eio),this.index=Qt.length;var e=this;Qt.push(function(t){e.onData(t)}),this.query.j=this.index,P.document&&P.addEventListener&&P.addEventListener("beforeunload",function(){e.script&&(e.script.onerror=_)},!1)}function N(t){t&&t.forceBase64&&(this.supportsBinary=!1),this.perMessageDeflate=t.perMessageDeflate,this.usingBrowserWebSocket=se&&!t.forceNode,this.protocols=t.protocols,this.usingBrowserWebSocket||(ae=ee),Rt.call(this,t)}function T(t){var e=!1,n=!1,o=!1!==t.jsonp;if(P.location){var r="https:"===location.protocol,i=location.port;i||(i=r?443:80),e=t.hostname!==location.hostname||i!==t.port,n=t.secure!==r}if(t.xdomain=e,t.xscheme=n,"open"in new wt(t)&&!t.forceJSONP)return new Kt(t);if(!o)throw new Error("JSONP disabled");return new Gt(t)}function S(t,e){if(!(this instanceof S))return new S(t,e);e=e||{},t&&"object"===(void 0===t?"undefined":L(t))&&(e=t,t=null),t?(t=U(t),e.hostname=t.host,e.secure="https"===t.protocol||"wss"===t.protocol,e.port=t.port,t.query&&(e.query=t.query)):e.host&&(e.hostname=U(e.host).host),this.secure=null!=e.secure?e.secure:P.location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.agent=e.agent||!1,this.hostname=e.hostname||(P.location?location.hostname:"localhost"),this.port=e.port||(P.location&&location.port?location.port:this.secure?443:80),this.query=e.query||{},"string"==typeof this.query&&(this.query=Ht.decode(this.query)),this.upgrade=!1!==e.upgrade,this.path=(e.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!e.forceJSONP,this.jsonp=!1!==e.jsonp,this.forceBase64=!!e.forceBase64,this.enablesXDR=!!e.enablesXDR,this.timestampParam=e.timestampParam||"t",this.timestampRequests=e.timestampRequests,this.transports=e.transports||["polling","websocket"],this.transportOptions=e.transportOptions||{},this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.policyPort=e.policyPort||843,this.rememberUpgrade=e.rememberUpgrade||!1,this.binaryType=null,this.onlyBinaryUpgrades=e.onlyBinaryUpgrades,this.perMessageDeflate=!1!==e.perMessageDeflate&&(e.perMessageDeflate||{}),!0===this.perMessageDeflate&&(this.perMessageDeflate={}),this.perMessageDeflate&&null==this.perMessageDeflate.threshold&&(this.perMessageDeflate.threshold=1024),this.pfx=e.pfx||null,this.key=e.key||null,this.passphrase=e.passphrase||null,this.cert=e.cert||null,this.ca=e.ca||null,this.ciphers=e.ciphers||null,this.rejectUnauthorized=void 0===e.rejectUnauthorized||e.rejectUnauthorized,this.forceNode=!!e.forceNode;var n="object"===L(P)&&P;n.global===n&&(e.extraHeaders&&Object.keys(e.extraHeaders).length>0&&(this.extraHeaders=e.extraHeaders),e.localAddress&&(this.localAddress=e.localAddress)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingIntervalTimer=null,this.pingTimeoutTimer=null,this.open()}function B(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function O(t,e){var n=[];e=e||0;for(var o=e||0;o<t.length;o++)n[o-e]=t[o];return n}function x(t,e,n){return t.on(e,n),{destroy:function(){t.removeListener(e,n)}}}function I(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor=t.factor||2,this.jitter=t.jitter>0&&t.jitter<=1?t.jitter:0,this.attempts=0}function R(t,e){if(!(this instanceof R))return new R(t,e);t&&"object"===(void 0===t?"undefined":L(t))&&(e=t,t=void 0),e=e||{},e.path=e.path||"/socket.io",this.nsps={},this.subs=[],this.opts=e,this.reconnection(!1!==e.reconnection),this.reconnectionAttempts(e.reconnectionAttempts||1/0),this.reconnectionDelay(e.reconnectionDelay||1e3),this.reconnectionDelayMax(e.reconnectionDelayMax||5e3),this.randomizationFactor(e.randomizationFactor||.5),this.backoff=new xe({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==e.timeout?2e4:e.timeout),this.readyState="closed",this.uri=t,this.connecting=[],this.lastPing=null,this.encoding=!1,this.packetBuffer=[];var n=e.parser||bt;this.encoder=new n.Encoder,this.decoder=new n.Decoder,this.autoConnect=!1!==e.autoConnect,this.autoConnect&&this.open()}function D(t){var e=function(e){function n(t,e){if(q(this,n),void 0===e)throw new Error("Options must not be undefined!");e.role="slave",e.preferUntransformed=!0,!1!==e.initSync&&(e.initSync=!0);var o=X(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,t,e));if(o._sentSync=!1,e.options=e.options||{},o.options=e,null==e.url)throw new Error("No rte url provided!");o.serverVersion=null,o.sessionID=null,o.contentHash=e.contentHash,o.lastUpdateMarker=-1,o.clientID=o.y.userID,o.rteEvents=[],o.handshakeTimeout=null,o._handshakeTimeoutHandler=o._handshakeTimeoutHandler.bind(o);var r=function(){return null};return o.errorHandler=e.errorHandler,o.socketHandlers={connect:e.socketHandlers.connect||r,connectError:e.socketHandlers.connectError||r,reconnect:e.socketHandlers.reconnect||r,reconnectAttempt:e.socketHandlers.reconnectAttempt||r,reconnectError:e.socketHandlers.reconnectError||r,disconnect:e.socketHandlers.disconnect||r},o.utilities={resetYjsModel:e.utilities.resetYjsModel||r,noteSavedNotification:e.utilities.noteSavedNotification||r,errorHandler:e.utilities.errorHandler||r,permissionsHandler:e.utilities.permissionsHandler||r},o._setupErrorHandler(),o._sessionEstablished=!1,o._previousConnectionAttemptTime=0,o._setupReconnectWatchdog(),o.createWebSocketIO(),o}return z(n,e),M(n,[{key:"createWebSocketIO",value:function(){var e=this,n=new Date;if(this._previousConnectionAttemptTime+Ze>n)return void ze.debug("previous connection is still trying to establish");this._previousConnectionAttemptTime=n,ze.debug("going to attempt to reconnect now"),this.socket&&this.destroy(),this.options.options.reconnection=!0,this.options.options.reconnectionDelay=$e,this.options.options.reconnectionDelayMax=1e4,this.options.options.reconnectionAttempts=1/0,this.options.options.transports=["websocket"],this.options.options.timeout=Ge,"query"in this.options.options||(this.options.options.query={}),this.options.options.query.version=tn,this.options.options.query.room=this.options.room;var o=this.options.socket||Pe(this.options.url,this.options.options);this.socket=o;var r=new Date;o.on("pong",function(){r=new Date});var i=setInterval(function(){o!=e.socket?clearInterval(i):new Date-r>3e4&&(ze.debug("en-y-websockets-client: Health Check timed out! Creating new socket.io instance"),e.createWebSocketIO())},15e3),s=this;this._onConnect=function(){s.options.initSync&&(e._sentSync=!0,e._previousConnectionAttemptTime=0,ze.debug("Connected to room "+s.options.room),o.emit("joinRoom",s.options.room),s._verifyContentVersion("server"))},o.on("connect",this._onConnect),o.connected?this._onConnect():o.connect();var a=function(){s._previousConnectionAttemptTime=0,s.socketHandlers.connectError(),s._notifyAboutInitialConnectionFailureIfNeeded()};o.on("connect_error",a),o.on("connect_timeout",a),this.onRteEvent(function(n){if(ze.debug("received msg type = "+n.type+" from "+o.id),null!=n.type){if("handshake"===n.type)return ze.debug("Received handshake response: "+JSON.stringify(n)),ze.debug("message.accpeted = "+n.accepted),clearTimeout(e.handshakeTimeout),e.handshakeTimeout=null,void(n.accepted?(s._sessionEstablished=!0,s.sessionID=n.sessionID,s.serverVersion=n.serverVersion,null!=n.contentHash&&e._setContentHash(n.contentHash),s.utilities.permissionsHandler(!1===n.canEditNote),s.userJoined("server","master"),null!=e._onYjsEvent&&o.off("yjsEvent",e._onYjsEvent),e._onYjsEvent=function(e){new t.utils.BinaryDecoder(e).readVarString()===s.options.room&&s.receiveMessage("server",e)},o.on("yjsEvent",e._onYjsEvent),s.y.on("synced",function(){s.socketHandlers.connect(!0)})):(s.utilities.errorHandler(Ke(n.errorCode)),s.socketHandlers.connect(!1),s.destroy()));if("updateContentHash"===n.type)return ze.debug("Updated contentHash: "+n.contentHash+"; last saved marker: "+n.updateMarker),s._setContentHash(n.contentHash),void(s.lastUpdateMarker>=0&&s.lastUpdateMarker<=n.updateMarker&&s.utilities.noteSavedNotification());if("lastUpdateMarker"===n.type)return void(s.lastUpdateMarker=n.updateMarker);if("resetSession"===n.type)return void s.utilities.resetYjsModel();if("realtimeError"===n.type)return void s.utilities.errorHandler(Ke(n.errorCode));ze.error("Unexpected message!"),n.room===s.options.room&&null!=s.options.afterMessageHandler&&s.options.afterMessageHandler(n)}}),o.on("reconnect",this.socketHandlers.reconnect),o.on("reconnect_attempt",this.socketHandlers.reconnectAttempt),o.on("reconnect_error",this.socketHandlers.reconnectError),this._onDisconnect=function(e){ze.debug("got disconnect"),s.destroy(),t.AbstractConnector.prototype.disconnect.call(s)},o.on("disconnect",this._onDisconnect)}},{key:"initSync",value:function(t){this.options.initSync||(this.options.initSync=!0,null!=t.room&&(this.options.room=t.room)),this.socket.connected&&this._onConnect()}},{key:"disconnect",value:function(){if(!this.socket)return void ze.error("Trying to disconnect when socket has been destroyed.");ze.debug("Disconnected from room "+this.options.room),this.socket.emit("leaveRoom",this.options.room),this._disconnect()}},{key:"destroy",value:function(){var t=this;this.socket&&(ze.debug("Destroy"),this.socket.off("disconnect",this._onDisconnect),this.socket.off("yjsEvent",this._onYjsEvent),this.rteEvents.forEach(function(e){return t.socket.off("rteEvent",e)}),this.rteEvents=[],this.socket.off("connect",this._onConnect),this.options.socket||(this.socket.close(),this.socket.destroy()),this._disconnect(),this.socket=null)}},{key:"reconnect",value:function(){ze.debug("Reconnect"),V(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"reconnect",this).call(this)}},{key:"sendRteEvent",value:function(t){t.room=this.options.room,this.socket.emit("rteEvent",t)}},{key:"onRteEvent",value:function(t){this.rteEvents.push(t),this.socket.on("rteEvent",t)}},{key:"send",value:function(t,e){if(this._sentSync){if(!this.socket)return void ze.error("Trying to send message "+e+" when socket has been destroyed.");this.socket.emit("yjsEvent",e),V(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"send",this).call(this,t,e)}}},{key:"broadcast",value:function(t){if(this._sentSync){if(!this.socket)return void ze.error("Trying to broadcast message "+t+" when socket has been destroyed.");this.socket.emit("yjsEvent",t),V(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"broadcast",this).call(this,t)}}},{key:"whenRemoteResponsive",value:function(){var t=this;return new Promise(function(e){t.socket.emit("yjsResponsive",t.options.room,e)})}},{key:"isDisconnected",value:function(){return this.socket.disconnected}},{key:"sendDeleteNoteMessage",value:function(){if(!this.socket)return void ze.error("Trying to send delete note message when socket has been destroyed.");this.sendRteEvent({type:"deleteNote",contentVersion:this.contentVersion,protocolVersion:this.protocolVersion,auth:this.authInfo})}},{key:"updateAuthToken",value:function(t){this.options.authToken=t,this.socket&&this.sendRteEvent({type:"updateAuthToken",contentVersion:this.contentVersion,protocolVersion:this.protocolVersion,authToken:this.options.authToken})}},{key:"_verifyContentVersion",value:function(t){if(!this.socket)return void ze.error("Trying to send handshake message when socket has been destroyed.");this.handshakeTimeout=setTimeout(this._handshakeTimeoutHandler,15e3),this.sendRteEvent({type:"handshake",contentVersion:this.contentVersion,protocolVersion:this.protocolVersion,auth:this.authInfo,authToken:this.options.authToken,serviceHost:this.options.serviceHost,shardID:this.options.shardID,userName:this.options.userName,sessionID:this.sessionID,clientID:this.clientID,newNote:this.options.newNote,contentHash:this._getContentHash()})}},{key:"_handshakeTimeoutHandler",value:function(){this.handshakeTimeout=null,this.socketHandlers.connect(!1),this._notifyAboutInitialConnectionFailureIfNeeded(),this.destroy()}},{key:"_notifyAboutInitialConnectionFailureIfNeeded",value:function(){this._sessionEstablished||this.utilities.errorHandler(Je(Fe.INITIAL_CONNECTION))}},{key:"_shouldReconnect",value:function(){return this.options.should_reconnect||!0}},{key:"_setupReconnectWatchdog",value:function(){var t=this;setInterval(function(){t._shouldReconnect()&&!t.socket&&(ze.debug("making attempt to reconnect"),t.createWebSocketIO())},Qe)}},{key:"_setupErrorHandler",value:function(){var t=this;this.y.on("error",function(e){ze.error("Unexpected YJS error: "+e),t.utilities.errorHandler(Je(Fe.INTERNAL_FAILURE))})}},{key:"_disconnect",value:function(){ze.debug("Leaving from room "+this.options.room),this.socketHandlers.disconnect(),this.options.socket||this.socket.disconnect(),V(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"disconnect",this).call(this)}},{key:"_setContentHash",value:function(t){ze.debug2("setting content hash to "+t),this.contentHash=t}},{key:"_getContentHash",value:function(){return ze.debug2("getting content hash to "+this.contentHash),this.contentHash}}]),n}(t.AbstractConnector);e.io=Pe,t["websockets-client"]=e}var P="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},j=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,H=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],U=function(t){var e=t,n=t.indexOf("["),o=t.indexOf("]");-1!=n&&-1!=o&&(t=t.substring(0,n)+t.substring(n,o).replace(/:/g,";")+t.substring(o,t.length));for(var r=j.exec(t||""),i={},s=14;s--;)i[H[s]]=r[s]||"";return-1!=n&&-1!=o&&(i.source=e,i.host=i.host.substring(1,i.host.length-1).replace(/;/g,":"),i.authority=i.authority.replace("[","").replace("]","").replace(/;/g,":"),i.ipv6uri=!0),i},L="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},q=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},M=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),V=function t(e,n,o){null===e&&(e=Function.prototype);var r=Object.getOwnPropertyDescriptor(e,n);if(void 0===r){var i=Object.getPrototypeOf(e);return null===i?void 0:t(i,n,o)}if("value"in r)return r.value;var s=r.get;if(void 0!==s)return s.call(o)},z=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},X=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},F=1e3,W=60*F,J=60*W,K=24*J,$=365.25*K,Q=function(t,r){r=r||{};var i=void 0===t?"undefined":L(t);if("string"===i&&t.length>0)return e(t);if("number"===i&&!1===isNaN(t))return r.long?o(t):n(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))},G=t(function(t,e){function n(t){var n,o=0;for(n in t)o=(o<<5)-o+t.charCodeAt(n),o|=0;return e.colors[Math.abs(o)%e.colors.length]}function o(t){function o(){if(o.enabled){var t=o,n=+new Date,r=n-(c||n);t.diff=r,t.prev=c,t.curr=n,c=n;for(var i=new Array(arguments.length),s=0;s<i.length;s++)i[s]=arguments[s];i[0]=e.coerce(i[0]),"string"!=typeof i[0]&&i.unshift("%O");var a=0;i[0]=i[0].replace(/%([a-zA-Z%])/g,function(n,o){if("%%"===n)return n;a++;var r=e.formatters[o];if("function"==typeof r){var s=i[a];n=r.call(t,s),i.splice(a,1),a--}return n}),e.formatArgs.call(t,i);(o.log||e.log||console.log.bind(console)).apply(t,i)}}return o.namespace=t,o.enabled=e.enabled(t),o.useColors=e.useColors(),o.color=n(t),"function"==typeof e.init&&e.init(o),o}function r(t){e.save(t),e.names=[],e.skips=[];for(var n=("string"==typeof t?t:"").split(/[\s,]+/),o=n.length,r=0;r<o;r++)n[r]&&(t=n[r].replace(/\*/g,".*?"),"-"===t[0]?e.skips.push(new RegExp("^"+t.substr(1)+"$")):e.names.push(new RegExp("^"+t+"$")))}function i(){e.enable("")}function s(t){var n,o;for(n=0,o=e.skips.length;n<o;n++)if(e.skips[n].test(t))return!1;for(n=0,o=e.names.length;n<o;n++)if(e.names[n].test(t))return!0;return!1}function a(t){return t instanceof Error?t.stack||t.message:t}e=t.exports=o.debug=o.default=o,e.coerce=a,e.disable=i,e.enable=r,e.enabled=s,e.humanize=Q,e.names=[],e.skips=[],e.formatters={};var c}),Z=t(function(t,e){function n(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function o(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+t[0]+(n?"%c ":" ")+"+"+e.humanize(this.diff),n){var o="color: "+this.color;t.splice(1,0,o,"color: inherit");var r=0,i=0;t[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(r++,"%c"===t&&(i=r))}),t.splice(i,0,o)}}function r(){return"object"===("undefined"==typeof console?"undefined":L(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function i(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=t}catch(t){}}function s(){var t;try{t=e.storage.debug}catch(t){}return!t&&"undefined"!=typeof process&&"env"in process&&(t=process.env.DEBUG),t}e=t.exports=G,e.log=r,e.formatArgs=o,e.save=i,e.load=s,e.useColors=n,e.storage="undefined"!=typeof chrome&&void 0!==chrome.storage?chrome.storage.local:function(){try{return window.localStorage}catch(t){}}(),e.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],e.formatters.j=function(t){try{return JSON.stringify(t)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}},e.enable(s())}),tt=Z("socket.io-client:url"),et=i,nt=t(function(t){function e(t){if(t)return n(t)}function n(t){for(var n in e.prototype)t[n]=e.prototype[n];return t}t.exports=e,e.prototype.on=e.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},e.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},e.prototype.off=e.prototype.removeListener=e.prototype.removeAllListeners=e.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var o,r=0;r<n.length;r++)if((o=n[r])===e||o.fn===e){n.splice(r,1);break}return this},e.prototype.emit=function(t){this._callbacks=this._callbacks||{};var e=[].slice.call(arguments,1),n=this._callbacks["$"+t];if(n){n=n.slice(0);for(var o=0,r=n.length;o<r;++o)n[o].apply(this,e)}return this},e.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},e.prototype.hasListeners=function(t){return!!this.listeners(t).length}}),ot={}.toString,rt=Array.isArray||function(t){return"[object Array]"==ot.call(t)},it=Object.prototype.toString,st="function"==typeof P.Blob||"[object BlobConstructor]"===it.call(P.Blob),at="function"==typeof P.File||"[object FileConstructor]"===it.call(P.File),ct=s,ht={}.toString,ut=Array.isArray||function(t){return"[object Array]"==ht.call(t)},pt=a,ft=Object.prototype.toString,lt="function"==typeof P.Blob||"[object BlobConstructor]"===ft.call(P.Blob),dt="function"==typeof P.File||"[object FileConstructor]"===ft.call(P.File),yt=function(t){var e=[],n=t.data,o=t;return o.data=c(n,e),o.attachments=e.length,{packet:o,buffers:e}},mt=function(t,e){return t.data=h(t.data,e),t.attachments=void 0,t},gt=function(t,e){function n(t,i,s){if(!t)return t;if(lt&&t instanceof Blob||dt&&t instanceof File){o++;var a=new FileReader;a.onload=function(){s?s[i]=this.result:r=this.result,--o||e(r)},a.readAsArrayBuffer(t)}else if(ut(t))for(var c=0;c<t.length;c++)n(t[c],c,t);else if("object"===(void 0===t?"undefined":L(t))&&!pt(t))for(var h in t)n(t[h],h,t)}var o=0,r=t;n(r),o||e(r)},vt={deconstructPacket:yt,reconstructPacket:mt,removeBlobs:gt},bt=t(function(t,e){function n(){}function o(t){var n=""+t.type;return e.BINARY_EVENT!==t.type&&e.BINARY_ACK!==t.type||(n+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(n+=t.nsp+","),null!=t.id&&(n+=t.id),null!=t.data&&(n+=JSON.stringify(t.data)),u("encoded %j as %s",t,n),n}function r(t,e){function n(t){var n=vt.deconstructPacket(t),r=o(n.packet),i=n.buffers;i.unshift(r),e(i)}vt.removeBlobs(t,n)}function i(){this.reconstructor=null}function s(t){var n=0,o={type:Number(t.charAt(0))};if(null==e.types[o.type])return h();if(e.BINARY_EVENT===o.type||e.BINARY_ACK===o.type){for(var r="";"-"!==t.charAt(++n)&&(r+=t.charAt(n),n!=t.length););if(r!=Number(r)||"-"!==t.charAt(n))throw new Error("Illegal attachments");o.attachments=Number(r)}if("/"===t.charAt(n+1))for(o.nsp="";++n;){var i=t.charAt(n);if(","===i)break;if(o.nsp+=i,n===t.length)break}else o.nsp="/";var s=t.charAt(n+1);if(""!==s&&Number(s)==s){for(o.id="";++n;){var i=t.charAt(n);if(null==i||Number(i)!=i){--n;break}if(o.id+=t.charAt(n),n===t.length)break}o.id=Number(o.id)}return t.charAt(++n)&&(o=a(o,t.substr(n))),u("decoded %s as %j",t,o),o}function a(t,e){try{t.data=JSON.parse(e)}catch(t){return h()}return t}function c(t){this.reconPack=t,this.buffers=[]}function h(){return{type:e.ERROR,data:"parser error"}}var u=Z("socket.io-parser");e.protocol=4,e.types=["CONNECT","DISCONNECT","EVENT","ACK","ERROR","BINARY_EVENT","BINARY_ACK"],e.CONNECT=0,e.DISCONNECT=1,e.EVENT=2,e.ACK=3,e.ERROR=4,e.BINARY_EVENT=5,e.BINARY_ACK=6,e.Encoder=n,e.Decoder=i,n.prototype.encode=function(t,n){if(t.type!==e.EVENT&&t.type!==e.ACK||!ct(t.data)||(t.type=t.type===e.EVENT?e.BINARY_EVENT:e.BINARY_ACK),u("encoding packet %j",t),e.BINARY_EVENT===t.type||e.BINARY_ACK===t.type)r(t,n);else{n([o(t)])}},nt(i.prototype),i.prototype.add=function(t){var n;if("string"==typeof t)n=s(t),e.BINARY_EVENT===n.type||e.BINARY_ACK===n.type?(this.reconstructor=new c(n),0===this.reconstructor.reconPack.attachments&&this.emit("decoded",n)):this.emit("decoded",n);else{if(!pt(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");(n=this.reconstructor.takeBinaryData(t))&&(this.reconstructor=null,this.emit("decoded",n))}},i.prototype.destroy=function(){this.reconstructor&&this.reconstructor.finishedReconstruction()},c.prototype.takeBinaryData=function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=vt.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null},c.prototype.finishedReconstruction=function(){this.reconPack=null,this.buffers=[]}}),kt=t(function(t){try{t.exports="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(e){t.exports=!1}}),wt=function(t){var e=t.xdomain,n=t.xscheme,o=t.enablesXDR;try{if("undefined"!=typeof XMLHttpRequest&&(!e||kt))return new XMLHttpRequest}catch(t){}try{if("undefined"!=typeof XDomainRequest&&!n&&o)return new XDomainRequest}catch(t){}if(!e)try{return new(P[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}},Et=Object.keys||function(t){var e=[],n=Object.prototype.hasOwnProperty;for(var o in t)n.call(t,o)&&e.push(o);return e},At=function(t,e,n){var o=t.byteLength;if(e=e||0,n=n||o,t.slice)return t.slice(e,n);if(e<0&&(e+=o),n<0&&(n+=o),n>o&&(n=o),e>=o||e>=n||0===o)return new ArrayBuffer(0);for(var r=new Uint8Array(t),i=new Uint8Array(n-e),s=e,a=0;s<n;s++,a++)i[a]=r[s];return i.buffer},_t=u,Ct=t(function(t,e){!function(n){function o(t){for(var e,n,o=[],r=0,i=t.length;r<i;)e=t.charCodeAt(r++),e>=55296&&e<=56319&&r<i?(n=t.charCodeAt(r++),56320==(64512&n)?o.push(((1023&e)<<10)+(1023&n)+65536):(o.push(e),r--)):o.push(e);return o}function r(t){for(var e,n=t.length,o=-1,r="";++o<n;)e=t[o],e>65535&&(e-=65536,r+=v(e>>>10&1023|55296),e=56320|1023&e),r+=v(e);return r}function i(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate U+"+t.toString(16).toUpperCase()+" is not a scalar value");return!1}return!0}function s(t,e){return v(t>>e&63|128)}function a(t,e){if(0==(4294967168&t))return v(t);var n="";return 0==(4294965248&t)?n=v(t>>6&31|192):0==(4294901760&t)?(i(t,e)||(t=65533),n=v(t>>12&15|224),n+=s(t,6)):0==(4292870144&t)&&(n=v(t>>18&7|240),n+=s(t,12),n+=s(t,6)),n+=v(63&t|128)}function c(t,e){e=e||{};for(var n,r=!1!==e.strict,i=o(t),s=i.length,c=-1,h="";++c<s;)n=i[c],h+=a(n,r);return h}function h(){if(g>=m)throw Error("Invalid byte index");var t=255&y[g];if(g++,128==(192&t))return 63&t;throw Error("Invalid continuation byte")}function u(t){var e,n,o,r,s;if(g>m)throw Error("Invalid byte index");if(g==m)return!1;if(e=255&y[g],g++,0==(128&e))return e;if(192==(224&e)){if(n=h(),(s=(31&e)<<6|n)>=128)return s;throw Error("Invalid continuation byte")}if(224==(240&e)){if(n=h(),o=h(),(s=(15&e)<<12|n<<6|o)>=2048)return i(s,t)?s:65533;throw Error("Invalid continuation byte")}if(240==(248&e)&&(n=h(),o=h(),r=h(),(s=(7&e)<<18|n<<12|o<<6|r)>=65536&&s<=1114111))return s;throw Error("Invalid UTF-8 detected")}function p(t,e){e=e||{};var n=!1!==e.strict;y=o(t),m=y.length,g=0;for(var i,s=[];!1!==(i=u(n));)s.push(i);return r(s)}var f=e,l=t&&t.exports==f&&t,d="object"==L(P)&&P;d.global!==d&&d.window!==d||(n=d);var y,m,g,v=String.fromCharCode,b={version:"2.1.2",encode:c,decode:p};if(f&&!f.nodeType)if(l)l.exports=b;else{var k={},w=k.hasOwnProperty;for(var E in b)w.call(b,E)&&(f[E]=b[E])}else n.utf8=b}(P)}),Nt=t(function(t,e){!function(){for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(256),o=0;o<t.length;o++)n[t.charCodeAt(o)]=o;e.encode=function(e){var n,o=new Uint8Array(e),r=o.length,i="";for(n=0;n<r;n+=3)i+=t[o[n]>>2],i+=t[(3&o[n])<<4|o[n+1]>>4],i+=t[(15&o[n+1])<<2|o[n+2]>>6],
i+=t[63&o[n+2]];return r%3==2?i=i.substring(0,i.length-1)+"=":r%3==1&&(i=i.substring(0,i.length-2)+"=="),i},e.decode=function(t){var e,o,r,i,s,a=.75*t.length,c=t.length,h=0;"="===t[t.length-1]&&(a--,"="===t[t.length-2]&&a--);var u=new ArrayBuffer(a),p=new Uint8Array(u);for(e=0;e<c;e+=4)o=n[t.charCodeAt(e)],r=n[t.charCodeAt(e+1)],i=n[t.charCodeAt(e+2)],s=n[t.charCodeAt(e+3)],p[h++]=o<<2|r>>4,p[h++]=(15&r)<<4|i>>2,p[h++]=(3&i)<<6|63&s;return u}}()}),Tt=P.BlobBuilder||P.WebKitBlobBuilder||P.MSBlobBuilder||P.MozBlobBuilder,St=function(){try{return 2===new Blob(["hi"]).size}catch(t){return!1}}(),Bt=St&&function(){try{return 2===new Blob([new Uint8Array([1,2])]).size}catch(t){return!1}}(),Ot=Tt&&Tt.prototype.append&&Tt.prototype.getBlob,xt=function(){return St?Bt?P.Blob:d:Ot?l:void 0}(),It=t(function(t,e){function n(t,n){return n("b"+e.packets[t.type]+t.data.data)}function o(t,n,o){if(!n)return e.encodeBase64Packet(t,o);var r=t.data,i=new Uint8Array(r),s=new Uint8Array(1+r.byteLength);s[0]=f[t.type];for(var a=0;a<i.length;a++)s[a+1]=i[a];return o(s.buffer)}function r(t,n,o){if(!n)return e.encodeBase64Packet(t,o);var r=new FileReader;return r.onload=function(){t.data=r.result,e.encodePacket(t,n,!0,o)},r.readAsArrayBuffer(t.data)}function i(t,n,o){if(!n)return e.encodeBase64Packet(t,o);if(p)return r(t,n,o);var i=new Uint8Array(1);return i[0]=f[t.type],o(new xt([i.buffer,t.data]))}function s(t){try{t=Ct.decode(t,{strict:!1})}catch(t){return!1}return t}function a(t,e,n){for(var o=new Array(t.length),r=_t(t.length,n),i=0;i<t.length;i++)!function(t,n,r){e(n,function(e,n){o[t]=n,r(e,o)})}(i,t[i],r)}var c;P&&P.ArrayBuffer&&(c=Nt);var h="undefined"!=typeof navigator&&/Android/i.test(navigator.userAgent),u="undefined"!=typeof navigator&&/PhantomJS/i.test(navigator.userAgent),p=h||u;e.protocol=3;var f=e.packets={open:0,close:1,ping:2,pong:3,message:4,upgrade:5,noop:6},l=Et(f),d={type:"error",data:"parser error"};e.encodePacket=function(t,e,r,s){"function"==typeof e&&(s=e,e=!1),"function"==typeof r&&(s=r,r=null);var a=void 0===t.data?void 0:t.data.buffer||t.data;if(P.ArrayBuffer&&a instanceof ArrayBuffer)return o(t,e,s);if(xt&&a instanceof P.Blob)return i(t,e,s);if(a&&a.base64)return n(t,s);var c=f[t.type];return void 0!==t.data&&(c+=r?Ct.encode(String(t.data),{strict:!1}):String(t.data)),s(""+c)},e.encodeBase64Packet=function(t,n){var o="b"+e.packets[t.type];if(xt&&t.data instanceof P.Blob){var r=new FileReader;return r.onload=function(){var t=r.result.split(",")[1];n(o+t)},r.readAsDataURL(t.data)}var i;try{i=String.fromCharCode.apply(null,new Uint8Array(t.data))}catch(e){for(var s=new Uint8Array(t.data),a=new Array(s.length),c=0;c<s.length;c++)a[c]=s[c];i=String.fromCharCode.apply(null,a)}return o+=P.btoa(i),n(o)},e.decodePacket=function(t,n,o){if(void 0===t)return d;if("string"==typeof t){if("b"===t.charAt(0))return e.decodeBase64Packet(t.substr(1),n);if(o&&!1===(t=s(t)))return d;var r=t.charAt(0);return Number(r)==r&&l[r]?t.length>1?{type:l[r],data:t.substring(1)}:{type:l[r]}:d}var i=new Uint8Array(t),r=i[0],a=At(t,1);return xt&&"blob"===n&&(a=new xt([a])),{type:l[r],data:a}},e.decodeBase64Packet=function(t,e){var n=l[t.charAt(0)];if(!c)return{type:n,data:{base64:!0,data:t.substr(1)}};var o=c.decode(t.substr(1));return"blob"===e&&xt&&(o=new xt([o])),{type:n,data:o}},e.encodePayload=function(t,n,o){function r(t){return t.length+":"+t}function i(t,o){e.encodePacket(t,!!s&&n,!1,function(t){o(null,r(t))})}"function"==typeof n&&(o=n,n=null);var s=ct(t);return n&&s?xt&&!p?e.encodePayloadAsBlob(t,o):e.encodePayloadAsArrayBuffer(t,o):t.length?void a(t,i,function(t,e){return o(e.join(""))}):o("0:")},e.decodePayload=function(t,n,o){if("string"!=typeof t)return e.decodePayloadAsBinary(t,n,o);"function"==typeof n&&(o=n,n=null);var r;if(""===t)return o(d,0,1);for(var i,s,a="",c=0,h=t.length;c<h;c++){var u=t.charAt(c);if(":"===u){if(""===a||a!=(i=Number(a)))return o(d,0,1);if(s=t.substr(c+1,i),a!=s.length)return o(d,0,1);if(s.length){if(r=e.decodePacket(s,n,!1),d.type===r.type&&d.data===r.data)return o(d,0,1);if(!1===o(r,c+i,h))return}c+=i,a=""}else a+=u}return""!==a?o(d,0,1):void 0},e.encodePayloadAsArrayBuffer=function(t,n){function o(t,n){e.encodePacket(t,!0,!0,function(t){return n(null,t)})}if(!t.length)return n(new ArrayBuffer(0));a(t,o,function(t,e){var o=e.reduce(function(t,e){var n;return n="string"==typeof e?e.length:e.byteLength,t+n.toString().length+n+2},0),r=new Uint8Array(o),i=0;return e.forEach(function(t){var e="string"==typeof t,n=t;if(e){for(var o=new Uint8Array(t.length),s=0;s<t.length;s++)o[s]=t.charCodeAt(s);n=o.buffer}r[i++]=e?0:1;for(var a=n.byteLength.toString(),s=0;s<a.length;s++)r[i++]=parseInt(a[s]);r[i++]=255;for(var o=new Uint8Array(n),s=0;s<o.length;s++)r[i++]=o[s]}),n(r.buffer)})},e.encodePayloadAsBlob=function(t,n){function o(t,n){e.encodePacket(t,!0,!0,function(t){var e=new Uint8Array(1);if(e[0]=1,"string"==typeof t){for(var o=new Uint8Array(t.length),r=0;r<t.length;r++)o[r]=t.charCodeAt(r);t=o.buffer,e[0]=0}for(var i=t instanceof ArrayBuffer?t.byteLength:t.size,s=i.toString(),a=new Uint8Array(s.length+1),r=0;r<s.length;r++)a[r]=parseInt(s[r]);if(a[s.length]=255,xt){var c=new xt([e.buffer,a.buffer,t]);n(null,c)}})}a(t,o,function(t,e){return n(new xt(e))})},e.decodePayloadAsBinary=function(t,n,o){"function"==typeof n&&(o=n,n=null);for(var r=t,i=[];r.byteLength>0;){for(var s=new Uint8Array(r),a=0===s[0],c="",h=1;255!==s[h];h++){if(c.length>310)return o(d,0,1);c+=s[h]}r=At(r,2+c.length),c=parseInt(c);var u=At(r,0,c);if(a)try{u=String.fromCharCode.apply(null,new Uint8Array(u))}catch(t){var p=new Uint8Array(u);u="";for(var h=0;h<p.length;h++)u+=String.fromCharCode(p[h])}i.push(u),r=At(r,c)}var f=i.length;i.forEach(function(t,r){o(e.decodePacket(t,n,!0),r,f)})}}),Rt=y;nt(y.prototype),y.prototype.onError=function(t,e){var n=new Error(t);return n.type="TransportError",n.description=e,this.emit("error",n),this},y.prototype.open=function(){return"closed"!==this.readyState&&""!==this.readyState||(this.readyState="opening",this.doOpen()),this},y.prototype.close=function(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this},y.prototype.send=function(t){if("open"!==this.readyState)throw new Error("Transport not open");this.write(t)},y.prototype.onOpen=function(){this.readyState="open",this.writable=!0,this.emit("open")},y.prototype.onData=function(t){var e=It.decodePacket(t,this.socket.binaryType);this.onPacket(e)},y.prototype.onPacket=function(t){this.emit("packet",t)},y.prototype.onClose=function(){this.readyState="closed",this.emit("close")};for(var Dt,Pt=function(t){var e="";for(var n in t)t.hasOwnProperty(n)&&(e.length&&(e+="&"),e+=encodeURIComponent(n)+"="+encodeURIComponent(t[n]));return e},jt=function(t){for(var e={},n=t.split("&"),o=0,r=n.length;o<r;o++){var i=n[o].split("=");e[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return e},Ht={encode:Pt,decode:jt},Ut=function(t,e){var n=function(){};n.prototype=e.prototype,t.prototype=new n,t.prototype.constructor=t},Lt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),qt=64,Mt={},Vt=0,zt=0;zt<qt;zt++)Mt[Lt[zt]]=zt;v.encode=m,v.decode=g;var Xt=v,Ft=Z("engine.io-client:polling"),Wt=b,Yt=function(){return null!=new wt({xdomain:!1}).responseType}();Ut(b,Rt),b.prototype.name="polling",b.prototype.doOpen=function(){this.poll()},b.prototype.pause=function(t){function e(){Ft("paused"),n.readyState="paused",t()}var n=this;if(this.readyState="pausing",this.polling||!this.writable){var o=0;this.polling&&(Ft("we are currently polling - waiting to pause"),o++,this.once("pollComplete",function(){Ft("pre-pause polling complete"),--o||e()})),this.writable||(Ft("we are currently writing - waiting to pause"),o++,this.once("drain",function(){Ft("pre-pause writing complete"),--o||e()}))}else e()},b.prototype.poll=function(){Ft("polling"),this.polling=!0,this.doPoll(),this.emit("poll")},b.prototype.onData=function(t){var e=this;Ft("polling got data %s",t);var n=function(t,n,o){if("opening"===e.readyState&&e.onOpen(),"close"===t.type)return e.onClose(),!1;e.onPacket(t)};It.decodePayload(t,this.socket.binaryType,n),"closed"!==this.readyState&&(this.polling=!1,this.emit("pollComplete"),"open"===this.readyState?this.poll():Ft('ignoring poll - transport state "%s"',this.readyState))},b.prototype.doClose=function(){function t(){Ft("writing close packet"),e.write([{type:"close"}])}var e=this;"open"===this.readyState?(Ft("transport open - closing"),t()):(Ft("transport not open - deferring close"),this.once("open",t))},b.prototype.write=function(t){var e=this;this.writable=!1;var n=function(){e.writable=!0,e.emit("drain")};It.encodePayload(t,this.supportsBinary,function(t){e.doWrite(t,n)})},b.prototype.uri=function(){var t=this.query||{},e=this.secure?"https":"http",n="";return!1!==this.timestampRequests&&(t[this.timestampParam]=Xt()),this.supportsBinary||t.sid||(t.b64=1),t=Ht.encode(t),this.port&&("https"===e&&443!==Number(this.port)||"http"===e&&80!==Number(this.port))&&(n=":"+this.port),t.length&&(t="?"+t),e+"://"+(-1!==this.hostname.indexOf(":")?"["+this.hostname+"]":this.hostname)+n+this.path+t};var Jt=Z("engine.io-client:polling-xhr"),Kt=w,$t=E;Ut(w,Wt),w.prototype.supportsBinary=!0,w.prototype.request=function(t){return t=t||{},t.uri=this.uri(),t.xd=this.xd,t.xs=this.xs,t.agent=this.agent||!1,t.supportsBinary=this.supportsBinary,t.enablesXDR=this.enablesXDR,t.pfx=this.pfx,t.key=this.key,t.passphrase=this.passphrase,t.cert=this.cert,t.ca=this.ca,t.ciphers=this.ciphers,t.rejectUnauthorized=this.rejectUnauthorized,t.requestTimeout=this.requestTimeout,t.extraHeaders=this.extraHeaders,new E(t)},w.prototype.doWrite=function(t,e){var n="string"!=typeof t&&void 0!==t,o=this.request({method:"POST",data:t,isBinary:n}),r=this;o.on("success",e),o.on("error",function(t){r.onError("xhr post error",t)}),this.sendXhr=o},w.prototype.doPoll=function(){Jt("xhr poll");var t=this.request(),e=this;t.on("data",function(t){e.onData(t)}),t.on("error",function(t){e.onError("xhr poll error",t)}),this.pollXhr=t},nt(E.prototype),E.prototype.create=function(){var t={agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR};t.pfx=this.pfx,t.key=this.key,t.passphrase=this.passphrase,t.cert=this.cert,t.ca=this.ca,t.ciphers=this.ciphers,t.rejectUnauthorized=this.rejectUnauthorized;var e=this.xhr=new wt(t),n=this;try{Jt("xhr open %s: %s",this.method,this.uri),e.open(this.method,this.uri,this.async);try{if(this.extraHeaders){e.setDisableHeaderCheck&&e.setDisableHeaderCheck(!0);for(var o in this.extraHeaders)this.extraHeaders.hasOwnProperty(o)&&e.setRequestHeader(o,this.extraHeaders[o])}}catch(t){}if("POST"===this.method)try{this.isBinary?e.setRequestHeader("Content-type","application/octet-stream"):e.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{e.setRequestHeader("Accept","*/*")}catch(t){}"withCredentials"in e&&(e.withCredentials=!0),this.requestTimeout&&(e.timeout=this.requestTimeout),this.hasXDR()?(e.onload=function(){n.onLoad()},e.onerror=function(){n.onError(e.responseText)}):e.onreadystatechange=function(){if(2===e.readyState){var t;try{t=e.getResponseHeader("Content-Type")}catch(t){}"application/octet-stream"===t&&(e.responseType="arraybuffer")}4===e.readyState&&(200===e.status||1223===e.status?n.onLoad():setTimeout(function(){n.onError(e.status)},0))},Jt("xhr data %s",this.data),e.send(this.data)}catch(t){return void setTimeout(function(){n.onError(t)},0)}P.document&&(this.index=E.requestsCount++,E.requests[this.index]=this)},E.prototype.onSuccess=function(){this.emit("success"),this.cleanup()},E.prototype.onData=function(t){this.emit("data",t),this.onSuccess()},E.prototype.onError=function(t){this.emit("error",t),this.cleanup(!0)},E.prototype.cleanup=function(t){if(void 0!==this.xhr&&null!==this.xhr){if(this.hasXDR()?this.xhr.onload=this.xhr.onerror=k:this.xhr.onreadystatechange=k,t)try{this.xhr.abort()}catch(t){}P.document&&delete E.requests[this.index],this.xhr=null}},E.prototype.onLoad=function(){var t;try{var e;try{e=this.xhr.getResponseHeader("Content-Type")}catch(t){}t="application/octet-stream"===e?this.xhr.response||this.xhr.responseText:this.xhr.responseText}catch(t){this.onError(t)}null!=t&&this.onData(t)},E.prototype.hasXDR=function(){return void 0!==P.XDomainRequest&&!this.xs&&this.enablesXDR},E.prototype.abort=function(){this.cleanup()},E.requestsCount=0,E.requests={},P.document&&(P.attachEvent?P.attachEvent("onunload",A):P.addEventListener&&P.addEventListener("beforeunload",A,!1)),Kt.Request=$t;var Qt,Gt=C,Zt=/\n/g,te=/\\n/g;Ut(C,Wt),C.prototype.supportsBinary=!1,C.prototype.doClose=function(){this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),this.form&&(this.form.parentNode.removeChild(this.form),this.form=null,this.iframe=null),Wt.prototype.doClose.call(this)},C.prototype.doPoll=function(){var t=this,e=document.createElement("script");this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),e.async=!0,e.src=this.uri(),e.onerror=function(e){t.onError("jsonp poll error",e)};var n=document.getElementsByTagName("script")[0];n?n.parentNode.insertBefore(e,n):(document.head||document.body).appendChild(e),this.script=e,"undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent)&&setTimeout(function(){var t=document.createElement("iframe");document.body.appendChild(t),document.body.removeChild(t)},100)},C.prototype.doWrite=function(t,e){function n(){o(),e()}function o(){if(r.iframe)try{r.form.removeChild(r.iframe)}catch(t){r.onError("jsonp polling iframe removal error",t)}try{var t='<iframe src="javascript:0" name="'+r.iframeId+'">';i=document.createElement(t)}catch(t){i=document.createElement("iframe"),i.name=r.iframeId,i.src="javascript:0"}i.id=r.iframeId,r.form.appendChild(i),r.iframe=i}var r=this;if(!this.form){var i,s=document.createElement("form"),a=document.createElement("textarea"),c=this.iframeId="eio_iframe_"+this.index;s.className="socketio",s.style.position="absolute",s.style.top="-1000px",s.style.left="-1000px",s.target=c,s.method="POST",s.setAttribute("accept-charset","utf-8"),a.name="d",s.appendChild(a),document.body.appendChild(s),this.form=s,this.area=a}this.form.action=this.uri(),o(),t=t.replace(te,"\\\n"),this.area.value=t.replace(Zt,"\\n");try{this.form.submit()}catch(t){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===r.iframe.readyState&&n()}:this.iframe.onload=n};var ee,ne={},oe=Object.freeze({default:ne}),re=oe&&ne||oe,ie=Z("engine.io-client:websocket"),se=P.WebSocket||P.MozWebSocket;if("undefined"==typeof window)try{ee=re}catch(t){}var ae=se;ae||"undefined"!=typeof window||(ae=ee);var ce=N;Ut(N,Rt),N.prototype.name="websocket",N.prototype.supportsBinary=!0,N.prototype.doOpen=function(){if(this.check()){var t=this.uri(),e=this.protocols,n={agent:this.agent,perMessageDeflate:this.perMessageDeflate};n.pfx=this.pfx,n.key=this.key,n.passphrase=this.passphrase,n.cert=this.cert,n.ca=this.ca,n.ciphers=this.ciphers,n.rejectUnauthorized=this.rejectUnauthorized,this.extraHeaders&&(n.headers=this.extraHeaders),this.localAddress&&(n.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket?e?new ae(t,e):new ae(t):new ae(t,e,n)}catch(t){return this.emit("error",t)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},N.prototype.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.onOpen()},this.ws.onclose=function(){t.onClose()},this.ws.onmessage=function(e){t.onData(e.data)},this.ws.onerror=function(e){t.onError("websocket error",e)}},N.prototype.write=function(t){function e(){n.emit("flush"),setTimeout(function(){n.writable=!0,n.emit("drain")},0)}var n=this;this.writable=!1;for(var o=t.length,r=0,i=o;r<i;r++)!function(t){It.encodePacket(t,n.supportsBinary,function(r){if(!n.usingBrowserWebSocket){var i={};if(t.options&&(i.compress=t.options.compress),n.perMessageDeflate){("string"==typeof r?P.Buffer.byteLength(r):r.length)<n.perMessageDeflate.threshold&&(i.compress=!1)}}try{n.usingBrowserWebSocket?n.ws.send(r):n.ws.send(r,i)}catch(t){ie("websocket closed before onclose event")}--o||e()})}(t[r])},N.prototype.onClose=function(){Rt.prototype.onClose.call(this)},N.prototype.doClose=function(){void 0!==this.ws&&this.ws.close()},N.prototype.uri=function(){var t=this.query||{},e=this.secure?"wss":"ws",n="";return this.port&&("wss"===e&&443!==Number(this.port)||"ws"===e&&80!==Number(this.port))&&(n=":"+this.port),this.timestampRequests&&(t[this.timestampParam]=Xt()),this.supportsBinary||(t.b64=1),t=Ht.encode(t),t.length&&(t="?"+t),e+"://"+(-1!==this.hostname.indexOf(":")?"["+this.hostname+"]":this.hostname)+n+this.path+t},N.prototype.check=function(){return!(!ae||"__initialize"in ae&&this.name===N.prototype.name)};var he=T,ue=ce,pe={polling:he,websocket:ue},fe=[].indexOf,le=function(t,e){if(fe)return t.indexOf(e);for(var n=0;n<t.length;++n)if(t[n]===e)return n;return-1},de=/^[\],:{}\s]*$/,ye=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,me=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,ge=/(?:^|:|,)(?:\s*\[)+/g,ve=/^\s+/,be=/\s+$/,ke=function(t){return"string"==typeof t&&t?(t=t.replace(ve,"").replace(be,""),P.JSON&&JSON.parse?JSON.parse(t):de.test(t.replace(ye,"@").replace(me,"]").replace(ge,""))?new Function("return "+t)():void 0):null},we=Z("engine.io-client:socket"),Ee=S;S.priorWebsocketSuccess=!1,nt(S.prototype),S.protocol=It.protocol,S.Socket=S,S.Transport=Rt,S.transports=pe,S.parser=It,S.prototype.createTransport=function(t){we('creating transport "%s"',t);var e=B(this.query);e.EIO=It.protocol,e.transport=t;var n=this.transportOptions[t]||{};return this.id&&(e.sid=this.id),new pe[t]({query:e,socket:this,agent:n.agent||this.agent,hostname:n.hostname||this.hostname,port:n.port||this.port,secure:n.secure||this.secure,path:n.path||this.path,forceJSONP:n.forceJSONP||this.forceJSONP,jsonp:n.jsonp||this.jsonp,forceBase64:n.forceBase64||this.forceBase64,enablesXDR:n.enablesXDR||this.enablesXDR,timestampRequests:n.timestampRequests||this.timestampRequests,timestampParam:n.timestampParam||this.timestampParam,policyPort:n.policyPort||this.policyPort,pfx:n.pfx||this.pfx,key:n.key||this.key,passphrase:n.passphrase||this.passphrase,cert:n.cert||this.cert,ca:n.ca||this.ca,ciphers:n.ciphers||this.ciphers,rejectUnauthorized:n.rejectUnauthorized||this.rejectUnauthorized,perMessageDeflate:n.perMessageDeflate||this.perMessageDeflate,extraHeaders:n.extraHeaders||this.extraHeaders,forceNode:n.forceNode||this.forceNode,localAddress:n.localAddress||this.localAddress,requestTimeout:n.requestTimeout||this.requestTimeout,protocols:n.protocols||void 0})},S.prototype.open=function(){var t;if(this.rememberUpgrade&&S.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket"))t="websocket";else{if(0===this.transports.length){var e=this;return void setTimeout(function(){e.emit("error","No transports available")},0)}t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(t){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)},S.prototype.setTransport=function(t){we("setting transport %s",t.name);var e=this;this.transport&&(we("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=t,t.on("drain",function(){e.onDrain()}).on("packet",function(t){e.onPacket(t)}).on("error",function(t){e.onError(t)}).on("close",function(){e.onClose("transport close")})},S.prototype.probe=function(t){function e(){if(u.onlyBinaryUpgrades){var e=!this.supportsBinary&&u.transport.supportsBinary;h=h||e}h||(we('probe transport "%s" opened',t),c.send([{type:"ping",data:"probe"}]),c.once("packet",function(e){if(!h)if("pong"===e.type&&"probe"===e.data){if(we('probe transport "%s" pong',t),u.upgrading=!0,u.emit("upgrading",c),!c)return;S.priorWebsocketSuccess="websocket"===c.name,we('pausing current transport "%s"',u.transport.name),u.transport.pause(function(){h||"closed"!==u.readyState&&(we("changing transport and sending upgrade packet"),a(),u.setTransport(c),c.send([{type:"upgrade"}]),u.emit("upgrade",c),c=null,u.upgrading=!1,u.flush())})}else{we('probe transport "%s" failed',t);var n=new Error("probe error");n.transport=c.name,u.emit("upgradeError",n)}}))}function n(){h||(h=!0,a(),c.close(),c=null)}function o(e){var o=new Error("probe error: "+e);o.transport=c.name,n(),we('probe transport "%s" failed because of error: %s',t,e),u.emit("upgradeError",o)}function r(){o("transport closed")}function i(){o("socket closed")}function s(t){c&&t.name!==c.name&&(we('"%s" works - aborting "%s"',t.name,c.name),n())}function a(){c.removeListener("open",e),c.removeListener("error",o),c.removeListener("close",r),u.removeListener("close",i),u.removeListener("upgrading",s)}we('probing transport "%s"',t);var c=this.createTransport(t,{probe:1}),h=!1,u=this;S.priorWebsocketSuccess=!1,c.once("open",e),c.once("error",o),c.once("close",r),this.once("close",i),this.once("upgrading",s),c.open()},S.prototype.onOpen=function(){if(we("socket open"),this.readyState="open",S.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.upgrade&&this.transport.pause){we("starting upgrade probes");for(var t=0,e=this.upgrades.length;t<e;t++)this.probe(this.upgrades[t])}},S.prototype.onPacket=function(t){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(we('socket receive: type "%s", data "%s"',t.type,t.data),this.emit("packet",t),this.emit("heartbeat"),t.type){case"open":this.onHandshake(ke(t.data));break;case"pong":this.setPing(),this.emit("pong");break;case"error":var e=new Error("server error");e.code=t.data,this.onError(e);break;case"message":this.emit("data",t.data),this.emit("message",t.data)}else we('packet received with socket readyState "%s"',this.readyState)},S.prototype.onHandshake=function(t){this.emit("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this.upgrades=this.filterUpgrades(t.upgrades),this.pingInterval=t.pingInterval,this.pingTimeout=t.pingTimeout,this.onOpen(),"closed"!==this.readyState&&(this.setPing(),this.removeListener("heartbeat",this.onHeartbeat),this.on("heartbeat",this.onHeartbeat))},S.prototype.onHeartbeat=function(t){clearTimeout(this.pingTimeoutTimer);var e=this;e.pingTimeoutTimer=setTimeout(function(){"closed"!==e.readyState&&e.onClose("ping timeout")},t||e.pingInterval+e.pingTimeout)},S.prototype.setPing=function(){var t=this;clearTimeout(t.pingIntervalTimer),t.pingIntervalTimer=setTimeout(function(){we("writing ping packet - expecting pong within %sms",t.pingTimeout),t.ping(),t.onHeartbeat(t.pingTimeout)},t.pingInterval)},S.prototype.ping=function(){var t=this;this.sendPacket("ping",function(){t.emit("ping")})},S.prototype.onDrain=function(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emit("drain"):this.flush()},S.prototype.flush=function(){"closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length&&(we("flushing %d packets in socket",this.writeBuffer.length),this.transport.send(this.writeBuffer),this.prevBufferLen=this.writeBuffer.length,this.emit("flush"))},S.prototype.write=S.prototype.send=function(t,e,n){return this.sendPacket("message",t,e,n),this},S.prototype.sendPacket=function(t,e,n,o){if("function"==typeof e&&(o=e,e=void 0),"function"==typeof n&&(o=n,n=null),"closing"!==this.readyState&&"closed"!==this.readyState){n=n||{},n.compress=!1!==n.compress;var r={type:t,data:e,options:n};this.emit("packetCreate",r),this.writeBuffer.push(r),o&&this.once("flush",o),this.flush()}},S.prototype.close=function(){function t(){o.onClose("forced close"),we("socket closing - telling transport to close"),o.transport.close()}function e(){o.removeListener("upgrade",e),o.removeListener("upgradeError",e),t()}function n(){o.once("upgrade",e),o.once("upgradeError",e)}if("opening"===this.readyState||"open"===this.readyState){this.readyState="closing";var o=this;this.writeBuffer.length?this.once("drain",function(){this.upgrading?n():t()}):this.upgrading?n():t()}return this},S.prototype.onError=function(t){we("socket error %j",t),S.priorWebsocketSuccess=!1,this.emit("error",t),this.onClose("transport error",t)},S.prototype.onClose=function(t,e){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){we('socket close with reason: "%s"',t);var n=this;clearTimeout(this.pingIntervalTimer),clearTimeout(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),this.readyState="closed",this.id=null,this.emit("close",t,e),n.writeBuffer=[],n.prevBufferLen=0}},S.prototype.filterUpgrades=function(t){for(var e=[],n=0,o=t.length;n<o;n++)~le(this.transports,t[n])&&e.push(t[n]);return e};var Ae=Ee,_e=It;Ae.parser=_e;var Ce=Ae,Ne=O,Te=x,Se=[].slice,Be=function(t,e){if("string"==typeof e&&(e=t[e]),"function"!=typeof e)throw new Error("bind() requires a function");var n=Se.call(arguments,2);return function(){return e.apply(t,n.concat(Se.call(arguments)))}},Oe=t(function(t,e){function n(t,e,n){this.io=t,this.nsp=e,this.json=this,this.ids=0,this.acks={},this.receiveBuffer=[],this.sendBuffer=[],this.connected=!1,this.disconnected=!0,n&&n.query&&(this.query=n.query),this.io.autoConnect&&this.open()}var o=Z("socket.io-client:socket");t.exports=n;var r={connect:1,connect_error:1,connect_timeout:1,connecting:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1,ping:1,pong:1},i=nt.prototype.emit;nt(n.prototype),n.prototype.subEvents=function(){if(!this.subs){var t=this.io;this.subs=[Te(t,"open",Be(this,"onopen")),Te(t,"packet",Be(this,"onpacket")),Te(t,"close",Be(this,"onclose"))]}},n.prototype.open=n.prototype.connect=function(){return this.connected?this:(this.subEvents(),this.io.open(),"open"===this.io.readyState&&this.onopen(),this.emit("connecting"),this)},n.prototype.send=function(){var t=Ne(arguments);return t.unshift("message"),this.emit.apply(this,t),this},n.prototype.emit=function(t){if(r.hasOwnProperty(t))return i.apply(this,arguments),this;var e=Ne(arguments),n={type:bt.EVENT,data:e};return n.options={},n.options.compress=!this.flags||!1!==this.flags.compress,"function"==typeof e[e.length-1]&&(o("emitting packet with ack id %d",this.ids),this.acks[this.ids]=e.pop(),n.id=this.ids++),this.connected?this.packet(n):this.sendBuffer.push(n),delete this.flags,this},n.prototype.packet=function(t){t.nsp=this.nsp,this.io.packet(t)},n.prototype.onopen=function(){if(o("transport is open - connecting"),"/"!==this.nsp)if(this.query){var t="object"===L(this.query)?Ht.encode(this.query):this.query;o("sending connect packet with query %s",t),this.packet({type:bt.CONNECT,query:t})}else this.packet({type:bt.CONNECT})},n.prototype.onclose=function(t){o("close (%s)",t),this.connected=!1,this.disconnected=!0,delete this.id,this.emit("disconnect",t)},n.prototype.onpacket=function(t){if(t.nsp===this.nsp)switch(t.type){case bt.CONNECT:this.onconnect();break;case bt.EVENT:case bt.BINARY_EVENT:this.onevent(t);break;case bt.ACK:case bt.BINARY_ACK:this.onack(t);break;case bt.DISCONNECT:this.ondisconnect();break;case bt.ERROR:this.emit("error",t.data)}},n.prototype.onevent=function(t){var e=t.data||[];o("emitting event %j",e),null!=t.id&&(o("attaching ack callback to event"),e.push(this.ack(t.id))),this.connected?i.apply(this,e):this.receiveBuffer.push(e)},n.prototype.ack=function(t){var e=this,n=!1;return function(){if(!n){n=!0;var r=Ne(arguments);o("sending ack %j",r),e.packet({type:bt.ACK,id:t,data:r})}}},n.prototype.onack=function(t){var e=this.acks[t.id];"function"==typeof e?(o("calling ack %s with %j",t.id,t.data),e.apply(this,t.data),delete this.acks[t.id]):o("bad ack %s",t.id)},n.prototype.onconnect=function(){this.connected=!0,this.disconnected=!1,this.emit("connect"),this.emitBuffered()},n.prototype.emitBuffered=function(){var t;for(t=0;t<this.receiveBuffer.length;t++)i.apply(this,this.receiveBuffer[t]);for(this.receiveBuffer=[],t=0;t<this.sendBuffer.length;t++)this.packet(this.sendBuffer[t]);this.sendBuffer=[]},n.prototype.ondisconnect=function(){o("server disconnect (%s)",this.nsp),this.destroy(),this.onclose("io server disconnect")},n.prototype.destroy=function(){if(this.subs){for(var t=0;t<this.subs.length;t++)this.subs[t].destroy();this.subs=null}this.io.destroy(this)},n.prototype.close=n.prototype.disconnect=function(){return this.connected&&(o("performing disconnect (%s)",this.nsp),this.packet({type:bt.DISCONNECT})),this.destroy(),this.connected&&this.onclose("io client disconnect"),this},n.prototype.compress=function(t){return this.flags=this.flags||{},this.flags.compress=t,this}}),xe=I;I.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},I.prototype.reset=function(){this.attempts=0},I.prototype.setMin=function(t){this.ms=t},I.prototype.setMax=function(t){this.max=t},I.prototype.setJitter=function(t){this.jitter=t};var Ie=Z("socket.io-client:manager"),Re=Object.prototype.hasOwnProperty,De=R;R.prototype.emitAll=function(){this.emit.apply(this,arguments);for(var t in this.nsps)Re.call(this.nsps,t)&&this.nsps[t].emit.apply(this.nsps[t],arguments)},R.prototype.updateSocketIds=function(){for(var t in this.nsps)Re.call(this.nsps,t)&&(this.nsps[t].id=this.generateId(t))},R.prototype.generateId=function(t){return("/"===t?"":t+"#")+this.engine.id},nt(R.prototype),R.prototype.reconnection=function(t){return arguments.length?(this._reconnection=!!t,this):this._reconnection},R.prototype.reconnectionAttempts=function(t){return arguments.length?(this._reconnectionAttempts=t,this):this._reconnectionAttempts},R.prototype.reconnectionDelay=function(t){return arguments.length?(this._reconnectionDelay=t,this.backoff&&this.backoff.setMin(t),this):this._reconnectionDelay},R.prototype.randomizationFactor=function(t){return arguments.length?(this._randomizationFactor=t,this.backoff&&this.backoff.setJitter(t),this):this._randomizationFactor},R.prototype.reconnectionDelayMax=function(t){return arguments.length?(this._reconnectionDelayMax=t,this.backoff&&this.backoff.setMax(t),this):this._reconnectionDelayMax},R.prototype.timeout=function(t){return arguments.length?(this._timeout=t,this):this._timeout},R.prototype.maybeReconnectOnOpen=function(){!this.reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()},R.prototype.open=R.prototype.connect=function(t,e){if(Ie("readyState %s",this.readyState),~this.readyState.indexOf("open"))return this;Ie("opening %s",this.uri),this.engine=Ce(this.uri,this.opts);var n=this.engine,o=this;this.readyState="opening",this.skipReconnect=!1;var r=Te(n,"open",function(){o.onopen(),t&&t()}),i=Te(n,"error",function(e){if(Ie("connect_error"),o.cleanup(),o.readyState="closed",o.emitAll("connect_error",e),t){var n=new Error("Connection error");n.data=e,t(n)}else o.maybeReconnectOnOpen()});if(!1!==this._timeout){var s=this._timeout;Ie("connect attempt will timeout after %d",s);var a=setTimeout(function(){Ie("connect attempt timed out after %d",s),r.destroy(),n.close(),n.emit("error","timeout"),o.emitAll("connect_timeout",s)},s);this.subs.push({destroy:function(){clearTimeout(a)}})}return this.subs.push(r),this.subs.push(i),this},R.prototype.onopen=function(){Ie("open"),this.cleanup(),this.readyState="open",this.emit("open");var t=this.engine;this.subs.push(Te(t,"data",Be(this,"ondata"))),this.subs.push(Te(t,"ping",Be(this,"onping"))),this.subs.push(Te(t,"pong",Be(this,"onpong"))),this.subs.push(Te(t,"error",Be(this,"onerror"))),this.subs.push(Te(t,"close",Be(this,"onclose"))),
this.subs.push(Te(this.decoder,"decoded",Be(this,"ondecoded")))},R.prototype.onping=function(){this.lastPing=new Date,this.emitAll("ping")},R.prototype.onpong=function(){this.emitAll("pong",new Date-this.lastPing)},R.prototype.ondata=function(t){this.decoder.add(t)},R.prototype.ondecoded=function(t){this.emit("packet",t)},R.prototype.onerror=function(t){Ie("error",t),this.emitAll("error",t)},R.prototype.socket=function(t,e){function n(){~le(r.connecting,o)||r.connecting.push(o)}var o=this.nsps[t];if(!o){o=new Oe(this,t,e),this.nsps[t]=o;var r=this;o.on("connecting",n),o.on("connect",function(){o.id=r.generateId(t)}),this.autoConnect&&n()}return o},R.prototype.destroy=function(t){var e=le(this.connecting,t);~e&&this.connecting.splice(e,1),this.connecting.length||this.close()},R.prototype.packet=function(t){Ie("writing packet %j",t);var e=this;t.query&&0===t.type&&(t.nsp+="?"+t.query),e.encoding?e.packetBuffer.push(t):(e.encoding=!0,this.encoder.encode(t,function(n){for(var o=0;o<n.length;o++)e.engine.write(n[o],t.options);e.encoding=!1,e.processPacketQueue()}))},R.prototype.processPacketQueue=function(){if(this.packetBuffer.length>0&&!this.encoding){var t=this.packetBuffer.shift();this.packet(t)}},R.prototype.cleanup=function(){Ie("cleanup");for(var t=this.subs.length,e=0;e<t;e++){this.subs.shift().destroy()}this.packetBuffer=[],this.encoding=!1,this.lastPing=null,this.decoder.destroy()},R.prototype.close=R.prototype.disconnect=function(){Ie("disconnect"),this.skipReconnect=!0,this.reconnecting=!1,"opening"===this.readyState&&this.cleanup(),this.backoff.reset(),this.readyState="closed",this.engine&&this.engine.close()},R.prototype.onclose=function(t){Ie("onclose"),this.cleanup(),this.backoff.reset(),this.readyState="closed",this.emit("close",t),this._reconnection&&!this.skipReconnect&&this.reconnect()},R.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var t=this;if(this.backoff.attempts>=this._reconnectionAttempts)Ie("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var e=this.backoff.duration();Ie("will wait %dms before reconnect attempt",e),this.reconnecting=!0;var n=setTimeout(function(){t.skipReconnect||(Ie("attempting reconnect"),t.emitAll("reconnect_attempt",t.backoff.attempts),t.emitAll("reconnecting",t.backoff.attempts),t.skipReconnect||t.open(function(e){e?(Ie("reconnect attempt error"),t.reconnecting=!1,t.reconnect(),t.emitAll("reconnect_error",e.data)):(Ie("reconnect success"),t.onreconnect())}))},e);this.subs.push({destroy:function(){clearTimeout(n)}})}},R.prototype.onreconnect=function(){var t=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",t)};var Pe=t(function(t,e){function n(t,e){"object"===(void 0===t?"undefined":L(t))&&(e=t,t=void 0),e=e||{};var n,i=et(t),s=i.source,a=i.id,c=i.path,h=r[a]&&c in r[a].nsps,u=e.forceNew||e["force new connection"]||!1===e.multiplex||h;return u?(o("ignoring socket cache for %s",s),n=De(s,e)):(r[a]||(o("new io instance for %s",s),r[a]=De(s,e)),n=r[a]),i.query&&!e.query&&(e.query=i.query),n.socket(i.path,e)}var o=Z("socket.io-client");t.exports=e=n;var r=e.managers={};e.protocol=bt.protocol,e.connect=n,e.Manager=De,e.Socket=Oe}),je={trace:1,debug3:2,debug2:3,debug:4,info:5,warn:6,error:7},He=function(){return(new Error).stack.split("\n")[4].split("at ")[1].trim()},Ue=function(t){var e=t.split(/\s+/);if(e.length>1){var n=/\(.*\/(.*)\)/g.exec(e[e.length-1]);if(null!=n&&n.length>1)return e[0]+"::"+n[1]}return t},Le=function(){if(1==Ve){var t=He();return Ue(t)}return""},qe=function(){return(new Date).toISOString()},Me=4,Ve=!1,ze=function(){function t(){q(this,t)}return M(t,null,[{key:"setLevel",value:function(t){if(!(t in je))throw new Error("invalid log type");Me=je[t]}},{key:"showFileAndLineInfo",value:function(t){Ve=t}},{key:"trace",value:function(t){Me<=je.trace&&console.trace(qe()+"TRACE "+Le()+" "+t)}},{key:"debug",value:function(t){Me<=je.debug&&console.log(qe()+"DEBUG "+Le()+" "+t)}},{key:"debug2",value:function(t){Me<=je.debug2&&console.log(qe()+"DEBUG2 "+Le()+" "+t)}},{key:"debug3",value:function(t){Me<=je.debug3&&console.log(qe()+"DEBUG3 "+Le()+" "+t)}},{key:"info",value:function(t){Me<=je.info&&console.info(qe()+"INFO "+Le()+" "+t)}},{key:"warn",value:function(t){Me<=je.warn&&console.warn(qe()+"WARN "+Le()+" "+t)}},{key:"error",value:function(t){Me<=je.error&&console.error(qe()+"ERROR "+Le()+" "+t)}}]),t}(),Xe={CLIENT:"RealtimeClientDomain",SERVER:"RealtimeServerDomain"},Fe={UNKNOWN:-1,INITIAL_CONNECTION:1,INTERNAL_FAILURE:2},We={UNKNOWN:-1,AUTH_EXPIRED:1,SESSION_START_DENIED:2,CANNOT_ACQUIRE_LOCK:3,INCOMPATIBLE_MODEL:4,INCOMPATIBLE_CONTENT_CLASS:5},Ye={AUTH_EXPIRED:0,SESSION_START_DENIED:1,CANNOT_ACQUIRE_LOCK:2,INCOMPATIBLE_MODEL:3,INCOMPATIBLE_CONTENT_CLASS:4},Je=function(t){var e=Fe.UNKNOWN,n="Unknown client error. Code: "+t;switch(t){case Fe.INITIAL_CONNECTION:e=t,n="It was not possible to establish connection to RTE server.";break;case Fe.INTERNAL_FAILURE:e=t,n="Internal error."}return{code:e,domain:Xe.CLIENT,message:n}},Ke=function(t){var e=We.UNKNOWN,n="Unknown server error. Code: "+t;switch(t){case Ye.AUTH_EXPIRED:e=We.AUTH_EXPIRED,n="Auth token has been expired.";break;case Ye.SESSION_START_DENIED:e=We.SESSION_START_DENIED,n="User has no permissions to start RTE session.";break;case Ye.CANNOT_ACQUIRE_LOCK:e=We.CANNOT_ACQUIRE_LOCK,n="It was not possible to acquire the note lock.";break;case Ye.INCOMPATIBLE_MODEL:e=We.INCOMPATIBLE_MODEL,n="Client and server have incompatible model states.";break;case We.INCOMPATIBLE_CONTENT_CLASS:e=We.INCOMPATIBLE_CONTENT_CLASS,n="The note was created in a another app."}return{code:e,domain:Xe.SERVER,message:n}},$e=1e3,Qe=5e3,Ge=15e3,Ze=2e4,tn=9;return"undefined"!=typeof Y&&D(Y),D});
//# sourceMappingURL=y-websockets-client.js.map
!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new c;return t.on=function(t,i){var u,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,u=e.indexOf(o)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function S(){ao.event.preventDefault()}function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=ao.event;i.target=n,ao.event=i,t[i.type].apply(e,r)}finally{ao.event=u}}},t}function E(n){return ko(n,Co),n}function A(n){return"function"==typeof n?n:function(){return No(n,this)}}function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ao.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?u:i}function L(n){return n.trim().replace(/\s+/g," ")}function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=T(n).map(D);var i=n.length;return"function"==typeof t?r:e}function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",L(i+" "+n))):e.setAttribute("class",L(i.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e===zo&&t.documentElement.namespaceURI===zo?t.createElement(n):t.createElementNS(e,n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ao.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return Ao(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t<l;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function i(){var i=l(t,co(arguments));r.call(this),this.addEventListener(n,this[o]=i,i.$=e),i._=t}function u(){var t,e=new RegExp("^__on([^.]+)"+ao.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),l=$;a>0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n?n.n=t.n:oa=t.n;return aa=n,e}function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(l,a)),null!=(i=ya[e=n.charAt(++a)])&&(e=n.charAt(++a)),(u=A[e])&&(e=u(t,null==i?"e"===e?" ":"0":i)),o.push(e),l=a+1);return o.push(n.slice(l,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},i=e(r,n,t,0);if(i!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var u=null!=r.Z&&va!==Hn,o=new(u?Hn:va);return"j"in r?o.setFullYear(r.y,0,r.j):"W"in r||"U"in r?("w"in r||(r.w="W"in r?1:0),o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),u?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var i,u,o,a=0,l=t.length,c=e.length;l>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.y=Qn(+r[0]),e+r[0].length):-1}function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Qn(n){return n+(n>68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ft(){}function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1],r[2]);t.lineEnd()}function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e],t,1);t.polygonEnd()}function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n),a=u*Math.sin(n),l=Math.sin(i),c=Math.atan2(Math.sqrt((c=e*l-r*a)*c+(c=r*o-t*l)*c+(c=t*a-e*o)*c),t*o+e*a+r*l);Aa+=c,qa+=c*(t+(t=o)),Ta+=c*(e+(e=a)),Ra+=c*(r+(r=l)),kt(t,e,r)}var t,e,r;ja.point=function(i,u){i*=Yo;var o=Math.cos(u*=Yo);t=o*Math.cos(i),e=o*Math.sin(i),r=Math.sin(u),ja.point=n,kt(t,e,r)}}function Et(){ja.point=St}function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n),a=e*Math.sin(n),l=Math.sin(t),c=i*l-u*a,f=u*o-r*l,s=r*a-i*o,h=Math.sqrt(c*c+f*f+s*s),p=r*o+i*a+u*l,g=h&&-nn(p)/h,v=Math.atan2(h,p);Da+=g*c,Pa+=g*f,Ua+=g*s,Aa+=v,qa+=v*(r+(r=o)),Ta+=v*(i+(i=a)),Ra+=v*(u+(u=l)),kt(r,i,u)}var t,e,r,i,u;ja.point=function(o,a){t=o,e=a,ja.point=n,o*=Yo;var l=Math.cos(a*=Yo);r=l*Math.cos(o),i=l*Math.sin(o),u=Math.sin(a),kt(r,i,u)},ja.lineEnd=function(){n(t,e),ja.lineEnd=Et,ja.point=St}}function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function zt(){return!0}function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(wt(e,r)){i.lineStart();for(var a=0;t>a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e.p=i,i=e;i.n=e=n[0],e.p=i}}function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n(t=r[0],e=r[1])&&u.point(t,e)}function a(n,t){var e=i(n,t);d.point(e[0],e[1])}function l(){m.point=a,d.lineStart()}function c(){m.point=o,d.lineEnd()}function f(n,t){v.push([n,t]);var e=i(n,t);x.point(e[0],e[1])}function s(){x.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),g.push(v),v=null,r)if(1&t){n=e[0];var i,r=n.length-1,o=-1;if(r>0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o<r;)u.point((i=n[o])[0],i[1]);u.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)<Uo?(n.point(e,r=(r+o)/2>0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)<Uo&&(e-=i*Uo),xo(u-a)<Uo&&(u-=a*Uo),r=Ft(e,r,u,o),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=u,r=o),i=a},lineEnd:function(){n.lineEnd(),e=r=NaN},clean:function(){return 2-t}}}function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]<t[0]?Fo:-Fo;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=0;ka.reset();for(var a=0,l=t.length;l>a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)<Uo,C=A||Uo>E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)<Uo?k:N):k<=b[1]&&b[1]<=N:E>Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0]-e)<Uo?i>0?2:1:xo(r[1]-t)<Uo?i>0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){
r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)<Uo||xo(r-h)<Uo?(r+h)/2:Math.atan2(_,b),E=n(N,k),A=E[0],C=E[1],z=A-t,L=C-e,q=M*z-m*L;(q*q/x>u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)<Uo?ce:(e.invert=function(n,t){var e=u-t;return[Math.atan2(n,e)/i,u-K(i)*Math.sqrt(n*n+e*e)]},e)}function Ne(n,t){return[n,Math.log(Math.tan(Fo/4+t/2))]}function Ee(n){var t,e=oe(n),r=e.scale,i=e.translate,u=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=i.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=u.apply(e,arguments);if(o===e){if(t=null==n){var a=Fo*r(),l=i();u([[l[0]-a,l[1]-a],[l[0]+a,l[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Ae(n,t){return[Math.log(Math.tan(Fo/4+t/2)),-n]}function Ce(n){return n[0]}function ze(n){return n[1]}function Le(n){for(var t=n.length,e=[0,1],r=2,i=2;t>i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)<Uo&&xo(r-l.circle.cy)<Uo;)u=l.P,a.unshift(l),je(l),l=u;a.unshift(l),Be(l);for(var c=o;c.circle&&xo(e-c.circle.x)<Uo&&xo(r-c.circle.cy)<Uo;)o=c.N,a.push(c),je(c),c=o;a.push(c),Be(c);var f,s=a.length;for(f=1;s>f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)<Uo&&g-i>Uo?{x:s,y:xo(t-s)<Uo?e:g}:xo(i-g)<Uo&&h-r>Uo?{x:xo(e-g)<Uo?t:h,y:g}:xo(r-h)<Uo&&i-p>Uo?{x:h,y:xo(t-h)<Uo?e:p}:xo(i-p)<Uo&&r-s>Uo?{x:xo(e-p)<Uo?t:s,y:p}:null),u.site,null)),++l)}function Ve(n,t){return t.angle-n.angle}function Xe(){rr(this),this.x=this.y=this.arc=this.site=this.cy=null}function $e(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,i=n.site,u=e.site;if(r!==u){var o=i.x,a=i.y,l=r.x-o,c=r.y-a,f=u.x-o,s=u.y-a,h=2*(l*s-c*f);if(!(h>=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.y<M.y||y.y===M.y&&y.x<=M.x){if(!M.L){m=M.P;break}M=M.L}else{if(!M.R){m=M;break}M=M.R}ll.insert(m,y),m||(al=y)}}}}function Be(n){var t=n.circle;t&&(t.P||(al=t.N),ll.remove(t),fl.push(t),rr(t),n.circle=null)}function We(n){for(var t,e=il,r=Yt(n[0][0],n[0][1],n[1][0],n[1][1]),i=e.length;i--;)t=e[i],(!Je(t,n)||!r(t)||xo(t.a.x-t.b.x)<Uo&&xo(t.a.y-t.b.y)<Uo)&&(t.a=t.b=null,e.splice(i,1))}function Je(n,t){var e=n.b;if(e)return!0;var r,i,u=n.a,o=t[0][0],a=t[1][0],l=t[0][1],c=t[1][1],f=n.l,s=n.r,h=f.x,p=f.y,g=s.x,v=s.y,d=(h+g)/2,y=(p+v)/2;if(v===p){if(o>d||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.y<l)return}else u={x:d,y:c};e={x:d,y:l}}}else if(r=(h-g)/(v-p),i=y-r*d,-1>r||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.y<l)return}else u={x:(c-i)/r,y:c};e={x:(l-i)/r,y:l}}else if(v>p){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.x<o)return}else u={x:a,y:r*a+i};e={x:o,y:r*o+i}}return n.a=u,n.b=e,!0}function Ge(n,t){this.l=n,this.r=t,this.a=this.b=null}function Ke(n,t,e,r){var i=new Ge(n,t);return il.push(i),e&&nr(i,n,t,e),r&&nr(i,t,n,r),ul[n.i].edges.push(new tr(i,n,t)),ul[t.i].edges.push(new tr(i,t,n)),i}function Qe(n,t,e){var r=new Ge(n,null);return r.a=t,r.b=e,il.push(r),r}function nr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function tr(n,t,e){var r=n.a,i=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(i.x-r.x,r.y-i.y):Math.atan2(r.x-i.x,i.y-r.y)}function er(){this._=null}function rr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function ir(n,t){var e=t,r=t.R,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ur(n,t){var e=t,r=t.L,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function or(n){for(;n.L;)n=n.L;return n}function ar(n,t){var e,r,i,u=n.sort(lr).pop();for(il=[],ul=new Array(n.length),ol=new er,ll=new er;;)if(i=al,u&&(!i||u.y<i.y||u.y===i.y&&u.x<i.x))u.x===e&&u.y===r||(ul[u.i]=new Ye(u),He(u),e=u.x,r=u.y),u=n.pop();else{if(!i)break;Fe(i.arc)}t&&(We(t),Ze(t));var o={cells:ul,edges:il};return ol=ll=il=ul=null,o}function lr(n,t){return t.y-n.y||t.x-n.x}function cr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function fr(n){return n.x}function sr(n){return n.y}function hr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function pr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var o=.5*(e+i),a=.5*(r+u),l=t.nodes;l[0]&&pr(n,l[0],e,r,o,a),l[1]&&pr(n,l[1],o,r,i,a),l[2]&&pr(n,l[2],e,a,o,u),l[3]&&pr(n,l[3],o,a,i,u)}}function gr(n,t,e,r,i,u,o){var a,l=1/0;return function c(n,f,s,h,p){if(!(f>u||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return u<t.length&&(i=t.slice(u),a[o]?a[o]+=i:a[++o]=i),a.length<2?l[0]?(t=l[0].x,function(n){return t(n)+""}):function(){return t}:(t=l.length,function(n){for(var e,r=0;t>r;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Zo,this.translate=[n.e,n.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Zo:0}function Fr(n,t){return n[0]*t[0]+n[1]*t[1]}function Hr(n){var t=Math.sqrt(Fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Or(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ir(n){return n.length?n.pop()+",":""}function Yr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push("translate(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else(t[0]||t[1])&&e.push("translate("+t+")")}function Zr(n,t,e,r){n!==t?(n-t>180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i<u;)e[(t=r[i]).i]=t.x(n);return e.join("")}}function Br(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Wr(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Jr(n){for(var t=n.source,e=n.target,r=Kr(t,e),i=[t];t!==r;)t=t.parent,i.push(t);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Gr(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Kr(n,t){if(n===t)return n;for(var e=Gr(n),r=Gr(t),i=e.pop(),u=r.pop(),o=null;i===u;)o=i,i=e.pop(),u=r.pop();return o}function Qr(n){n.fixed|=2}function ni(n){n.fixed&=-7}function ti(n){n.fixed|=4,n.px=n.x,n.py=n.y}function ei(n){n.fixed&=-5}function ri(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,o=n.nodes,a=o.length,l=-1;++l<a;)u=o[l],null!=u&&(ri(u,t,e),n.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var c=t*e[n.point.index];n.charge+=n.pointCharge=c,r+=c*n.point.x,i+=c*n.point.y}n.cx=r/n.charge,n.cy=i/n.charge}function ii(n,t){return ao.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=fi,n}function ui(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(i=n.children)&&(r=i.length))for(var r,i;--r>=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++o<i;)e.push(u[o]);for(;null!=(n=r.pop());)t(n)}function ai(n){return n.children}function li(n){return n.value}function ci(n,t){return t.value-n.value}function fi(n){return ao.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function si(n){return n.x}function hi(n){return n.y}function pi(n,t,e){n.y0=t,n.y=e}function gi(n){return ao.range(n.length)}function vi(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function di(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.r<r.r?Si(r,i=a):Si(r=l,i),o--):(wi(r,u),i=u,t(u))}var y=(f+s)/2,m=(h+p)/2,M=0;for(o=0;c>o;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u<o;)Ci(i[u],t,e,r)}function zi(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var o=t.r+e.r,a=i*i+u*u;o*=o,r*=r;var l=.5+(r-o)/(2*a),c=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+l*i+c*u,e.y=n.y+l*u-c*i}else e.x=n.x+r,e.y=n.y}function Li(n,t){return n.parent==t.parent?1:2}function qi(n){var t=n.children;return t.length?t[0]:n.t}function Ti(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ri(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Di(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)i.push(e(n[o-1],n[o])),u.push(r(t[o-1],t[o]));return function(t){var e=ao.bisect(n,t,1,a)-1;return u[e](i[e](t))}}function Wi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++<f;)for(var h=s-1;h>0;h--)o.push(u(c)*h);for(c=0;o[c]<a;c++);for(f=o.length;o[f-1]>l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++o<a;)i.has(u=r[o])||i.set(u,n.push(u));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(u=n,o=0,t={t:"range",a:arguments},e):u},e.rangePoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=(l+c)/2,0):(c-l)/(n.length-1+a);return u=r(l+f*a/2,f),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=c=Math.round((l+c)/2),0):(c-l)/(n.length-1+a)|0;return u=r(l+Math.round(f*a/2+(c-l-(n.length-1+a)*f)/2),f),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=(s-f)/(n.length-a+2*l);return u=r(f+h*l,h),c&&u.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=Math.floor((s-f)/(n.length-a+2*l));return u=r(f+Math.round((s-f-(n.length-a)*h)/2),h),c&&u.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Yi(t.a[0])},e.copy=function(){return ou(n,t)},e.domain(n)}function au(n,t){function u(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ao.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ao.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(i).sort(e),u()):n},o.range=function(n){return arguments.length?(t=n,u()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[NaN,NaN]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return au(n,t)},u()}function lu(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(u*(t-n))))]}function i(){return u=e.length/(t-n),o=e.length-1,r}var u,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],i()):[n,t]},r.range=function(n){return arguments.length?(e=n,i()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s<h;)i.call(this,l=t[s],s)?f.push([+p.call(this,l,s),+g.call(this,l,s)]):f.length&&(o(),f=[]);return f.length&&o(),c.length?c.join(""):null}var e=Ce,r=ze,i=zt,u=xu,o=u.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(i=n,t):i},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?u=n:(u=Tl.get(n)||xu).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function xu(n){return n.length>1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("V",(r=n[t])[1],"H",r[0]);return i.join("")}function Su(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r=n[t])[0],"V",r[1]);return i.join("")}function ku(n,t){return n.length<4?xu(n):n[1]+Au(n.slice(1,-1),Cu(n,t))}function Nu(n,t){return n.length<3?bu(n):n[0]+Au((n.push(n[0]),n),Cu([n[n.length-2]].concat(n,[n[1]]),t))}function Eu(n,t){return n.length<3?xu(n):n[0]+Au(n,Cu(n,t))}function Au(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return xu(n);var e=n.length!=t.length,r="",i=n[0],u=n[1],o=t[0],a=o,l=1;if(e&&(r+="Q"+(u[0]-2*o[0]/3)+","+(u[1]-2*o[1]/3)+","+u[0]+","+u[1],i=n[1],l=2),t.length>1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c<t.length;c++,l++)u=n[l],a=t[c],r+="S"+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1]}if(e){var f=n[l];r+="Q"+(u[0]+2*a[0]/3)+","+(u[1]+2*a[1]/3)+","+f[0]+","+f[1]}return r}function Cu(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],o=n[1],a=1,l=n.length;++a<l;)e=u,u=o,o=n[a],r.push([i*(o[0]-e[0]),i*(o[1]-e[1])]);return r}function zu(n){if(n.length<3)return xu(n);var t=1,e=n.length,r=n[0],i=r[0],u=r[1],o=[i,i,i,(r=n[1])[0]],a=[u,u,u,r[1]],l=[i,",",u,"L",Ru(Pl,o),",",Ru(Pl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Du(l,o,a);return n.pop(),l.push("L",r),l.join("")}function Lu(n){if(n.length<4)return xu(n);for(var t,e=[],r=-1,i=n.length,u=[0],o=[0];++r<3;)t=n[r],u.push(t[0]),o.push(t[1]);for(e.push(Ru(Pl,u)+","+Ru(Pl,o)),--r;++r<i;)t=n[r],u.shift(),u.push(t[0]),o.shift(),o.push(t[1]),Du(e,u,o);return e.join("")}function qu(n){for(var t,e,r=-1,i=n.length,u=i+4,o=[],a=[];++r<4;)e=n[r%i],o.push(e[0]),a.push(e[1]);for(t=[Ru(Pl,o),",",Ru(Pl,a)],--r;++r<u;)e=n[r%i],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Du(t,o,a);return t.join("")}function Tu(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],o=n[0][1],a=n[e][0]-u,l=n[e][1]-o,c=-1;++c<=e;)r=n[c],i=c/e,r[0]=t*r[0]+(1-t)*(u+i*a),r[1]=t*r[1]+(1-t)*(o+i*l);return zu(n)}function Ru(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Du(n,t,e){n.push("C",Ru(Rl,t),",",Ru(Rl,e),",",Ru(Dl,t),",",Ru(Dl,e),",",Ru(Pl,t),",",Ru(Pl,e))}function Pu(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Uu(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],o=r[0]=Pu(i,u);++t<e;)r[t]=(o+(o=Pu(i=u,u=n[t+1])))/2;return r[t]=o,r}function ju(n){for(var t,e,r,i,u=[],o=Uu(n),a=-1,l=n.length-1;++a<l;)t=Pu(n[a],n[a+1]),xo(t)<Uo?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,i=e*e+r*r,i>9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]-Io,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Ou(n){function t(t){function l(){v.push("M",a(n(y),s),f,c(n(d.reverse()),s),"Z")}for(var h,p,g,v=[],d=[],y=[],m=-1,M=t.length,x=En(e),b=En(i),_=e===r?function(){
return p}:En(r),w=i===u?function(){return g}:En(u);++m<M;)o.call(this,h=t[m],m)?(d.push([p=+x.call(this,h,m),g=+b.call(this,h,m)]),y.push([+_.call(this,h,m),+w.call(this,h,m)])):d.length&&(l(),d=[],y=[]);return d.length&&l(),v.length?v.join(""):null}var e=Ce,r=Ce,i=0,u=ze,o=zt,a=xu,l=a.key,c=a,f="L",s=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(i=u=n,t):u},t.y0=function(n){return arguments.length?(i=n,t):i},t.y1=function(n){return arguments.length?(u=n,t):u},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(l="function"==typeof n?a=n:(a=Tl.get(n)||xu).key,c=a.reverse||a,f=a.closed?"M":"L",t):l},t.tension=function(n){return arguments.length?(s=n,t):s},t}function Iu(n){return n.radius}function Yu(n){return[n.x,n.y]}function Zu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Io;return[e*Math.cos(r),e*Math.sin(r)]}}function Vu(){return 64}function Xu(){return"circle"}function $u(n){var t=Math.sqrt(n/Fo);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Bu(n){return function(){var t,e,r;(t=this[n])&&(r=t[e=t.active])&&(r.timer.c=null,r.timer.t=NaN,--t.count?delete t[e]:delete this[n],t.active+=.5,r.event&&r.event.interrupt.call(this,this.__data__,r.index))}}function Wu(n,t,e){return ko(n,Yl),n.namespace=t,n.id=e,n}function Ju(n,t,e,r){var i=n.id,u=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[u][i].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[u][i].tween.set(t,e)}))}function Gu(n){return null==n&&(n=""),function(){this.textContent=n}}function Ku(n){return null==n?"__transition__":"__transition_"+n+"__"}function Qu(n,t,e,r,i){function u(n){var t=v.delay;return f.t=t+l,n>=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]<Kl[u]/i?u-1:u]:[tc,Ki(n,e)[2]]}return r.invert=function(t){return io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,io(+e+1),t).length}var u=r.domain(),o=Yi(u),a=null==n?i(o,10):"number"==typeof n&&i(o,n);return a&&(n=a[0],t=a[1]),r.domain(Xi(u,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&e>r&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&e>r&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&r>e&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&r>e&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u<o;)if(null!=(r=n[u])&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=n[u])&&(e>r&&(e=r),r>i&&(i=r))}else{for(;++u<o;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=t.call(n,n[u],u))&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o<u;)i(e=+n[o])&&(r+=e);else for(;++o<u;)i(e=+t.call(n,n[o],o))&&(r+=e);return r},ao.mean=function(n,t){var e,u=0,o=n.length,a=-1,l=o;if(1===arguments.length)for(;++a<o;)i(e=r(n[a]))?u+=e:--l;else for(;++a<o;)i(e=r(t.call(n,n[a],a)))?u+=e:--l;return l?u/l:void 0},ao.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),i=+n[r-1],u=e-r;return u?i+u*(n[r]-i):i},ao.median=function(n,t){var u,o=[],a=n.length,l=-1;if(1===arguments.length)for(;++l<a;)i(u=r(n[l]))&&o.push(u);else for(;++l<a;)i(u=r(t.call(n,n[l],l)))&&o.push(u);return o.length?ao.quantile(o.sort(e),.5):void 0},ao.variance=function(n,t){var e,u,o=n.length,a=0,l=0,c=-1,f=0;if(1===arguments.length)for(;++c<o;)i(e=r(n[c]))&&(u=e-a,a+=u/++f,l+=u*(e-a));else for(;++c<o;)i(e=r(t.call(n,n[c],c)))&&(u=e-a,a+=u/++f,l+=u*(e-a));return f>1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t<e;)for(var i,u=-1,a=r[t]=new Array(i);++u<i;)a[u]=n[u][t];return r},ao.zip=function(){return ao.transpose(arguments)},ao.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ao.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ao.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ao.merge=function(n){for(var t,e,r,i=n.length,u=-1,o=0;++u<i;)o+=n[u].length;for(e=new Array(o);--i>=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)<t;)i.push(r/u);return i},ao.map=function(n,t){var e=new c;if(n instanceof c)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,i=-1,u=n.length;if(1===arguments.length)for(;++i<u;)e.set(i,n[i]);else for(;++i<u;)e.set(t.call(n,r=n[i],i),r)}else for(var o in n)e.set(o,n[o]);return e};var bo="__proto__",_o="\x00";l(c,{has:h,get:function(n){return this._[f(n)]},set:function(n,t){return this._[f(n)]=t},remove:p,keys:g,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:s(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t),this._[t])}}),ao.nest=function(){function n(t,o,a){if(a>=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p<g;)(h=d.get(l=v(f=o[p])))?h.push(f):d.set(l,[f]);return t?(f=t(),s=function(e,r){f.set(e,n(t,r,a))}):(f={},s=function(e,r){f[e]=n(t,r,a)}),d.forEach(s),f}function t(n,e){if(e>=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r<i;)n[e=arguments[r]]=M(n,t,t[e]);return n};var wo=["webkit","ms","moz","Moz","o","O"];ao.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o<a;){u.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var l=-1,c=r.length;++l<c;)(i=r[l])?(t.push(e=n.call(i,i.__data__,l,o)),e&&"__data__"in i&&(e.__data__=i.__data__)):t.push(null)}return E(u)},Co.selectAll=function(n){var t,e,r=[];n=C(n);for(var i=-1,u=this.length;++i<u;)for(var o=this[i],a=-1,l=o.length;++a<l;)(e=o[a])&&(r.push(t=co(n.call(e,e.__data__,a,i))),t.parentNode=e);return E(r)};var zo="http://www.w3.org/1999/xhtml",Lo={svg:"http://www.w3.org/2000/svg",xhtml:zo,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ao.ns={prefix:Lo,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++i<r;)if(!t.contains(n[i]))return!1}else for(t=e.getAttribute("class");++i<r;)if(!q(n[i]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},Co.style=function(n,e,r){var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++r<o;)(i=n[r])&&(y.has(d=t.call(i,i.__data__,r))?v[r]=i:y.set(d,i),m[r]=d);for(r=-1;++r<s;)(i=y.get(d=t.call(e,u=e[r],r)))?i!==!0&&(p[r]=i,i.__data__=u):g[r]=H(u),y.set(d,!0);for(r=-1;++r<o;)r in m&&y.get(m[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],u=e[r],i?(i.__data__=u,p[r]=i):g[r]=H(u);for(;s>r;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++u<o;)(i=r[u])&&(n[u]=i.__data__);return n}var a=Z([]),l=E([]),f=E([]);if("function"==typeof n)for(;++u<o;)e(r=this[u],n.call(r,r.parentNode.__data__,u));else for(;++u<o;)e(r=this[u],n);return l.enter=function(){return a},l.exit=function(){return f},l},Co.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},Co.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},Co.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},Co.call=function(n){var t=co(arguments);return n.apply(t[0]=this,t),this},Co.empty=function(){return!this.node()},Co.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++a<l;){r=(i=this[a]).update,o.push(t=[]),t.parentNode=i.parentNode;for(var c=-1,f=i.length;++c<f;)(u=i[c])?(t.push(r[c]=e=n.call(i.parentNode,u.__data__,c,a)),e.__data__=u.__data__):t.push(null)}return E(o)},qo.insert=function(n,t){return arguments.length<2&&(t=V(this)),Co.insert.call(this,n,t)},ao.select=function(t){var e;return"string"==typeof t?(e=[No(t,fo)],e.parentNode=fo.documentElement):(e=[t],e.parentNode=n(t)),E([e])},ao.selectAll=function(n){var t;return"string"==typeof n?(t=co(Eo(n,fo)),t.parentNode=fo.documentElement):(t=co(n),t.parentNode=null),E([t])},Co.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++<c;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}f=e+2;var r=n.charCodeAt(e+1);return 13===r?(i=!0,10===n.charCodeAt(e+2)&&++f):10===r&&(i=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;c>f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv("	","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++r<i;)ht(e[r].geometry,t)}},wa={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){pt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)pt(e[r],t,0)},Polygon:function(n,t){gt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)gt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,i=e.length;++r<i;)ht(e[r],t)}};ao.geo.area=function(n){return Sa=0,ao.geo.stream(n,Na),Sa};var Sa,ka=new ft,Na={sphere:function(){Sa+=4*Fo},point:b,lineStart:b,lineEnd:b,polygonStart:function(){ka.reset(),Na.lineStart=vt},polygonEnd:function(){var n=2*ka;Sa+=0>n?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var f,s,h,p,g,v,d,y,m,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=i,b.lineStart=u,b.lineEnd=o,m=0,Na.polygonStart()},polygonEnd:function(){Na.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>ka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t<f.length-h;++t)p.push(n[a[f[t]][2]]);return p}var e=Ce,r=ze;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ao.geom.polygon=function(n){return ko(n,rl),n};var rl=ao.geom.polygon.prototype=[];rl.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],i=0;++t<e;)n=r,r=this[t],i+=n[1]*r[0]-n[0]*r[1];return.5*i},rl.centroid=function(n){var t,e,r=-1,i=this.length,u=0,o=0,a=this[i-1];for(arguments.length||(n=-1/(6*this.area()));++r<i;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],u+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[u*n,o*n]},rl.clip=function(n){for(var t,e,r,i,u,o,a=De(n),l=-1,c=this.length-De(this),f=this[c-1];++l<c;){for(t=n.slice(),n.length=0,i=this[l],u=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Te(o,f,i)?(Te(u,f,i)||n.push(Re(u,o,f,i)),n.push(o)):Te(u,f,i)&&n.push(Re(u,o,f,i)),u=o;a&&n.push(n[0]),f=i}return n};var il,ul,ol,al,ll,cl=[],fl=[];Ye.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Ve),t.length},tr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},er.prototype={insert:function(n,t){var e,r,i;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=or(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.R&&(ir(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ur(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.L&&(ur(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ir(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,i=n.U,u=n.L,o=n.R;if(e=u?o?or(o):u:o,i?i.L===n?i.L=e:i.R=e:this._=e,u&&o?(r=e.C,e.C=n.C,e.L=u,u.U=e,e!==o?(i=e.U,e.U=n.U,n=e.R,i.L=n,e.R=o,o.U=e):(e.U=i,i=e,n=e.R)):(r=n.C,n=e),n&&(n.U=i),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===i.L){if(t=i.R,t.C&&(t.C=!1,i.C=!0,ir(this,i),t=i.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ur(this,t),t=i.R),t.C=i.C,i.C=t.R.C=!1,ir(this,i),n=this._;break}}else if(t=i.L,t.C&&(t.C=!1,i.C=!0,ur(this,i),t=i.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,ir(this,t),t=i.L),t.C=i.C,i.C=t.L.C=!1,ur(this,i),n=this._;break}t.C=!0,n=i,i=i.U}while(!n.C);n&&(n.C=!1)}}},ao.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],i=a[0][1],u=a[1][0],o=a[1][1];return ar(e(n),a).cells.forEach(function(e,a){var l=e.edges,c=e.site,f=t[a]=l.length?l.map(function(n){var t=n.start();return[t.x,t.y]}):c.x>=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l<c;)i=f,u=s,f=a[l].edge,s=f.l===o?f.r:f.l,r<u.i&&r<s.i&&cr(o,u,s)<0&&t.push([n[r],n[u.i],n[s.i]])}),t},t.x=function(n){return arguments.length?(u=En(r=n),t):r},t.y=function(n){return arguments.length?(o=En(i=n),t):i},t.clipExtent=function(n){return arguments.length?(a=null==n?sl:n,t):a===sl?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===sl?null:a&&a[1]},t)};var sl=[[-1e6,-1e6],[1e6,1e6]];ao.geom.delaunay=function(n){return ao.geom.voronoi().triangles(n)},ao.geom.quadtree=function(n,t,e,r,i){function u(n){function u(n,t,e,r,i,u,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var l=n.x,f=n.y;if(null!=l)if(xo(l-e)+xo(f-r)<.01)c(n,t,e,r,i,u,o,a);else{var s=n.point;n.x=n.y=n.point=null,c(n,s,l,f,i,u,o,a),c(n,t,e,r,i,u,o,a)}else n.x=e,n.y=r,n.point=t}else c(n,t,e,r,i,u,o,a)}function c(n,t,e,r,i,o,a,l){var c=.5*(i+a),f=.5*(o+l),s=e>=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.x<v&&(v=f.x),f.y<d&&(d=f.y),f.x>y&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p<g;)u(k,n[p],s[p],h[p],v,d,y,m);--p}else n.forEach(k.add);return s=h=n=f=null,k}var o,a=Ce,l=ze;return(o=arguments.length)?(a=fr,l=sr,3===o&&(i=e,r=t,e=t=0),u(n)):(u.x=function(n){return arguments.length?(a=n,u):a},u.y=function(n){return arguments.length?(l=n,u):l},u.extent=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],i=+n[1][1]),u):null==t?null:[[t,e],[r,i]]},u.size=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=e=0,r=+n[0],i=+n[1]),u):null==t?null:[r-t,i-e]},u)},ao.interpolateRgb=vr,ao.interpolateObject=dr,ao.interpolateNumber=yr,ao.interpolateString=mr;var hl=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,pl=new RegExp(hl.source,"g");ao.interpolate=Mr,ao.interpolators=[function(n,t){var e=typeof t;return("string"===e?ua.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?vr:mr:t instanceof an?vr:Array.isArray(t)?xr:"object"===e&&isNaN(t)?dr:yr)(n,t)}],ao.interpolateArray=xr;var gl=function(){return m},vl=ao.map({linear:gl,poly:Er,quad:function(){return Sr},cubic:function(){return kr},sin:function(){return Ar},exp:function(){return Cr},circle:function(){return zr},elastic:Lr,back:qr,bounce:function(){return Tr}}),dl=ao.map({"in":m,out:_r,"in-out":wr,"out-in":function(n){return wr(_r(n))}});ao.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Jr(n[e]));return t}},ao.layout.chord=function(){function n(){var n,c,s,h,p,g={},v=[],d=ao.range(u),y=[];for(e=[],r=[],n=0,h=-1;++h<u;){for(c=0,p=-1;++p<u;)c+=i[h][p];v.push(c),y.push(ao.range(u)),n+=c}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&y.forEach(function(n,t){n.sort(function(n,e){return a(i[t][n],i[t][e])})}),n=(Ho-f*u)/n,c=0,h=-1;++h<u;){for(s=c,p=-1;++p<u;){var m=d[h],M=y[m][p],x=i[m][M],b=c,_=c+=x*n;g[m+"-"+M]={index:m,subindex:M,startAngle:b,endAngle:_,value:x}}r[m]={index:m,startAngle:s,endAngle:c,value:v[m]},c+=f}for(h=-1;++h<u;)for(p=h-1;++p<u;){var w=g[h+"-"+p],S=g[p+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}l&&t()}function t(){e.sort(function(n,t){return l((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,i,u,o,a,l,c={},f=0;return c.matrix=function(n){return arguments.length?(u=(i=n)&&i.length,e=r=null,c):i},c.padding=function(n){return arguments.length?(f=n,e=r=null,c):f},c.sortGroups=function(n){return arguments.length?(o=n,e=r=null,c):o},c.sortSubgroups=function(n){return arguments.length?(a=n,e=null,c):a},c.sortChords=function(n){return arguments.length?(l=n,e&&t(),c):l},c.chords=function(){return e||n(),e},c.groups=function(){return r||n(),r},c},ao.layout.force=function(){function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,o=t.cy-n.y,a=i-e,l=u*u+o*o;if(l>a*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++l<f;)if(!isNaN(o=a[l][n]))return o;return Math.random()*r}var t,e,r,i=M.length,c=x.length,s=f[0],v=f[1];for(t=0;i>t;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++c<o;)n(a=u[c],e,l=a.value*r,i),e+=l}}function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u<i;)r=Math.max(r,t(e[u]));return 1+r}function e(e,u){var o=r.call(this,e,u);return n(o[0],0,i[0],i[1]/t(o[0])),o}var r=ao.layout.hierarchy(),i=[1,1];return e.size=function(n){return arguments.length?(i=n,e):i},ii(e,r)},ao.layout.pie=function(){function n(o){var a,l=o.length,c=o.map(function(e,r){return+t.call(n,e,r)}),f=+("function"==typeof r?r.apply(this,arguments):r),s=("function"==typeof i?i.apply(this,arguments):i)-f,h=Math.min(Math.abs(s)/l,+("function"==typeof u?u.apply(this,arguments):u)),p=h*(0>s?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u<p;)o=l[u]=[],o.dx=s[u+1]-(o.x=s[u]),o.y=0;if(p>0)for(u=-1;++u<h;)a=c[u],a>=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.x<p.x&&(p=n),n.x>g.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0;
if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++u<o;)i=n[u],i.x=a,i.y=c,i.dy=f,a+=i.dx=Math.min(e.x+e.dx-a,f?l(i.area/f):0);i.z=!0,i.dx+=e.x+e.dx-a,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);++u<o;)i=n[u],i.x=a,i.y=c,i.dx=f,c+=i.dy=Math.min(e.y+e.dy-c,f?l(i.area/f):0);i.z=!1,i.dy+=e.y+e.dy-c,e.x+=f,e.dx-=f}}function u(r){var i=o||a(r),u=i[0];return u.x=u.y=0,u.value?(u.dx=c[0],u.dy=c[1]):u.dx=u.dy=0,o&&a.revalue(u),n([u],u.dx*u.dy/u.value),(o?e:t)(u),h&&(o=i),i}var o,a=ao.layout.hierarchy(),l=Math.round,c=[1,1],f=null,s=Oi,h=!1,p="squarify",g=.5*(1+Math.sqrt(5));return u.size=function(n){return arguments.length?(c=n,u):c},u.padding=function(n){function t(t){var e=n.call(u,t,t.depth);return null==e?Oi(t):Ii(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Ii(t,n)}if(!arguments.length)return f;var r;return s=null==(f=n)?Oi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,u},u.round=function(n){return arguments.length?(l=n?Math.round:Number,u):l!=Number},u.sticky=function(n){return arguments.length?(h=n,o=null,u):h},u.ratio=function(n){return arguments.length?(g=n,u):g},u.mode=function(n){return arguments.length?(p=n+"",u):p},ii(u,a)},ao.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++a<l;){u.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(e=c[f])&&Qu(e,f,i,r,o),t.push(e)}return Wu(u,i,r)},Co.interrupt=function(n){return this.each(null==n?Il:Bu(Ku(n)))};var Hl,Ol,Il=Bu(Ku()),Yl=[],Zl=0;Yl.call=Co.call,Yl.empty=Co.empty,Yl.node=Co.node,Yl.size=Co.size,ao.transition=function(n,t){return n&&n.transition?Hl?n.transition(t):n:ao.selection().transition(n)},ao.transition.prototype=Yl,Yl.select=function(n){var t,e,r,i=this.id,u=this.namespace,o=[];n=A(n);for(var a=-1,l=this.length;++a<l;){o.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(r=c[f])&&(e=n.call(r,r.__data__,f,a))?("__data__"in r&&(e.__data__=r.__data__),Qu(e,f,u,i,r[u][i]),t.push(e)):t.push(null)}return Wu(o,u,i)},Yl.selectAll=function(n){var t,e,r,i,u,o=this.id,a=this.namespace,l=[];n=C(n);for(var c=-1,f=this.length;++c<f;)for(var s=this[c],h=-1,p=s.length;++h<p;)if(r=s[h]){u=r[a][o],e=n.call(r,r.__data__,h,c),l.push(t=[]);for(var g=-1,v=e.length;++g<v;)(i=e[g])&&Qu(i,g,a,o,u),t.push(i)}return Wu(l,a,o)},Yl.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]<M[0])],L[1]=h[+(n[1]<M[1])]):M=null),E&&y(n,c,0)&&(r(k),t=!0),A&&y(n,f,1)&&(i(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function y(n,t,e){var r,i,u=Zi(t),l=u[0],c=u[1],f=L[e],v=e?h:s,d=v[1]-v[0];return C&&(l-=f,c-=d+f),r=(e?g:p)?Math.max(l,Math.min(c,n[e])):n[e],C?i=(r+=f)+d:(M&&(f=Math.max(l,Math.min(c,2*M[e]-r))),r>f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}();!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/",t(t.s=20)}([function(e,t,n){"use strict";e.exports=n(21)},function(e,t,n){(function(t){!function(t,n){e.exports=n()}(0,function(){"use strict";function e(e,t){return t={exports:{}},e(t,t.exports),t.exports}var n=function(e){var t=e.id,n=e.viewBox,r=e.content;this.id=t,this.viewBox=n,this.content=r};n.prototype.stringify=function(){return this.content},n.prototype.toString=function(){return this.stringify()},n.prototype.destroy=function(){var e=this;["id","viewBox","content"].forEach(function(t){return delete e[t]})};var r=function(e){var t=!!document.importNode,n=(new DOMParser).parseFromString(e,"image/svg+xml").documentElement;return t?document.importNode(n,!0):n},o=("undefined"!=typeof window?window:void 0!==t||"undefined"!=typeof self&&self,e(function(e,t){!function(t,n){e.exports=n()}(0,function(){function e(e){return e&&"object"==typeof e&&"[object RegExp]"!==Object.prototype.toString.call(e)&&"[object Date]"!==Object.prototype.toString.call(e)}function t(e){return Array.isArray(e)?[]:{}}function n(n,r){return r&&!0===r.clone&&e(n)?a(t(n),n,r):n}function r(t,r,o){var i=t.slice();return r.forEach(function(r,l){void 0===i[l]?i[l]=n(r,o):e(r)?i[l]=a(t[l],r,o):-1===t.indexOf(r)&&i.push(n(r,o))}),i}function o(t,r,o){var i={};return e(t)&&Object.keys(t).forEach(function(e){i[e]=n(t[e],o)}),Object.keys(r).forEach(function(l){e(r[l])&&t[l]?i[l]=a(t[l],r[l],o):i[l]=n(r[l],o)}),i}function a(e,t,a){var i=Array.isArray(t),l=a||{arrayMerge:r},u=l.arrayMerge||r;return i?Array.isArray(e)?u(e,t,a):n(t,a):o(e,t,a)}return a.all=function(e,t){if(!Array.isArray(e)||e.length<2)throw new Error("first argument should be an array with at least two elements");return e.reduce(function(e,n){return a(e,n,t)})},a})})),a=e(function(e,t){var n={svg:{name:"xmlns",uri:"http://www.w3.org/2000/svg"},xlink:{name:"xmlns:xlink",uri:"http://www.w3.org/1999/xlink"}};t.default=n,e.exports=t.default}),i=function(e){return Object.keys(e).map(function(t){return t+'="'+e[t].toString().replace(/"/g,"&quot;")+'"'}).join(" ")},l=a.svg,u=a.xlink,s={};s[l.name]=l.uri,s[u.name]=u.uri;var c=function(e,t){void 0===e&&(e="");var n=o(s,t||{});return"<svg "+i(n)+">"+e+"</svg>"};return function(e){function t(){e.apply(this,arguments)}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var n={isMounted:{}};return n.isMounted.get=function(){return!!this.node},t.createFromExistingNode=function(e){return new t({id:e.getAttribute("id"),viewBox:e.getAttribute("viewBox"),content:e.outerHTML})},t.prototype.destroy=function(){this.isMounted&&this.unmount(),e.prototype.destroy.call(this)},t.prototype.mount=function(e){if(this.isMounted)return this.node;var t="string"==typeof e?document.querySelector(e):e,n=this.render();return this.node=n,t.appendChild(n),n},t.prototype.render=function(){var e=this.stringify();return r(c(e)).childNodes[0]},t.prototype.unmount=function(){this.node.parentNode.removeChild(this.node)},Object.defineProperties(t.prototype,n),t}(n)})}).call(t,n(19))},function(e,t,n){(function(t){!function(t,n){e.exports=n()}(0,function(){"use strict";function e(e,t){return t={exports:{}},e(t,t.exports),t.exports}function n(e){return e=e||Object.create(null),{on:function(t,n){(e[t]||(e[t]=[])).push(n)},off:function(t,n){e[t]&&e[t].splice(e[t].indexOf(n)>>>0,1)},emit:function(t,n){(e[t]||[]).map(function(e){e(n)}),(e["*"]||[]).map(function(e){e(t,n)})}}}function r(e,t){return w(e).reduce(function(e,n){if(!n.attributes)return e;var r=w(n.attributes),o=t?r.filter(t):r;return e.concat(o)},[])}function o(e){return e.replace(I,function(e){return"%"+e[0].charCodeAt(0).toString(16).toUpperCase()})}function a(e,t,n){return w(e).forEach(function(e){var r=e.getAttribute(L);if(r&&0===r.indexOf(t)){var o=r.replace(t,n);e.setAttributeNS(P,L,o)}}),e}var i=("undefined"!=typeof window?window:void 0!==t||"undefined"!=typeof self&&self,e(function(e,t){!function(t,n){e.exports=n()}(0,function(){function e(e){return e&&"object"==typeof e&&"[object RegExp]"!==Object.prototype.toString.call(e)&&"[object Date]"!==Object.prototype.toString.call(e)}function t(e){return Array.isArray(e)?[]:{}}function n(n,r){return r&&!0===r.clone&&e(n)?a(t(n),n,r):n}function r(t,r,o){var i=t.slice();return r.forEach(function(r,l){void 0===i[l]?i[l]=n(r,o):e(r)?i[l]=a(t[l],r,o):-1===t.indexOf(r)&&i.push(n(r,o))}),i}function o(t,r,o){var i={};return e(t)&&Object.keys(t).forEach(function(e){i[e]=n(t[e],o)}),Object.keys(r).forEach(function(l){e(r[l])&&t[l]?i[l]=a(t[l],r[l],o):i[l]=n(r[l],o)}),i}function a(e,t,a){var i=Array.isArray(t),l=a||{arrayMerge:r},u=l.arrayMerge||r;return i?Array.isArray(e)?u(e,t,a):n(t,a):o(e,t,a)}return a.all=function(e,t){if(!Array.isArray(e)||e.length<2)throw new Error("first argument should be an array with at least two elements");return e.reduce(function(e,n){return a(e,n,t)})},a})})),l=e(function(e,t){var n={svg:{name:"xmlns",uri:"http://www.w3.org/2000/svg"},xlink:{name:"xmlns:xlink",uri:"http://www.w3.org/1999/xlink"}};t.default=n,e.exports=t.default}),u=function(e){return Object.keys(e).map(function(t){return t+'="'+e[t].toString().replace(/"/g,"&quot;")+'"'}).join(" ")},s=l.svg,c=l.xlink,d={};d[s.name]=s.uri,d[c.name]=c.uri;var f,p=function(e,t){void 0===e&&(e="");var n=i(d,t||{});return"<svg "+u(n)+">"+e+"</svg>"},h=l.svg,m=l.xlink,g={attrs:(f={style:["position: absolute","width: 0","height: 0"].join("; ")},f[h.name]=h.uri,f[m.name]=m.uri,f)},v=function(e){this.config=i(g,e||{}),this.symbols=[]};v.prototype.add=function(e){var t=this,n=t.symbols,r=this.find(e.id);return r?(n[n.indexOf(r)]=e,!1):(n.push(e),!0)},v.prototype.remove=function(e){var t=this,n=t.symbols,r=this.find(e);return!!r&&(n.splice(n.indexOf(r),1),r.destroy(),!0)},v.prototype.find=function(e){return this.symbols.filter(function(t){return t.id===e})[0]||null},v.prototype.has=function(e){return null!==this.find(e)},v.prototype.stringify=function(){var e=this.config,t=e.attrs,n=this.symbols.map(function(e){return e.stringify()}).join("");return p(n,t)},v.prototype.toString=function(){return this.stringify()},v.prototype.destroy=function(){this.symbols.forEach(function(e){return e.destroy()})};var y=function(e){var t=e.id,n=e.viewBox,r=e.content;this.id=t,this.viewBox=n,this.content=r};y.prototype.stringify=function(){return this.content},y.prototype.toString=function(){return this.stringify()},y.prototype.destroy=function(){var e=this;["id","viewBox","content"].forEach(function(t){return delete e[t]})};var b,x=function(e){var t=!!document.importNode,n=(new DOMParser).parseFromString(e,"image/svg+xml").documentElement;return t?document.importNode(n,!0):n},_=function(e){function t(){e.apply(this,arguments)}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var n={isMounted:{}};return n.isMounted.get=function(){return!!this.node},t.createFromExistingNode=function(e){return new t({id:e.getAttribute("id"),viewBox:e.getAttribute("viewBox"),content:e.outerHTML})},t.prototype.destroy=function(){this.isMounted&&this.unmount(),e.prototype.destroy.call(this)},t.prototype.mount=function(e){if(this.isMounted)return this.node;var t="string"==typeof e?document.querySelector(e):e,n=this.render();return this.node=n,t.appendChild(n),n},t.prototype.render=function(){var e=this.stringify();return x(p(e)).childNodes[0]},t.prototype.unmount=function(){this.node.parentNode.removeChild(this.node)},Object.defineProperties(t.prototype,n),t}(y),k={autoConfigure:!0,mountTo:"body",syncUrlsWithBaseTag:!1,listenLocationChangeEvent:!0,locationChangeEvent:"locationChange",locationChangeAngularEmitter:!1,usagesToUpdate:"use[*|href]",moveGradientsOutsideSymbol:!1},w=function(e){return Array.prototype.slice.call(e,0)},C=navigator.userAgent,E={isChrome:/chrome/i.test(C),isFirefox:/firefox/i.test(C),isIE:/msie/i.test(C)||/trident/i.test(C),isEdge:/edge/i.test(C)},T=function(e,t){var n=document.createEvent("CustomEvent");n.initCustomEvent(e,!1,!1,t),window.dispatchEvent(n)},O=function(e){var t=[];return w(e.querySelectorAll("style")).forEach(function(e){e.textContent+="",t.push(e)}),t},M=function(e){return(e||window.location.href).split("#")[0]},S=function(e){angular.module("ng").run(["$rootScope",function(t){t.$on("$locationChangeSuccess",function(t,n,r){T(e,{oldUrl:r,newUrl:n})})}])},N=function(e,t){return void 0===t&&(t="linearGradient, radialGradient, pattern"),w(e.querySelectorAll("symbol")).forEach(function(e){w(e.querySelectorAll(t)).forEach(function(t){e.parentNode.insertBefore(t,e)})}),e},P=l.xlink.uri,L="xlink:href",I=/[{}|\\\^\[\]`"<>]/g,R=["clipPath","colorProfile","src","cursor","fill","filter","marker","markerStart","markerMid","markerEnd","mask","stroke","style"],A=R.map(function(e){return"["+e+"]"}).join(","),D=function(e,t,n,i){var l=o(n),u=o(i);r(e.querySelectorAll(A),function(e){var t=e.localName,n=e.value;return-1!==R.indexOf(t)&&-1!==n.indexOf("url("+l)}).forEach(function(e){return e.value=e.value.replace(l,u)}),a(t,l,u)},j={MOUNT:"mount",SYMBOL_MOUNT:"symbol_mount"},U=function(e){function t(t){var r=this;void 0===t&&(t={}),e.call(this,i(k,t));var o=n();this._emitter=o,this.node=null;var a=this,l=a.config;if(l.autoConfigure&&this._autoConfigure(t),l.syncUrlsWithBaseTag){var u=document.getElementsByTagName("base")[0].getAttribute("href");o.on(j.MOUNT,function(){return r.updateUrls("#",u)})}var s=this._handleLocationChange.bind(this);this._handleLocationChange=s,l.listenLocationChangeEvent&&window.addEventListener(l.locationChangeEvent,s),l.locationChangeAngularEmitter&&S(l.locationChangeEvent),o.on(j.MOUNT,function(e){l.moveGradientsOutsideSymbol&&N(e)}),o.on(j.SYMBOL_MOUNT,function(e){l.moveGradientsOutsideSymbol&&N(e.parentNode),(E.isIE||E.isEdge)&&O(e)})}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var r={isMounted:{}};return r.isMounted.get=function(){return!!this.node},t.prototype._autoConfigure=function(e){var t=this,n=t.config;void 0===e.syncUrlsWithBaseTag&&(n.syncUrlsWithBaseTag=void 0!==document.getElementsByTagName("base")[0]),void 0===e.locationChangeAngularEmitter&&(n.locationChangeAngularEmitter="angular"in window),void 0===e.moveGradientsOutsideSymbol&&(n.moveGradientsOutsideSymbol=E.isFirefox)},t.prototype._handleLocationChange=function(e){var t=e.detail,n=t.oldUrl,r=t.newUrl;this.updateUrls(n,r)},t.prototype.add=function(t){var n=this,r=e.prototype.add.call(this,t);return this.isMounted&&r&&(t.mount(n.node),this._emitter.emit(j.SYMBOL_MOUNT,t.node)),r},t.prototype.attach=function(e){var t=this,n=this;if(n.isMounted)return n.node;var r="string"==typeof e?document.querySelector(e):e;return n.node=r,this.symbols.forEach(function(e){e.mount(n.node),t._emitter.emit(j.SYMBOL_MOUNT,e.node)}),w(r.querySelectorAll("symbol")).forEach(function(e){var t=_.createFromExistingNode(e);t.node=e,n.add(t)}),this._emitter.emit(j.MOUNT,r),r},t.prototype.destroy=function(){var e=this,t=e.config,n=e.symbols,r=e._emitter;n.forEach(function(e){return e.destroy()}),r.off("*"),window.removeEventListener(t.locationChangeEvent,this._handleLocationChange),this.isMounted&&this.unmount()},t.prototype.mount=function(e,t){void 0===e&&(e=this.config.mountTo),void 0===t&&(t=!1);var n=this;if(n.isMounted)return n.node;var r="string"==typeof e?document.querySelector(e):e,o=n.render();return this.node=o,t&&r.childNodes[0]?r.insertBefore(o,r.childNodes[0]):r.appendChild(o),this._emitter.emit(j.MOUNT,o),o},t.prototype.render=function(){return x(this.stringify())},t.prototype.unmount=function(){this.node.parentNode.removeChild(this.node)},t.prototype.updateUrls=function(e,t){if(!this.isMounted)return!1;var n=document.querySelectorAll(this.config.usagesToUpdate);return D(this.node,n,M(e)+"#",M(t)+"#"),!0},Object.defineProperties(t.prototype,r),t}(v),F=e(function(e){/*!
  * domready (c) Dustin Diaz 2014 - License MIT
  */
!function(t,n){e.exports=function(){var e,t=[],n=document,r=n.documentElement.doScroll,o=(r?/^loaded|^c/:/^loaded|^i|^c/).test(n.readyState);return o||n.addEventListener("DOMContentLoaded",e=function(){for(n.removeEventListener("DOMContentLoaded",e),o=1;e=t.shift();)e()}),function(e){o?setTimeout(e,0):t.push(e)}}()}()}),H=!!window.__SVG_SPRITE__;H?b=window.__SVG_SPRITE__:(b=new U({attrs:{id:"__SVG_SPRITE_NODE__"}}),window.__SVG_SPRITE__=b);var K=function(){var e=document.getElementById("__SVG_SPRITE_NODE__");e?b.attach(e):b.mount(document.body,!0)};return document.body?K():F(K),b})}).call(t,n(19))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=t.flattenDeep=function e(t){return t.reduce(function(t,n){return t.concat(Array.isArray(n)?e(n):n)},[])};t.css=function(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];return o(t).filter(Boolean).join(" ")},t.equal=function e(t,n){if(t===n)return!0;var o=Array.isArray(t),a=Array.isArray(n),i=void 0;if(o&&a){if(t.length!==n.length)return!1;for(i=0;i<t.length;i++)if(!e(t[i],n[i]))return!1;return!0}if(o!=a)return!1;if(t&&n&&"object"===(void 0===t?"undefined":r(t))&&"object"===(void 0===n?"undefined":r(n))){var l=Object.keys(t);if(l.length!==Object.keys(n).length)return!1;var u=t instanceof Date,s=n instanceof Date;if(u&&s)return t.getTime()==n.getTime();if(u!=s)return!1;var c=t instanceof RegExp,d=n instanceof RegExp;if(c&&d)return t.toString()==n.toString();if(c!=d)return!1;for(i=0;i<l.length;i++)if(!Object.prototype.hasOwnProperty.call(n,l[i]))return!1;for(i=0;i<l.length;i++)if(!e(t[l[i]],n[l[i]]))return!1;return!0}return!1},t.humanize=function(e){var t=navigator.language||navigator.userLanguage||"en",n=new Date,o=new Date(e),a=n.getTime(),i=o.getTime();if(isNaN(i))return"Invalid Date";if(i>a)return"From the Future";if("object"!==("undefined"==typeof Intl?"undefined":r(Intl))||"function"!=typeof Intl.DateTimeFormat)return o.getHours()+":"+o.getMinutes()+" "+o.toLocaleDateString();if(i>a-1728e5){var l=new Date(Date.now()-864e5),u=o.getMonth()+"-"+o.getDate(),s=n.getMonth()+"-"+n.getDate(),c=l.getMonth()+"-"+l.getDate(),d=new Intl.DateTimeFormat(t,{minute:"numeric",hour:"numeric"}).format(o);if(u===s)return d+" Today";if(u===c)return d+" Yesterday"}return new Intl.DateTimeFormat(t,{minute:"numeric",hour:"numeric",day:"numeric",month:"short",year:o.getFullYear()===n.getFullYear()?void 0:"numeric"}).format(o)},t.rect=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.x,r=void 0===n?0:n,o=t.y,a=void 0===o?0:o,i=e.getClientRects();if(!i.length)return{x:0,y:0,width:0,height:0};var l=Array.from(i).reduce(function(e,t){return e.left=Math.min(e.left,t.left),e.top=Math.min(e.top,t.top),e.bottom=Math.max(e.bottom,t.bottom),e.right=Math.max(e.right,t.right),e},{left:1/0,top:1/0,bottom:-1/0,right:-1/0});return{x:window.scrollX+l.left+r,y:window.scrollY+l.top+a,width:Math.abs(l.right-l.left),height:Math.abs(l.bottom-l.top)}}},function(e,t){function n(e,t){var n=e[1]||"",o=e[3];if(!o)return n;if(t&&"function"==typeof btoa){var a=r(o);return[n].concat(o.sources.map(function(e){return"/*# sourceURL="+o.sourceRoot+e+" */"})).concat([a]).join("\n")}return[n].join("\n")}function r(e){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e))))+" */"}e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var r=n(t,e);return t[2]?"@media "+t[2]+"{"+r+"}":r}).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},o=0;o<this.length;o++){var a=this[o][0];"number"==typeof a&&(r[a]=!0)}for(o=0;o<e.length;o++){var i=e[o];"number"==typeof i[0]&&r[i[0]]||(n&&!i[2]?i[2]=n:n&&(i[2]="("+i[2]+") and ("+n+")"),t.push(i))}},t}},function(e,t,n){function r(e,t){for(var n=0;n<e.length;n++){var r=e[n],o=h[r.id];if(o){o.refs++;for(var a=0;a<o.parts.length;a++)o.parts[a](r.parts[a]);for(;a<r.parts.length;a++)o.parts.push(c(r.parts[a],t))}else{for(var i=[],a=0;a<r.parts.length;a++)i.push(c(r.parts[a],t));h[r.id]={id:r.id,refs:1,parts:i}}}}function o(e,t){for(var n=[],r={},o=0;o<e.length;o++){var a=e[o],i=t.base?a[0]+t.base:a[0],l=a[1],u=a[2],s=a[3],c={css:l,media:u,sourceMap:s};r[i]?r[i].parts.push(c):n.push(r[i]={id:i,parts:[c]})}return n}function a(e,t){var n=g(e.insertInto);if(!n)throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");var r=b[b.length-1];if("top"===e.insertAt)r?r.nextSibling?n.insertBefore(t,r.nextSibling):n.appendChild(t):n.insertBefore(t,n.firstChild),b.push(t);else if("bottom"===e.insertAt)n.appendChild(t);else{if("object"!=typeof e.insertAt||!e.insertAt.before)throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");var o=g(e.insertInto+" "+e.insertAt.before);n.insertBefore(t,o)}}function i(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e);var t=b.indexOf(e);t>=0&&b.splice(t,1)}function l(e){var t=document.createElement("style");return e.attrs.type="text/css",s(t,e.attrs),a(e,t),t}function u(e){var t=document.createElement("link");return e.attrs.type="text/css",e.attrs.rel="stylesheet",s(t,e.attrs),a(e,t),t}function s(e,t){Object.keys(t).forEach(function(n){e.setAttribute(n,t[n])})}function c(e,t){var n,r,o,a;if(t.transform&&e.css){if(!(a=t.transform(e.css)))return function(){};e.css=a}if(t.singleton){var s=y++;n=v||(v=l(t)),r=d.bind(null,n,s,!1),o=d.bind(null,n,s,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=u(t),r=p.bind(null,n,t),o=function(){i(n),n.href&&URL.revokeObjectURL(n.href)}):(n=l(t),r=f.bind(null,n),o=function(){i(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else o()}}function d(e,t,n,r){var o=n?"":r.css;if(e.styleSheet)e.styleSheet.cssText=_(t,o);else{var a=document.createTextNode(o),i=e.childNodes;i[t]&&e.removeChild(i[t]),i.length?e.insertBefore(a,i[t]):e.appendChild(a)}}function f(e,t){var n=t.css,r=t.media;if(r&&e.setAttribute("media",r),e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}function p(e,t,n){var r=n.css,o=n.sourceMap,a=void 0===t.convertToAbsoluteUrls&&o;(t.convertToAbsoluteUrls||a)&&(r=x(r)),o&&(r+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var i=new Blob([r],{type:"text/css"}),l=e.href;e.href=URL.createObjectURL(i),l&&URL.revokeObjectURL(l)}var h={},m=function(e){var t;return function(){return void 0===t&&(t=e.apply(this,arguments)),t}}(function(){return window&&document&&document.all&&!window.atob}),g=function(e){var t={};return function(n){if(void 0===t[n]){var r=e.call(this,n);if(r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(e){r=null}t[n]=r}return t[n]}}(function(e){return document.querySelector(e)}),v=null,y=0,b=[],x=n(39);e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");t=t||{},t.attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||(t.singleton=m()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=o(e,t);return r(n,t),function(e){for(var a=[],i=0;i<n.length;i++){var l=n[i],u=h[l.id];u.refs--,a.push(u)}if(e){r(o(e,t),t)}for(var i=0;i<a.length;i++){var u=a[i];if(0===u.refs){for(var s=0;s<u.parts.length;s++)u.parts[s]();delete h[u.id]}}}};var _=function(){var e=[];return function(t,n){return e[t]=n,e.filter(Boolean).join("\n")}}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),o=function(e){return e&&e.__esModule?e:{default:e}}(r),a=function(e){var t=e.svg;return o.default.createElement("svg",{viewBox:t.viewBox},o.default.createElement("use",{xlinkHref:"#"+t.id}))};t.default=a},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.AvatarGroup=void 0;var o=n(0),a=r(o),i=n(3),l=n(36),u=n(37),s=r(u),c=function(e){var t=e.initial,n=(e.title,e.color),r=e.photoUrl,o=e.className,u=e.onMouseOver,c=e.onMouseOut,d=e.onClick;return a.default.createElement("div",{onMouseOver:u,onMouseOut:c,onClick:d,className:(0,i.css)(s.default.avatar,o&&o),"data-initial":t,style:{backgroundColor:n}},r&&a.default.createElement("div",{className:s.default.photo,style:{backgroundImage:"url("+(0,l.platformPhotoUrl)(r)+")"}}))};t.default=c;t.AvatarGroup=function(e){var t=e.className,n=e.children;return a.default.createElement("div",{className:(0,i.css)(s.default.group,t&&t)},a.default.Children.map(n,function(e){return a.default.createElement("div",{className:s.default.wrapper},e)}))}},function(e,t,n){"use strict";function r(e){return function(){return e}}var o=function(){};o.thatReturns=r,o.thatReturnsFalse=r(!1),o.thatReturnsTrue=r(!0),o.thatReturnsNull=r(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},e.exports=o},function(e,t,n){"use strict";function r(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(r)}catch(e){console.error(e)}}r(),e.exports=n(22)},function(e,t,n){var r=n(51);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0};o.transform=void 0;n(5)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=n(0),s=r(u),c=n(9),d=n(3),f=n(47),p=r(f),h=function(e){function t(e){o(this,t);var n=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return n.container=document.createElement("div"),n}return i(t,e),l(t,[{key:"updatePosition",value:function(){if(this.tooltipRef){var e=this.props.rect,t=this.tooltipRef,n=t.clientWidth,r=t.clientHeight,o=window,a=o.innerWidth,i=(o.innerHeight,o.scrollY),l=e.x+e.width/2-n/2,u=Math.min(Math.max(l,4),a-4-n),s=e.y-r-i-10;s>=4?(s+=i,this.arrowRef.classList.remove(p.default.flipped)):(s=e.y+e.height+10,this.arrowRef.classList.add(p.default.flipped)),this.tooltipRef.style.top=Math.round(s)+"px",this.tooltipRef.style.left=Math.round(u)+"px",u!==l&&(this.arrowRef.style.left="calc(50% + "+Math.round(l-u-6)+"px)")}}},{key:"componentDidUpdate",value:function(e){(0,d.equal)(e.rect,this.props.rect)||this.updatePosition()}},{key:"componentDidMount",value:function(){document.body.appendChild(this.container),this.updatePosition()}},{key:"componentWillUnmount",value:function(){document.body.removeChild(this.container)}},{key:"render",value:function(){var e=this,t=this.props,n=t.children,r=t.className;return(0,c.createPortal)(s.default.createElement("div",{ref:function(t){e.tooltipRef=t},className:(0,d.css)(p.default.tooltip,r&&r)},s.default.createElement("div",{ref:function(t){e.arrowRef=t},className:p.default.arrow}),n),this.container)}}]),t}(u.Component);t.default=h},function(e,t,n){"use strict";function r(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
var o=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,l,u=r(e),s=1;s<arguments.length;s++){n=Object(arguments[s]);for(var c in n)a.call(n,c)&&(u[c]=n[c]);if(o){l=o(n);for(var d=0;d<l.length;d++)i.call(n,l[d])&&(u[l[d]]=n[l[d]])}}return u}},function(e,t,n){"use strict";var r={};e.exports=r},function(e,t,n){e.exports=n(32)()},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),c=r(s),d=n(6),f=r(d),p=n(16),h=r(p),m=n(3),g=n(53),v=r(g),y=n(10),b=r(y),x=function(e){function t(e){o(this,t);var n=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return n.handleLayout=n.handleLayout.bind(n),n.handleActivationClick=n.handleActivationClick.bind(n),n.handleBubbleClick=n.handleBubbleClick.bind(n),n.handleResolveClick=n.handleResolveClick.bind(n),n.handleReopenClick=n.handleReopenClick.bind(n),n}return i(t,e),u(t,[{key:"handleActivationClick",value:function(e){var t=this.props,n=t.id;t.active||EN.execCommand("comment",{action:"highlight",threadId:n})}},{key:"handleBubbleClick",value:function(e){this.props.collapsed||this.props.compact||(e.preventDefault(),e.stopPropagation(),EN.execCommand("comment",{action:"collapse"}))}},{key:"handleResolveClick",value:function(e){e.stopPropagation(),EN.execCommand("comment",{action:"resolve",threadId:this.props.id})}},{key:"handleReopenClick",value:function(e){e.stopPropagation(),EN.execCommand("comment",{action:"reopen",threadId:this.props.id})}},{key:"handleLayout",value:function(){this.elementRef&&this.props.floating&&this.props.updateHeight({height:this.elementRef.clientHeight,id:this.props.id})}},{key:"componentDidMount",value:function(){this.handleLayout()}},{key:"componentDidUpdate",value:function(e){e.active===this.props.active&&e.collapsed===this.props.collapsed&&e.compact===this.props.compact&&e.comments===this.props.comments&&e.readonly===this.props.readonly||this.handleLayout()}},{key:"render",value:function(){var e=this,t=this.props,n=t.comments,r=t.top,o=t.id,a=t.active,i=t.collapsed,u=t.compact,s=t.user,d=t.readonly,p=t.floating,g=t.archive,y=(0,m.css)(b.default.thread,a&&!g&&b.default.active,i&&b.default.collapsed,u&&b.default.compact,p&&b.default.floating),x=g?null:{top:r},_=null,k=null,w=null,C=!1;return i||u||(k=n.map(function(t){return t.editing&&(C=!0),c.default.createElement(h.default,l({},t,{editable:!g&&t.editable,key:t.id,threadId:o,onLayout:e.handleLayout}))}),w=s&&!C&&!d&&a&&!g&&c.default.createElement(h.default,{initial:s.initial,name:s.name,color:s.color,threadId:o,onLayout:this.handleLayout,initiater:0===n.length,creating:!0})),g?_=c.default.createElement("div",{className:b.default.toolbar},n[0].selectedText&&c.default.createElement("div",{className:b.default.highlight},c.default.createElement("span",null,n[0].selectedText)),n[0].resolved&&null!=r&&c.default.createElement("button",{className:b.default.reopen,onClick:this.handleReopenClick},"Unresolve")):n.length>0&&(_=c.default.createElement("div",{className:b.default.toolbar},!i&&!u&&a&&c.default.createElement("button",{className:b.default.resolve,onClick:this.handleResolveClick},"Resolve"),c.default.createElement("button",{className:b.default.bubble,"data-count":n.length,onClick:this.handleBubbleClick},c.default.createElement(f.default,{svg:v.default})))),c.default.createElement("div",{className:y,style:x,ref:function(t){e.elementRef=t},onClick:this.handleActivationClick},_,k,w)}}]),t}(s.PureComponent);t.default=x,x.defaultProps={collapsed:!1,compact:!1,active:!1,readonly:!1,floating:!1,archive:!1,user:null,comments:[]}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function l(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),c=r(s),d=n(6),f=r(d),p=n(7),h=r(p),m=n(40),g=r(m),v=n(3),y=n(52),b=r(y),x=n(10),_=r(x),k=function(e){function t(e){a(this,t);var n=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return n.handleOptClick=n.handleOptClick.bind(n),n}return l(t,e),u(t,[{key:"handleOptClick",value:function(e){var t=e.target,n=t.getBoundingClientRect();e.stopPropagation(),EN.execCommand("comment",{action:"menu",threadId:this.props.threadId,id:this.props.id,x:n.left+n.width,y:n.top+n.height})}},{key:"render",value:function(){var e=this.props,t=e.name,n=e.initial,r=e.photoUrl,a=e.updated,i=e.editable,l=e.color,u=o(e,["name","initial","photoUrl","updated","editable","color"]),s=u.editing,d=u.creating,p=(0,v.css)(_.default.comment,s&&_.default.edit,d&&_.default.new);return c.default.createElement("div",{className:p},c.default.createElement(h.default,{className:_.default.avatar,initial:n,color:l,photoUrl:r}),!s&&!d&&c.default.createElement("div",{key:"header",className:_.default.header},c.default.createElement("div",{className:_.default.name},t),c.default.createElement("div",{className:_.default.time},(0,v.humanize)(a)),i&&c.default.createElement("button",{className:_.default.options,onClick:this.handleOptClick},c.default.createElement(f.default,{svg:b.default}))),c.default.createElement(g.default,u))}}]),t}(s.PureComponent);t.default=k},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.TokenKind=void 0;var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=n(42),i=function(e){return e&&e.__esModule?e:{default:e}}(a),l="<SOF>",u=(t.TokenKind={SOF:l,EOF:"<EOF>",MARK_CODE:"`",MARK_CODEBLOCK:"Codeblock",MARK_STRIKE_THROUGH:"~",MARK_BOLD:"*",MARK_ITALIC:"_",MARK_MENTION:"Mention",TEXT:"Text",NEW_LINE:"\n"},function(){function e(t){r(this,e),this.source=t,this.lastToken=new i.default(l,0,0),this.token=this.lastToken}return o(e,[{key:"advance",value:function(){var e=this.lastToken=this.token;return"<EOF>"!==e.kind&&(e=e.next=s(this,e),this.token=e),e}}]),e}());t.default=u;var s=function(e,t){if(t.next)return t.next.prev=t,t.next;var n=e.source,r=n.length,o=!1,a=null,l=t.end;if(l>=r)return new i.default("<EOF>",r,r,null,t);for(;l<r;){var u=n.charCodeAt(l);switch(u){case 160:if(64===n.charCodeAt(l+1)){a=c(n,l,!0);break}case 64:a=c(n,l);break;case 42:case 95:case 96:case 126:a=d(n,l,u);break;case 10:a=new i.default("\n",l,l+1,{text:"\n"})}if(a)break;l+=1,o=!0}if(o){var s={text:n.slice(t.end,l)};return new i.default("Text",t.end,l,s,t,a)}return a.prev=t,a},c=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!n&&t>0&&!f(e.charCodeAt(t-1)))return null;for(var r=t+1;r<e.length;){var o=e.charCodeAt(r);if(n&&160===o){r+=1;break}if(p(o)){n&&(r=-1);break}r+=1}if(-1===r)return null;var a={user:null,decorated:n,text:n?e.slice(t+2,r-1):e.slice(t+1,r)};return new i.default("Mention",t,r,a)},d=function(e,t,n){var r=96===n&&96===e.charCodeAt(t+1)&&96===e.charCodeAt(t+2)?3:1,o=0===t,a=t>=e.length-r;if(o||(o=h(e.charCodeAt(t-1))),a||(a=m(e.charCodeAt(t+r))),!o&&!a)return null;var l=r>1?"```":e.charAt(t),u=r>1?"Codeblock":l,s={ahead:o,behind:a,text:l};return new i.default(u,t,t+r,s)},f=function(e){switch(e){case 9:case 10:case 32:case 42:case 40:case 47:case 91:case 95:case 123:return!0}return!1},p=function(e){switch(e){case 9:case 10:case 32:case 33:case 34:case 39:case 41:case 42:case 44:case 46:case 47:case 58:case 59:case 93:case 96:case 125:case 126:return!0}return!1},h=function(e){switch(e){case 9:case 10:case 32:case 33:case 34:case 35:case 36:case 37:case 39:case 40:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 61:case 63:case 91:case 94:case 95:case 96:case 123:case 126:return!0}return!1},m=function(e){switch(e){case 9:case 10:case 32:case 33:case 34:case 35:case 36:case 37:case 39:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 93:case 94:case 95:case 96:case 125:case 126:return!0}return!1}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a=n(0),i=r(a),l=n(7),u=r(l),s=n(11),c=r(s),d=n(49),f=r(d),p=function(e){var t=e.user,n=e.rect;return i.default.createElement(c.default,{rect:n,className:f.default.tooltip},i.default.createElement(u.default,o({className:f.default.avatar},t)),i.default.createElement("span",{className:f.default.title},t.name,t.title&&i.default.createElement("span",{className:f.default.dim},"• "+t.title)),t.email&&i.default.createElement("span",{className:f.default.subtitle},t.email))};t.default=p},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a=n(0),i=r(a),l=n(9),u=n(31),s=r(u),c=n(59),d=r(c),f=null;window.reactRender=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};f||(f=document.createElement("en-components"),document.body.appendChild(f)),(0,l.render)([e.comments&&i.default.createElement(s.default,o({key:"comments"},e.comments)),e.realtime&&i.default.createElement(d.default,o({key:"realtime"},e.realtime))],f)}},function(e,t,n){"use strict";function r(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r<t;r++)n+="&args[]="+encodeURIComponent(arguments[r+1]);throw t=Error(n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."),t.name="Invariant Violation",t.framesToPop=1,t}function o(e,t,n){this.props=e,this.context=t,this.refs=b,this.updater=n||M}function a(e,t,n){this.props=e,this.context=t,this.refs=b,this.updater=n||M}function i(){}function l(e,t,n){this.props=e,this.context=t,this.refs=b,this.updater=n||M}function u(e,t,n){var r,o={},a=null,i=null;if(null!=t)for(r in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(a=""+t.key),t)L.call(t,r)&&!I.hasOwnProperty(r)&&(o[r]=t[r]);var l=arguments.length-2;if(1===l)o.children=n;else if(1<l){for(var u=Array(l),s=0;s<l;s++)u[s]=arguments[s+2];o.children=u}if(e&&e.defaultProps)for(r in l=e.defaultProps)void 0===o[r]&&(o[r]=l[r]);return{$$typeof:k,type:e,key:a,ref:i,props:o,_owner:P.current}}function s(e){return"object"==typeof e&&null!==e&&e.$$typeof===k}function c(e){var t={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,function(e){return t[e]})}function d(e,t,n,r){if(A.length){var o=A.pop();return o.result=e,o.keyPrefix=t,o.func=n,o.context=r,o.count=0,o}return{result:e,keyPrefix:t,func:n,context:r,count:0}}function f(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>A.length&&A.push(e)}function p(e,t,n,o){var a=typeof e;"undefined"!==a&&"boolean"!==a||(e=null);var i=!1;if(null===e)i=!0;else switch(a){case"string":case"number":i=!0;break;case"object":switch(e.$$typeof){case k:case w:case C:case E:i=!0}}if(i)return n(o,e,""===t?"."+h(e,0):t),1;if(i=0,t=""===t?".":t+":",Array.isArray(e))for(var l=0;l<e.length;l++){a=e[l];var u=t+h(a,l);i+=p(a,u,n,o)}else if(null===e||void 0===e?u=null:(u=O&&e[O]||e["@@iterator"],u="function"==typeof u?u:null),"function"==typeof u)for(e=u.call(e),l=0;!(a=e.next()).done;)a=a.value,u=t+h(a,l++),i+=p(a,u,n,o);else"object"===a&&(n=""+e,r("31","[object Object]"===n?"object with keys {"+Object.keys(e).join(", ")+"}":n,""));return i}function h(e,t){return"object"==typeof e&&null!==e&&null!=e.key?c(e.key):t.toString(36)}function m(e,t){e.func.call(e.context,t,e.count++)}function g(e,t,n){var r=e.result,o=e.keyPrefix;e=e.func.call(e.context,t,e.count++),Array.isArray(e)?v(e,r,n,x.thatReturnsArgument):null!=e&&(s(e)&&(t=o+(!e.key||t&&t.key===e.key?"":(""+e.key).replace(R,"$&/")+"/")+n,e={$$typeof:k,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}),r.push(e))}function v(e,t,n,r,o){var a="";null!=n&&(a=(""+n).replace(R,"$&/")+"/"),t=d(t,a,r,o),null==e||p(e,"",g,t),f(t)}/** @license React v16.2.0
 * react.production.min.js
 *
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
var y=n(12),b=n(13),x=n(8),_="function"==typeof Symbol&&Symbol.for,k=_?Symbol.for("react.element"):60103,w=_?Symbol.for("react.call"):60104,C=_?Symbol.for("react.return"):60105,E=_?Symbol.for("react.portal"):60106,T=_?Symbol.for("react.fragment"):60107,O="function"==typeof Symbol&&Symbol.iterator,M={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}};o.prototype.isReactComponent={},o.prototype.setState=function(e,t){"object"!=typeof e&&"function"!=typeof e&&null!=e&&r("85"),this.updater.enqueueSetState(this,e,t,"setState")},o.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},i.prototype=o.prototype;var S=a.prototype=new i;S.constructor=a,y(S,o.prototype),S.isPureReactComponent=!0;var N=l.prototype=new i;N.constructor=l,y(N,o.prototype),N.unstable_isAsyncReactComponent=!0,N.render=function(){return this.props.children};var P={current:null},L=Object.prototype.hasOwnProperty,I={key:!0,ref:!0,__self:!0,__source:!0},R=/\/+/g,A=[],D={Children:{map:function(e,t,n){if(null==e)return e;var r=[];return v(e,r,null,t,n),r},forEach:function(e,t,n){if(null==e)return e;t=d(null,null,t,n),null==e||p(e,"",m,t),f(t)},count:function(e){return null==e?0:p(e,"",x.thatReturnsNull,null)},toArray:function(e){var t=[];return v(e,t,null,x.thatReturnsArgument),t},only:function(e){return s(e)||r("143"),e}},Component:o,PureComponent:a,unstable_AsyncComponent:l,Fragment:T,createElement:u,cloneElement:function(e,t,n){var r=y({},e.props),o=e.key,a=e.ref,i=e._owner;if(null!=t){if(void 0!==t.ref&&(a=t.ref,i=P.current),void 0!==t.key&&(o=""+t.key),e.type&&e.type.defaultProps)var l=e.type.defaultProps;for(u in t)L.call(t,u)&&!I.hasOwnProperty(u)&&(r[u]=void 0===t[u]&&void 0!==l?l[u]:t[u])}var u=arguments.length-2;if(1===u)r.children=n;else if(1<u){l=Array(u);for(var s=0;s<u;s++)l[s]=arguments[s+2];r.children=l}return{$$typeof:k,type:e.type,key:o,ref:a,props:r,_owner:i}},createFactory:function(e){var t=u.bind(null,e);return t.type=e,t},isValidElement:s,version:"16.2.0",__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{ReactCurrentOwner:P,assign:y}},j=Object.freeze({default:D}),U=j&&D||j;e.exports=U.default?U.default:U},function(e,t,n){"use strict";function r(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r<t;r++)n+="&args[]="+encodeURIComponent(arguments[r+1]);throw t=Error(n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."),t.name="Invariant Violation",t.framesToPop=1,t}function o(e,t){return(e&t)===t}function a(e,t){if(Sn.hasOwnProperty(e)||2<e.length&&("o"===e[0]||"O"===e[0])&&("n"===e[1]||"N"===e[1]))return!1;if(null===t)return!0;switch(typeof t){case"boolean":return Sn.hasOwnProperty(e)?e=!0:(t=i(e))?e=t.hasBooleanValue||t.hasStringBooleanValue||t.hasOverloadedBooleanValue:(e=e.toLowerCase().slice(0,5),e="data-"===e||"aria-"===e),e;case"undefined":case"number":case"string":case"object":return!0;default:return!1}}function i(e){return Pn.hasOwnProperty(e)?Pn[e]:null}function l(e){return e[1].toUpperCase()}function u(e,t,n,r,o,a,i,l,u){Vn._hasCaughtError=!1,Vn._caughtError=null;var s=Array.prototype.slice.call(arguments,3);try{t.apply(n,s)}catch(e){Vn._caughtError=e,Vn._hasCaughtError=!0}}function s(){if(Vn._hasRethrowError){var e=Vn._rethrowError;throw Vn._rethrowError=null,Vn._hasRethrowError=!1,e}}function c(){if(Wn)for(var e in Zn){var t=Zn[e],n=Wn.indexOf(e);if(-1<n||r("96",e),!Gn[n]){t.extractEvents||r("97",e),Gn[n]=t,n=t.eventTypes;for(var o in n){var a=void 0,i=n[o],l=t,u=o;Yn.hasOwnProperty(u)&&r("99",u),Yn[u]=i;var s=i.phasedRegistrationNames;if(s){for(a in s)s.hasOwnProperty(a)&&d(s[a],l,u);a=!0}else i.registrationName?(d(i.registrationName,l,u),a=!0):a=!1;a||r("98",o,e)}}}}function d(e,t,n){qn[e]&&r("100",e),qn[e]=t,Qn[e]=t.eventTypes[n].dependencies}function f(e){Wn&&r("101"),Wn=Array.prototype.slice.call(e),c()}function p(e){var t,n=!1;for(t in e)if(e.hasOwnProperty(t)){var o=e[t];Zn.hasOwnProperty(t)&&Zn[t]===o||(Zn[t]&&r("102",t),Zn[t]=o,n=!0)}n&&c()}function h(e,t,n,r){t=e.type||"unknown-event",e.currentTarget=er(r),Vn.invokeGuardedCallbackAndCatchFirstError(t,n,void 0,e),e.currentTarget=null}function m(e,t){return null==t&&r("30"),null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}function g(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}function v(e,t){if(e){var n=e._dispatchListeners,r=e._dispatchInstances;if(Array.isArray(n))for(var o=0;o<n.length&&!e.isPropagationStopped();o++)h(e,t,n[o],r[o]);else n&&h(e,t,n,r);e._dispatchListeners=null,e._dispatchInstances=null,e.isPersistent()||e.constructor.release(e)}}function y(e){return v(e,!0)}function b(e){return v(e,!1)}function x(e,t){var n=e.stateNode;if(!n)return null;var o=Jn(n);if(!o)return null;n=o[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":(o=!o.disabled)||(e=e.type,o=!("button"===e||"input"===e||"select"===e||"textarea"===e)),e=!o;break e;default:e=!1}return e?null:(n&&"function"!=typeof n&&r("231",t,typeof n),n)}function _(e,t,n,r){for(var o,a=0;a<Gn.length;a++){var i=Gn[a];i&&(i=i.extractEvents(e,t,n,r))&&(o=m(o,i))}return o}function k(e){e&&(tr=m(tr,e))}function w(e){var t=tr;tr=null,t&&(e?g(t,y):g(t,b),tr&&r("95"),Vn.rethrowCaughtError())}function C(e){if(e[ar])return e[ar];for(var t=[];!e[ar];){if(t.push(e),!e.parentNode)return null;e=e.parentNode}var n=void 0,r=e[ar];if(5===r.tag||6===r.tag)return r;for(;e&&(r=e[ar]);e=t.pop())n=r;return n}function E(e){if(5===e.tag||6===e.tag)return e.stateNode;r("33")}function T(e){return e[ir]||null}function O(e){do{e=e.return}while(e&&5!==e.tag);return e||null}function M(e,t,n){for(var r=[];e;)r.push(e),e=O(e);for(e=r.length;0<e--;)t(r[e],"captured",n);for(e=0;e<r.length;e++)t(r[e],"bubbled",n)}function S(e,t,n){(t=x(e,n.dispatchConfig.phasedRegistrationNames[t]))&&(n._dispatchListeners=m(n._dispatchListeners,t),n._dispatchInstances=m(n._dispatchInstances,e))}function N(e){e&&e.dispatchConfig.phasedRegistrationNames&&M(e._targetInst,S,e)}function P(e){if(e&&e.dispatchConfig.phasedRegistrationNames){var t=e._targetInst;t=t?O(t):null,M(t,S,e)}}function L(e,t,n){e&&n&&n.dispatchConfig.registrationName&&(t=x(e,n.dispatchConfig.registrationName))&&(n._dispatchListeners=m(n._dispatchListeners,t),n._dispatchInstances=m(n._dispatchInstances,e))}function I(e){e&&e.dispatchConfig.registrationName&&L(e._targetInst,null,e)}function R(e){g(e,N)}function A(e,t,n,r){if(n&&r)e:{for(var o=n,a=r,i=0,l=o;l;l=O(l))i++;l=0;for(var u=a;u;u=O(u))l++;for(;0<i-l;)o=O(o),i--;for(;0<l-i;)a=O(a),l--;for(;i--;){if(o===a||o===a.alternate)break e;o=O(o),a=O(a)}o=null}else o=null;for(a=o,o=[];n&&n!==a&&(null===(i=n.alternate)||i!==a);)o.push(n),n=O(n);for(n=[];r&&r!==a&&(null===(i=r.alternate)||i!==a);)n.push(r),r=O(r);for(r=0;r<o.length;r++)L(o[r],"bubbled",e);for(e=n.length;0<e--;)L(n[e],"captured",t)}function D(){return!sr&&xn.canUseDOM&&(sr="textContent"in document.documentElement?"textContent":"innerText"),sr}function j(){if(cr._fallbackText)return cr._fallbackText;var e,t,n=cr._startText,r=n.length,o=U(),a=o.length;for(e=0;e<r&&n[e]===o[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===o[a-t];t++);return cr._fallbackText=o.slice(e,1<t?1-t:void 0),cr._fallbackText}function U(){return"value"in cr._root?cr._root.value:cr._root[D()]}function F(e,t,n,r){this.dispatchConfig=e,this._targetInst=t,this.nativeEvent=n,e=this.constructor.Interface;for(var o in e)e.hasOwnProperty(o)&&((t=e[o])?this[o]=t(n):"target"===o?this.target=r:this[o]=n[o]);return this.isDefaultPrevented=(null!=n.defaultPrevented?n.defaultPrevented:!1===n.returnValue)?kn.thatReturnsTrue:kn.thatReturnsFalse,this.isPropagationStopped=kn.thatReturnsFalse,this}function H(e,t,n,r){if(this.eventPool.length){var o=this.eventPool.pop();return this.call(o,e,t,n,r),o}return new this(e,t,n,r)}function K(e){e instanceof this||r("223"),e.destructor(),10>this.eventPool.length&&this.eventPool.push(e)}function B(e){e.eventPool=[],e.getPooled=H,e.release=K}function z(e,t,n,r){return F.call(this,e,t,n,r)}function V(e,t,n,r){return F.call(this,e,t,n,r)}function W(e,t){switch(e){case"topKeyUp":return-1!==pr.indexOf(t.keyCode);case"topKeyDown":return 229!==t.keyCode;case"topKeyPress":case"topMouseDown":case"topBlur":return!0;default:return!1}}function Z(e){return e=e.detail,"object"==typeof e&&"data"in e?e.data:null}function G(e,t){switch(e){case"topCompositionEnd":return Z(t);case"topKeyPress":return 32!==t.which?null:(wr=!0,_r);case"topTextInput":return e=t.data,e===_r&&wr?null:e;default:return null}}function Y(e,t){if(Cr)return"topCompositionEnd"===e||!hr&&W(e,t)?(e=j(),cr._root=null,cr._startText=null,cr._fallbackText=null,Cr=!1,e):null;switch(e){case"topPaste":return null;case"topKeyPress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"topCompositionEnd":return xr?null:t.data;default:return null}}function q(e){if(e=Xn(e)){Tr&&"function"==typeof Tr.restoreControlledState||r("194");var t=Jn(e.stateNode);Tr.restoreControlledState(e.stateNode,e.type,t)}}function Q(e){Or?Mr?Mr.push(e):Mr=[e]:Or=e}function $(){if(Or){var e=Or,t=Mr;if(Mr=Or=null,q(e),t)for(e=0;e<t.length;e++)q(t[e])}}function J(e,t){return e(t)}function X(e,t){if(Pr)return J(e,t);Pr=!0;try{return J(e,t)}finally{Pr=!1,$()}}function ee(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Lr[e.type]:"textarea"===t}function te(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}function ne(e,t){if(!xn.canUseDOM||t&&!("addEventListener"in document))return!1;t="on"+e;var n=t in document;return n||(n=document.createElement("div"),n.setAttribute(t,"return;"),n="function"==typeof n[t]),!n&&yr&&"wheel"===e&&(n=document.implementation.hasFeature("Events.wheel","3.0")),n}function re(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function oe(e){var t=re(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&"function"==typeof n.get&&"function"==typeof n.set)return Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:!0,get:function(){return n.get.call(this)},set:function(e){r=""+e,n.set.call(this,e)}}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}function ae(e){e._valueTracker||(e._valueTracker=oe(e))}function ie(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=re(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function le(e,t,n){return e=F.getPooled(Ir.change,e,t,n),e.type="change",Q(n),R(e),e}function ue(e){k(e),w(!1)}function se(e){if(ie(E(e)))return e}function ce(e,t){if("topChange"===e)return t}function de(){Rr&&(Rr.detachEvent("onpropertychange",fe),Ar=Rr=null)}function fe(e){"value"===e.propertyName&&se(Ar)&&(e=le(Ar,e,te(e)),X(ue,e))}function pe(e,t,n){"topFocus"===e?(de(),Rr=t,Ar=n,Rr.attachEvent("onpropertychange",fe)):"topBlur"===e&&de()}function he(e){if("topSelectionChange"===e||"topKeyUp"===e||"topKeyDown"===e)return se(Ar)}function me(e,t){if("topClick"===e)return se(t)}function ge(e,t){if("topInput"===e||"topChange"===e)return se(t)}function ve(e,t,n,r){return F.call(this,e,t,n,r)}function ye(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=Ur[e])&&!!t[e]}function be(){return ye}function xe(e,t,n,r){return F.call(this,e,t,n,r)}function _e(e){return e=e.type,"string"==typeof e?e:"function"==typeof e?e.displayName||e.name:null}function ke(e){var t=e;if(e.alternate)for(;t.return;)t=t.return;else{if(0!=(2&t.effectTag))return 1;for(;t.return;)if(t=t.return,0!=(2&t.effectTag))return 1}return 3===t.tag?2:3}function we(e){return!!(e=e._reactInternalFiber)&&2===ke(e)}function Ce(e){2!==ke(e)&&r("188")}function Ee(e){var t=e.alternate;if(!t)return t=ke(e),3===t&&r("188"),1===t?null:e;for(var n=e,o=t;;){var a=n.return,i=a?a.alternate:null;if(!a||!i)break;if(a.child===i.child){for(var l=a.child;l;){if(l===n)return Ce(a),e;if(l===o)return Ce(a),t;l=l.sibling}r("188")}if(n.return!==o.return)n=a,o=i;else{l=!1;for(var u=a.child;u;){if(u===n){l=!0,n=a,o=i;break}if(u===o){l=!0,o=a,n=i;break}u=u.sibling}if(!l){for(u=i.child;u;){if(u===n){l=!0,n=i,o=a;break}if(u===o){l=!0,o=i,n=a;break}u=u.sibling}l||r("189")}}n.alternate!==o&&r("190")}return 3!==n.tag&&r("188"),n.stateNode.current===n?e:t}function Te(e){if(!(e=Ee(e)))return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function Oe(e){if(!(e=Ee(e)))return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child&&4!==t.tag)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function Me(e){var t=e.targetInst;do{if(!t){e.ancestors.push(t);break}var n;for(n=t;n.return;)n=n.return;if(!(n=3!==n.tag?null:n.stateNode.containerInfo))break;e.ancestors.push(t),t=C(n)}while(t);for(n=0;n<e.ancestors.length;n++)t=e.ancestors[n],Vr(e.topLevelType,t,e.nativeEvent,te(e.nativeEvent))}function Se(e){zr=!!e}function Ne(e,t,n){return n?wn.listen(n,t,Le.bind(null,e)):null}function Pe(e,t,n){return n?wn.capture(n,t,Le.bind(null,e)):null}function Le(e,t){if(zr){var n=te(t);if(n=C(n),null===n||"number"!=typeof n.tag||2===ke(n)||(n=null),Br.length){var r=Br.pop();r.topLevelType=e,r.nativeEvent=t,r.targetInst=n,e=r}else e={topLevelType:e,nativeEvent:t,targetInst:n,ancestors:[]};try{X(Me,e)}finally{e.topLevelType=null,e.nativeEvent=null,e.targetInst=null,e.ancestors.length=0,10>Br.length&&Br.push(e)}}}function Ie(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n["ms"+e]="MS"+t,n["O"+e]="o"+t.toLowerCase(),n}function Re(e){if(Gr[e])return Gr[e];if(!Zr[e])return e;var t,n=Zr[e];for(t in n)if(n.hasOwnProperty(t)&&t in Yr)return Gr[e]=n[t];return""}function Ae(e){return Object.prototype.hasOwnProperty.call(e,Jr)||(e[Jr]=$r++,Qr[e[Jr]]={}),Qr[e[Jr]]}function De(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function je(e,t){var n=De(e);e=0;for(var r;n;){if(3===n.nodeType){if(r=e+n.textContent.length,e<=t&&r>=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=De(n)}}function Ue(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&"text"===e.type||"textarea"===t||"true"===e.contentEditable)}function Fe(e,t){if(oo||null==to||to!==Cn())return null;var n=to;return"selectionStart"in n&&Ue(n)?n={start:n.selectionStart,end:n.selectionEnd}:window.getSelection?(n=window.getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset}):n=void 0,ro&&En(ro,n)?null:(ro=n,e=F.getPooled(eo.select,no,e,t),e.type="select",e.target=to,R(e),e)}function He(e,t,n,r){return F.call(this,e,t,n,r)}function Ke(e,t,n,r){return F.call(this,e,t,n,r)}function Be(e,t,n,r){return F.call(this,e,t,n,r)}function ze(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,32<=e||13===e?e:0}function Ve(e,t,n,r){return F.call(this,e,t,n,r)}function We(e,t,n,r){return F.call(this,e,t,n,r)}function Ze(e,t,n,r){return F.call(this,e,t,n,r)}function Ge(e,t,n,r){return F.call(this,e,t,n,r)}function Ye(e,t,n,r){return F.call(this,e,t,n,r)}function qe(e){0>po||(e.current=fo[po],fo[po]=null,po--)}function Qe(e,t){po++,fo[po]=e.current,e.current=t}function $e(e){return Xe(e)?go:ho.current}function Je(e,t){var n=e.type.contextTypes;if(!n)return Mn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in n)a[o]=t[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function Xe(e){return 2===e.tag&&null!=e.type.childContextTypes}function et(e){Xe(e)&&(qe(mo,e),qe(ho,e))}function tt(e,t,n){null!=ho.cursor&&r("168"),Qe(ho,t,e),Qe(mo,n,e)}function nt(e,t){var n=e.stateNode,o=e.type.childContextTypes;if("function"!=typeof n.getChildContext)return t;n=n.getChildContext();for(var a in n)a in o||r("108",_e(e)||"Unknown",a);return _n({},t,n)}function rt(e){if(!Xe(e))return!1;var t=e.stateNode;return t=t&&t.__reactInternalMemoizedMergedChildContext||Mn,go=ho.current,Qe(ho,t,e),Qe(mo,mo.current,e),!0}function ot(e,t){var n=e.stateNode;if(n||r("169"),t){var o=nt(e,go);n.__reactInternalMemoizedMergedChildContext=o,qe(mo,e),qe(ho,e),Qe(ho,o,e)}else qe(mo,e);Qe(mo,t,e)}function at(e,t,n){this.tag=e,this.key=t,this.stateNode=this.type=null,this.sibling=this.child=this.return=null,this.index=0,this.memoizedState=this.updateQueue=this.memoizedProps=this.pendingProps=this.ref=null,this.internalContextTag=n,this.effectTag=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.expirationTime=0,this.alternate=null}function it(e,t,n){var r=e.alternate;return null===r?(r=new at(e.tag,e.key,e.internalContextTag),r.type=e.type,r.stateNode=e.stateNode,r.alternate=e,e.alternate=r):(r.effectTag=0,r.nextEffect=null,r.firstEffect=null,r.lastEffect=null),r.expirationTime=n,r.pendingProps=t,r.child=e.child,r.memoizedProps=e.memoizedProps,r.memoizedState=e.memoizedState,r.updateQueue=e.updateQueue,r.sibling=e.sibling,r.index=e.index,r.ref=e.ref,r}function lt(e,t,n){var o=void 0,a=e.type,i=e.key;return"function"==typeof a?(o=a.prototype&&a.prototype.isReactComponent?new at(2,i,t):new at(0,i,t),o.type=a,o.pendingProps=e.props):"string"==typeof a?(o=new at(5,i,t),o.type=a,o.pendingProps=e.props):"object"==typeof a&&null!==a&&"number"==typeof a.tag?(o=a,o.pendingProps=e.props):r("130",null==a?a:typeof a,""),o.expirationTime=n,o}function ut(e,t,n,r){return t=new at(10,r,t),t.pendingProps=e,t.expirationTime=n,t}function st(e,t,n){return t=new at(6,null,t),t.pendingProps=e,t.expirationTime=n,t}function ct(e,t,n){return t=new at(7,e.key,t),t.type=e.handler,t.pendingProps=e,t.expirationTime=n,t}function dt(e,t,n){return e=new at(9,null,t),e.expirationTime=n,e}function ft(e,t,n){return t=new at(4,e.key,t),t.pendingProps=e.children||[],t.expirationTime=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function pt(e){return function(t){try{return e(t)}catch(e){}}}function ht(e){if("undefined"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled||!t.supportsFiber)return!0;try{var n=t.inject(e);vo=pt(function(e){return t.onCommitFiberRoot(n,e)}),yo=pt(function(e){return t.onCommitFiberUnmount(n,e)})}catch(e){}return!0}function mt(e){"function"==typeof vo&&vo(e)}function gt(e){"function"==typeof yo&&yo(e)}function vt(e){return{baseState:e,expirationTime:0,first:null,last:null,callbackList:null,hasForceUpdate:!1,isInitialized:!1}}function yt(e,t){null===e.last?e.first=e.last=t:(e.last.next=t,e.last=t),(0===e.expirationTime||e.expirationTime>t.expirationTime)&&(e.expirationTime=t.expirationTime)}function bt(e,t){var n=e.alternate,r=e.updateQueue;null===r&&(r=e.updateQueue=vt(null)),null!==n?null===(e=n.updateQueue)&&(e=n.updateQueue=vt(null)):e=null,e=e!==r?e:null,null===e?yt(r,t):null===r.last||null===e.last?(yt(r,t),yt(e,t)):(yt(r,t),e.last=t)}function xt(e,t,n,r){return e=e.partialState,"function"==typeof e?e.call(t,n,r):e}function _t(e,t,n,r,o,a){null!==e&&e.updateQueue===n&&(n=t.updateQueue={baseState:n.baseState,expirationTime:n.expirationTime,first:n.first,last:n.last,isInitialized:n.isInitialized,callbackList:null,hasForceUpdate:!1}),n.expirationTime=0,n.isInitialized?e=n.baseState:(e=n.baseState=t.memoizedState,n.isInitialized=!0);for(var i=!0,l=n.first,u=!1;null!==l;){var s=l.expirationTime;if(s>a){var c=n.expirationTime;(0===c||c>s)&&(n.expirationTime=s),u||(u=!0,n.baseState=e)}else u||(n.first=l.next,null===n.first&&(n.last=null)),l.isReplace?(e=xt(l,r,e,o),i=!0):(s=xt(l,r,e,o))&&(e=i?_n({},e,s):_n(e,s),i=!1),l.isForced&&(n.hasForceUpdate=!0),null!==l.callback&&(s=n.callbackList,null===s&&(s=n.callbackList=[]),s.push(l));l=l.next}return null!==n.callbackList?t.effectTag|=32:null!==n.first||n.hasForceUpdate||(t.updateQueue=null),u||(n.baseState=e),e}function kt(e,t){var n=e.callbackList;if(null!==n)for(e.callbackList=null,e=0;e<n.length;e++){var o=n[e],a=o.callback;o.callback=null,"function"!=typeof a&&r("191",a),a.call(t)}}function wt(e,t,n,o){function a(e,t){t.updater=i,e.stateNode=t,t._reactInternalFiber=e}var i={isMounted:we,enqueueSetState:function(n,r,o){n=n._reactInternalFiber,o=void 0===o?null:o;var a=t(n);bt(n,{expirationTime:a,partialState:r,callback:o,isReplace:!1,isForced:!1,nextCallback:null,next:null}),e(n,a)},enqueueReplaceState:function(n,r,o){n=n._reactInternalFiber,o=void 0===o?null:o;var a=t(n);bt(n,{expirationTime:a,partialState:r,callback:o,isReplace:!0,isForced:!1,nextCallback:null,next:null}),e(n,a)},enqueueForceUpdate:function(n,r){n=n._reactInternalFiber,r=void 0===r?null:r;var o=t(n);bt(n,{expirationTime:o,partialState:null,callback:r,isReplace:!1,isForced:!0,nextCallback:null,next:null}),e(n,o)}};return{adoptClassInstance:a,constructClassInstance:function(e,t){var n=e.type,r=$e(e),o=2===e.tag&&null!=e.type.contextTypes,i=o?Je(e,r):Mn;return t=new n(t,i),a(e,t),o&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=r,e.__reactInternalMemoizedMaskedChildContext=i),t},mountClassInstance:function(e,t){var n=e.alternate,o=e.stateNode,a=o.state||null,l=e.pendingProps;l||r("158");var u=$e(e);o.props=l,o.state=e.memoizedState=a,o.refs=Mn,o.context=Je(e,u),null!=e.type&&null!=e.type.prototype&&!0===e.type.prototype.unstable_isAsyncReactComponent&&(e.internalContextTag|=1),"function"==typeof o.componentWillMount&&(a=o.state,o.componentWillMount(),a!==o.state&&i.enqueueReplaceState(o,o.state,null),null!==(a=e.updateQueue)&&(o.state=_t(n,e,a,o,l,t))),"function"==typeof o.componentDidMount&&(e.effectTag|=4)},updateClassInstance:function(e,t,a){var l=t.stateNode;l.props=t.memoizedProps,l.state=t.memoizedState;var u=t.memoizedProps,s=t.pendingProps;s||null==(s=u)&&r("159");var c=l.context,d=$e(t);if(d=Je(t,d),"function"!=typeof l.componentWillReceiveProps||u===s&&c===d||(c=l.state,l.componentWillReceiveProps(s,d),l.state!==c&&i.enqueueReplaceState(l,l.state,null)),c=t.memoizedState,a=null!==t.updateQueue?_t(e,t,t.updateQueue,l,s,a):c,!(u!==s||c!==a||mo.current||null!==t.updateQueue&&t.updateQueue.hasForceUpdate))return"function"!=typeof l.componentDidUpdate||u===e.memoizedProps&&c===e.memoizedState||(t.effectTag|=4),!1;var f=s;if(null===u||null!==t.updateQueue&&t.updateQueue.hasForceUpdate)f=!0;else{var p=t.stateNode,h=t.type;f="function"==typeof p.shouldComponentUpdate?p.shouldComponentUpdate(f,a,d):!h.prototype||!h.prototype.isPureReactComponent||(!En(u,f)||!En(c,a))}return f?("function"==typeof l.componentWillUpdate&&l.componentWillUpdate(s,a,d),"function"==typeof l.componentDidUpdate&&(t.effectTag|=4)):("function"!=typeof l.componentDidUpdate||u===e.memoizedProps&&c===e.memoizedState||(t.effectTag|=4),n(t,s),o(t,a)),l.props=s,l.state=a,l.context=d,f}}}function Ct(e){return null===e||void 0===e?null:(e=Eo&&e[Eo]||e["@@iterator"],"function"==typeof e?e:null)}function Et(e,t){var n=t.ref;if(null!==n&&"function"!=typeof n){if(t._owner){t=t._owner;var o=void 0;t&&(2!==t.tag&&r("110"),o=t.stateNode),o||r("147",n);var a=""+n;return null!==e&&null!==e.ref&&e.ref._stringRef===a?e.ref:(e=function(e){var t=o.refs===Mn?o.refs={}:o.refs;null===e?delete t[a]:t[a]=e},e._stringRef=a,e)}"string"!=typeof n&&r("148"),t._owner||r("149",n)}return n}function Tt(e,t){"textarea"!==e.type&&r("31","[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t,"")}function Ot(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.effectTag=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function o(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function a(e,t,n){return e=it(e,t,n),e.index=0,e.sibling=null,e}function i(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index,r<n?(t.effectTag=2,n):r):(t.effectTag=2,n):n}function l(t){return e&&null===t.alternate&&(t.effectTag=2),t}function u(e,t,n,r){return null===t||6!==t.tag?(t=st(n,e.internalContextTag,r),t.return=e,t):(t=a(t,n,r),t.return=e,t)}function s(e,t,n,r){return null!==t&&t.type===n.type?(r=a(t,n.props,r),r.ref=Et(t,n),r.return=e,r):(r=lt(n,e.internalContextTag,r),r.ref=Et(t,n),r.return=e,r)}function c(e,t,n,r){return null===t||7!==t.tag?(t=ct(n,e.internalContextTag,r),t.return=e,t):(t=a(t,n,r),t.return=e,t)}function d(e,t,n,r){return null===t||9!==t.tag?(t=dt(n,e.internalContextTag,r),t.type=n.value,t.return=e,t):(t=a(t,null,r),t.type=n.value,t.return=e,t)}function f(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?(t=ft(n,e.internalContextTag,r),t.return=e,t):(t=a(t,n.children||[],r),t.return=e,t)}function p(e,t,n,r,o){return null===t||10!==t.tag?(t=ut(n,e.internalContextTag,r,o),t.return=e,t):(t=a(t,n,r),t.return=e,t)}function h(e,t,n){if("string"==typeof t||"number"==typeof t)return t=st(""+t,e.internalContextTag,n),t.return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case xo:return t.type===Co?(t=ut(t.props.children,e.internalContextTag,n,t.key),t.return=e,t):(n=lt(t,e.internalContextTag,n),n.ref=Et(null,t),n.return=e,n);case _o:return t=ct(t,e.internalContextTag,n),t.return=e,t;case ko:return n=dt(t,e.internalContextTag,n),n.type=t.value,n.return=e,n;case wo:return t=ft(t,e.internalContextTag,n),t.return=e,t}if(To(t)||Ct(t))return t=ut(t,e.internalContextTag,n,null),t.return=e,t;Tt(e,t)}return null}function m(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==o?null:u(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case xo:return n.key===o?n.type===Co?p(e,t,n.props.children,r,o):s(e,t,n,r):null;case _o:return n.key===o?c(e,t,n,r):null;case ko:return null===o?d(e,t,n,r):null;case wo:return n.key===o?f(e,t,n,r):null}if(To(n)||Ct(n))return null!==o?null:p(e,t,n,r,null);Tt(e,n)}return null}function g(e,t,n,r,o){if("string"==typeof r||"number"==typeof r)return e=e.get(n)||null,u(t,e,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case xo:return e=e.get(null===r.key?n:r.key)||null,r.type===Co?p(t,e,r.props.children,o,r.key):s(t,e,r,o);case _o:return e=e.get(null===r.key?n:r.key)||null,c(t,e,r,o);case ko:return e=e.get(n)||null,d(t,e,r,o);case wo:return e=e.get(null===r.key?n:r.key)||null,f(t,e,r,o)}if(To(r)||Ct(r))return e=e.get(n)||null,p(t,e,r,o,null);Tt(t,r)}return null}function v(r,a,l,u){for(var s=null,c=null,d=a,f=a=0,p=null;null!==d&&f<l.length;f++){d.index>f?(p=d,d=null):p=d.sibling;var v=m(r,d,l[f],u);if(null===v){null===d&&(d=p);break}e&&d&&null===v.alternate&&t(r,d),a=i(v,a,f),null===c?s=v:c.sibling=v,c=v,d=p}if(f===l.length)return n(r,d),s;if(null===d){for(;f<l.length;f++)(d=h(r,l[f],u))&&(a=i(d,a,f),null===c?s=d:c.sibling=d,c=d);return s}for(d=o(r,d);f<l.length;f++)(p=g(d,r,f,l[f],u))&&(e&&null!==p.alternate&&d.delete(null===p.key?f:p.key),a=i(p,a,f),null===c?s=p:c.sibling=p,c=p);return e&&d.forEach(function(e){return t(r,e)}),s}function y(a,l,u,s){var c=Ct(u);"function"!=typeof c&&r("150"),null==(u=c.call(u))&&r("151");for(var d=c=null,f=l,p=l=0,v=null,y=u.next();null!==f&&!y.done;p++,y=u.next()){f.index>p?(v=f,f=null):v=f.sibling;var b=m(a,f,y.value,s);if(null===b){f||(f=v);break}e&&f&&null===b.alternate&&t(a,f),l=i(b,l,p),null===d?c=b:d.sibling=b,d=b,f=v}if(y.done)return n(a,f),c;if(null===f){for(;!y.done;p++,y=u.next())null!==(y=h(a,y.value,s))&&(l=i(y,l,p),null===d?c=y:d.sibling=y,d=y);return c}for(f=o(a,f);!y.done;p++,y=u.next())null!==(y=g(f,a,p,y.value,s))&&(e&&null!==y.alternate&&f.delete(null===y.key?p:y.key),l=i(y,l,p),null===d?c=y:d.sibling=y,d=y);return e&&f.forEach(function(e){return t(a,e)}),c}return function(e,o,i,u){"object"==typeof i&&null!==i&&i.type===Co&&null===i.key&&(i=i.props.children);var s="object"==typeof i&&null!==i;if(s)switch(i.$$typeof){case xo:e:{var c=i.key;for(s=o;null!==s;){if(s.key===c){if(10===s.tag?i.type===Co:s.type===i.type){n(e,s.sibling),o=a(s,i.type===Co?i.props.children:i.props,u),o.ref=Et(s,i),o.return=e,e=o;break e}n(e,s);break}t(e,s),s=s.sibling}i.type===Co?(o=ut(i.props.children,e.internalContextTag,u,i.key),o.return=e,e=o):(u=lt(i,e.internalContextTag,u),u.ref=Et(o,i),u.return=e,e=u)}return l(e);case _o:e:{for(s=i.key;null!==o;){if(o.key===s){if(7===o.tag){n(e,o.sibling),o=a(o,i,u),o.return=e,e=o;break e}n(e,o);break}t(e,o),o=o.sibling}o=ct(i,e.internalContextTag,u),o.return=e,e=o}return l(e);case ko:e:{if(null!==o){if(9===o.tag){n(e,o.sibling),o=a(o,null,u),o.type=i.value,o.return=e,e=o;break e}n(e,o)}o=dt(i,e.internalContextTag,u),o.type=i.value,o.return=e,e=o}return l(e);case wo:e:{for(s=i.key;null!==o;){if(o.key===s){if(4===o.tag&&o.stateNode.containerInfo===i.containerInfo&&o.stateNode.implementation===i.implementation){n(e,o.sibling),o=a(o,i.children||[],u),o.return=e,e=o;break e}n(e,o);break}t(e,o),o=o.sibling}o=ft(i,e.internalContextTag,u),o.return=e,e=o}return l(e)}if("string"==typeof i||"number"==typeof i)return i=""+i,null!==o&&6===o.tag?(n(e,o.sibling),o=a(o,i,u)):(n(e,o),o=st(i,e.internalContextTag,u)),o.return=e,e=o,l(e);if(To(i))return v(e,o,i,u);if(Ct(i))return y(e,o,i,u);if(s&&Tt(e,i),void 0===i)switch(e.tag){case 2:case 1:u=e.type,r("152",u.displayName||u.name||"Component")}return n(e,o)}}function Mt(e,t,n,o,a){function i(e,t,n){var r=t.expirationTime;t.child=null===e?Mo(t,null,n,r):Oo(t,e.child,n,r)}function l(e,t){var n=t.ref;null===n||e&&e.ref===n||(t.effectTag|=128)}function u(e,t,n,r){if(l(e,t),!n)return r&&ot(t,!1),c(e,t);n=t.stateNode,Kr.current=t;var o=n.render();return t.effectTag|=1,i(e,t,o),t.memoizedState=n.state,t.memoizedProps=n.props,r&&ot(t,!0),t.child}function s(e){var t=e.stateNode;t.pendingContext?tt(e,t.pendingContext,t.pendingContext!==t.context):t.context&&tt(e,t.context,!1),g(e,t.containerInfo)}function c(e,t){if(null!==e&&t.child!==e.child&&r("153"),null!==t.child){e=t.child;var n=it(e,e.pendingProps,e.expirationTime);for(t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,n=n.sibling=it(e,e.pendingProps,e.expirationTime),n.return=t;n.sibling=null}return t.child}function d(e,t){switch(t.tag){case 3:s(t);break;case 2:rt(t);break;case 4:g(t,t.stateNode.containerInfo)}return null}var f=e.shouldSetTextContent,p=e.useSyncScheduling,h=e.shouldDeprioritizeSubtree,m=t.pushHostContext,g=t.pushHostContainer,v=n.enterHydrationState,y=n.resetHydrationState,b=n.tryToClaimNextHydratableInstance;e=wt(o,a,function(e,t){e.memoizedProps=t},function(e,t){e.memoizedState=t});var x=e.adoptClassInstance,_=e.constructClassInstance,k=e.mountClassInstance,w=e.updateClassInstance;return{beginWork:function(e,t,n){if(0===t.expirationTime||t.expirationTime>n)return d(e,t);switch(t.tag){case 0:null!==e&&r("155");var o=t.type,a=t.pendingProps,C=$e(t);return C=Je(t,C),o=o(a,C),t.effectTag|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render?(t.tag=2,a=rt(t),x(t,o),k(t,n),t=u(e,t,!0,a)):(t.tag=1,i(e,t,o),t.memoizedProps=a,t=t.child),t;case 1:e:{if(a=t.type,n=t.pendingProps,o=t.memoizedProps,mo.current)null===n&&(n=o);else if(null===n||o===n){t=c(e,t);break e}o=$e(t),o=Je(t,o),a=a(n,o),t.effectTag|=1,i(e,t,a),t.memoizedProps=n,t=t.child}return t;case 2:return a=rt(t),o=void 0,null===e?t.stateNode?r("153"):(_(t,t.pendingProps),k(t,n),o=!0):o=w(e,t,n),u(e,t,o,a);case 3:return s(t),a=t.updateQueue,null!==a?(o=t.memoizedState,a=_t(e,t,a,null,null,n),o===a?(y(),t=c(e,t)):(o=a.element,C=t.stateNode,(null===e||null===e.child)&&C.hydrate&&v(t)?(t.effectTag|=2,t.child=Mo(t,null,o,n)):(y(),i(e,t,o)),t.memoizedState=a,t=t.child)):(y(),t=c(e,t)),t;case 5:m(t),null===e&&b(t),a=t.type;var E=t.memoizedProps;return o=t.pendingProps,null===o&&null===(o=E)&&r("154"),C=null!==e?e.memoizedProps:null,mo.current||null!==o&&E!==o?(E=o.children,f(a,o)?E=null:C&&f(a,C)&&(t.effectTag|=16),l(e,t),2147483647!==n&&!p&&h(a,o)?(t.expirationTime=2147483647,t=null):(i(e,t,E),t.memoizedProps=o,t=t.child)):t=c(e,t),t;case 6:return null===e&&b(t),e=t.pendingProps,null===e&&(e=t.memoizedProps),t.memoizedProps=e,null;case 8:t.tag=7;case 7:return a=t.pendingProps,mo.current?null===a&&null===(a=e&&e.memoizedProps)&&r("154"):null!==a&&t.memoizedProps!==a||(a=t.memoizedProps),o=a.children,t.stateNode=null===e?Mo(t,t.stateNode,o,n):Oo(t,t.stateNode,o,n),t.memoizedProps=a,t.stateNode;case 9:return null;case 4:e:{if(g(t,t.stateNode.containerInfo),a=t.pendingProps,mo.current)null===a&&null==(a=e&&e.memoizedProps)&&r("154");else if(null===a||t.memoizedProps===a){t=c(e,t);break e}null===e?t.child=Oo(t,null,a,n):i(e,t,a),t.memoizedProps=a,t=t.child}return t;case 10:e:{if(n=t.pendingProps,mo.current)null===n&&(n=t.memoizedProps);else if(null===n||t.memoizedProps===n){t=c(e,t);break e}i(e,t,n),t.memoizedProps=n,t=t.child}return t;default:r("156")}},beginFailedWork:function(e,t,n){switch(t.tag){case 2:rt(t);break;case 3:s(t);break;default:r("157")}return t.effectTag|=64,null===e?t.child=null:t.child!==e.child&&(t.child=e.child),0===t.expirationTime||t.expirationTime>n?d(e,t):(t.firstEffect=null,t.lastEffect=null,t.child=null===e?Mo(t,null,null,n):Oo(t,e.child,null,n),2===t.tag&&(e=t.stateNode,t.memoizedProps=e.props,t.memoizedState=e.state),t.child)}}}function St(e,t,n){function o(e){e.effectTag|=4}var a=e.createInstance,i=e.createTextInstance,l=e.appendInitialChild,u=e.finalizeInitialChildren,s=e.prepareUpdate,c=e.persistence,d=t.getRootHostContainer,f=t.popHostContext,p=t.getHostContext,h=t.popHostContainer,m=n.prepareToHydrateHostInstance,g=n.prepareToHydrateHostTextInstance,v=n.popHydrationState,y=void 0,b=void 0,x=void 0;return e.mutation?(y=function(){},b=function(e,t,n){(t.updateQueue=n)&&o(t)},x=function(e,t,n,r){n!==r&&o(t)}):r(c?"235":"236"),{completeWork:function(e,t,n){var c=t.pendingProps;switch(null===c?c=t.memoizedProps:2147483647===t.expirationTime&&2147483647!==n||(t.pendingProps=null),t.tag){case 1:return null;case 2:return et(t),null;case 3:return h(t),qe(mo,t),qe(ho,t),c=t.stateNode,c.pendingContext&&(c.context=c.pendingContext,c.pendingContext=null),null!==e&&null!==e.child||(v(t),t.effectTag&=-3),y(t),null;case 5:f(t),n=d();var _=t.type;if(null!==e&&null!=t.stateNode){var k=e.memoizedProps,w=t.stateNode,C=p();w=s(w,_,k,c,n,C),b(e,t,w,_,k,c,n),e.ref!==t.ref&&(t.effectTag|=128)}else{if(!c)return null===t.stateNode&&r("166"),null;if(e=p(),v(t))m(t,n,e)&&o(t);else{e=a(_,c,n,e,t);e:for(k=t.child;null!==k;){if(5===k.tag||6===k.tag)l(e,k.stateNode);else if(4!==k.tag&&null!==k.child){k.child.return=k,k=k.child;continue}if(k===t)break;for(;null===k.sibling;){if(null===k.return||k.return===t)break e;k=k.return}k.sibling.return=k.return,k=k.sibling}u(e,_,c,n)&&o(t),t.stateNode=e}null!==t.ref&&(t.effectTag|=128)}return null;case 6:if(e&&null!=t.stateNode)x(e,t,e.memoizedProps,c);else{if("string"!=typeof c)return null===t.stateNode&&r("166"),null;e=d(),n=p(),v(t)?g(t)&&o(t):t.stateNode=i(c,e,n,t)}return null;case 7:(c=t.memoizedProps)||r("165"),t.tag=8,_=[];e:for((k=t.stateNode)&&(k.return=t);null!==k;){if(5===k.tag||6===k.tag||4===k.tag)r("247");else if(9===k.tag)_.push(k.type);else if(null!==k.child){k.child.return=k,k=k.child;continue}for(;null===k.sibling;){if(null===k.return||k.return===t)break e;k=k.return}k.sibling.return=k.return,k=k.sibling}return k=c.handler,c=k(c.props,_),t.child=Oo(t,null!==e?e.child:null,c,n),t.child;case 8:return t.tag=7,null;case 9:case 10:return null;case 4:return h(t),y(t),null;case 0:r("167");default:r("156")}}}}function Nt(e,t){function n(e){var n=e.ref;if(null!==n)try{n(null)}catch(n){t(e,n)}}function o(e){switch("function"==typeof gt&&gt(e),e.tag){case 2:n(e);var r=e.stateNode;if("function"==typeof r.componentWillUnmount)try{r.props=e.memoizedProps,r.state=e.memoizedState,r.componentWillUnmount()}catch(n){t(e,n)}break;case 5:n(e);break;case 7:a(e.stateNode);break;case 4:s&&l(e)}}function a(e){for(var t=e;;)if(o(t),null===t.child||s&&4===t.tag){if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return;t=t.return}t.sibling.return=t.return,t=t.sibling}else t.child.return=t,t=t.child}function i(e){return 5===e.tag||3===e.tag||4===e.tag}function l(e){for(var t=e,n=!1,i=void 0,l=void 0;;){if(!n){n=t.return;e:for(;;){switch(null===n&&r("160"),n.tag){case 5:i=n.stateNode,l=!1;break e;case 3:case 4:i=n.stateNode.containerInfo,l=!0;break e}n=n.return}n=!0}if(5===t.tag||6===t.tag)a(t),l?b(i,t.stateNode):y(i,t.stateNode);else if(4===t.tag?i=t.stateNode.containerInfo:o(t),null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return;t=t.return,4===t.tag&&(n=!1)}t.sibling.return=t.return,t=t.sibling}}var u=e.getPublicInstance,s=e.mutation;e=e.persistence,s||r(e?"235":"236");var c=s.commitMount,d=s.commitUpdate,f=s.resetTextContent,p=s.commitTextUpdate,h=s.appendChild,m=s.appendChildToContainer,g=s.insertBefore,v=s.insertInContainerBefore,y=s.removeChild,b=s.removeChildFromContainer;return{commitResetTextContent:function(e){f(e.stateNode)},commitPlacement:function(e){e:{for(var t=e.return;null!==t;){if(i(t)){var n=t;break e}t=t.return}r("160"),n=void 0}var o=t=void 0;switch(n.tag){case 5:t=n.stateNode,o=!1;break;case 3:case 4:t=n.stateNode.containerInfo,o=!0;break;default:r("161")}16&n.effectTag&&(f(t),n.effectTag&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||i(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag;){if(2&n.effectTag)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.effectTag)){n=n.stateNode;break e}}for(var a=e;;){if(5===a.tag||6===a.tag)n?o?v(t,a.stateNode,n):g(t,a.stateNode,n):o?m(t,a.stateNode):h(t,a.stateNode);else if(4!==a.tag&&null!==a.child){a.child.return=a,a=a.child;continue}if(a===e)break;for(;null===a.sibling;){if(null===a.return||a.return===e)return;a=a.return}a.sibling.return=a.return,a=a.sibling}},commitDeletion:function(e){l(e),e.return=null,e.child=null,e.alternate&&(e.alternate.child=null,e.alternate.return=null)},commitWork:function(e,t){switch(t.tag){case 2:break;case 5:var n=t.stateNode;if(null!=n){var o=t.memoizedProps;e=null!==e?e.memoizedProps:o;var a=t.type,i=t.updateQueue;t.updateQueue=null,null!==i&&d(n,i,a,e,o,t)}break;case 6:null===t.stateNode&&r("162"),n=t.memoizedProps,p(t.stateNode,null!==e?e.memoizedProps:n,n);break;case 3:break;default:r("163")}},commitLifeCycles:function(e,t){switch(t.tag){case 2:var n=t.stateNode;if(4&t.effectTag)if(null===e)n.props=t.memoizedProps,n.state=t.memoizedState,n.componentDidMount();else{var o=e.memoizedProps;e=e.memoizedState,n.props=t.memoizedProps,n.state=t.memoizedState,n.componentDidUpdate(o,e)}t=t.updateQueue,null!==t&&kt(t,n);break;case 3:n=t.updateQueue,null!==n&&kt(n,null!==t.child?t.child.stateNode:null);break;case 5:n=t.stateNode,null===e&&4&t.effectTag&&c(n,t.type,t.memoizedProps,t);break;case 6:case 4:break;default:r("163")}},commitAttachRef:function(e){var t=e.ref;if(null!==t){var n=e.stateNode;switch(e.tag){case 5:t(u(n));break;default:t(n)}}},commitDetachRef:function(e){null!==(e=e.ref)&&e(null)}}}function Pt(e){function t(e){return e===So&&r("174"),e}var n=e.getChildHostContext,o=e.getRootHostContext,a={current:So},i={current:So},l={current:So};return{getHostContext:function(){return t(a.current)},getRootHostContainer:function(){return t(l.current)},popHostContainer:function(e){qe(a,e),qe(i,e),qe(l,e)},popHostContext:function(e){i.current===e&&(qe(a,e),qe(i,e))},pushHostContainer:function(e,t){Qe(l,t,e),t=o(t),Qe(i,e,e),Qe(a,t,e)},pushHostContext:function(e){var r=t(l.current),o=t(a.current);r=n(o,e.type,r),o!==r&&(Qe(i,e,e),Qe(a,r,e))},resetHostContainer:function(){a.current=So,l.current=So}}}function Lt(e){function t(e,t){var n=new at(5,null,0);n.type="DELETED",n.stateNode=t,n.return=e,n.effectTag=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function n(e,t){switch(e.tag){case 5:return null!==(t=i(t,e.type,e.pendingProps))&&(e.stateNode=t,!0);case 6:return null!==(t=l(t,e.pendingProps))&&(e.stateNode=t,!0);default:return!1}}function o(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag;)e=e.return;f=e}var a=e.shouldSetTextContent;if(!(e=e.hydration))return{enterHydrationState:function(){return!1},resetHydrationState:function(){},tryToClaimNextHydratableInstance:function(){},prepareToHydrateHostInstance:function(){r("175")},prepareToHydrateHostTextInstance:function(){r("176")},popHydrationState:function(){return!1}};var i=e.canHydrateInstance,l=e.canHydrateTextInstance,u=e.getNextHydratableSibling,s=e.getFirstHydratableChild,c=e.hydrateInstance,d=e.hydrateTextInstance,f=null,p=null,h=!1;return{enterHydrationState:function(e){return p=s(e.stateNode.containerInfo),f=e,h=!0},resetHydrationState:function(){p=f=null,h=!1},tryToClaimNextHydratableInstance:function(e){if(h){var r=p;if(r){if(!n(e,r)){if(!(r=u(r))||!n(e,r))return e.effectTag|=2,h=!1,void(f=e);t(f,p)}f=e,p=s(r)}else e.effectTag|=2,h=!1,f=e}},prepareToHydrateHostInstance:function(e,t,n){return t=c(e.stateNode,e.type,e.memoizedProps,t,n,e),e.updateQueue=t,null!==t},prepareToHydrateHostTextInstance:function(e){return d(e.stateNode,e.memoizedProps,e)},popHydrationState:function(e){if(e!==f)return!1;if(!h)return o(e),h=!0,!1;var n=e.type;if(5!==e.tag||"head"!==n&&"body"!==n&&!a(n,e.memoizedProps))for(n=p;n;)t(e,n),n=u(n);return o(e),p=f?u(e.stateNode):null,!0}}}function It(e){function t(e){ae=q=!0;var t=e.stateNode;if(t.current===e&&r("177"),t.isReadyForCommit=!1,Kr.current=null,1<e.effectTag)if(null!==e.lastEffect){e.lastEffect.nextEffect=e;var n=e.firstEffect}else n=e;else n=e.firstEffect;for(V(),X=n;null!==X;){var o=!1,a=void 0;try{for(;null!==X;){var i=X.effectTag;if(16&i&&I(X),128&i){var l=X.alternate;null!==l&&F(l)}switch(-242&i){case 2:R(X),X.effectTag&=-3;break;case 6:R(X),X.effectTag&=-3,D(X.alternate,X);break;case 4:D(X.alternate,X);break;case 8:ie=!0,A(X),ie=!1}X=X.nextEffect}}catch(e){o=!0,a=e}o&&(null===X&&r("178"),u(X,a),null!==X&&(X=X.nextEffect))}for(W(),t.current=e,X=n;null!==X;){n=!1,o=void 0;try{for(;null!==X;){var s=X.effectTag;if(36&s&&j(X.alternate,X),128&s&&U(X),64&s)switch(a=X,i=void 0,null!==ee&&(i=ee.get(a),ee.delete(a),null==i&&null!==a.alternate&&(a=a.alternate,i=ee.get(a),ee.delete(a))),null==i&&r("184"),a.tag){case 2:a.stateNode.componentDidCatch(i.error,{componentStack:i.componentStack});break;case 3:null===re&&(re=i.error);break;default:r("157")}var c=X.nextEffect;X.nextEffect=null,X=c}}catch(e){n=!0,o=e}n&&(null===X&&r("178"),u(X,o),null!==X&&(X=X.nextEffect))}return q=ae=!1,"function"==typeof mt&&mt(e.stateNode),ne&&(ne.forEach(m),ne=null),null!==re&&(e=re,re=null,w(e)),t=t.current.expirationTime,0===t&&(te=ee=null),t}function n(e){for(;;){var t=L(e.alternate,e,J),n=e.return,r=e.sibling,o=e;if(2147483647===J||2147483647!==o.expirationTime){if(2!==o.tag&&3!==o.tag)var a=0;else a=o.updateQueue,a=null===a?0:a.expirationTime;for(var i=o.child;null!==i;)0!==i.expirationTime&&(0===a||a>i.expirationTime)&&(a=i.expirationTime),i=i.sibling;o.expirationTime=a}if(null!==t)return t;if(null!==n&&(null===n.firstEffect&&(n.firstEffect=e.firstEffect),null!==e.lastEffect&&(null!==n.lastEffect&&(n.lastEffect.nextEffect=e.firstEffect),n.lastEffect=e.lastEffect),1<e.effectTag&&(null!==n.lastEffect?n.lastEffect.nextEffect=e:n.firstEffect=e,n.lastEffect=e)),null!==r)return r;if(null===n){e.stateNode.isReadyForCommit=!0;break}e=n}return null}function o(e){var t=N(e.alternate,e,J);return null===t&&(t=n(e)),Kr.current=null,t}function a(e){var t=P(e.alternate,e,J);return null===t&&(t=n(e)),Kr.current=null,t}function i(e){if(null!==ee){if(!(0===J||J>e))if(J<=G)for(;null!==Q;)Q=s(Q)?a(Q):o(Q);else for(;null!==Q&&!k();)Q=s(Q)?a(Q):o(Q)}else if(!(0===J||J>e))if(J<=G)for(;null!==Q;)Q=o(Q);else for(;null!==Q&&!k();)Q=o(Q)}function l(e,t){if(q&&r("243"),q=!0,e.isReadyForCommit=!1,e!==$||t!==J||null===Q){for(;-1<po;)fo[po]=null,po--;go=Mn,ho.current=Mn,mo.current=!1,M(),$=e,J=t,Q=it($.current,null,t)}var n=!1,o=null;try{i(t)}catch(e){n=!0,o=e}for(;n;){if(oe){re=o;break}var l=Q;if(null===l)oe=!0;else{var s=u(l,o);if(null===s&&r("183"),!oe){try{for(n=s,o=t,s=n;null!==l;){switch(l.tag){case 2:et(l);break;case 5:O(l);break;case 3:T(l);break;case 4:T(l)}if(l===s||l.alternate===s)break;l=l.return}Q=a(n),i(o)}catch(e){n=!0,o=e;continue}break}}}return t=re,oe=q=!1,re=null,null!==t&&w(t),e.isReadyForCommit?e.current.alternate:null}function u(e,t){var n=Kr.current=null,r=!1,o=!1,a=null;if(3===e.tag)n=e,c(e)&&(oe=!0);else for(var i=e.return;null!==i&&null===n;){if(2===i.tag?"function"==typeof i.stateNode.componentDidCatch&&(r=!0,a=_e(i),n=i,o=!0):3===i.tag&&(n=i),c(i)){if(ie||null!==ne&&(ne.has(i)||null!==i.alternate&&ne.has(i.alternate)))return null;n=null,o=!1}i=i.return}if(null!==n){null===te&&(te=new Set),te.add(n);var l="";i=e;do{e:switch(i.tag){case 0:case 1:case 2:case 5:var u=i._debugOwner,s=i._debugSource,d=_e(i),f=null;u&&(f=_e(u)),u=s,d="\n    in "+(d||"Unknown")+(u?" (at "+u.fileName.replace(/^.*[\\\/]/,"")+":"+u.lineNumber+")":f?" (created by "+f+")":"");break e;default:d=""}l+=d,i=i.return}while(i);i=l,e=_e(e),null===ee&&(ee=new Map),t={componentName:e,componentStack:i,error:t,errorBoundary:r?n.stateNode:null,errorBoundaryFound:r,errorBoundaryName:a,willRetry:o},ee.set(n,t);try{var p=t.error;p&&p.suppressReactErrorLogging||console.error(p)}catch(e){e&&e.suppressReactErrorLogging||console.error(e)}return ae?(null===ne&&(ne=new Set),ne.add(n)):m(n),n}return null===re&&(re=t),null}function s(e){return null!==ee&&(ee.has(e)||null!==e.alternate&&ee.has(e.alternate))}function c(e){return null!==te&&(te.has(e)||null!==e.alternate&&te.has(e.alternate))}function d(){return 20*(1+((g()+100)/20|0))}function f(e){return 0!==Y?Y:q?ae?1:J:!z||1&e.internalContextTag?d():1}function p(e,t){return h(e,t,!1)}function h(e,t){for(;null!==e;){if((0===e.expirationTime||e.expirationTime>t)&&(e.expirationTime=t),null!==e.alternate&&(0===e.alternate.expirationTime||e.alternate.expirationTime>t)&&(e.alternate.expirationTime=t),null===e.return){if(3!==e.tag)break;var n=e.stateNode;!q&&n===$&&t<J&&(Q=$=null,J=0);var o=n,a=t;if(ke>xe&&r("185"),null===o.nextScheduledRoot)o.remainingExpirationTime=a,null===ue?(le=ue=o,o.nextScheduledRoot=o):(ue=ue.nextScheduledRoot=o,ue.nextScheduledRoot=le);else{var i=o.remainingExpirationTime;(0===i||a<i)&&(o.remainingExpirationTime=a)}de||(ye?be&&(fe=o,pe=1,_(fe,pe)):1===a?x(1,null):v(a)),!q&&n===$&&t<J&&(Q=$=null,J=0)}e=e.return}}function m(e){h(e,1,!0)}function g(){return G=2+((H()-Z)/10|0)}function v(e){if(0!==se){if(e>se)return;B(ce)}var t=H()-Z;se=e,ce=K(b,{timeout:10*(e-2)-t})}function y(){var e=0,t=null;if(null!==ue)for(var n=ue,o=le;null!==o;){var a=o.remainingExpirationTime;if(0===a){if((null===n||null===ue)&&r("244"),o===o.nextScheduledRoot){le=ue=o.nextScheduledRoot=null;break}if(o===le)le=a=o.nextScheduledRoot,ue.nextScheduledRoot=a,o.nextScheduledRoot=null;else{if(o===ue){ue=n,ue.nextScheduledRoot=le,o.nextScheduledRoot=null;break}n.nextScheduledRoot=o.nextScheduledRoot,o.nextScheduledRoot=null}o=n.nextScheduledRoot}else{if((0===e||a<e)&&(e=a,t=o),o===ue)break;n=o,o=o.nextScheduledRoot}}n=fe,null!==n&&n===t?ke++:ke=0,fe=t,pe=e}function b(e){x(0,e)}function x(e,t){for(ve=t,y();null!==fe&&0!==pe&&(0===e||pe<=e)&&!he;)_(fe,pe),y();if(null!==ve&&(se=0,ce=-1),0!==pe&&v(pe),ve=null,he=!1,ke=0,me)throw e=ge,ge=null,me=!1,e}function _(e,n){if(de&&r("245"),de=!0,n<=g()){var o=e.finishedWork;null!==o?(e.finishedWork=null,e.remainingExpirationTime=t(o)):(e.finishedWork=null,null!==(o=l(e,n))&&(e.remainingExpirationTime=t(o)))}else o=e.finishedWork,null!==o?(e.finishedWork=null,e.remainingExpirationTime=t(o)):(e.finishedWork=null,null!==(o=l(e,n))&&(k()?e.finishedWork=o:e.remainingExpirationTime=t(o)));de=!1}function k(){return!(null===ve||ve.timeRemaining()>we)&&(he=!0)}function w(e){null===fe&&r("246"),fe.remainingExpirationTime=0,me||(me=!0,ge=e)}var C=Pt(e),E=Lt(e),T=C.popHostContainer,O=C.popHostContext,M=C.resetHostContainer,S=Mt(e,C,E,p,f),N=S.beginWork,P=S.beginFailedWork,L=St(e,C,E).completeWork;C=Nt(e,u);var I=C.commitResetTextContent,R=C.commitPlacement,A=C.commitDeletion,D=C.commitWork,j=C.commitLifeCycles,U=C.commitAttachRef,F=C.commitDetachRef,H=e.now,K=e.scheduleDeferredCallback,B=e.cancelDeferredCallback,z=e.useSyncScheduling,V=e.prepareForCommit,W=e.resetAfterCommit,Z=H(),G=2,Y=0,q=!1,Q=null,$=null,J=0,X=null,ee=null,te=null,ne=null,re=null,oe=!1,ae=!1,ie=!1,le=null,ue=null,se=0,ce=-1,de=!1,fe=null,pe=0,he=!1,me=!1,ge=null,ve=null,ye=!1,be=!1,xe=1e3,ke=0,we=1;return{computeAsyncExpiration:d,computeExpirationForFiber:f,scheduleWork:p,batchedUpdates:function(e,t){var n=ye;ye=!0;try{return e(t)}finally{(ye=n)||de||x(1,null)}},unbatchedUpdates:function(e){if(ye&&!be){be=!0;try{return e()}finally{be=!1}}return e()},flushSync:function(e){var t=ye;ye=!0;try{e:{var n=Y;Y=1;try{var o=e();break e}finally{Y=n}o=void 0}return o}finally{ye=t,de&&r("187"),x(1,null)}},deferredUpdates:function(e){var t=Y;Y=d();try{return e()}finally{Y=t}}}}function Rt(e){function t(e){return e=Te(e),null===e?null:e.stateNode}var n=e.getPublicInstance;e=It(e);var o=e.computeAsyncExpiration,a=e.computeExpirationForFiber,i=e.scheduleWork;return{createContainer:function(e,t){var n=new at(3,null,0);return e={current:n,containerInfo:e,pendingChildren:null,remainingExpirationTime:0,isReadyForCommit:!1,finishedWork:null,context:null,pendingContext:null,hydrate:t,nextScheduledRoot:null},n.stateNode=e},updateContainer:function(e,t,n,l){var u=t.current;if(n){n=n._reactInternalFiber;var s;e:{for(2===ke(n)&&2===n.tag||r("170"),s=n;3!==s.tag;){if(Xe(s)){s=s.stateNode.__reactInternalMemoizedMergedChildContext;break e}(s=s.return)||r("171")}s=s.stateNode.context}n=Xe(n)?nt(n,s):s}else n=Mn;null===t.context?t.context=n:t.pendingContext=n,t=l,t=void 0===t?null:t,l=null!=e&&null!=e.type&&null!=e.type.prototype&&!0===e.type.prototype.unstable_isAsyncReactComponent?o():a(u),bt(u,{expirationTime:l,partialState:{element:e},callback:t,isReplace:!1,isForced:!1,nextCallback:null,next:null}),i(u,l)},batchedUpdates:e.batchedUpdates,unbatchedUpdates:e.unbatchedUpdates,deferredUpdates:e.deferredUpdates,flushSync:e.flushSync,getPublicRootInstance:function(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return n(e.child.stateNode);default:return e.child.stateNode}},findHostInstance:t,findHostInstanceWithNoPortals:function(e){return e=Oe(e),null===e?null:e.stateNode},injectIntoDevTools:function(e){var n=e.findFiberByHostInstance;return ht(_n({},e,{findHostInstanceByFiber:function(e){return t(e)},findFiberByHostInstance:function(e){return n?n(e):null}}))}}}function At(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:wo,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}function Dt(e){return!!qo.hasOwnProperty(e)||!Yo.hasOwnProperty(e)&&(Go.test(e)?qo[e]=!0:(Yo[e]=!0,!1))}function jt(e,t,n){var r=i(t);if(r&&a(t,n)){var o=r.mutationMethod;o?o(e,n):null==n||r.hasBooleanValue&&!n||r.hasNumericValue&&isNaN(n)||r.hasPositiveNumericValue&&1>n||r.hasOverloadedBooleanValue&&!1===n?Ft(e,t):r.mustUseProperty?e[r.propertyName]=n:(t=r.attributeName,(o=r.attributeNamespace)?e.setAttributeNS(o,t,""+n):r.hasBooleanValue||r.hasOverloadedBooleanValue&&!0===n?e.setAttribute(t,""):e.setAttribute(t,""+n))}else Ut(e,t,a(t,n)?n:null)}function Ut(e,t,n){Dt(t)&&(null==n?e.removeAttribute(t):e.setAttribute(t,""+n))}function Ft(e,t){var n=i(t);n?(t=n.mutationMethod)?t(e,void 0):n.mustUseProperty?e[n.propertyName]=!n.hasBooleanValue&&"":e.removeAttribute(n.attributeName):e.removeAttribute(t)}function Ht(e,t){var n=t.value,r=t.checked;return _n({type:void 0,step:void 0,min:void 0,max:void 0},t,{defaultChecked:void 0,defaultValue:void 0,value:null!=n?n:e._wrapperState.initialValue,checked:null!=r?r:e._wrapperState.initialChecked})}function Kt(e,t){var n=t.defaultValue;e._wrapperState={initialChecked:null!=t.checked?t.checked:t.defaultChecked,initialValue:null!=t.value?t.value:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Bt(e,t){null!=(t=t.checked)&&jt(e,"checked",t)}function zt(e,t){Bt(e,t);var n=t.value;null!=n?0===n&&""===e.value?e.value="0":"number"===t.type?(t=parseFloat(e.value)||0,(n!=t||n==t&&e.value!=n)&&(e.value=""+n)):e.value!==""+n&&(e.value=""+n):(null==t.value&&null!=t.defaultValue&&e.defaultValue!==""+t.defaultValue&&(e.defaultValue=""+t.defaultValue),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked))}function Vt(e,t){switch(t.type){case"submit":case"reset":break;case"color":case"date":case"datetime":case"datetime-local":case"month":case"time":case"week":e.value="",e.value=e.defaultValue;break;default:e.value=e.value}t=e.name,""!==t&&(e.name=""),e.defaultChecked=!e.defaultChecked,e.defaultChecked=!e.defaultChecked,""!==t&&(e.name=t)}function Wt(e){var t="";return bn.Children.forEach(e,function(e){null==e||"string"!=typeof e&&"number"!=typeof e||(t+=e)}),t}function Zt(e,t){return e=_n({children:void 0},t),(t=Wt(t.children))&&(e.children=t),e}function Gt(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+n,t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function Yt(e,t){var n=t.value;e._wrapperState={initialValue:null!=n?n:t.defaultValue,wasMultiple:!!t.multiple}}function qt(e,t){return null!=t.dangerouslySetInnerHTML&&r("91"),_n({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function Qt(e,t){var n=t.value;null==n&&(n=t.defaultValue,t=t.children,null!=t&&(null!=n&&r("92"),Array.isArray(t)&&(1>=t.length||r("93"),t=t[0]),n=""+t),null==n&&(n="")),e._wrapperState={initialValue:""+n}}function $t(e,t){var n=t.value;null!=n&&(n=""+n,n!==e.value&&(e.value=n),null==t.defaultValue&&(e.defaultValue=n)),null!=t.defaultValue&&(e.defaultValue=t.defaultValue)}function Jt(e){var t=e.textContent;t===e._wrapperState.initialValue&&(e.value=t)}function Xt(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function en(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?Xt(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}function tn(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}function nn(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=n,a=t[n];o=null==a||"boolean"==typeof a||""===a?"":r||"number"!=typeof a||0===a||Xo.hasOwnProperty(o)&&Xo[o]?(""+a).trim():a+"px","float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}function rn(e,t,n){t&&(ta[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML)&&r("137",e,n()),null!=t.dangerouslySetInnerHTML&&(null!=t.children&&r("60"),"object"==typeof t.dangerouslySetInnerHTML&&"__html"in t.dangerouslySetInnerHTML||r("61")),null!=t.style&&"object"!=typeof t.style&&r("62",n()))}function on(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function an(e,t){e=9===e.nodeType||11===e.nodeType?e:e.ownerDocument;var n=Ae(e);t=Qn[t];for(var r=0;r<t.length;r++){var o=t[r];n.hasOwnProperty(o)&&n[o]||("topScroll"===o?Pe("topScroll","scroll",e):"topFocus"===o||"topBlur"===o?(Pe("topFocus","focus",e),Pe("topBlur","blur",e),n.topBlur=!0,n.topFocus=!0):"topCancel"===o?(ne("cancel",!0)&&Pe("topCancel","cancel",e),n.topCancel=!0):"topClose"===o?(ne("close",!0)&&Pe("topClose","close",e),n.topClose=!0):qr.hasOwnProperty(o)&&Ne(o,qr[o],e),n[o]=!0)}}function ln(e,t,n,r){return n=9===n.nodeType?n:n.ownerDocument,r===na&&(r=Xt(e)),r===na?"script"===e?(e=n.createElement("div"),e.innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):e="string"==typeof t.is?n.createElement(e,{is:t.is}):n.createElement(e):e=n.createElementNS(r,e),e}function un(e,t){return(9===t.nodeType?t:t.ownerDocument).createTextNode(e)}function sn(e,t,n,r){var o=on(t,n);switch(t){case"iframe":case"object":Ne("topLoad","load",e);var a=n;break;case"video":case"audio":for(a in oa)oa.hasOwnProperty(a)&&Ne(a,oa[a],e);a=n;break;case"source":Ne("topError","error",e),a=n;break;case"img":case"image":Ne("topError","error",e),Ne("topLoad","load",e),a=n;break;case"form":Ne("topReset","reset",e),Ne("topSubmit","submit",e),a=n;break;case"details":Ne("topToggle","toggle",e),a=n;break;case"input":Kt(e,n),a=Ht(e,n),Ne("topInvalid","invalid",e),an(r,"onChange");break;case"option":a=Zt(e,n);break;case"select":Yt(e,n),a=_n({},n,{value:void 0}),Ne("topInvalid","invalid",e),an(r,"onChange");break;case"textarea":Qt(e,n),a=qt(e,n),Ne("topInvalid","invalid",e),an(r,"onChange");break;default:a=n}rn(t,a,ra);var i,l=a;for(i in l)if(l.hasOwnProperty(i)){var u=l[i];"style"===i?nn(e,u,ra):"dangerouslySetInnerHTML"===i?null!=(u=u?u.__html:void 0)&&Jo(e,u):"children"===i?"string"==typeof u?("textarea"!==t||""!==u)&&tn(e,u):"number"==typeof u&&tn(e,""+u):"suppressContentEditableWarning"!==i&&"suppressHydrationWarning"!==i&&"autoFocus"!==i&&(qn.hasOwnProperty(i)?null!=u&&an(r,i):o?Ut(e,i,u):null!=u&&jt(e,i,u))}switch(t){case"input":ae(e),Vt(e,n);break;case"textarea":ae(e),Jt(e,n);break;case"option":null!=n.value&&e.setAttribute("value",n.value);break;case"select":e.multiple=!!n.multiple,t=n.value,null!=t?Gt(e,!!n.multiple,t,!1):null!=n.defaultValue&&Gt(e,!!n.multiple,n.defaultValue,!0);break;default:"function"==typeof a.onClick&&(e.onclick=kn)}}function cn(e,t,n,r,o){var a=null;switch(t){case"input":n=Ht(e,n),r=Ht(e,r),a=[];break;case"option":n=Zt(e,n),r=Zt(e,r),a=[];break;case"select":n=_n({},n,{value:void 0}),r=_n({},r,{value:void 0}),a=[];break;case"textarea":n=qt(e,n),r=qt(e,r),a=[];break;default:"function"!=typeof n.onClick&&"function"==typeof r.onClick&&(e.onclick=kn)}rn(t,r,ra);var i,l;e=null;for(i in n)if(!r.hasOwnProperty(i)&&n.hasOwnProperty(i)&&null!=n[i])if("style"===i)for(l in t=n[i])t.hasOwnProperty(l)&&(e||(e={}),e[l]="");else"dangerouslySetInnerHTML"!==i&&"children"!==i&&"suppressContentEditableWarning"!==i&&"suppressHydrationWarning"!==i&&"autoFocus"!==i&&(qn.hasOwnProperty(i)?a||(a=[]):(a=a||[]).push(i,null));for(i in r){var u=r[i];if(t=null!=n?n[i]:void 0,r.hasOwnProperty(i)&&u!==t&&(null!=u||null!=t))if("style"===i)if(t){for(l in t)!t.hasOwnProperty(l)||u&&u.hasOwnProperty(l)||(e||(e={}),e[l]="");for(l in u)u.hasOwnProperty(l)&&t[l]!==u[l]&&(e||(e={}),e[l]=u[l])}else e||(a||(a=[]),a.push(i,e)),e=u;else"dangerouslySetInnerHTML"===i?(u=u?u.__html:void 0,t=t?t.__html:void 0,null!=u&&t!==u&&(a=a||[]).push(i,""+u)):"children"===i?t===u||"string"!=typeof u&&"number"!=typeof u||(a=a||[]).push(i,""+u):"suppressContentEditableWarning"!==i&&"suppressHydrationWarning"!==i&&(qn.hasOwnProperty(i)?(null!=u&&an(o,i),a||t===u||(a=[])):(a=a||[]).push(i,u))}return e&&(a=a||[]).push("style",e),a}function dn(e,t,n,r,o){"input"===n&&"radio"===o.type&&null!=o.name&&Bt(e,o),on(n,r),r=on(n,o);for(var a=0;a<t.length;a+=2){var i=t[a],l=t[a+1];"style"===i?nn(e,l,ra):"dangerouslySetInnerHTML"===i?Jo(e,l):"children"===i?tn(e,l):r?null!=l?Ut(e,i,l):e.removeAttribute(i):null!=l?jt(e,i,l):Ft(e,i)}switch(n){case"input":zt(e,o);break;case"textarea":$t(e,o);break;case"select":e._wrapperState.initialValue=void 0,t=e._wrapperState.wasMultiple,e._wrapperState.wasMultiple=!!o.multiple,n=o.value,null!=n?Gt(e,!!o.multiple,n,!1):t!==!!o.multiple&&(null!=o.defaultValue?Gt(e,!!o.multiple,o.defaultValue,!0):Gt(e,!!o.multiple,o.multiple?[]:"",!1))}}function fn(e,t,n,r,o){switch(t){case"iframe":case"object":Ne("topLoad","load",e);break;case"video":case"audio":for(var a in oa)oa.hasOwnProperty(a)&&Ne(a,oa[a],e);break;case"source":Ne("topError","error",e);break;case"img":case"image":Ne("topError","error",e),Ne("topLoad","load",e);break;case"form":Ne("topReset","reset",e),Ne("topSubmit","submit",e);break;case"details":Ne("topToggle","toggle",e);break;case"input":Kt(e,n),Ne("topInvalid","invalid",e),an(o,"onChange");break;case"select":Yt(e,n),Ne("topInvalid","invalid",e),an(o,"onChange");break;case"textarea":Qt(e,n),Ne("topInvalid","invalid",e),an(o,"onChange")}rn(t,n,ra),r=null;for(var i in n)n.hasOwnProperty(i)&&(a=n[i],"children"===i?"string"==typeof a?e.textContent!==a&&(r=["children",a]):"number"==typeof a&&e.textContent!==""+a&&(r=["children",""+a]):qn.hasOwnProperty(i)&&null!=a&&an(o,i));switch(t){case"input":ae(e),Vt(e,n);break;case"textarea":ae(e),Jt(e,n);break;case"select":case"option":break;default:"function"==typeof n.onClick&&(e.onclick=kn)}return r}function pn(e,t){return e.nodeValue!==t}function hn(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function mn(e){return!(!(e=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==e.nodeType||!e.hasAttribute("data-reactroot"))}function gn(e,t,n,o,a){hn(n)||r("200");var i=n._reactRootContainer;if(i)ua.updateContainer(t,i,e,a);else{if(!(o=o||mn(n)))for(i=void 0;i=n.lastChild;)n.removeChild(i);var l=ua.createContainer(n,o);i=n._reactRootContainer=l,ua.unbatchedUpdates(function(){ua.updateContainer(t,l,e,a)})}return ua.getPublicRootInstance(i)}function vn(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;return hn(t)||r("200"),At(e,t,null,n)}function yn(e,t){this._reactRootContainer=ua.createContainer(e,t)}/** @license React v16.2.0
 * react-dom.production.min.js
 *
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
var bn=n(0),xn=n(23),_n=n(12),kn=n(8),wn=n(24),Cn=n(25),En=n(26),Tn=n(27),On=n(30),Mn=n(13);bn||r("227");var Sn={children:!0,dangerouslySetInnerHTML:!0,defaultValue:!0,defaultChecked:!0,innerHTML:!0,suppressContentEditableWarning:!0,suppressHydrationWarning:!0,style:!0},Nn={MUST_USE_PROPERTY:1,HAS_BOOLEAN_VALUE:4,HAS_NUMERIC_VALUE:8,HAS_POSITIVE_NUMERIC_VALUE:24,HAS_OVERLOADED_BOOLEAN_VALUE:32,HAS_STRING_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(e){var t=Nn,n=e.Properties||{},a=e.DOMAttributeNamespaces||{},i=e.DOMAttributeNames||{};e=e.DOMMutationMethods||{};for(var l in n){Pn.hasOwnProperty(l)&&r("48",l);var u=l.toLowerCase(),s=n[l];u={attributeName:u,attributeNamespace:null,propertyName:l,mutationMethod:null,mustUseProperty:o(s,t.MUST_USE_PROPERTY),hasBooleanValue:o(s,t.HAS_BOOLEAN_VALUE),hasNumericValue:o(s,t.HAS_NUMERIC_VALUE),hasPositiveNumericValue:o(s,t.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:o(s,t.HAS_OVERLOADED_BOOLEAN_VALUE),hasStringBooleanValue:o(s,t.HAS_STRING_BOOLEAN_VALUE)},1>=u.hasBooleanValue+u.hasNumericValue+u.hasOverloadedBooleanValue||r("50",l),i.hasOwnProperty(l)&&(u.attributeName=i[l]),a.hasOwnProperty(l)&&(u.attributeNamespace=a[l]),e.hasOwnProperty(l)&&(u.mutationMethod=e[l]),Pn[l]=u}}},Pn={},Ln=Nn,In=Ln.MUST_USE_PROPERTY,Rn=Ln.HAS_BOOLEAN_VALUE,An=Ln.HAS_NUMERIC_VALUE,Dn=Ln.HAS_POSITIVE_NUMERIC_VALUE,jn=Ln.HAS_OVERLOADED_BOOLEAN_VALUE,Un=Ln.HAS_STRING_BOOLEAN_VALUE,Fn={Properties:{allowFullScreen:Rn,async:Rn,autoFocus:Rn,autoPlay:Rn,capture:jn,checked:In|Rn,cols:Dn,contentEditable:Un,controls:Rn,default:Rn,defer:Rn,disabled:Rn,download:jn,draggable:Un,formNoValidate:Rn,hidden:Rn,loop:Rn,multiple:In|Rn,muted:In|Rn,noValidate:Rn,open:Rn,playsInline:Rn,readOnly:Rn,required:Rn,reversed:Rn,rows:Dn,rowSpan:An,scoped:Rn,seamless:Rn,selected:In|Rn,size:Dn,start:An,span:Dn,spellCheck:Un,style:0,tabIndex:0,itemScope:Rn,acceptCharset:0,className:0,htmlFor:0,httpEquiv:0,value:Un},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMMutationMethods:{value:function(e,t){if(null==t)return e.removeAttribute("value");"number"!==e.type||!1===e.hasAttribute("value")?e.setAttribute("value",""+t):e.validity&&!e.validity.badInput&&e.ownerDocument.activeElement!==e&&e.setAttribute("value",""+t)}}},Hn=Ln.HAS_STRING_BOOLEAN_VALUE,Kn={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace"},Bn={Properties:{autoReverse:Hn,externalResourcesRequired:Hn,preserveAlpha:Hn},DOMAttributeNames:{autoReverse:"autoReverse",externalResourcesRequired:"externalResourcesRequired",preserveAlpha:"preserveAlpha"},DOMAttributeNamespaces:{xlinkActuate:Kn.xlink,xlinkArcrole:Kn.xlink,xlinkHref:Kn.xlink,xlinkRole:Kn.xlink,xlinkShow:Kn.xlink,xlinkTitle:Kn.xlink,xlinkType:Kn.xlink,xmlBase:Kn.xml,xmlLang:Kn.xml,xmlSpace:Kn.xml}},zn=/[\-\:]([a-z])/g;"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode x-height xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xmlns:xlink xml:lang xml:space".split(" ").forEach(function(e){var t=e.replace(zn,l);Bn.Properties[t]=0,Bn.DOMAttributeNames[t]=e}),Ln.injectDOMPropertyConfig(Fn),Ln.injectDOMPropertyConfig(Bn);var Vn={_caughtError:null,_hasCaughtError:!1,_rethrowError:null,_hasRethrowError:!1,injection:{injectErrorUtils:function(e){"function"!=typeof e.invokeGuardedCallback&&r("197"),u=e.invokeGuardedCallback}},invokeGuardedCallback:function(e,t,n,r,o,a,i,l,s){u.apply(Vn,arguments)},invokeGuardedCallbackAndCatchFirstError:function(e,t,n,r,o,a,i,l,u){if(Vn.invokeGuardedCallback.apply(this,arguments),Vn.hasCaughtError()){var s=Vn.clearCaughtError();Vn._hasRethrowError||(Vn._hasRethrowError=!0,Vn._rethrowError=s)}},rethrowCaughtError:function(){return s.apply(Vn,arguments)},hasCaughtError:function(){return Vn._hasCaughtError},clearCaughtError:function(){if(Vn._hasCaughtError){var e=Vn._caughtError;return Vn._caughtError=null,Vn._hasCaughtError=!1,e}r("198")}},Wn=null,Zn={},Gn=[],Yn={},qn={},Qn={},$n=Object.freeze({plugins:Gn,eventNameDispatchConfigs:Yn,registrationNameModules:qn,registrationNameDependencies:Qn,possibleRegistrationNames:null,injectEventPluginOrder:f,injectEventPluginsByName:p}),Jn=null,Xn=null,er=null,tr=null,nr={injectEventPluginOrder:f,injectEventPluginsByName:p},rr=Object.freeze({injection:nr,getListener:x,extractEvents:_,enqueueEvents:k,processEventQueue:w}),or=Math.random().toString(36).slice(2),ar="__reactInternalInstance$"+or,ir="__reactEventHandlers$"+or,lr=Object.freeze({precacheFiberNode:function(e,t){t[ar]=e},getClosestInstanceFromNode:C,getInstanceFromNode:function(e){return e=e[ar],!e||5!==e.tag&&6!==e.tag?null:e},getNodeFromInstance:E,getFiberCurrentPropsFromNode:T,updateFiberProps:function(e,t){e[ir]=t}}),ur=Object.freeze({accumulateTwoPhaseDispatches:R,accumulateTwoPhaseDispatchesSkipTarget:function(e){g(e,P)},accumulateEnterLeaveDispatches:A,accumulateDirectDispatches:function(e){g(e,I)}}),sr=null,cr={_root:null,_startText:null,_fallbackText:null},dr="dispatchConfig _targetInst nativeEvent isDefaultPrevented isPropagationStopped _dispatchListeners _dispatchInstances".split(" "),fr={type:null,target:null,currentTarget:kn.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};_n(F.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=kn.thatReturnsTrue)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=kn.thatReturnsTrue)},persist:function(){this.isPersistent=kn.thatReturnsTrue},isPersistent:kn.thatReturnsFalse,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;for(t=0;t<dr.length;t++)this[dr[t]]=null}}),F.Interface=fr,F.augmentClass=function(e,t){function n(){}n.prototype=this.prototype;var r=new n;_n(r,e.prototype),e.prototype=r,e.prototype.constructor=e,e.Interface=_n({},this.Interface,t),e.augmentClass=this.augmentClass,B(e)},B(F),F.augmentClass(z,{data:null}),F.augmentClass(V,{data:null});var pr=[9,13,27,32],hr=xn.canUseDOM&&"CompositionEvent"in window,mr=null;xn.canUseDOM&&"documentMode"in document&&(mr=document.documentMode);var gr;if(gr=xn.canUseDOM&&"TextEvent"in window&&!mr){var vr=window.opera;gr=!("object"==typeof vr&&"function"==typeof vr.version&&12>=parseInt(vr.version(),10))}var yr,br=gr,xr=xn.canUseDOM&&(!hr||mr&&8<mr&&11>=mr),_r=String.fromCharCode(32),kr={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["topCompositionEnd","topKeyPress","topTextInput","topPaste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"topBlur topCompositionEnd topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"topBlur topCompositionStart topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"topBlur topCompositionUpdate topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")}},wr=!1,Cr=!1,Er={eventTypes:kr,extractEvents:function(e,t,n,r){var o;if(hr)e:{switch(e){case"topCompositionStart":var a=kr.compositionStart;break e;case"topCompositionEnd":a=kr.compositionEnd;break e;case"topCompositionUpdate":a=kr.compositionUpdate;break e}a=void 0}else Cr?W(e,n)&&(a=kr.compositionEnd):"topKeyDown"===e&&229===n.keyCode&&(a=kr.compositionStart);return a?(xr&&(Cr||a!==kr.compositionStart?a===kr.compositionEnd&&Cr&&(o=j()):(cr._root=r,cr._startText=U(),Cr=!0)),a=z.getPooled(a,t,n,r),o?a.data=o:null!==(o=Z(n))&&(a.data=o),R(a),o=a):o=null,(e=br?G(e,n):Y(e,n))?(t=V.getPooled(kr.beforeInput,t,n,r),t.data=e,R(t)):t=null,[o,t]}},Tr=null,Or=null,Mr=null,Sr={injectFiberControlledHostComponent:function(e){Tr=e}},Nr=Object.freeze({injection:Sr,enqueueStateRestore:Q,restoreStateIfNeeded:$}),Pr=!1,Lr={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};xn.canUseDOM&&(yr=document.implementation&&document.implementation.hasFeature&&!0!==document.implementation.hasFeature("",""));var Ir={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:"topBlur topChange topClick topFocus topInput topKeyDown topKeyUp topSelectionChange".split(" ")}},Rr=null,Ar=null,Dr=!1;xn.canUseDOM&&(Dr=ne("input")&&(!document.documentMode||9<document.documentMode));var jr={eventTypes:Ir,_isInputEventSupported:Dr,extractEvents:function(e,t,n,r){var o=t?E(t):window,a=o.nodeName&&o.nodeName.toLowerCase();if("select"===a||"input"===a&&"file"===o.type)var i=ce;else if(ee(o))if(Dr)i=ge;else{i=he;var l=pe}else!(a=o.nodeName)||"input"!==a.toLowerCase()||"checkbox"!==o.type&&"radio"!==o.type||(i=me);if(i&&(i=i(e,t)))return le(i,n,r);l&&l(e,o,t),"topBlur"===e&&null!=t&&(e=t._wrapperState||o._wrapperState)&&e.controlled&&"number"===o.type&&(e=""+o.value,o.getAttribute("value")!==e&&o.setAttribute("value",e))}};F.augmentClass(ve,{view:null,detail:null});var Ur={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};ve.augmentClass(xe,{screenX:null,screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:be,button:null,buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)}});var Fr={mouseEnter:{registrationName:"onMouseEnter",dependencies:["topMouseOut","topMouseOver"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["topMouseOut","topMouseOver"]}},Hr={eventTypes:Fr,extractEvents:function(e,t,n,r){if("topMouseOver"===e&&(n.relatedTarget||n.fromElement)||"topMouseOut"!==e&&"topMouseOver"!==e)return null;var o=r.window===r?r:(o=r.ownerDocument)?o.defaultView||o.parentWindow:window;if("topMouseOut"===e?(e=t,t=(t=n.relatedTarget||n.toElement)?C(t):null):e=null,e===t)return null;var a=null==e?o:E(e);o=null==t?o:E(t);var i=xe.getPooled(Fr.mouseLeave,e,n,r);return i.type="mouseleave",i.target=a,i.relatedTarget=o,n=xe.getPooled(Fr.mouseEnter,t,n,r),n.type="mouseenter",n.target=o,n.relatedTarget=a,A(i,n,e,t),[i,n]}},Kr=bn.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Br=[],zr=!0,Vr=void 0,Wr=Object.freeze({get _enabled(){return zr},get _handleTopLevel(){return Vr},setHandleTopLevel:function(e){Vr=e},setEnabled:Se,isEnabled:function(){return zr},trapBubbledEvent:Ne,trapCapturedEvent:Pe,dispatchEvent:Le}),Zr={animationend:Ie("Animation","AnimationEnd"),animationiteration:Ie("Animation","AnimationIteration"),animationstart:Ie("Animation","AnimationStart"),transitionend:Ie("Transition","TransitionEnd")},Gr={},Yr={};xn.canUseDOM&&(Yr=document.createElement("div").style,"AnimationEvent"in window||(delete Zr.animationend.animation,delete Zr.animationiteration.animation,delete Zr.animationstart.animation),"TransitionEvent"in window||delete Zr.transitionend.transition);var qr={topAbort:"abort",topAnimationEnd:Re("animationend")||"animationend",topAnimationIteration:Re("animationiteration")||"animationiteration",topAnimationStart:Re("animationstart")||"animationstart",topBlur:"blur",topCancel:"cancel",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topChange:"change",topClick:"click",topClose:"close",topCompositionEnd:"compositionend",topCompositionStart:"compositionstart",topCompositionUpdate:"compositionupdate",topContextMenu:"contextmenu",topCopy:"copy",topCut:"cut",topDoubleClick:"dblclick",topDrag:"drag",topDragEnd:"dragend",topDragEnter:"dragenter",topDragExit:"dragexit",topDragLeave:"dragleave",topDragOver:"dragover",topDragStart:"dragstart",topDrop:"drop",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topFocus:"focus",topInput:"input",topKeyDown:"keydown",topKeyPress:"keypress",topKeyUp:"keyup",topLoadedData:"loadeddata",topLoad:"load",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topMouseDown:"mousedown",topMouseMove:"mousemove",topMouseOut:"mouseout",topMouseOver:"mouseover",topMouseUp:"mouseup",topPaste:"paste",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topScroll:"scroll",topSeeked:"seeked",topSeeking:"seeking",topSelectionChange:"selectionchange",topStalled:"stalled",topSuspend:"suspend",topTextInput:"textInput",topTimeUpdate:"timeupdate",topToggle:"toggle",topTouchCancel:"touchcancel",topTouchEnd:"touchend",topTouchMove:"touchmove",topTouchStart:"touchstart",topTransitionEnd:Re("transitionend")||"transitionend",topVolumeChange:"volumechange",topWaiting:"waiting",topWheel:"wheel"},Qr={},$r=0,Jr="_reactListenersID"+(""+Math.random()).slice(2),Xr=xn.canUseDOM&&"documentMode"in document&&11>=document.documentMode,eo={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:"topBlur topContextMenu topFocus topKeyDown topKeyUp topMouseDown topMouseUp topSelectionChange".split(" ")}},to=null,no=null,ro=null,oo=!1,ao={eventTypes:eo,extractEvents:function(e,t,n,r){var o,a=r.window===r?r.document:9===r.nodeType?r:r.ownerDocument;if(!(o=!a)){e:{a=Ae(a),o=Qn.onSelect;for(var i=0;i<o.length;i++){var l=o[i];if(!a.hasOwnProperty(l)||!a[l]){a=!1;break e}}a=!0}o=!a}if(o)return null;switch(a=t?E(t):window,e){case"topFocus":(ee(a)||"true"===a.contentEditable)&&(to=a,no=t,ro=null);break;case"topBlur":ro=no=to=null;break;case"topMouseDown":oo=!0;break;case"topContextMenu":case"topMouseUp":return oo=!1,Fe(n,r);case"topSelectionChange":if(Xr)break;case"topKeyDown":case"topKeyUp":return Fe(n,r)}return null}};F.augmentClass(He,{animationName:null,elapsedTime:null,pseudoElement:null}),F.augmentClass(Ke,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),ve.augmentClass(Be,{relatedTarget:null});var io={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},lo={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};ve.augmentClass(Ve,{key:function(e){if(e.key){var t=io[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?(e=ze(e),13===e?"Enter":String.fromCharCode(e)):"keydown"===e.type||"keyup"===e.type?lo[e.keyCode]||"Unidentified":""},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:be,charCode:function(e){return"keypress"===e.type?ze(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?ze(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),xe.augmentClass(We,{dataTransfer:null}),ve.augmentClass(Ze,{touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:be}),F.augmentClass(Ge,{propertyName:null,elapsedTime:null,pseudoElement:null}),xe.augmentClass(Ye,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null});var uo={},so={};"abort animationEnd animationIteration animationStart blur cancel canPlay canPlayThrough click close contextMenu copy cut doubleClick drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error focus input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing progress rateChange reset scroll seeked seeking stalled submit suspend timeUpdate toggle touchCancel touchEnd touchMove touchStart transitionEnd volumeChange waiting wheel".split(" ").forEach(function(e){var t=e[0].toUpperCase()+e.slice(1),n="on"+t;t="top"+t,n={phasedRegistrationNames:{bubbled:n,captured:n+"Capture"},dependencies:[t]},uo[e]=n,so[t]=n});var co={eventTypes:uo,extractEvents:function(e,t,n,r){var o=so[e];if(!o)return null;switch(e){case"topKeyPress":if(0===ze(n))return null;case"topKeyDown":case"topKeyUp":e=Ve;break;case"topBlur":case"topFocus":e=Be;break;case"topClick":if(2===n.button)return null;case"topDoubleClick":case"topMouseDown":case"topMouseMove":case"topMouseUp":case"topMouseOut":case"topMouseOver":case"topContextMenu":e=xe;break;case"topDrag":case"topDragEnd":case"topDragEnter":case"topDragExit":case"topDragLeave":case"topDragOver":case"topDragStart":case"topDrop":e=We;break;case"topTouchCancel":case"topTouchEnd":case"topTouchMove":case"topTouchStart":e=Ze;break;case"topAnimationEnd":case"topAnimationIteration":case"topAnimationStart":e=He;break;case"topTransitionEnd":e=Ge;break;case"topScroll":e=ve;break;case"topWheel":e=Ye;break;case"topCopy":case"topCut":case"topPaste":e=Ke;break;default:e=F}return t=e.getPooled(o,t,n,r),R(t),t}};Vr=function(e,t,n,r){e=_(e,t,n,r),k(e),w(!1)},nr.injectEventPluginOrder("ResponderEventPlugin SimpleEventPlugin TapEventPlugin EnterLeaveEventPlugin ChangeEventPlugin SelectEventPlugin BeforeInputEventPlugin".split(" ")),Jn=lr.getFiberCurrentPropsFromNode,Xn=lr.getInstanceFromNode,er=lr.getNodeFromInstance,nr.injectEventPluginsByName({SimpleEventPlugin:co,EnterLeaveEventPlugin:Hr,ChangeEventPlugin:jr,SelectEventPlugin:ao,BeforeInputEventPlugin:Er});var fo=[],po=-1;new Set;var ho={current:Mn},mo={current:!1},go=Mn,vo=null,yo=null,bo="function"==typeof Symbol&&Symbol.for,xo=bo?Symbol.for("react.element"):60103,_o=bo?Symbol.for("react.call"):60104,ko=bo?Symbol.for("react.return"):60105,wo=bo?Symbol.for("react.portal"):60106,Co=bo?Symbol.for("react.fragment"):60107,Eo="function"==typeof Symbol&&Symbol.iterator,To=Array.isArray,Oo=Ot(!0),Mo=Ot(!1),So={},No=Object.freeze({default:Rt}),Po=No&&Rt||No,Lo=Po.default?Po.default:Po,Io="object"==typeof performance&&"function"==typeof performance.now,Ro=void 0;Ro=Io?function(){return performance.now()}:function(){return Date.now()};var Ao=void 0,Do=void 0;if(xn.canUseDOM)if("function"!=typeof requestIdleCallback||"function"!=typeof cancelIdleCallback){var jo,Uo=null,Fo=!1,Ho=-1,Ko=!1,Bo=0,zo=33,Vo=33;jo=Io?{didTimeout:!1,timeRemaining:function(){var e=Bo-performance.now();return 0<e?e:0}}:{didTimeout:!1,timeRemaining:function(){var e=Bo-Date.now();return 0<e?e:0}};var Wo="__reactIdleCallback$"+Math.random().toString(36).slice(2);window.addEventListener("message",function(e){if(e.source===window&&e.data===Wo){if(Fo=!1,e=Ro(),0>=Bo-e){if(!(-1!==Ho&&Ho<=e))return void(Ko||(Ko=!0,requestAnimationFrame(Zo)));jo.didTimeout=!0}else jo.didTimeout=!1;Ho=-1,e=Uo,Uo=null,null!==e&&e(jo)}},!1);var Zo=function(e){Ko=!1;var t=e-Bo+Vo;t<Vo&&zo<Vo?(8>t&&(t=8),Vo=t<zo?zo:t):zo=t,Bo=e+Vo,Fo||(Fo=!0,window.postMessage(Wo,"*"))};Ao=function(e,t){return Uo=e,null!=t&&"number"==typeof t.timeout&&(Ho=Ro()+t.timeout),Ko||(Ko=!0,requestAnimationFrame(Zo)),0},Do=function(){Uo=null,Fo=!1,Ho=-1}}else Ao=window.requestIdleCallback,Do=window.cancelIdleCallback;else Ao=function(e){return setTimeout(function(){e({timeRemaining:function(){return 1/0}})})},Do=function(e){clearTimeout(e)};var Go=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Yo={},qo={},Qo={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"},$o=void 0,Jo=function(e){return"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(t,n,r,o){MSApp.execUnsafeLocalFunction(function(){return e(t,n)})}:e}(function(e,t){if(e.namespaceURI!==Qo.svg||"innerHTML"in e)e.innerHTML=t;else{for($o=$o||document.createElement("div"),$o.innerHTML="<svg>"+t+"</svg>",t=$o.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}}),Xo={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ea=["Webkit","ms","Moz","O"];Object.keys(Xo).forEach(function(e){ea.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Xo[t]=Xo[e]})});var ta=_n({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}),na=Qo.html,ra=kn.thatReturns(""),oa={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},aa=Object.freeze({createElement:ln,createTextNode:un,setInitialProperties:sn,diffProperties:cn,updateProperties:dn,diffHydratedProperties:fn,diffHydratedText:pn,warnForUnmatchedText:function(){},warnForDeletedHydratableElement:function(){},warnForDeletedHydratableText:function(){},warnForInsertedHydratedElement:function(){},warnForInsertedHydratedText:function(){},restoreControlledState:function(e,t,n){switch(t){case"input":if(zt(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var o=n[t];if(o!==e&&o.form===e.form){var a=T(o);a||r("90"),ie(o),zt(o,a)}}}break;case"textarea":$t(e,n);break;case"select":null!=(t=n.value)&&Gt(e,!!n.multiple,t,!1)}}});Sr.injectFiberControlledHostComponent(aa);var ia=null,la=null,ua=Lo({getRootHostContext:function(e){var t=e.nodeType;switch(t){case 9:case 11:e=(e=e.documentElement)?e.namespaceURI:en(null,"");break;default:t=8===t?e.parentNode:e,e=t.namespaceURI||null,t=t.tagName,e=en(e,t)}return e},getChildHostContext:function(e,t){return en(e,t)},getPublicInstance:function(e){return e},prepareForCommit:function(){ia=zr;var e=Cn();if(Ue(e)){if("selectionStart"in e)var t={start:e.selectionStart,end:e.selectionEnd};else e:{var n=window.getSelection&&window.getSelection();if(n&&0!==n.rangeCount){t=n.anchorNode;var r=n.anchorOffset,o=n.focusNode;n=n.focusOffset;try{t.nodeType,o.nodeType}catch(e){t=null;break e}var a=0,i=-1,l=-1,u=0,s=0,c=e,d=null;t:for(;;){for(var f;c!==t||0!==r&&3!==c.nodeType||(i=a+r),c!==o||0!==n&&3!==c.nodeType||(l=a+n),3===c.nodeType&&(a+=c.nodeValue.length),null!==(f=c.firstChild);)d=c,c=f;for(;;){if(c===e)break t;if(d===t&&++u===r&&(i=a),d===o&&++s===n&&(l=a),null!==(f=c.nextSibling))break;c=d,d=c.parentNode}c=f}t=-1===i||-1===l?null:{start:i,end:l}}else t=null}t=t||{start:0,end:0}}else t=null;la={focusedElem:e,selectionRange:t},Se(!1)},resetAfterCommit:function(){var e=la,t=Cn(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&Tn(document.documentElement,n)){if(Ue(n))if(t=r.start,e=r.end,void 0===e&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(window.getSelection){t=window.getSelection();var o=n[D()].length;e=Math.min(r.start,o),r=void 0===r.end?e:Math.min(r.end,o),!t.extend&&e>r&&(o=r,r=e,e=o),o=je(n,e);var a=je(n,r);if(o&&a&&(1!==t.rangeCount||t.anchorNode!==o.node||t.anchorOffset!==o.offset||t.focusNode!==a.node||t.focusOffset!==a.offset)){var i=document.createRange();i.setStart(o.node,o.offset),t.removeAllRanges(),e>r?(t.addRange(i),t.extend(a.node,a.offset)):(i.setEnd(a.node,a.offset),t.addRange(i))}}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(On(n),n=0;n<t.length;n++)e=t[n],e.element.scrollLeft=e.left,e.element.scrollTop=e.top}la=null,Se(ia),ia=null},createInstance:function(e,t,n,r,o){return e=ln(e,t,n,r),e[ar]=o,e[ir]=t,e},appendInitialChild:function(e,t){e.appendChild(t)},finalizeInitialChildren:function(e,t,n,r){sn(e,t,n,r);e:{switch(t){case"button":case"input":case"select":case"textarea":e=!!n.autoFocus;break e}e=!1}return e},prepareUpdate:function(e,t,n,r,o){return cn(e,t,n,r,o)},shouldSetTextContent:function(e,t){return"textarea"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&"string"==typeof t.dangerouslySetInnerHTML.__html},shouldDeprioritizeSubtree:function(e,t){return!!t.hidden},createTextInstance:function(e,t,n,r){return e=un(e,t),e[ar]=r,e},now:Ro,mutation:{commitMount:function(e){e.focus()},commitUpdate:function(e,t,n,r,o){e[ir]=o,dn(e,t,n,r,o)},resetTextContent:function(e){e.textContent=""},commitTextUpdate:function(e,t,n){e.nodeValue=n},appendChild:function(e,t){e.appendChild(t)},appendChildToContainer:function(e,t){8===e.nodeType?e.parentNode.insertBefore(t,e):e.appendChild(t)},insertBefore:function(e,t,n){e.insertBefore(t,n)},insertInContainerBefore:function(e,t,n){8===e.nodeType?e.parentNode.insertBefore(t,n):e.insertBefore(t,n)},removeChild:function(e,t){e.removeChild(t)},removeChildFromContainer:function(e,t){8===e.nodeType?e.parentNode.removeChild(t):e.removeChild(t)}},hydration:{canHydrateInstance:function(e,t){return 1!==e.nodeType||t.toLowerCase()!==e.nodeName.toLowerCase()?null:e},canHydrateTextInstance:function(e,t){return""===t||3!==e.nodeType?null:e},getNextHydratableSibling:function(e){for(e=e.nextSibling;e&&1!==e.nodeType&&3!==e.nodeType;)e=e.nextSibling;return e},getFirstHydratableChild:function(e){for(e=e.firstChild;e&&1!==e.nodeType&&3!==e.nodeType;)e=e.nextSibling;return e},hydrateInstance:function(e,t,n,r,o,a){return e[ar]=a,e[ir]=n,fn(e,t,n,o,r)},hydrateTextInstance:function(e,t,n){return e[ar]=n,pn(e,t)},didNotMatchHydratedContainerTextInstance:function(){},didNotMatchHydratedTextInstance:function(){},didNotHydrateContainerInstance:function(){},didNotHydrateInstance:function(){},didNotFindHydratableContainerInstance:function(){},didNotFindHydratableContainerTextInstance:function(){},didNotFindHydratableInstance:function(){},didNotFindHydratableTextInstance:function(){}},scheduleDeferredCallback:Ao,cancelDeferredCallback:Do,useSyncScheduling:!0});J=ua.batchedUpdates,yn.prototype.render=function(e,t){ua.updateContainer(e,this._reactRootContainer,null,t)},yn.prototype.unmount=function(e){ua.updateContainer(null,this._reactRootContainer,null,e)};var sa={createPortal:vn,findDOMNode:function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternalFiber;if(t)return ua.findHostInstance(t);"function"==typeof e.render?r("188"):r("213",Object.keys(e))},hydrate:function(e,t,n){return gn(null,e,t,!0,n)},render:function(e,t,n){return gn(null,e,t,!1,n)},unstable_renderSubtreeIntoContainer:function(e,t,n,o){return(null==e||void 0===e._reactInternalFiber)&&r("38"),gn(e,t,n,!1,o)},unmountComponentAtNode:function(e){return hn(e)||r("40"),!!e._reactRootContainer&&(ua.unbatchedUpdates(function(){gn(null,null,e,!1,function(){e._reactRootContainer=null})}),!0)},unstable_createPortal:vn,unstable_batchedUpdates:X,unstable_deferredUpdates:ua.deferredUpdates,flushSync:ua.flushSync,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{EventPluginHub:rr,EventPluginRegistry:$n,EventPropagators:ur,ReactControlledComponent:Nr,ReactDOMComponentTree:lr,ReactDOMEventListener:Wr}};ua.injectIntoDevTools({findFiberByHostInstance:C,bundleType:0,version:"16.2.0",rendererPackageName:"react-dom"});var ca=Object.freeze({default:sa}),da=ca&&sa||ca;e.exports=da.default?da.default:da},function(e,t,n){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),o={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen,isInWorker:!r};e.exports=o},function(e,t,n){"use strict";var r=n(8),o={listen:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!1),{remove:function(){e.removeEventListener(t,n,!1)}}):e.attachEvent?(e.attachEvent("on"+t,n),{remove:function(){e.detachEvent("on"+t,n)}}):void 0},capture:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!0),{remove:function(){e.removeEventListener(t,n,!0)}}):{remove:r}},registerDefault:function(){}};e.exports=o},function(e,t,n){"use strict";function r(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}e.exports=r},function(e,t,n){"use strict";function r(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!==e&&t!==t}function o(e,t){if(r(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),o=Object.keys(t);if(n.length!==o.length)return!1;for(var i=0;i<n.length;i++)if(!a.call(t,n[i])||!r(e[n[i]],t[n[i]]))return!1;return!0}var a=Object.prototype.hasOwnProperty;e.exports=o},function(e,t,n){"use strict";function r(e,t){return!(!e||!t)&&(e===t||!o(e)&&(o(t)?r(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}var o=n(28);e.exports=r},function(e,t,n){"use strict";function r(e){return o(e)&&3==e.nodeType}var o=n(29);e.exports=r},function(e,t,n){"use strict";function r(e){var t=e?e.ownerDocument||e:document,n=t.defaultView||window;return!(!e||!("function"==typeof n.Node?e instanceof n.Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}e.exports=r},function(e,t,n){"use strict";function r(e){try{e.focus()}catch(e){}}e.exports=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),c=r(s),d=n(14),f=r(d),p=n(6),h=r(p),m=n(35),g=r(m),v=n(16),y=(r(v),n(15)),b=r(y),x=n(58),_=r(x),k=n(10),w=r(k),C=function(e){function t(e){o(this,t);var n=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return n.state={offsets:{}},n.heights={},n.paddingBottom=0,n.lastActiveId=null,n.lastActiveIndex=-1,n.pendingLayout=!0,n.batchedLayout=!0,n.handleHeightChange=n.handleHeightChange.bind(n),n.handleInsert=n.handleInsert.bind(n),n}return i(t,e),u(t,[{key:"getChildContext",value:function(){return{findMentions:this.props.findMentions}}},{key:"layout",value:function(){var e=this.props,t=e.threads,n=e.collapsed,r=e.compact,o=e.field,a={},i=null,l=null,u=null,s=null,c=null,d=t.findIndex(function(e){return!0===e.active});-1===d&&this.lastActiveIndex>-1&&t.length>0&&(d=Math.min(this.lastActiveIndex,t.length-1)),this.lastActiveIndex=d,d>-1?(i=t[d],u=i.y-12,c=u-(i.active?12:4),s=u+this.heights[i.id]+4,a[i.id]=u,this.lastActiveId=i.id):this.lastActiveId=null;for(var f=d-1;f>=0;f--)i=t[f],l=r||n?26:this.heights[i.id],u=Math.min(i.y-12,c-l),c=u-4,a[i.id]=u;for(var p=d+1;p<t.length;p++)i=t[p],l=r||n?26:this.heights[i.id],u=Math.max(i.y-12,s),s=u+l+4,a[i.id]=u;var h=Math.max(o.scrollHeight-this.paddingBottom,window.innerHeight),m=Math.max(0,s+64-h);m!==this.paddingBottom&&(this.paddingBottom=m,o.style.paddingBottom=m?64+this.paddingBottom+"px":""),this.needsLayout=!1,this.setState({offsets:a})}},{key:"handleHeightChange",value:function(e){var t=e.height,n=e.id,r=this.heights[n]!==t,o=this.lastActiveId!==n;this.heights[n]=t,(r||o)&&(this.batchedLayout?this.needsLayout=!0:this.layout())}},{key:"handleInsert",value:function(e){e.preventDefault(),EN.execCommand("comment")}},{key:"componentWillUpdate",value:function(){this.batchedLayout=!0}},{key:"componentDidUpdate",value:function(e){e.collapsed!==this.props.collapsed&&(this.lastActiveId=null,this.lastActiveIndex=-1),(this.needsLayout||e.threads!==this.props.threads)&&this.layout(),this.batchedLayout=!1}},{key:"componentDidMount",value:function(){this.layout(),this.batchedLayout=!1}},{key:"componentWillUnmount",value:function(){0!==this.paddingBottom&&this.props.field&&(this.props.field.style.paddingBottom="")}},{key:"render",value:function(){var e=this,t=this.props,n=t.threads,r=t.user,o=t.collapsed,a=t.compact,i=t.readonly,u=t.focusY,s=t.archive,d=this.state.offsets,f=u?u-4:0,p=0===n.length?12:o||a?52:260;return c.default.createElement("div",{className:w.default.comments},!!u&&c.default.createElement("button",{className:w.default.adder,style:{top:f,right:p},onMouseDown:this.handleInsert},c.default.createElement(h.default,{svg:_.default})),n.map(function(t){return c.default.createElement(b.default,l({},t,{key:t.id,user:r,collapsed:o,compact:!t.active&&a,top:d[t.id]||t.y,updateHeight:e.handleHeightChange,readonly:i,floating:!0}))}),s&&c.default.createElement(g.default,l({},s,{user:r})))}}]),t}(s.PureComponent);t.default=C,C.childContextTypes={findMentions:f.default.func}},function(e,t,n){"use strict";var r=n(8),o=n(33),a=n(34);e.exports=function(){function e(e,t,n,r,i,l){l!==a&&o(!1,"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=r,n.PropTypes=n,n}},function(e,t,n){"use strict";function r(e,t,n,r,a,i,l,u){if(o(t),!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,i,l,u],d=0;s=new Error(t.replace(/%s/g,function(){return c[d++]})),s.name="Invariant Violation"}throw s.framesToPop=1,s}}var o=function(e){};e.exports=r},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),c=r(s),d=n(9),f=n(6),p=r(f),h=n(15),m=r(h),g=(n(3),n(54)),v=r(g),y=n(55),b=r(y),x=n(56),_=r(x),k=function(e){function t(e){o(this,t);var n=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return n.container=document.createElement("div"),n.handleClose=n.handleClose.bind(n),n}return i(t,e),u(t,[{key:"handleClose",value:function(e){e.target===this.overlayRef&&this.props.close()}},{key:"componentDidMount",value:function(){document.body.appendChild(this.container)}},{key:"componentWillUnmount",value:function(){document.body.removeChild(this.container)}},{key:"render",value:function(){var e=this,t=this.props,n=(t.handleClose,t.threads),r=t.user,o=t.title,a=t.close;return(0,d.createPortal)(c.default.createElement("div",{className:_.default.overlay,onClick:this.handleClose,ref:function(t){e.overlayRef=t}},c.default.createElement("div",{className:_.default.archive},c.default.createElement("div",{className:_.default.header},c.default.createElement("div",{className:_.default.wrapper},c.default.createElement("h1",null,"Comment archive"),c.default.createElement("h2",null,c.default.createElement(p.default,{svg:b.default}),o)),c.default.createElement("button",{className:_.default.btnClose,onClick:a},c.default.createElement(p.default,{svg:v.default}))),c.default.createElement("div",{className:_.default.content},n.map(function(e){return c.default.createElement(m.default,l({},e,{top:e.y,key:e.id,user:r,archive:!0}))})))),this.container)}}]),t}(s.PureComponent);t.default=k},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){return"mac"===ed.config.client};t.platformPhotoUrl=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return r()&&rte.config&&rte.config.user.userID?e.replace(/^http?s:\/\/([^\/]+)\/(.*)\/?$/,function(e,t,n){return"enavatar://"+t+"/"+t.replace(/\./g,"")+"/"+rte.config.user.userID+"/"+n+"/3"}):e}},function(e,t,n){var r=n(38);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0};o.transform=void 0;n(5)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){t=e.exports=n(4)(!1),t.push([e.i,"._2sDos{width:26px;height:26px;background-color:#aaa;border-radius:50%;overflow:hidden;position:relative;z-index:10;pointer-events:none}._2sDos:after{content:attr(data-initial);position:absolute;font-size:11px;color:#fff;top:6px;left:0;width:100%;text-align:center}._2sDos ._1hd46{width:100%;height:100%;position:relative;z-index:1;background-size:cover;background-repeat:no-repeat}.q6XoE{flex:0 0 auto;display:flex;flex-direction:row-reverse}._32Y1t{flex:0 0 auto;position:relative;width:24px;height:30px}._32Y1t ._2sDos{top:0;right:0;position:absolute;width:30px;height:30px;border:2px solid #fff;pointer-events:auto}._32Y1t ._2sDos:after{left:1px}._32Y1t:last-child{width:30px}._32Y1t:last-child ._2sDos:after{left:0}",""]),t.locals={avatar:"_2sDos",photo:"_1hd46",group:"q6XoE",wrapper:"_32Y1t"}},function(e,t){e.exports=function(e){var t="undefined"!=typeof window&&window.location;if(!t)throw new Error("fixUrls requires window.location");if(!e||"string"!=typeof e)return e;var n=t.protocol+"//"+t.host,r=n+t.pathname.replace(/\/[^\/]*$/,"/");return e.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,function(e,t){var o=t.trim().replace(/^"(.*)"$/,function(e,t){return t}).replace(/^'(.*)'$/,function(e,t){return t});if(/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(o))return e;var a;return a=0===o.indexOf("//")?o:0===o.indexOf("/")?n+o:r+o.replace(/^\.\//,""),"url("+JSON.stringify(a)+")"})}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),c=r(s),d=n(14),f=r(d),p=n(7),h=(r(p),n(41)),m=r(h),g=n(44),v=r(g),y=n(11),b=r(y),x=n(18),_=r(x),k=n(3),w=n(10),C=r(w),E=function(e){function t(e,n){o(this,t);var r=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));return r.editingStarted=e.editing||e.creating&&e.initiater,r.content=e.editing||e.creating?new m.default(e.text,n.findMentions,C.default):null,r.state={editText:r.editingStarted?e.text:"",suggestions:null,tooltip:null},r.handleMouseOver=r.handleMouseOver.bind(r),r.handleMouseOut=r.handleMouseOut.bind(r),r.handleMouseDown=r.handleMouseDown.bind(r),r.handleMentionChange=r.handleMentionChange.bind(r),r.handleBlur=r.handleBlur.bind(r),r.handleChange=r.handleChange.bind(r),r.handleSelectionChange=r.handleSelectionChange.bind(r),r.handleKeyDown=r.handleKeyDown.bind(r),r.handleCancel=r.handleCancel.bind(r),r.handleSubmit=r.handleSubmit.bind(r),r}return i(t,e),u(t,[{key:"resizeAndFocusIfNeeded",value:function(){var e=this;(this.editingStarted||this.props.creating)&&this.textareaRef&&T(this.textareaRef),this.editingStarted&&this.textareaRef&&(setTimeout(function(){e.textareaRef&&e.textareaRef.focus()},310),this.editingStarted=!1)}},{key:"selectMention",value:function(e){var t=this.state.suggestions;this.textareaRef&&t&&t.users[e]&&(this.content.setSuggestion(this.textareaRef,t.users[e].username),T(this.textareaRef),this.setState({editText:this.textareaRef.value,suggestions:null}))}},{key:"setChangeWithSuggestions",value:function(e){var t=this.content.getSuggestions(),n=t.length?{users:t,selectedIndex:0,rect:this.content.getMentionRect(this.measureRef,e.getBoundingClientRect().left-59)}:null;this.setState({editText:e.value,suggestions:n,tooltip:null})}},{key:"handleMouseOver",value:function(e){var t=e.target;if(t.dataset&&t.dataset.username){var n={};Object.keys(t.dataset).forEach(function(e){n[e]=t.dataset[e]}),this.setState({tooltip:c.default.createElement(_.default,{rect:(0,k.rect)(t),user:n})})}else if(t.dataset&&t.dataset.tokenStart&&!this.state.suggestions){var r="Several matches for "+t.textContent;this.setState({tooltip:c.default.createElement(b.default,{rect:(0,k.rect)(t)},r)})}}},{key:"handleMouseOut",value:function(){this.state.tooltip&&this.setState({tooltip:null})}},{key:"handleMouseDown",value:function(e){var t=e.target;if(t&&t.dataset&&t.dataset.tokenStart){e.preventDefault();var n=parseInt(t.dataset.tokenStart,10);!isNaN(n)&&this.textareaRef.value.length>=n&&(this.textareaRef.setSelectionRange(n,n),this.setState({tooltip:null}))}}},{key:"handleMentionChange",value:function(e){this.setState({suggestions:l({},this.state.suggestions,{selectedIndex:e})})}},{key:"handleBlur",value:function(){this.setState({suggestions:null})}},{key:"handleChange",value:function(e){var t=e.target;this.content.applyChange(t),T(t),this.setChangeWithSuggestions(t)}},{key:"handleSelectionChange",value:function(){var e=this.textareaRef;e&&document.activeElement===e&&this.content.applySelection(e)&&this.setChangeWithSuggestions(e)}},{key:"handleKeyDown",value:function(e){var t=this.state.suggestions,n=e.keyCode,r=e.metaKey,o=e.ctrlKey;8===n||46===n?this.content.allowDelete(e.target,46===n)||e.preventDefault():t?9===n||13===n?(e.preventDefault(),this.selectMention(t.selectedIndex)):38===n?(e.preventDefault(),t.selectedIndex>0&&this.setState({suggestions:l({},t,{selectedIndex:t.selectedIndex-1})})):40===n&&(e.preventDefault(),t.users.length-1>t.selectedIndex&&this.setState({suggestions:l({},t,{selectedIndex:t.selectedIndex+1})})):(r||o)&&13===n&&(e.preventDefault(),this.handleSubmit())}},{key:"handleCancel",value:function(e){var t=this.props,n=(t.creating,t.editing),r=t.initiater,o=t.id;t.threadId;n?EN.execCommand("comment",{action:"canceledit",id:o}):r?EN.execCommand("comment",{action:"highlight"}):(this.editingStarted=!0,this.content.clear(),this.setState({editText:"",suggestions:null}))}},{key:"handleSubmit",value:function(){var e=this.props,t=e.creating,n=e.editing,r=e.id,o=e.threadId,a=this.content.getRichText();n&&a?EN.execCommand("comment",{action:"edit",id:r,text:a}):n?EN.execCommand("comment",{action:"remove",id:r}):t&&(this.content.clear(),this.setState({editText:"",suggestions:null},function(){EN.execCommand("comment",{action:"insert",threadId:o,text:a})}))}},{key:"componentWillReceiveProps",value:function(e){var t=e.editing,n=e.text;t&&!this.props.editing&&(this.editingStarted=!0,this.content=new m.default(n,this.context.findMentions,C.default),this.setState({editText:this.content.getEditText(),suggestions:null}))}},{key:"componentDidUpdate",value:function(e,t){this.resizeAndFocusIfNeeded();var n=this.props,r=n.editing,o=n.creating;(r||o)&&this.state.editText!==t.editText&&this.props.onLayout(),!r&&!o||e.editing||e.creating||document.addEventListener("selectionchange",this.handleSelectionChange)}},{key:"componentDidMount",value:function(){this.resizeAndFocusIfNeeded(),(this.props.editing||this.props.creating)&&document.addEventListener("selectionchange",this.handleSelectionChange)}},{key:"componentWillUnmount",value:function(){(this.props.editing||this.props.creating)&&document.removeEventListener("selectionchange",this.handleSelectionChange)}},{key:"render",value:function(){var e=this,t=this.props,n=(t.id,t.editing),r=t.creating,o=t.text,a=t.initiater,i=this.state,u=i.editText,s=i.tooltip,d=i.suggestions,f=n&&!u?C.default.destroy:C.default.primary,p=n||r,h=n||r&&u,m=p?this.content.getPreview():o,g=null,y=null;return n&&!u?y="Delete":n?y="Save Changes":r&&(y="Post",g=a?"Add a comment...":"Reply..."),c.default.createElement("div",{className:C.default.wrapper},c.default.createElement("div",{className:C.default.body},c.default.createElement("div",{className:C.default.text,dangerouslySetInnerHTML:{__html:m},onMouseOver:this.handleMouseOver,onMouseOut:this.handleMouseOut,onMouseDown:this.handleMouseDown}),p&&c.default.createElement("textarea",{maxLength:"700",onChange:this.handleChange,onKeyDown:this.handleKeyDown,onBlur:this.handleBlur,placeholder:g,ref:function(t){e.textareaRef=t},value:u}),p&&c.default.createElement("div",{ref:function(t){e.measureRef=t},className:C.default.text},u)),h&&c.default.createElement("div",{className:C.default.controls},c.default.createElement("button",{onClick:this.handleSubmit,className:f},y),c.default.createElement("button",{onClick:this.handleCancel},"Cancel")),d&&c.default.createElement(v.default,l({},d,{onChange:this.handleMentionChange,onSelect:function(t){return e.selectMention(t)}})),s)}}]),t}(s.PureComponent);t.default=E,E.contextTypes={findMentions:f.default.func};var T=function(e){e.style.height="",e.style.height=e.scrollHeight+"px"}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),l=n(17),u=r(l),s=n(43),c=r(s),d=n(3),f=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments[1],r=arguments[2];o(this,e),this.matcher_=n,this.renderer_=new c.default(r),this.mentionToken_=null,this.firstToken_=null,this.cache_={},this.selectionStart_=-1,this.selectionEnd_=-1,this.source=null,this.parse(this.preprocess(t)),this.decorateMentions(null,!0,-1,-1)}return i(e,[{key:"clear",value:function(){this.mentionToken_=null,this.firstToken_=null,this.selectionStart_=-1,this.selectionEnd_=-1,this.source=""}},{key:"preprocess",value:function(e){var t=this;return e.replace(/<\/?b>/g,"*").replace(/<\/?em>/g,"_").replace(/<\/?s>/g,"~").replace(/<\/?pre>/g,"```").replace(/<\/?code>/g,"`").replace(/<br\/?>/g,"\n").replace(/\u00a0/g,"").replace(/<span\s(.*?)>(@.*?)<\/span>/g,function(e,n,r){var o=n.trim().split(" ").reduce(function(e,t){var n=t.match(/^data-(.*?)=["'](.*)["']$/);if(n){e[n[1].trim().toLowerCase().replace(/-([a-z])/g,function(e,t){return t.toUpperCase()})]=n[2].trim()}return e},{});return o.username&&(t.cache_[o.username]=o)," "+r+" "}).replace(/<[^>]+?>/g,"").replace(/(?:^[\u0008-\u0013\u0020]+|[\u0008-\u0013\u0020]+$)/g,"")}},{key:"parse",value:function(e){if(this.source!==e){var t=new u.default(e);this.firstToken_=t.token,h(t,l.TokenKind.SOF);do{t.token.kind===l.TokenKind.MARK_MENTION&&m(t.token,this.cache_,this.matcher_)}while(!p(t,l.TokenKind.EOF));h(t,l.TokenKind.EOF),this.source=e,this.selectionStart_=-1,this.selectionEnd_=-1}}},{key:"applyChange",value:function(e){this.parse(e.value);var t=e.selectionStart,n=e.selectionEnd,r=null,o=null,a=null,i=!0;if(-1!==t&&t===n)for(r=this.firstToken_;r=r.next;)r.start<=t&&r.end>=t&&r.kind!==l.TokenKind.EOF?(o=r,r.kind===l.TokenKind.MARK_MENTION&&!r.data.decorated&&Math.max(t,r.start)-Math.min(n,r.end)<=0&&(a=r)):r.kind!==l.TokenKind.MARK_MENTION||r.data.decorated||(i=!0);return!a&&o&&o.kind===l.TokenKind.TEXT&&this.matcher_&&(a=g(o,e,this.matcher_)),this.mentionToken_=a,i&&this.decorateMentions(e),!0}},{key:"applySelection",value:function(e){if(!this.firstToken_)return!1;var t=e.selectionStart,n=e.selectionEnd,r=!1;if(this.selectionStart_===t&&this.selectionEnd_===n)return!1;this.mentionToken_&&(r=!0,this.mentionToken_=null);for(var o=this.firstToken_;o=o.next;)if(o.kind===l.TokenKind.MARK_MENTION&&o.data.decorated&&(o.start<t&&o.end>t&&(t=o.start),o.start<n&&o.end>n)){n=o.end;break}return t===e.selectionStart&&n===e.selectionEnd||(e.value=this.getEditText(),e.setSelectionRange(t,n),r=!0,o.data.user||(this.mentionToken_=o),this.selectionStart_=e.selectionStart,this.selectionEnd_=e.selectionEnd),r}},{key:"allowDelete",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=e.selectionStart;if(n!==e.selectionEnd)return!0;for(var r=this.firstToken_,o=!0;r=r.next;)r.kind===l.TokenKind.MARK_MENTION&&r.data.decorated&&(t&&r.start===n?(n+=1,o=!1):t||r.end!==n||(n-=1,o=!1));return o||e.setSelectionRange(n,n),o}},{key:"decorateMentions",value:function(e){for(var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.selectionStart,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:e.selectionEnd,o=this.firstToken_,a=!1,i=[];o=o.next;){var u=o.kind===l.TokenKind.MARK_MENTION,s=o.start<=n&&o.end>=r;if(u&&t&&!s&&!o.data.decorated&&o.data.suggestions.length>0&&(a=!0,i.push(o),o.end<=n&&(n+=2,r+=2),o.data.decorated=!0,o.end+=2),o.next){var c=o.next.end-o.next.start;o.next.start=o.end,o.next.end=o.next.start+c}}return a&&(this.source=this.getEditText(),e&&(e.value=this.source,e.setSelectionRange(n,r),n=e.selectionStart,r=e.selectionEnd)),this.selectionStart_=n,this.selectionEnd_=r,a}},{key:"setSuggestion",value:function(e,t){if(this.mentionToken_){var n=this.mentionToken_,r=n.start+t.length+2;e.value=this.source.substr(0,n.start)+"@"+t+" "+this.source.substr(n.end),e.focus(),e.setSelectionRange(r,r),this.parse(e.value),this.decorateMentions(e)}}},{key:"getSuggestions",value:function(){return this.mentionToken_?this.mentionToken_.data.suggestions:[]}},{key:"getMentionRect",value:function(e,t){var n={x:0,y:0,width:0,height:0};if(!this.mentionToken_)return n;e.innerHTML=this.renderer_.escapeHTML(this.source),this.measureRange_||(this.measureRange_=document.createRange());var r=e.firstChild;return this.measureRange_.setStart(r,this.mentionToken_.start),this.measureRange_.setEnd(r,this.mentionToken_.end),a({},(0,d.rect)(this.measureRange_,t),{x:t})}},{key:"getRichText",value:function(){return this.renderer_.renderRichtText(this.firstToken_)}},{key:"getEditText",value:function(){return this.renderer_.renderEditText(this.firstToken_)}},{key:"getPreview",value:function(){return this.renderer_.renderPreview(this.firstToken_)}}]),e}();t.default=f;var p=function(e,t){var n=e.token.kind===t;return n||e.advance(),n},h=function(e,t){var n=e.token;if(n.kind===t)return e.advance(),n;throw new Error("Parser synax error, expected "+t+", found "+n)},m=function(e,t,n){var r=e.data.text,o=n?n(r):[];e.data.suggestions=[],e.data.user=null,!o.length&&t[r]?e.data.user=t[r]:1===o.length&&o[0].username===r?(e.data.user=o[0],e.data.suggestions=o):o.length>0&&(e.data.suggestions=o)},g=function(e,t,n){var r=t.selectionEnd,o=e.prev;do{if(o.kind===l.TokenKind.MARK_MENTION&&!o.data.decorated&&o.data.suggestions.length>0){var a=t.value.slice(o.start+1,r),i=n(a);if(i.length>0)return o.data.suggestions=i,e.end===r?(o.next.prev=null,o.next=e.next,o.end=r,e.next=null):(e.prev.next=null,o.next&&(o.next.prev=null),e.start=r,o.end=r,e.prev.next=null,e.prev=o,o.next=e),o}}while((o=o.prev)&&o.kind===l.TokenKind.TEXT);return null}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=function(){function e(t,n,o){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,l=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null;r(this,e),this.kind=t,this.start=n,this.end=o,this.data=a,this.prev=i,this.next=l,this.selected=!1}return o(e,[{key:"toString",value:function(){return this.data?this.kind+' "'+JSON.stringify(this.data)+'"':this.kind}},{key:"inspect",value:function(){return{kind:this.kind,data:this.data,start:this.start,end:this.end}}}]),e}();t.default=a},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=n(17),i=function(){function e(t){r(this,e),this.markEndPos_={},this.styles=t}return o(e,[{key:"mentionToHTML_",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1,n=e.data,r=n.text,o=n.user;if(t>=0)return'<span data-token-start="'+t+'"><span></span>@'+r+"</span>";if(o){var a=o.initial,i=o.username,l=o.title,u=o.email,s=o.name,c=o.photoUrl,d={initial:a,username:i,title:l,email:u,name:s},f=Object.keys(d).reduce(function(e,t){return d[t]&&e.push("data-"+t+'="'+d[t]+'"'),e},[]);return c&&f.push('data-photo-url="'+c+'"'),"<span "+f.join(" ")+">@"+r+"</span>"}return"@"+r}},{key:"markToHTML_",value:function(e,t){return e===a.TokenKind.MARK_CODE?t?"<code>":"</code>":e===a.TokenKind.MARK_CODEBLOCK?t?"<pre>":"</pre>":e===a.TokenKind.MARK_STRIKE_THROUGH?t?"<s>":"</s>":e===a.TokenKind.MARK_BOLD?t?"<b>":"</b>":e===a.TokenKind.MARK_ITALIC?t?"<em>":"</em>":(console.error("Invalid mark "+(t?"ahead":"behind")+' "'+e+'"'),"")}},{key:"shouldMarkStart_",value:function(e){var t=e.kind;if(!e.data||!e.data.ahead||t===e.prev.kind||t===e.next.kind)return!1;var n=this.markEndPos_[t];if(n&&n>e.start)return!1;for(var r=e.next;r;){if(r.kind===a.TokenKind.NEW_LINE&&t!==a.TokenKind.MARK_CODEBLOCK)return!1;if(r.kind===t&&r.data.behind)return r.prev.kind!==t&&r.next.kind!==t&&(this.markEndPos_[t]=r.start,!0);r=r.next}return!1}},{key:"shouldMarkEnd_",value:function(e){return this.markEndPos_[e.kind]===e.start&&(this.markEndPos_[e.kind]=null,!0)}},{key:"escapeHTML",value:function(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}},{key:"renderRichtText",value:function(e){if(!e)return"";this.markEndPos_={};for(var t="";e=e.next;){var n=e,r=n.kind,o=n.data,i=this.markEndPos_[a.TokenKind.MARK_CODE]||this.markEndPos_[a.TokenKind.MARK_CODEBLOCK];!i&&r===a.TokenKind.MARK_MENTION&&o.user?t+=this.mentionToHTML_(e):r===a.TokenKind.MARK_MENTION?t+="@"+o.text:!i&&this.shouldMarkStart_(e)?t+=this.markToHTML_(r,!0):this.shouldMarkEnd_(e)?t+=this.markToHTML_(r,!1):i||r!==a.TokenKind.NEW_LINE?o&&(t+=this.escapeHTML(o.text)):e.prev.kind===a.TokenKind.MARK_CODEBLOCK&&e.prev.data.behind||(t+="<br>")}return t.replace(/\u00a0/g,"").trim()}},{key:"renderEditText",value:function(e){if(!e)return"";for(var t="";e=e.next;)e.kind===a.TokenKind.MARK_MENTION&&e.data.decorated?t+=" @"+e.data.text+" ":e.kind===a.TokenKind.MARK_MENTION?t+="@"+e.data.text:e.data&&(t+=e.data.text);return t}},{key:"renderPreview",value:function(e){if(!e)return"";for(var t="";e=e.next;)e.kind===a.TokenKind.MARK_MENTION&&e.data.decorated&&!e.data.user?t+=this.mentionToHTML_(e,e.start+1):e.kind===a.TokenKind.MARK_MENTION&&e.data.decorated?t+=this.mentionToHTML_(e):e.kind===a.TokenKind.MARK_MENTION?t+="@"+e.data.text:e.data&&(t+=this.escapeHTML(e.data.text));return t}}]),e}();t.default=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),c=r(s),d=n(9),f=n(7),p=r(f),h=n(3),m=n(45),g=r(m),v=function(e){function t(e){o(this,t);var n=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return n.container=document.createElement("div"),n.handleWheel=n.handleWheel.bind(n),n.handleMouseDown=n.handleMouseDown.bind(n),n}return i(t,e),u(t,[{key:"updatePosition",value:function(){if(this.modalRef){var e=this.props.rect,t=this.modalRef,n=(t.clientWidth,t.clientHeight),r=window,o=(r.innerWidth,r.innerHeight),a=r.scrollY,i=e.y+e.height+6-a;i=i+168<=o-4?i+a:e.y-n-6,this.modalRef.style.top=Math.round(i)+"px",this.modalRef.style.left=Math.round(e.x)+"px"}}},{key:"updateScrollTop",value:function(){var e=this.props.selectedIndex;if(this.modalRef||!(e<4)){var t=this.modalRef.scrollTop,n=t+168,r=42*e,o=r+42;r<t?this.modalRef.scrollTop=r:o>n&&(this.modalRef.scrollTop=o-168)}}},{key:"handleChange",value:function(e){e!==this.props.selectedIndex&&this.props.onChange(e)}},{key:"handleMouseDown",value:function(e){e.preventDefault()}},{key:"handleWheel",value:function(e){this.modalRef.scrollTop+=e.deltaY,e.preventDefault()}},{key:"componentDidUpdate",value:function(e){e.selectedIndex!==this.props.selectedIndex&&this.updateScrollTop(),(0,h.equal)(e.rect,this.props.rect)||this.updatePosition()}},{key:"componentDidMount",value:function(){document.body.appendChild(this.container),this.updateScrollTop(),this.updatePosition()}},{key:"componentWillUnmount",value:function(){document.body.removeChild(this.container)}},{key:"render",value:function(){var e=this,t=this.props,n=t.users,r=t.onSelect,o=t.selectedIndex;return(0,d.createPortal)(c.default.createElement("div",{className:g.default.suggestbox,onWheel:this.handleWheel,onMouseDown:this.handleMouseDown,ref:function(t){e.modalRef=t}},n.map(function(t,n){return c.default.createElement("div",{className:(0,h.css)(g.default.cell,o===n&&g.default.selected),key:t.id,onMouseOver:function(){return e.handleChange(n)},onClick:function(){return r(n)}},c.default.createElement(p.default,l({},t,{className:g.default.avatar})),c.default.createElement("div",{className:g.default.title},t.name),c.default.createElement("div",{className:g.default.subtitle},t.email))})),this.container)}}]),t}(s.Component);t.default=v},function(e,t,n){var r=n(46);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0};o.transform=void 0;n(5)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){t=e.exports=n(4)(!1),t.push([e.i,"._2rGYT{position:absolute;width:240px;min-height:42px;max-height:168px;overflow:hidden;overflow-y:auto;background-color:#fff;border-radius:3px;box-shadow:0 0 6px 0 rgba(0,0,0,.3);color:#2a2a2a;z-index:2147480650;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial;font-size:13px}._2rGYT .ijaJk{position:relative;height:42px;cursor:pointer;display:flex;flex-direction:column;justify-content:center}._2rGYT .ijaJk._2a4aS{background-color:#f0f1f1}._2rGYT ._2BOBz,._2rGYT ._2GQyK{flex:0 0 auto;padding:0 10px 0 40px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._2rGYT ._2GQyK{font-size:12px;color:#a0a0a0;font-weight:400}._2rGYT .yjTh5{position:absolute;top:8px;left:8px}",""]),t.locals={suggestbox:"_2rGYT",cell:"ijaJk",selected:"_2a4aS",title:"_2BOBz",subtitle:"_2GQyK",avatar:"yjTh5"}},function(e,t,n){var r=n(48);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0};o.transform=void 0;n(5)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){t=e.exports=n(4)(!1),t.push([e.i,"._3C1DZ{position:absolute;pointer-events:none;z-index:2147480650;background-color:#202020;border-radius:4px;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial;font-size:13px;padding:6px 10px;color:#fff}._3C1DZ ._328PC{position:absolute;bottom:-6px;width:0;height:0;border-style:solid;border-width:6px 6px 0;border-color:#202020 transparent transparent;left:calc(50% - 6px)}._3C1DZ ._328PC._3CVky{top:-6px;bottom:auto;border-width:0 6px 6px;border-color:transparent transparent #202020}",""]),t.locals={tooltip:"_3C1DZ",arrow:"_328PC",flipped:"_3CVky"}},function(e,t,n){var r=n(50);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0};o.transform=void 0;n(5)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){t=e.exports=n(4)(!1),t.push([e.i,"._2imiI{height:42px;display:flex;flex-direction:column;justify-content:center;padding:0}._2imiI ._1tCIi,._2imiI ._2APC5{flex:0 0 auto;padding:0 10px 0 40px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}._2imiI ._1tCIi ._2keKv{color:#c3c3c3;padding-left:4px}._2imiI ._2APC5{font-size:12px;color:#c3c3c3}._2imiI ._2ih6K{position:absolute;top:8px;left:8px}",""]),t.locals={tooltip:"_2imiI",title:"_1tCIi",subtitle:"_2APC5",dim:"_2keKv",avatar:"_2ih6K"}},function(e,t,n){t=e.exports=n(4)(!1),t.push([e.i,'._2McyK{position:absolute;top:0;left:0;right:0;bottom:0;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial;color:#333;font-size:13px;overflow:hidden}._2McyK button,._2McyK textarea{color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;margin:0;padding:0;outline:none;background-color:transparent;border:none;-webkit-appearance:none;box-sizing:border-box}._2McyK button{cursor:pointer;-webkit-user-select:none;user-select:none}.fullsize ._2McyK{display:none}button._2rVmN{position:absolute;top:0;right:12px;width:28px;height:28px;pointer-events:auto;border-radius:5px;opacity:.4;transition:opacity .2s ease-in-out,box-shadow .2s ease-in-out;padding-top:2px;background-color:#fff}button._2rVmN:hover{opacity:1;box-shadow:0 0 4px 0 rgba(0,0,0,.14)}button._2rVmN svg{width:24px;height:24px}._3KmTm{background-color:#fff;border-radius:3px;margin:11px;pointer-events:auto;-webkit-user-select:text;user-select:text;transition:top .3s ease-in-out,right .2s ease-in-out,box-shadow .2s ease-in-out}._3KmTm._206oy{width:240px;position:absolute;right:10px;z-index:100;margin:0}._3KmTm._1CBLM,._3KmTm._3-P_k{pointer-events:none;background-color:transparent;transition:top .3s ease-in-out,right .2s ease-in-out}._3KmTm._1CBLM ._1VVLO,._3KmTm._3-P_k ._1VVLO{pointer-events:auto}._3KmTm._3-P_k ._1VVLO:after{color:#fff}._3KmTm._3-P_k ._1VVLO svg{fill:#fcb540;stroke:#fcb540}._3KmTm._3Ahry{right:20px;box-shadow:0 1px 7px 0 rgba(0,0,0,.2);z-index:2147480647}._3KmTm._3Ahry .NzceV{justify-content:space-between}._3KmTm .NzceV{display:flex;justify-content:flex-end;min-height:14px}._3KmTm ._3MO66{flex:0 0 auto;padding:0 10px;color:#2dbe60;height:34px}._3KmTm ._3CSpw{flex:0 0 auto;border:1px solid #d1d1d1;color:#666;font-size:13px;padding:0 12px;margin:16px 16px 0 0;height:32px}._3KmTm ._3ZiYf{flex:1 1 auto;margin:20px;max-height:48px;overflow:hidden}._3KmTm ._3ZiYf span{background-color:#ffebcc}._3KmTm ._1VVLO{flex:0 0 auto;width:32px;height:32px;position:relative;top:5px;right:5px;cursor:pointer}._3KmTm ._1VVLO:after{content:attr(data-count);position:absolute;top:8px;left:.5px;width:100%;text-align:center;font-size:11px;color:#c3c3c3}._3KmTm ._1VVLO svg{fill:none;stroke:#c3c3c3;width:inherit;height:inherit}._1rfNP{position:relative;padding:2px 0 18px 44px;min-height:44px}._1rfNP:after{content:"";position:absolute;z-index:5;top:42px;left:23px;bottom:0;width:1px;background-color:#e6e6e6}._1rfNP:last-child:after,._3KmTm._3Ahry ._1rfNP:nth-last-child(2):after{content:normal}._1rfNP._2f_KU{border-top:1px solid #ededed;padding-top:12px;padding-bottom:0;top:-1px}._1rfNP._2f_KU:first-child{top:0;border-top:none}._1rfNP._34c82{padding-bottom:0;padding-top:10px;background-color:#fafafa}._1rfNP._34c82:before{content:"";position:absolute;top:0;left:0;width:3px;bottom:0;z-index:15;background-color:#fee1b3}._1rfNP .yRVsF{position:absolute;top:8px;left:10px}._1rfNP ._2B9t7{position:relative;padding:2px 36px 4px 0;display:flex;flex-wrap:wrap}._1rfNP .jXcu_{font-weight:700;line-height:16px;padding-right:12px;flex:0 0 auto}._1rfNP ._1r33j{color:#c3c3c3;font-size:12px;flex:0 0 auto}._1rfNP ._3bH-f{position:absolute;top:1px;right:4px;width:24px;height:24px;display:none}._1rfNP ._3bH-f svg{fill:#c3c3c3;width:inherit;height:inherit}._1rfNP:hover ._3bH-f{display:block}._1rfNP span[data-token-start],._1rfNP span[data-username]{color:#127dbd;position:relative;padding:0 0 1px;background-color:rgba(18,125,189,.06);border-radius:3px;cursor:pointer}._1rfNP span[data-token-start]:hover,._1rfNP span[data-username]:hover{background-color:rgba(18,125,189,.15)}._1rfNP span[data-token-start]:after,._1rfNP span[data-token-start]:before,._1rfNP span[data-username]:after,._1rfNP span[data-username]:before{content:"\\A0"}._1rfNP span[data-token-start]{background-color:transparent;pointer-events:auto}._1rfNP span[data-token-start] span{pointer-events:none;position:absolute;display:block;top:0;left:0;right:0;bottom:0;border-radius:inherit;border:1px dotted #127dbd}._1rfNP span[data-token-start] span:before{content:"?";position:absolute;top:-6px;right:-6px;width:12px;height:12px;background-color:#2d9ee0;font-size:10px;border-radius:50%;color:#fff;font-family:sans-serif;line-height:12px;text-indent:3px}._1rfNP ._1QSlL{padding:0 16px 0 0}._1rfNP ._38hRh{position:relative}._1rfNP ._38hRh textarea{width:100%;resize:none;line-height:18px;height:18px;position:relative;z-index:2}._1rfNP ._38hRh textarea::-webkit-input-placeholder{color:#c3c3c3}._1rfNP ._38hRh textarea::-moz-placeholder{color:#c3c3c3}._1rfNP ._38hRh textarea::-ms-input-placeholder{color:#c3c3c3}._1rfNP ._38hRh textarea::placeholder{color:#c3c3c3}._1rfNP ._2rAcM{line-height:18px;word-break:break-word}._1rfNP ._2rAcM code,._1rfNP ._2rAcM pre{tab-size:4;border-radius:3px;font-family:Consolas,monaco,Ubuntu Mono,courier,monospace;font-size:11px}._1rfNP ._2rAcM code{color:#d72b3f;padding:1px 3px;background-color:#f7f7f9;border:1px solid #e1e1e8}._1rfNP ._2rAcM pre{white-space:pre-wrap;background:#f9f9f9;border:1px solid rgba(0,0,0,.15);margin:6px 0 3px;padding:4px 8px}._1rfNP ._2rAcM b code,._1rfNP ._2rAcM b pre{font-weight:400}._1rfNP ._2rAcM em code,._1rfNP ._2rAcM em pre{font-style:normal}._1rfNP ._2rAcM s code,._1rfNP ._2rAcM s pre{text-decoration:none}._1rfNP._2f_KU ._2rAcM,._1rfNP._34c82 ._2rAcM{pointer-events:none;position:absolute;top:0;left:0;right:0;color:transparent;white-space:pre-wrap}._1rfNP._2f_KU ._2rAcM:first-child,._1rfNP._34c82 ._2rAcM:first-child{z-index:3}._1rfNP._2f_KU ._2rAcM:last-child,._1rfNP._34c82 ._2rAcM:last-child{z-index:1}._1rfNP ._20UZE{display:flex;align-items:center;height:44px;padding:8px 0 12px}._1rfNP ._20UZE button{flex:0 0 auto;margin-right:14px;color:#aaa}._1rfNP ._20UZE ._2vEM5{color:#2dbe60;font-weight:700}._1rfNP ._20UZE ._3_XBY{color:#ff5151;font-weight:700}',""]),t.locals={comments:"_2McyK",adder:"_2rVmN",thread:"_3KmTm",floating:"_206oy",collapsed:"_3-P_k",compact:"_1CBLM",bubble:"_1VVLO",active:"_3Ahry",toolbar:"NzceV",resolve:"_3MO66",reopen:"_3CSpw",highlight:"_3ZiYf",comment:"_1rfNP",new:"_2f_KU",edit:"_34c82",avatar:"yRVsF",header:"_2B9t7",name:"jXcu_",time:"_1r33j",options:"_3bH-f",wrapper:"_1QSlL",body:"_38hRh",text:"_2rAcM",controls:"_20UZE",primary:"_2vEM5",destroy:"_3_XBY"}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"ise7I",use:"ise7I-usage",viewBox:"0 0 24 24",content:'<symbol viewBox="0 0 24 24" id="ise7I">\n  <path d="M7.5,13 C6.67157288,13 6,12.3284271 6,11.5 C6,10.6715729 6.67157288,10 7.5,10 C8.32842712,10 9,10.6715729 9,11.5 C9,12.3284271 8.32842712,13 7.5,13 Z M12.5,13 C11.6715729,13 11,12.3284271 11,11.5 C11,10.6715729 11.6715729,10 12.5,10 C13.3284271,10 14,10.6715729 14,11.5 C14,12.3284271 13.3284271,13 12.5,13 Z M17.5,13 C16.6715729,13 16,12.3284271 16,11.5 C16,10.6715729 16.6715729,10 17.5,10 C18.3284271,10 19,10.6715729 19,11.5 C19,12.3284271 18.3284271,13 17.5,13 Z" />\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"UJcC_",use:"UJcC_-usage",viewBox:"0 0 32 32",content:'<symbol viewBox="0 0 32 32" id="UJcC_">\n  <path d="M9.97861401,23.8640938 C11.7417413,25.2044152 13.9415355,26 16.3271484,26 C22.1261383,26 26.8271484,21.2989899 26.8271484,15.5 C26.8271484,9.70101013 22.1261383,5 16.3271484,5 C10.5281586,5 5.82714844,9.70101013 5.82714844,15.5 C5.82714844,17.1794923 6.22146275,18.7668876 6.92256379,20.1746583 L5,24.7011719 L9.97861401,23.8640938 Z" />\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"3IsE-",use:"3IsE--usage",viewBox:"0 0 12 12",content:'<symbol viewBox="0 0 12 12" id="3IsE-">\n    <g id="3IsE-_Final-for-MVP" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n        <g id="3IsE-_Artboard-Copy-11" transform="translate(-1057.000000, -207.000000)" fill="#C3C3C3">\n            <g id="3IsE-_Title-Area" transform="translate(414.000000, 181.000000)">\n                <g id="3IsE-_Close" transform="translate(648.899495, 31.899495) rotate(-315.000000) translate(-648.899495, -31.899495) translate(641.899495, 24.899495)">\n                    <rect id="3IsE-_Rectangle-26" x="6" y="0" width="2" height="14" />\n                    <rect id="3IsE-_Rectangle-26" transform="translate(7.000000, 7.000000) rotate(-90.000000) translate(-7.000000, -7.000000) " x="6" y="0" width="2" height="14" />\n                </g>\n            </g>\n        </g>\n    </g>\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"34UlQ",use:"34UlQ-usage",viewBox:"0 0 12 14",content:'<symbol viewBox="0 0 12 14" id="34UlQ">\n    <g id="34UlQ_Assets" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n        <g id="34UlQ_Artboard" fill="#A0A0A0">\n            <path d="M8.538,13.75 L1.5,13.75 C0.87,13.75 0.384,13.246 0.384,12.634 L0.384,1.366 C0.384,0.754 0.87,0.25 1.5,0.25 L10.5,0.25 C11.13,0.25 11.616,0.754 11.616,1.366 L11.616,10.654 L8.538,13.75 Z M10.5,9.808 L10.5,1.366 L1.5,1.366 L1.5,12.616 L7.692,12.616 L7.692,10.942 C7.692,10.312 8.196,9.808 8.808,9.808 L10.5,9.808 Z M3.192,3.904 L3.192,3.058 L8.808,3.058 L8.808,3.904 L3.192,3.904 Z M3.192,6.154 L3.192,5.308 L8.808,5.308 L8.808,6.154 L3.192,6.154 Z M3.192,8.404 L3.192,7.558 L8.808,7.558 L8.808,8.404 L3.192,8.404 Z M6.558,9.808 L6.558,10.654 L3.192,10.654 L3.192,9.808 L6.558,9.808 Z M8.538,12.346 L10.212,10.654 L8.538,10.654 L8.538,12.346 Z" id="34UlQ_Note_Icon_Comment_History" />\n        </g>\n    </g>\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){var r=n(57);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0};o.transform=void 0;n(5)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){t=e.exports=n(4)(!1),t.push([e.i,"._1DHLY{flex:1 1 auto;max-width:680px;height:100%;display:flex;flex-direction:column;overflow:hidden;background:#fff;border-radius:4px;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial;color:#333;font-size:13px;box-shadow:0 2px 4px 0 rgba(0,0,0,.5)}._1DHLY button,._1DHLY textarea{color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;margin:0;padding:0;outline:none;background-color:transparent;border:none;-webkit-appearance:none;box-sizing:border-box}._1DHLY button{cursor:pointer;-webkit-user-select:none;user-select:none}._1Zpwr{display:flex;height:76px;align-items:flex-start;border-bottom:1px solid #e4e4e4;flex:0 0 auto}._1Zpwr ._1GeGQ{flex:1 1 auto;padding:16px 0 0 20px}._1Zpwr h1{font-weight:500;font-size:20px;line-height:22px;margin:0 0 7px}._1Zpwr h2{font-size:14px;font-weight:400;color:#666;margin:0;display:flex;align-items:center}._1Zpwr h2 svg{width:13px;height:13px;margin-right:5px}._1Zpwr ._1Eko3{width:30px;height:30px;flex:0 0 auto;padding:9px;margin:16px 15px 0 12px}._1Zpwr ._1Eko3:hover{opacity:.7}._3ftjm{flex:1 1 auto;background-color:#f0f1f1;overflow:scroll}.YJFu2{z-index:2147480547;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.4);pointer-events:auto;align-items:center;justify-content:center;display:flex;padding:90px 60px}",""]),t.locals={archive:"_1DHLY",header:"_1Zpwr",wrapper:"_1GeGQ","btn-close":"_1Eko3",btnClose:"_1Eko3",content:"_3ftjm",overlay:"YJFu2"}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"1Ejmu",use:"1Ejmu-usage",viewBox:"0 0 24 24",content:'<symbol viewBox="0 0 24 24" id="1Ejmu">\n    <g transform="translate(3.000000, 3.000000)" fill="#666666">\n        <path d="M-0.819413277,16.762739 L3.97955612,15.962205 C5.5266647,17.0728542 7.38797437,17.6818182 9.34105857,17.6818182 C14.3985232,17.6818182 18.5,13.6125663 18.5,8.59090909 C18.5,8.10983109 18.4623084,7.63327193 18.3877934,7.1642387 L17.4001792,7.32114027 C17.4664577,7.73832922 17.5,8.16242622 17.5,8.59090909 C17.5,13.0585081 13.8479965,16.6818182 9.34105857,16.6818182 C7.53279169,16.6818182 5.81537718,16.09749 4.40674699,15.0350692 L4.23526252,14.9057317 L0.819413277,15.4755423 L2.13651926,12.3988921 L2.03232517,12.1913202 C1.47572456,11.0824791 1.18211713,9.85800197 1.18211713,8.59090909 C1.18211713,4.1233101 4.83412062,0.5 9.34105857,0.5 C9.85433737,0.5 10.3613051,0.546939794 10.8576375,0.639424924 L11.0408215,-0.343653719 C10.4841477,-0.447382703 9.9158607,-0.5 9.34105857,-0.5 C4.2835939,-0.5 0.182117131,3.56925192 0.182117131,8.59090909 C0.182117131,9.9348049 0.476480421,11.2378669 1.03597896,12.4286969 L-0.819413277,16.762739 Z" fill-rule="nonzero" />\n        <g transform="translate(13.000000, 0.000000)">\n            <rect x="2" y="0" width="1" height="5" />\n            <rect transform="translate(2.500000, 2.500000) rotate(-90.000000) translate(-2.500000, -2.500000) " x="2" y="0" width="1" height="5" />\n        </g>\n        <rect x="5" y="8" width="9" height="1" />\n        <rect x="5" y="11" width="7" height="1" />\n        <rect x="5" y="5" width="7" height="1" />\n    </g>\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),c=r(s),d=n(7),f=r(d),p=n(6),h=r(p),m=n(11),g=r(m),v=n(18),y=r(v),b=n(3),x=n(60),_=r(x),k=n(61),w=r(k),C=n(62),E=r(C),T=n(63),O=r(T),M=n(64),S=r(M),N=n(65),P=r(N),L=function(e){function t(e){o(this,t);var n=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return n.state={tooltip:null,tooltipUserId:null},n}return i(t,e),u(t,[{key:"handleMouseOverAction",value:function(e,t){this.setState({tooltipUserId:null,tooltip:c.default.createElement(g.default,{rect:(0,b.rect)(e.target,{y:6})},t)})}},{key:"handleMouseOverUser",value:function(e,t,n){this.setState({tooltipUserId:t.id,tooltip:c.default.createElement(y.default,{rect:(0,b.rect)(e.target),user:n?l({},t,{name:t.name+" (you)"}):t})})}},{key:"handleMouseOut",value:function(){this.state.tooltip&&this.setState({tooltip:null,tooltipUserId:null})}},{key:"componentWillReceiveProps",value:function(e){var t=e.users,n=void 0===t?[]:t,r=this.state.tooltipUserId;r&&!n.find(function(e){return e.id===r})&&this.setState({tooltip:null,tooltipUserId:null})}},{key:"componentDidMount",value:function(){document.body.classList.add("pb44");var e=document.querySelector("en-debug");e&&(e.style.display="none")}},{key:"componentWillUnmount",value:function(){document.body.classList.remove("pb44");var e=document.querySelector("en-debug");e&&(e.style.display="")}},{key:"render",value:function(){var e=this,t=this.props,n=t.overlap,r=t.loading,o=t.error,a=t.users,i=void 0===a?[]:a,u=t.version,s=t.message,p=t.actions,m=this.state.tooltip,g=i.map(function(t,n){return c.default.createElement(f.default,l({},t,{key:n,onMouseOver:function(r){return e.handleMouseOverUser(r,t,n===i.length-1)},onMouseOut:function(){return e.handleMouseOut()}}))}),v=w.default;return o?v=_.default:r&&(v=E.default),c.default.createElement("div",{className:(0,b.css)(P.default.realtime,n&&P.default.overlap)},p&&c.default.createElement("div",{className:P.default.actions},p.archive&&c.default.createElement("div",{onMouseDown:p.archive,onMouseOver:function(t){return e.handleMouseOverAction(t,"Open comment archive")},onMouseOut:function(){return e.handleMouseOut()},className:P.default.action},c.default.createElement(h.default,{svg:S.default})),p.debug&&c.default.createElement("div",{onMouseDown:p.debug,onMouseOver:function(t){return e.handleMouseOverAction(t,"Debug RTE in demo client")},onMouseOut:function(){return e.handleMouseOut()},className:(0,b.css)(P.default.action)},c.default.createElement(h.default,{svg:O.default}))),c.default.createElement("div",{className:P.default.message},s),g&&c.default.createElement(d.AvatarGroup,{className:P.default.avatars},g),c.default.createElement("div",{className:(0,b.css)(P.default.status,r&&!o&&P.default.loading)},c.default.createElement(h.default,{svg:v})),c.default.createElement("div",{className:P.default.version},u),m)}}]),t}(s.Component);t.default=L},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"1dfhb",use:"1dfhb-usage",viewBox:"0 0 24 24",content:'<symbol viewBox="0 0 24 24" id="1dfhb">\n    <path d="M8.89949494,17.0968018 C7.10609083,16.0593735 5.89949494,14.120342 5.89949494,11.8994949 C5.89949494,9.67864787 7.10609083,7.73961637 8.89949494,6.70218811 L8.89949494,17.0968018 Z M14.8994949,6.70218811 C16.692899,7.73961637 17.8994949,9.67864787 17.8994949,11.8994949 C17.8994949,14.120342 16.692899,16.0593735 14.8994949,17.0968018 L14.8994949,6.70218811 Z M10.8994949,3.89949494 L12.8994949,3.89949494 L12.8994949,19.8994949 L10.8994949,19.8994949 L10.8994949,3.89949494 Z" fill="#FF776D" transform="translate(11.899495, 11.899495) rotate(-315.000000) translate(-11.899495, -11.899495) " />\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"770mq",use:"770mq-usage",viewBox:"0 0 24 24",content:'<symbol viewBox="0 0 24 24" id="770mq">\n    <path d="M10.6390873,17.5533009 L10.6213203,17.5710678 L6.02512627,12.9748737 C4.65829124,11.6080387 4.65829124,9.39196129 6.02512627,8.02512627 L6.02512627,8.02512627 L6.02512627,8.02512627 C7.39196129,6.65829124 9.60803871,6.65829124 10.9748737,8.02512627 L10.9748737,8.02512627 L11.5606602,8.6109127 L12.1464466,8.02512627 L12.1464466,8.02512627 C13.5132816,6.65829124 15.7293591,6.65829124 17.0961941,8.02512627 L17.0961941,8.02512627 L17.0961941,8.02512627 C18.4630291,9.39196129 18.4630291,11.6080387 17.0961941,12.9748737 L12.5,17.5710678 L12.482233,17.5533009 L12.267767,17.767767 C11.8772427,18.1582912 11.2440777,18.1582912 10.8535534,17.767767 L10.6390873,17.5533009 Z" fill="#A6D156" />\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"1-u9S",use:"1-u9S-usage",viewBox:"0 0 24 24",content:'<symbol viewBox="0 0 24 24" id="1-u9S">\n    <path d="M12,6 C15.3137085,6 18,8.6862915 18,12 C18,15.3137085 15.3137085,18 12,18 L12,16 C14.209139,16 16,14.209139 16,12 C16,9.790861 14.209139,8 12,8 C9.790861,8 8,9.790861 8,12 L6,12 C6,8.6862915 8.6862915,6 12,6 Z" fill="#FFD16D" />\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"2Os1K",use:"2Os1K-usage",viewBox:"0 0 24 24",content:'<symbol viewBox="0 0 24 24" id="2Os1K">\n    <path d="M-74 29h48v48h-48V29z" fill="none" />\n    <path d="M22 9V7h-2V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-2h2v-2h-2v-2h2v-2h-2V9h2zm-4 10H4V5h14v14zM6 13h5v4H6zm6-6h4v3h-4zM6 7h5v5H6zm6 4h4v6h-4z" />\n    <path d="M0 0h24v24H0zm0 0h24v24H0z" fill="none" />\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n.n(r),a=n(2),i=n.n(a),l=new o.a({id:"2d8uh",use:"2d8uh-usage",viewBox:"0 0 24 24",content:'<symbol viewBox="0 0 24 24" id="2d8uh">\n    <path d="M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z" />\n    <path d="M0 0h24v24H0z" fill="none" />\n</symbol>'});i.a.add(l);t.default=l},function(e,t,n){var r=n(66);"string"==typeof r&&(r=[[e.i,r,""]]);var o={hmr:!0};o.transform=void 0;n(5)(r,o);r.locals&&(e.exports=r.locals)},function(e,t,n){t=e.exports=n(4)(!1),t.push([e.i,'._1CH_M{position:fixed;bottom:0;left:0;right:0;height:44px;background-color:#fff;z-index:2147480640;display:flex;padding:0 14px;align-items:center;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial;color:#848484;font-size:12px}._1CH_M.LGCc8{box-shadow:0 -1px 2px rgba(0,0,0,.06)}.fullsize ._1CH_M{display:none}._2W93z{flex:1 1 auto;text-align:right;font-weight:lighter;font-size:13px;color:#c3c3c3;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;line-height:20px}._1cRh3,._2WZ8J{flex:0 0 auto}._2WZ8J{padding:0 12px 0 0;display:flex}._2WZ8J ._3cKJw{flex:0 0 auto;width:36px;height:36px;padding:8px;cursor:pointer;pointer-events:auto}._2WZ8J ._3cKJw:hover{color:#2dbe60}._2WZ8J ._3cKJw svg{pointer-events:none;fill:currentColor;position:relative;top:-1px}._1dZzc{padding:0 4px 0 12px}.-mD9M{flex:0 0 auto;height:24px;width:30px;padding:0 3px}.-mD9M:before{content:"";bottom:6px;right:16px;opacity:0;position:absolute;width:38px;height:44px;background:url(\'data:image/svg+xml;utf8,<svg width="38px" height="44px" viewBox="0 0 38 44" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M34,37.0702576 L34,15 C34,6.71572875 27.2842712,-1.52179594e-15 19,0 L19,0 L19,0 C10.7157288,1.52179594e-15 4,6.71572875 4,15 L4,15 L4,29 C4,37.2842712 10.7157288,44 19,44 L19,44 L27,44 L38,44 C38,41.0388706 36.3912055,38.4534952 34,37.0702576 Z" fill="#E9F0F8"></path><path d="M14,19 L19,19 L19,19 C19.5522847,19 20,19.4477153 20,20 L20,21 L20,21 C20,22.1045695 19.1045695,23 18,23 L15,23 L15,23 C13.8954305,23 13,22.1045695 13,21 L13,20 L13,20 C13,19.4477153 13.4477153,19 14,19 Z" fill="#93A2B3"></path><rect fill="#93A2B3" x="9" y="11" width="3" height="6" rx="1.5"></rect><rect fill="#93A2B3" x="21" y="11" width="3" height="6" rx="1.5"></rect><path d="M4,18 L4,18 L4,30 L2,30 L2,30 C0.8954305,30 1.3527075e-16,29.1045695 0,28 L0,22 L0,22 C-2.705415e-16,19.790861 1.790861,18 4,18 Z" fill="#D0DBE8"></path><path d="M33,18 L34,18 L34,30 L29,30 L29,30 C27.8954305,30 27,29.1045695 27,28 L27,24 L27,24 C27,20.6862915 29.6862915,18 33,18 Z" fill="#D0DBE8"></path></g></svg>\');animation:_1gwOI 2.4s ease-in-out}.-mD9M._3kl-W svg{animation:_2_fZ1 1.1s linear infinite}.-mD9M svg{width:24px;height:24px}@keyframes _2_fZ1{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes _1gwOI{0%{opacity:0;bottom:6px}65%{opacity:1;bottom:36px}90%{opacity:0}to{opacity:0;bottom:6px}}',""]),t.locals={realtime:"_1CH_M",overlap:"LGCc8",message:"_2W93z",version:"_1cRh3",actions:"_2WZ8J",action:"_3cKJw",avatars:"_1dZzc",status:"-mD9M",ghost:"_1gwOI",loading:"_3kl-W",spin:"_2_fZ1"}}]);var CLOSURE_NO_DEPS = true;
var COMPILED = false;
var goog = goog || {};
goog.global = this;
goog.global.CLOSURE_UNCOMPILED_DEFINES;
goog.global.CLOSURE_DEFINES;
goog.isDef = function(val) {
  return val !== void 0;
};
goog.isString = function(val) {
  return typeof val == "string";
};
goog.isBoolean = function(val) {
  return typeof val == "boolean";
};
goog.isNumber = function(val) {
  return typeof val == "number";
};
goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
  var parts = name.split(".");
  var cur = opt_objectToExportTo || goog.global;
  if (!(parts[0] in cur) && cur.execScript) {
    cur.execScript("var " + parts[0]);
  }
  for (var part; parts.length && (part = parts.shift());) {
    if (!parts.length && goog.isDef(opt_object)) {
      cur[part] = opt_object;
    } else {
      if (cur[part] && cur[part] !== Object.prototype[part]) {
        cur = cur[part];
      } else {
        cur = cur[part] = {};
      }
    }
  }
};
goog.define = function(name, defaultValue) {
  var value = defaultValue;
  if (!COMPILED) {
    if (goog.global.CLOSURE_UNCOMPILED_DEFINES && goog.global.CLOSURE_UNCOMPILED_DEFINES.nodeType === undefined && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) {
      value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name];
    } else {
      if (goog.global.CLOSURE_DEFINES && goog.global.CLOSURE_DEFINES.nodeType === undefined && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES, name)) {
        value = goog.global.CLOSURE_DEFINES[name];
      }
    }
  }
  goog.exportPath_(name, value);
};
goog.define("goog.DEBUG", true);
goog.define("goog.LOCALE", "en");
goog.define("goog.TRUSTED_SITE", true);
goog.define("goog.STRICT_MODE_COMPATIBLE", false);
goog.define("goog.DISALLOW_TEST_ONLY_CODE", COMPILED && !goog.DEBUG);
goog.define("goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING", false);
goog.provide = function(name) {
  if (goog.isInModuleLoader_()) {
    throw Error("goog.provide can not be used within a goog.module.");
  }
  if (!COMPILED) {
    if (goog.isProvided_(name)) {
      throw Error('Namespace "' + name + '" already declared.');
    }
  }
  goog.constructNamespace_(name);
};
goog.constructNamespace_ = function(name, opt_obj) {
  if (!COMPILED) {
    delete goog.implicitNamespaces_[name];
    var namespace = name;
    while (namespace = namespace.substring(0, namespace.lastIndexOf("."))) {
      if (goog.getObjectByName(namespace)) {
        break;
      }
      goog.implicitNamespaces_[namespace] = true;
    }
  }
  goog.exportPath_(name, opt_obj);
};
goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;
goog.module = function(name) {
  if (!goog.isString(name) || !name || name.search(goog.VALID_MODULE_RE_) == -1) {
    throw Error("Invalid module identifier");
  }
  if (!goog.isInModuleLoader_()) {
    throw Error("Module " + name + " has been loaded incorrectly. Note, " + "modules cannot be loaded as normal scripts. They require some kind of " + "pre-processing step. You're likely trying to load a module via a " + "script tag or as a part of a concatenated bundle without rewriting the " + "module. For more info see: " + "https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.");
  }
  if (goog.moduleLoaderState_.moduleName) {
    throw Error("goog.module may only be called once per module.");
  }
  goog.moduleLoaderState_.moduleName = name;
  if (!COMPILED) {
    if (goog.isProvided_(name)) {
      throw Error('Namespace "' + name + '" already declared.');
    }
    delete goog.implicitNamespaces_[name];
  }
};
goog.module.get = function(name) {
  return goog.module.getInternal_(name);
};
goog.module.getInternal_ = function(name) {
  if (!COMPILED) {
    if (name in goog.loadedModules_) {
      return goog.loadedModules_[name];
    } else {
      if (!goog.implicitNamespaces_[name]) {
        var ns = goog.getObjectByName(name);
        return ns != null ? ns : null;
      }
    }
  }
  return null;
};
goog.moduleLoaderState_ = null;
goog.isInModuleLoader_ = function() {
  return goog.moduleLoaderState_ != null;
};
goog.module.declareLegacyNamespace = function() {
  if (!COMPILED && !goog.isInModuleLoader_()) {
    throw new Error("goog.module.declareLegacyNamespace must be called from " + "within a goog.module");
  }
  if (!COMPILED && !goog.moduleLoaderState_.moduleName) {
    throw Error("goog.module must be called prior to " + "goog.module.declareLegacyNamespace.");
  }
  goog.moduleLoaderState_.declareLegacyNamespace = true;
};
goog.setTestOnly = function(opt_message) {
  if (goog.DISALLOW_TEST_ONLY_CODE) {
    opt_message = opt_message || "";
    throw Error("Importing test-only code into non-debug environment" + (opt_message ? ": " + opt_message : "."));
  }
};
goog.forwardDeclare = function(name) {
};
goog.forwardDeclare("Document");
goog.forwardDeclare("HTMLScriptElement");
goog.forwardDeclare("XMLHttpRequest");
if (!COMPILED) {
  goog.isProvided_ = function(name) {
    return name in goog.loadedModules_ || !goog.implicitNamespaces_[name] && goog.isDefAndNotNull(goog.getObjectByName(name));
  };
  goog.implicitNamespaces_ = {"goog.module":true};
}
goog.getObjectByName = function(name, opt_obj) {
  var parts = name.split(".");
  var cur = opt_obj || goog.global;
  for (var part; part = parts.shift();) {
    if (goog.isDefAndNotNull(cur[part])) {
      cur = cur[part];
    } else {
      return null;
    }
  }
  return cur;
};
goog.globalize = function(obj, opt_global) {
  var global = opt_global || goog.global;
  for (var x in obj) {
    global[x] = obj[x];
  }
};
goog.addDependency = function(relPath, provides, requires, opt_loadFlags) {
  if (goog.DEPENDENCIES_ENABLED) {
    var provide, require;
    var path = relPath.replace(/\\/g, "/");
    var deps = goog.dependencies_;
    if (!opt_loadFlags || typeof opt_loadFlags === "boolean") {
      opt_loadFlags = opt_loadFlags ? {"module":"goog"} : {};
    }
    for (var i = 0; provide = provides[i]; i++) {
      deps.nameToPath[provide] = path;
      deps.loadFlags[path] = opt_loadFlags;
    }
    for (var j = 0; require = requires[j]; j++) {
      if (!(path in deps.requires)) {
        deps.requires[path] = {};
      }
      deps.requires[path][require] = true;
    }
  }
};
goog.define("goog.ENABLE_DEBUG_LOADER", true);
goog.logToConsole_ = function(msg) {
  if (goog.global.console) {
    goog.global.console["error"](msg);
  }
};
goog.require = function(name) {
  if (!COMPILED) {
    if (goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_) {
      goog.maybeProcessDeferredDep_(name);
    }
    if (goog.isProvided_(name)) {
      if (goog.isInModuleLoader_()) {
        return goog.module.getInternal_(name);
      }
    } else {
      if (goog.ENABLE_DEBUG_LOADER) {
        var path = goog.getPathFromDeps_(name);
        if (path) {
          goog.writeScripts_(path);
        } else {
          var errorMessage = "goog.require could not find: " + name;
          goog.logToConsole_(errorMessage);
          throw Error(errorMessage);
        }
      }
    }
    return null;
  }
};
goog.basePath = "";
goog.global.CLOSURE_BASE_PATH;
goog.global.CLOSURE_NO_DEPS;
goog.global.CLOSURE_IMPORT_SCRIPT;
goog.nullFunction = function() {
};
goog.abstractMethod = function() {
  throw Error("unimplemented abstract method");
};
goog.addSingletonGetter = function(ctor) {
  ctor.instance_ = undefined;
  ctor.getInstance = function() {
    if (ctor.instance_) {
      return ctor.instance_;
    }
    if (goog.DEBUG) {
      goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;
    }
    return ctor.instance_ = new ctor;
  };
};
goog.instantiatedSingletons_ = [];
goog.define("goog.LOAD_MODULE_USING_EVAL", true);
goog.define("goog.SEAL_MODULE_EXPORTS", goog.DEBUG);
goog.loadedModules_ = {};
goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
goog.define("goog.TRANSPILE", "detect");
goog.define("goog.TRANSPILER", "transpile.js");
if (goog.DEPENDENCIES_ENABLED) {
  goog.dependencies_ = {loadFlags:{}, nameToPath:{}, requires:{}, visited:{}, written:{}, deferred:{}};
  goog.inHtmlDocument_ = function() {
    var doc = goog.global.document;
    return doc != null && "write" in doc;
  };
  goog.findBasePath_ = function() {
    if (goog.isDef(goog.global.CLOSURE_BASE_PATH) && goog.isString(goog.global.CLOSURE_BASE_PATH)) {
      goog.basePath = goog.global.CLOSURE_BASE_PATH;
      return;
    } else {
      if (!goog.inHtmlDocument_()) {
        return;
      }
    }
    var doc = goog.global.document;
    var currentScript = doc.currentScript;
    if (currentScript) {
      var scripts = [currentScript];
    } else {
      var scripts = doc.getElementsByTagName("SCRIPT");
    }
    for (var i = scripts.length - 1; i >= 0; --i) {
      var script = scripts[i];
      var src = script.src;
      var qmark = src.lastIndexOf("?");
      var l = qmark == -1 ? src.length : qmark;
      if (src.substr(l - 7, 7) == "base.js") {
        goog.basePath = src.substr(0, l - 7);
        return;
      }
    }
  };
  goog.importScript_ = function(src, opt_sourceText) {
    var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_;
    if (importScript(src, opt_sourceText)) {
      goog.dependencies_.written[src] = true;
    }
  };
  goog.IS_OLD_IE_ = !!(!goog.global.atob && goog.global.document && goog.global.document.all);
  goog.oldIeWaiting_ = false;
  goog.importProcessedScript_ = function(src, isModule, needsTranspile) {
    var bootstrap = 'goog.retrieveAndExec_("' + src + '", ' + isModule + ", " + needsTranspile + ");";
    goog.importScript_("", bootstrap);
  };
  goog.queuedModules_ = [];
  goog.wrapModule_ = function(srcUrl, scriptText) {
    if (!goog.LOAD_MODULE_USING_EVAL || !goog.isDef(goog.global.JSON)) {
      return "" + "goog.loadModule(function(exports) {" + '"use strict";' + scriptText + "\n" + ";return exports" + "});" + "\n//# sourceURL=" + srcUrl + "\n";
    } else {
      return "" + "goog.loadModule(" + goog.global.JSON.stringify(scriptText + "\n//# sourceURL=" + srcUrl + "\n") + ");";
    }
  };
  goog.loadQueuedModules_ = function() {
    var count = goog.queuedModules_.length;
    if (count > 0) {
      var queue = goog.queuedModules_;
      goog.queuedModules_ = [];
      for (var i = 0; i < count; i++) {
        var path = queue[i];
        goog.maybeProcessDeferredPath_(path);
      }
    }
    goog.oldIeWaiting_ = false;
  };
  goog.maybeProcessDeferredDep_ = function(name) {
    if (goog.isDeferredModule_(name) && goog.allDepsAreAvailable_(name)) {
      var path = goog.getPathFromDeps_(name);
      goog.maybeProcessDeferredPath_(goog.basePath + path);
    }
  };
  goog.isDeferredModule_ = function(name) {
    var path = goog.getPathFromDeps_(name);
    var loadFlags = path && goog.dependencies_.loadFlags[path] || {};
    var languageLevel = loadFlags["lang"] || "es3";
    if (path && (loadFlags["module"] == "goog" || goog.needsTranspile_(languageLevel))) {
      var abspath = goog.basePath + path;
      return abspath in goog.dependencies_.deferred;
    }
    return false;
  };
  goog.allDepsAreAvailable_ = function(name) {
    var path = goog.getPathFromDeps_(name);
    if (path && path in goog.dependencies_.requires) {
      for (var requireName in goog.dependencies_.requires[path]) {
        if (!goog.isProvided_(requireName) && !goog.isDeferredModule_(requireName)) {
          return false;
        }
      }
    }
    return true;
  };
  goog.maybeProcessDeferredPath_ = function(abspath) {
    if (abspath in goog.dependencies_.deferred) {
      var src = goog.dependencies_.deferred[abspath];
      delete goog.dependencies_.deferred[abspath];
      goog.globalEval(src);
    }
  };
  goog.loadModuleFromUrl = function(url) {
    goog.retrieveAndExec_(url, true, false);
  };
  goog.writeScriptSrcNode_ = function(src) {
    goog.global.document.write('<script type="text/javascript" src="' + src + '"></' + "script>");
  };
  goog.appendScriptSrcNode_ = function(src) {
    var doc = goog.global.document;
    var scriptEl = doc.createElement("script");
    scriptEl.type = "text/javascript";
    scriptEl.src = src;
    scriptEl.defer = false;
    scriptEl.async = false;
    doc.head.appendChild(scriptEl);
  };
  goog.writeScriptTag_ = function(src, opt_sourceText) {
    if (goog.inHtmlDocument_()) {
      var doc = goog.global.document;
      if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING && doc.readyState == "complete") {
        var isDeps = /\bdeps.js$/.test(src);
        if (isDeps) {
          return false;
        } else {
          throw Error('Cannot write "' + src + '" after document load');
        }
      }
      if (opt_sourceText === undefined) {
        if (!goog.IS_OLD_IE_) {
          if (goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING) {
            goog.appendScriptSrcNode_(src);
          } else {
            goog.writeScriptSrcNode_(src);
          }
        } else {
          goog.oldIeWaiting_ = true;
          var state = " onreadystatechange='goog.onScriptLoad_(this, " + ++goog.lastNonModuleScriptIndex_ + ")' ";
          doc.write('<script type="text/javascript" src="' + src + '"' + state + "></" + "script>");
        }
      } else {
        doc.write('<script type="text/javascript">' + goog.protectScriptTag_(opt_sourceText) + "</" + "script>");
      }
      return true;
    } else {
      return false;
    }
  };
  goog.protectScriptTag_ = function(str) {
    return str.replace(/<\/(SCRIPT)/ig, "\\x3c/$1");
  };
  goog.needsTranspile_ = function(lang) {
    if (goog.TRANSPILE == "always") {
      return true;
    } else {
      if (goog.TRANSPILE == "never") {
        return false;
      } else {
        if (!goog.requiresTranspilation_) {
          goog.requiresTranspilation_ = goog.createRequiresTranspilation_();
        }
      }
    }
    if (lang in goog.requiresTranspilation_) {
      return goog.requiresTranspilation_[lang];
    } else {
      throw new Error("Unknown language mode: " + lang);
    }
  };
  goog.requiresTranspilation_ = null;
  goog.lastNonModuleScriptIndex_ = 0;
  goog.onScriptLoad_ = function(script, scriptIndex) {
    if (script.readyState == "complete" && goog.lastNonModuleScriptIndex_ == scriptIndex) {
      goog.loadQueuedModules_();
    }
    return true;
  };
  goog.writeScripts_ = function(pathToLoad) {
    var scripts = [];
    var seenScript = {};
    var deps = goog.dependencies_;
    function visitNode(path) {
      if (path in deps.written) {
        return;
      }
      if (path in deps.visited) {
        return;
      }
      deps.visited[path] = true;
      if (path in deps.requires) {
        for (var requireName in deps.requires[path]) {
          if (!goog.isProvided_(requireName)) {
            if (requireName in deps.nameToPath) {
              visitNode(deps.nameToPath[requireName]);
            } else {
              throw Error("Undefined nameToPath for " + requireName);
            }
          }
        }
      }
      if (!(path in seenScript)) {
        seenScript[path] = true;
        scripts.push(path);
      }
    }
    visitNode(pathToLoad);
    for (var i = 0; i < scripts.length; i++) {
      var path = scripts[i];
      goog.dependencies_.written[path] = true;
    }
    var moduleState = goog.moduleLoaderState_;
    goog.moduleLoaderState_ = null;
    for (var i = 0; i < scripts.length; i++) {
      var path = scripts[i];
      if (path) {
        var loadFlags = deps.loadFlags[path] || {};
        var languageLevel = loadFlags["lang"] || "es3";
        var needsTranspile = goog.needsTranspile_(languageLevel);
        if (loadFlags["module"] == "goog" || needsTranspile) {
          goog.importProcessedScript_(goog.basePath + path, loadFlags["module"] == "goog", needsTranspile);
        } else {
          goog.importScript_(goog.basePath + path);
        }
      } else {
        goog.moduleLoaderState_ = moduleState;
        throw Error("Undefined script input");
      }
    }
    goog.moduleLoaderState_ = moduleState;
  };
  goog.getPathFromDeps_ = function(rule) {
    if (rule in goog.dependencies_.nameToPath) {
      return goog.dependencies_.nameToPath[rule];
    } else {
      return null;
    }
  };
  goog.findBasePath_();
  if (!goog.global.CLOSURE_NO_DEPS) {
    goog.importScript_(goog.basePath + "deps.js");
  }
}
goog.hasBadLetScoping = null;
goog.useSafari10Workaround = function() {
  if (goog.hasBadLetScoping == null) {
    var hasBadLetScoping;
    try {
      hasBadLetScoping = !eval('"use strict";' + "let x = 1; function f() { return typeof x; };" + 'f() == "number";');
    } catch (e) {
      hasBadLetScoping = false;
    }
    goog.hasBadLetScoping = hasBadLetScoping;
  }
  return goog.hasBadLetScoping;
};
goog.workaroundSafari10EvalBug = function(moduleDef) {
  return "(function(){" + moduleDef + "\n" + ";" + "})();\n";
};
goog.loadModule = function(moduleDef) {
  var previousState = goog.moduleLoaderState_;
  try {
    goog.moduleLoaderState_ = {moduleName:undefined, declareLegacyNamespace:false};
    var exports;
    if (goog.isFunction(moduleDef)) {
      exports = moduleDef.call(undefined, {});
    } else {
      if (goog.isString(moduleDef)) {
        if (goog.useSafari10Workaround()) {
          moduleDef = goog.workaroundSafari10EvalBug(moduleDef);
        }
        exports = goog.loadModuleFromSource_.call(undefined, moduleDef);
      } else {
        throw Error("Invalid module definition");
      }
    }
    var moduleName = goog.moduleLoaderState_.moduleName;
    if (!goog.isString(moduleName) || !moduleName) {
      throw Error('Invalid module name "' + moduleName + '"');
    }
    if (goog.moduleLoaderState_.declareLegacyNamespace) {
      goog.constructNamespace_(moduleName, exports);
    } else {
      if (goog.SEAL_MODULE_EXPORTS && Object.seal && typeof exports == "object" && exports != null) {
        Object.seal(exports);
      }
    }
    goog.loadedModules_[moduleName] = exports;
  } finally {
    goog.moduleLoaderState_ = previousState;
  }
};
goog.loadModuleFromSource_ = function() {
  var exports = {};
  eval(arguments[0]);
  return exports;
};
goog.normalizePath_ = function(path) {
  var components = path.split("/");
  var i = 0;
  while (i < components.length) {
    if (components[i] == ".") {
      components.splice(i, 1);
    } else {
      if (i && components[i] == ".." && components[i - 1] && components[i - 1] != "..") {
        components.splice(--i, 2);
      } else {
        i++;
      }
    }
  }
  return components.join("/");
};
goog.global.CLOSURE_LOAD_FILE_SYNC;
goog.loadFileSync_ = function(src) {
  if (goog.global.CLOSURE_LOAD_FILE_SYNC) {
    return goog.global.CLOSURE_LOAD_FILE_SYNC(src);
  } else {
    try {
      var xhr = new goog.global["XMLHttpRequest"];
      xhr.open("get", src, false);
      xhr.send();
      return xhr.status == 0 || xhr.status == 200 ? xhr.responseText : null;
    } catch (err$0) {
      return null;
    }
  }
};
goog.retrieveAndExec_ = function(src, isModule, needsTranspile) {
  if (!COMPILED) {
    var originalPath = src;
    src = goog.normalizePath_(src);
    var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_;
    var scriptText = goog.loadFileSync_(src);
    if (scriptText == null) {
      throw new Error('Load of "' + src + '" failed');
    }
    if (needsTranspile) {
      scriptText = goog.transpile_.call(goog.global, scriptText, src);
    }
    if (isModule) {
      scriptText = goog.wrapModule_(src, scriptText);
    } else {
      scriptText += "\n//# sourceURL=" + src;
    }
    var isOldIE = goog.IS_OLD_IE_;
    if (isOldIE && goog.oldIeWaiting_) {
      goog.dependencies_.deferred[originalPath] = scriptText;
      goog.queuedModules_.push(originalPath);
    } else {
      importScript(src, scriptText);
    }
  }
};
goog.transpile_ = function(code, path) {
  var jscomp = goog.global["$jscomp"];
  if (!jscomp) {
    goog.global["$jscomp"] = jscomp = {};
  }
  var transpile = jscomp.transpile;
  if (!transpile) {
    var transpilerPath = goog.basePath + goog.TRANSPILER;
    var transpilerCode = goog.loadFileSync_(transpilerPath);
    if (transpilerCode) {
      eval(transpilerCode + "\n//# sourceURL=" + transpilerPath);
      if (goog.global["$gwtExport"] && goog.global["$gwtExport"]["$jscomp"] && !goog.global["$gwtExport"]["$jscomp"]["transpile"]) {
        throw new Error('The transpiler did not properly export the "transpile" ' + "method. $gwtExport: " + JSON.stringify(goog.global["$gwtExport"]));
      }
      goog.global["$jscomp"].transpile = goog.global["$gwtExport"]["$jscomp"]["transpile"];
      jscomp = goog.global["$jscomp"];
      transpile = jscomp.transpile;
    }
  }
  if (!transpile) {
    var suffix = " requires transpilation but no transpiler was found.";
    transpile = jscomp.transpile = function(code, path) {
      goog.logToConsole_(path + suffix);
      return code;
    };
  }
  return transpile(code, path);
};
goog.typeOf = function(value) {
  var s = typeof value;
  if (s == "object") {
    if (value) {
      if (value instanceof Array) {
        return "array";
      } else {
        if (value instanceof Object) {
          return s;
        }
      }
      var className = Object.prototype.toString.call(value);
      if (className == "[object Window]") {
        return "object";
      }
      if (className == "[object Array]" || typeof value.length == "number" && typeof value.splice != "undefined" && typeof value.propertyIsEnumerable != "undefined" && !value.propertyIsEnumerable("splice")) {
        return "array";
      }
      if (className == "[object Function]" || typeof value.call != "undefined" && typeof value.propertyIsEnumerable != "undefined" && !value.propertyIsEnumerable("call")) {
        return "function";
      }
    } else {
      return "null";
    }
  } else {
    if (s == "function" && typeof value.call == "undefined") {
      return "object";
    }
  }
  return s;
};
goog.isNull = function(val) {
  return val === null;
};
goog.isDefAndNotNull = function(val) {
  return val != null;
};
goog.isArray = function(val) {
  return goog.typeOf(val) == "array";
};
goog.isArrayLike = function(val) {
  var type = goog.typeOf(val);
  return type == "array" || type == "object" && typeof val.length == "number";
};
goog.isDateLike = function(val) {
  return goog.isObject(val) && typeof val.getFullYear == "function";
};
goog.isFunction = function(val) {
  return goog.typeOf(val) == "function";
};
goog.isObject = function(val) {
  var type = typeof val;
  return type == "object" && val != null || type == "function";
};
goog.getUid = function(obj) {
  return obj[goog.UID_PROPERTY_] || (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);
};
goog.hasUid = function(obj) {
  return !!obj[goog.UID_PROPERTY_];
};
goog.removeUid = function(obj) {
  if (obj !== null && "removeAttribute" in obj) {
    obj.removeAttribute(goog.UID_PROPERTY_);
  }
  try {
    delete obj[goog.UID_PROPERTY_];
  } catch (ex) {
  }
};
goog.UID_PROPERTY_ = "closure_uid_" + (Math.random() * 1e9 >>> 0);
goog.uidCounter_ = 0;
goog.getHashCode = goog.getUid;
goog.removeHashCode = goog.removeUid;
goog.cloneObject = function(obj) {
  var type = goog.typeOf(obj);
  if (type == "object" || type == "array") {
    if (obj.clone) {
      return obj.clone();
    }
    var clone = type == "array" ? [] : {};
    for (var key in obj) {
      clone[key] = goog.cloneObject(obj[key]);
    }
    return clone;
  }
  return obj;
};
goog.bindNative_ = function(fn, selfObj, var_args) {
  return fn.call.apply(fn.bind, arguments);
};
goog.bindJs_ = function(fn, selfObj, var_args) {
  if (!fn) {
    throw new Error;
  }
  if (arguments.length > 2) {
    var boundArgs = Array.prototype.slice.call(arguments, 2);
    return function() {
      var newArgs = Array.prototype.slice.call(arguments);
      Array.prototype.unshift.apply(newArgs, boundArgs);
      return fn.apply(selfObj, newArgs);
    };
  } else {
    return function() {
      return fn.apply(selfObj, arguments);
    };
  }
};
goog.bind = function(fn, selfObj, var_args) {
  if (Function.prototype.bind && Function.prototype.bind.toString().indexOf("native code") != -1) {
    goog.bind = goog.bindNative_;
  } else {
    goog.bind = goog.bindJs_;
  }
  return goog.bind.apply(null, arguments);
};
goog.partial = function(fn, var_args) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function() {
    var newArgs = args.slice();
    newArgs.push.apply(newArgs, arguments);
    return fn.apply(this, newArgs);
  };
};
goog.mixin = function(target, source) {
  for (var x in source) {
    target[x] = source[x];
  }
};
goog.now = goog.TRUSTED_SITE && Date.now || function() {
  return +new Date;
};
goog.globalEval = function(script) {
  if (goog.global.execScript) {
    goog.global.execScript(script, "JavaScript");
  } else {
    if (goog.global.eval) {
      if (goog.evalWorksForGlobals_ == null) {
        goog.global.eval("var _evalTest_ = 1;");
        if (typeof goog.global["_evalTest_"] != "undefined") {
          try {
            delete goog.global["_evalTest_"];
          } catch (ignore) {
          }
          goog.evalWorksForGlobals_ = true;
        } else {
          goog.evalWorksForGlobals_ = false;
        }
      }
      if (goog.evalWorksForGlobals_) {
        goog.global.eval(script);
      } else {
        var doc = goog.global.document;
        var scriptElt = doc.createElement("SCRIPT");
        scriptElt.type = "text/javascript";
        scriptElt.defer = false;
        scriptElt.appendChild(doc.createTextNode(script));
        doc.body.appendChild(scriptElt);
        doc.body.removeChild(scriptElt);
      }
    } else {
      throw Error("goog.globalEval not available");
    }
  }
};
goog.evalWorksForGlobals_ = null;
goog.cssNameMapping_;
goog.cssNameMappingStyle_;
goog.global.CLOSURE_CSS_NAME_MAP_FN;
goog.getCssName = function(className, opt_modifier) {
  if (String(className).charAt(0) == ".") {
    throw new Error('className passed in goog.getCssName must not start with ".".' + " You passed: " + className);
  }
  var getMapping = function(cssName) {
    return goog.cssNameMapping_[cssName] || cssName;
  };
  var renameByParts = function(cssName) {
    var parts = cssName.split("-");
    var mapped = [];
    for (var i = 0; i < parts.length; i++) {
      mapped.push(getMapping(parts[i]));
    }
    return mapped.join("-");
  };
  var rename;
  if (goog.cssNameMapping_) {
    rename = goog.cssNameMappingStyle_ == "BY_WHOLE" ? getMapping : renameByParts;
  } else {
    rename = function(a) {
      return a;
    };
  }
  var result = opt_modifier ? className + "-" + rename(opt_modifier) : rename(className);
  if (goog.global.CLOSURE_CSS_NAME_MAP_FN) {
    return goog.global.CLOSURE_CSS_NAME_MAP_FN(result);
  }
  return result;
};
goog.setCssNameMapping = function(mapping, opt_style) {
  goog.cssNameMapping_ = mapping;
  goog.cssNameMappingStyle_ = opt_style;
};
goog.global.CLOSURE_CSS_NAME_MAPPING;
if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {
  goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;
}
goog.getMsg = function(str, opt_values) {
  if (opt_values) {
    str = str.replace(/\{\$([^}]+)}/g, function(match, key) {
      return opt_values != null && key in opt_values ? opt_values[key] : match;
    });
  }
  return str;
};
goog.getMsgWithFallback = function(a, b) {
  return a;
};
goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
  goog.exportPath_(publicPath, object, opt_objectToExportTo);
};
goog.exportProperty = function(object, publicName, symbol) {
  object[publicName] = symbol;
};
goog.inherits = function(childCtor, parentCtor) {
  function tempCtor() {
  }
  tempCtor.prototype = parentCtor.prototype;
  childCtor.superClass_ = parentCtor.prototype;
  childCtor.prototype = new tempCtor;
  childCtor.prototype.constructor = childCtor;
  childCtor.base = function(me, methodName, var_args) {
    var args = new Array(arguments.length - 2);
    for (var i = 2; i < arguments.length; i++) {
      args[i - 2] = arguments[i];
    }
    return parentCtor.prototype[methodName].apply(me, args);
  };
};
goog.base = function(me, opt_methodName, var_args) {
  var caller = arguments.callee.caller;
  if (goog.STRICT_MODE_COMPATIBLE || goog.DEBUG && !caller) {
    throw Error("arguments.caller not defined.  goog.base() cannot be used " + "with strict mode code. See " + "http://www.ecma-international.org/ecma-262/5.1/#sec-C");
  }
  if (caller.superClass_) {
    var ctorArgs = new Array(arguments.length - 1);
    for (var i = 1; i < arguments.length; i++) {
      ctorArgs[i - 1] = arguments[i];
    }
    return caller.superClass_.constructor.apply(me, ctorArgs);
  }
  var args = new Array(arguments.length - 2);
  for (var i = 2; i < arguments.length; i++) {
    args[i - 2] = arguments[i];
  }
  var foundCaller = false;
  for (var ctor = me.constructor; ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {
    if (ctor.prototype[opt_methodName] === caller) {
      foundCaller = true;
    } else {
      if (foundCaller) {
        return ctor.prototype[opt_methodName].apply(me, args);
      }
    }
  }
  if (me[opt_methodName] === caller) {
    return me.constructor.prototype[opt_methodName].apply(me, args);
  } else {
    throw Error("goog.base called from a method of one name " + "to a method of a different name");
  }
};
goog.scope = function(fn) {
  if (goog.isInModuleLoader_()) {
    throw Error("goog.scope is not supported within a goog.module.");
  }
  fn.call(goog.global);
};
if (!COMPILED) {
  goog.global["COMPILED"] = COMPILED;
}
goog.defineClass = function(superClass, def) {
  var constructor = def.constructor;
  var statics = def.statics;
  if (!constructor || constructor == Object.prototype.constructor) {
    constructor = function() {
      throw Error("cannot instantiate an interface (no constructor defined).");
    };
  }
  var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);
  if (superClass) {
    goog.inherits(cls, superClass);
  }
  delete def.constructor;
  delete def.statics;
  goog.defineClass.applyProperties_(cls.prototype, def);
  if (statics != null) {
    if (statics instanceof Function) {
      statics(cls);
    } else {
      goog.defineClass.applyProperties_(cls, statics);
    }
  }
  return cls;
};
goog.defineClass.ClassDescriptor;
goog.define("goog.defineClass.SEAL_CLASS_INSTANCES", goog.DEBUG);
goog.defineClass.createSealingConstructor_ = function(ctr, superClass) {
  if (!goog.defineClass.SEAL_CLASS_INSTANCES) {
    return ctr;
  }
  var superclassSealable = !goog.defineClass.isUnsealable_(superClass);
  var wrappedCtr = function() {
    var instance = ctr.apply(this, arguments) || this;
    instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];
    if (this.constructor === wrappedCtr && superclassSealable && Object.seal instanceof Function) {
      Object.seal(instance);
    }
    return instance;
  };
  return wrappedCtr;
};
goog.defineClass.isUnsealable_ = function(ctr) {
  return ctr && ctr.prototype && ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_];
};
goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"];
goog.defineClass.applyProperties_ = function(target, source) {
  var key;
  for (key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      target[key] = source[key];
    }
  }
  for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {
    key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      target[key] = source[key];
    }
  }
};
goog.tagUnsealableClass = function(ctr) {
  if (!COMPILED && goog.defineClass.SEAL_CLASS_INSTANCES) {
    ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_] = true;
  }
};
goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = "goog_defineClass_legacy_unsealable";
goog.createRequiresTranspilation_ = function() {
  var requiresTranspilation = {"es3":false};
  var transpilationRequiredForAllLaterModes = false;
  function addNewerLanguageTranspilationCheck(modeName, isSupported) {
    if (transpilationRequiredForAllLaterModes) {
      requiresTranspilation[modeName] = true;
    } else {
      if (isSupported()) {
        requiresTranspilation[modeName] = false;
      } else {
        requiresTranspilation[modeName] = true;
        transpilationRequiredForAllLaterModes = true;
      }
    }
  }
  function evalCheck(code) {
    try {
      return !!eval(code);
    } catch (ignored) {
      return false;
    }
  }
  var userAgent = goog.global.navigator && goog.global.navigator.userAgent ? goog.global.navigator.userAgent : "";
  addNewerLanguageTranspilationCheck("es5", function() {
    return evalCheck("[1,].length==1");
  });
  addNewerLanguageTranspilationCheck("es6", function() {
    var re = /Edge\/(\d+)(\.\d)*/i;
    var edgeUserAgent = userAgent.match(re);
    if (edgeUserAgent && Number(edgeUserAgent[1]) < 15) {
      return false;
    }
    var es6fullTest = "class X{constructor(){if(new.target!=String)throw 1;this.x=42}}" + "let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof " + "String))throw 1;for(const a of[2,3]){if(a==2)continue;function " + "f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()" + "==3}";
    return evalCheck('(()=>{"use strict";' + es6fullTest + "})()");
  });
  addNewerLanguageTranspilationCheck("es6-impl", function() {
    return true;
  });
  addNewerLanguageTranspilationCheck("es7", function() {
    return evalCheck("2 ** 2 == 4");
  });
  addNewerLanguageTranspilationCheck("es8", function() {
    return evalCheck("async () => 1, true");
  });
  return requiresTranspilation;
};
goog.provide("goog.debug.Error");
goog.debug.Error = function(opt_msg) {
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, goog.debug.Error);
  } else {
    var stack = (new Error).stack;
    if (stack) {
      this.stack = stack;
    }
  }
  if (opt_msg) {
    this.message = String(opt_msg);
  }
  this.reportErrorToServer = true;
};
goog.inherits(goog.debug.Error, Error);
goog.debug.Error.prototype.name = "CustomError";
goog.provide("goog.dom.NodeType");
goog.dom.NodeType = {ELEMENT:1, ATTRIBUTE:2, TEXT:3, CDATA_SECTION:4, ENTITY_REFERENCE:5, ENTITY:6, PROCESSING_INSTRUCTION:7, COMMENT:8, DOCUMENT:9, DOCUMENT_TYPE:10, DOCUMENT_FRAGMENT:11, NOTATION:12};
goog.provide("goog.string");
goog.provide("goog.string.Unicode");
goog.define("goog.string.DETECT_DOUBLE_ESCAPING", false);
goog.define("goog.string.FORCE_NON_DOM_HTML_UNESCAPING", false);
goog.string.Unicode = {NBSP:"\u00a0"};
goog.string.startsWith = function(str, prefix) {
  return str.lastIndexOf(prefix, 0) == 0;
};
goog.string.endsWith = function(str, suffix) {
  var l = str.length - suffix.length;
  return l >= 0 && str.indexOf(suffix, l) == l;
};
goog.string.caseInsensitiveStartsWith = function(str, prefix) {
  return goog.string.caseInsensitiveCompare(prefix, str.substr(0, prefix.length)) == 0;
};
goog.string.caseInsensitiveEndsWith = function(str, suffix) {
  return goog.string.caseInsensitiveCompare(suffix, str.substr(str.length - suffix.length, suffix.length)) == 0;
};
goog.string.caseInsensitiveEquals = function(str1, str2) {
  return str1.toLowerCase() == str2.toLowerCase();
};
goog.string.subs = function(str, var_args) {
  var splitParts = str.split("%s");
  var returnString = "";
  var subsArguments = Array.prototype.slice.call(arguments, 1);
  while (subsArguments.length && splitParts.length > 1) {
    returnString += splitParts.shift() + subsArguments.shift();
  }
  return returnString + splitParts.join("%s");
};
goog.string.collapseWhitespace = function(str) {
  return str.replace(/[\s\xa0]+/g, " ").replace(/^\s+|\s+$/g, "");
};
goog.string.isEmptyOrWhitespace = function(str) {
  return /^[\s\xa0]*$/.test(str);
};
goog.string.isEmptyString = function(str) {
  return str.length == 0;
};
goog.string.isEmpty = goog.string.isEmptyOrWhitespace;
goog.string.isEmptyOrWhitespaceSafe = function(str) {
  return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str));
};
goog.string.isEmptySafe = goog.string.isEmptyOrWhitespaceSafe;
goog.string.isBreakingWhitespace = function(str) {
  return !/[^\t\n\r ]/.test(str);
};
goog.string.isAlpha = function(str) {
  return !/[^a-zA-Z]/.test(str);
};
goog.string.isNumeric = function(str) {
  return !/[^0-9]/.test(str);
};
goog.string.isAlphaNumeric = function(str) {
  return !/[^a-zA-Z0-9]/.test(str);
};
goog.string.isSpace = function(ch) {
  return ch == " ";
};
goog.string.isUnicodeChar = function(ch) {
  return ch.length == 1 && ch >= " " && ch <= "~" || ch >= "\u0080" && ch <= "\ufffd";
};
goog.string.stripNewlines = function(str) {
  return str.replace(/(\r\n|\r|\n)+/g, " ");
};
goog.string.canonicalizeNewlines = function(str) {
  return str.replace(/(\r\n|\r|\n)/g, "\n");
};
goog.string.normalizeWhitespace = function(str) {
  return str.replace(/\xa0|\s/g, " ");
};
goog.string.normalizeSpaces = function(str) {
  return str.replace(/\xa0|[ \t]+/g, " ");
};
goog.string.collapseBreakingSpaces = function(str) {
  return str.replace(/[\t\r\n ]+/g, " ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g, "");
};
goog.string.trim = goog.TRUSTED_SITE && String.prototype.trim ? function(str) {
  return str.trim();
} : function(str) {
  return str.replace(/^[\s\xa0]+|[\s\xa0]+$/g, "");
};
goog.string.trimLeft = function(str) {
  return str.replace(/^[\s\xa0]+/, "");
};
goog.string.trimRight = function(str) {
  return str.replace(/[\s\xa0]+$/, "");
};
goog.string.caseInsensitiveCompare = function(str1, str2) {
  var test1 = String(str1).toLowerCase();
  var test2 = String(str2).toLowerCase();
  if (test1 < test2) {
    return -1;
  } else {
    if (test1 == test2) {
      return 0;
    } else {
      return 1;
    }
  }
};
goog.string.numberAwareCompare_ = function(str1, str2, tokenizerRegExp) {
  if (str1 == str2) {
    return 0;
  }
  if (!str1) {
    return -1;
  }
  if (!str2) {
    return 1;
  }
  var tokens1 = str1.toLowerCase().match(tokenizerRegExp);
  var tokens2 = str2.toLowerCase().match(tokenizerRegExp);
  var count = Math.min(tokens1.length, tokens2.length);
  for (var i = 0; i < count; i++) {
    var a = tokens1[i];
    var b = tokens2[i];
    if (a != b) {
      var num1 = parseInt(a, 10);
      if (!isNaN(num1)) {
        var num2 = parseInt(b, 10);
        if (!isNaN(num2) && num1 - num2) {
          return num1 - num2;
        }
      }
      return a < b ? -1 : 1;
    }
  }
  if (tokens1.length != tokens2.length) {
    return tokens1.length - tokens2.length;
  }
  return str1 < str2 ? -1 : 1;
};
goog.string.intAwareCompare = function(str1, str2) {
  return goog.string.numberAwareCompare_(str1, str2, /\d+|\D+/g);
};
goog.string.floatAwareCompare = function(str1, str2) {
  return goog.string.numberAwareCompare_(str1, str2, /\d+|\.\d+|\D+/g);
};
goog.string.numerateCompare = goog.string.floatAwareCompare;
goog.string.urlEncode = function(str) {
  return encodeURIComponent(String(str));
};
goog.string.urlDecode = function(str) {
  return decodeURIComponent(str.replace(/\+/g, " "));
};
goog.string.newLineToBr = function(str, opt_xml) {
  return str.replace(/(\r\n|\r|\n)/g, opt_xml ? "<br />" : "<br>");
};
goog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {
  if (opt_isLikelyToContainHtmlChars) {
    str = str.replace(goog.string.AMP_RE_, "&amp;").replace(goog.string.LT_RE_, "&lt;").replace(goog.string.GT_RE_, "&gt;").replace(goog.string.QUOT_RE_, "&quot;").replace(goog.string.SINGLE_QUOTE_RE_, "&#39;").replace(goog.string.NULL_RE_, "&#0;");
    if (goog.string.DETECT_DOUBLE_ESCAPING) {
      str = str.replace(goog.string.E_RE_, "&#101;");
    }
    return str;
  } else {
    if (!goog.string.ALL_RE_.test(str)) {
      return str;
    }
    if (str.indexOf("&") != -1) {
      str = str.replace(goog.string.AMP_RE_, "&amp;");
    }
    if (str.indexOf("<") != -1) {
      str = str.replace(goog.string.LT_RE_, "&lt;");
    }
    if (str.indexOf(">") != -1) {
      str = str.replace(goog.string.GT_RE_, "&gt;");
    }
    if (str.indexOf('"') != -1) {
      str = str.replace(goog.string.QUOT_RE_, "&quot;");
    }
    if (str.indexOf("'") != -1) {
      str = str.replace(goog.string.SINGLE_QUOTE_RE_, "&#39;");
    }
    if (str.indexOf("\x00") != -1) {
      str = str.replace(goog.string.NULL_RE_, "&#0;");
    }
    if (goog.string.DETECT_DOUBLE_ESCAPING && str.indexOf("e") != -1) {
      str = str.replace(goog.string.E_RE_, "&#101;");
    }
    return str;
  }
};
goog.string.AMP_RE_ = /&/g;
goog.string.LT_RE_ = /</g;
goog.string.GT_RE_ = />/g;
goog.string.QUOT_RE_ = /"/g;
goog.string.SINGLE_QUOTE_RE_ = /'/g;
goog.string.NULL_RE_ = /\x00/g;
goog.string.E_RE_ = /e/g;
goog.string.ALL_RE_ = goog.string.DETECT_DOUBLE_ESCAPING ? /[\x00&<>"'e]/ : /[\x00&<>"']/;
goog.string.unescapeEntities = function(str) {
  if (goog.string.contains(str, "&")) {
    if (!goog.string.FORCE_NON_DOM_HTML_UNESCAPING && "document" in goog.global) {
      return goog.string.unescapeEntitiesUsingDom_(str);
    } else {
      return goog.string.unescapePureXmlEntities_(str);
    }
  }
  return str;
};
goog.string.unescapeEntitiesWithDocument = function(str, document) {
  if (goog.string.contains(str, "&")) {
    return goog.string.unescapeEntitiesUsingDom_(str, document);
  }
  return str;
};
goog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {
  var seen = {"&amp;":"&", "&lt;":"<", "&gt;":">", "&quot;":'"'};
  var div;
  if (opt_document) {
    div = opt_document.createElement("div");
  } else {
    div = goog.global.document.createElement("div");
  }
  return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {
    var value = seen[s];
    if (value) {
      return value;
    }
    if (entity.charAt(0) == "#") {
      var n = Number("0" + entity.substr(1));
      if (!isNaN(n)) {
        value = String.fromCharCode(n);
      }
    }
    if (!value) {
      div.innerHTML = s + " ";
      value = div.firstChild.nodeValue.slice(0, -1);
    }
    return seen[s] = value;
  });
};
goog.string.unescapePureXmlEntities_ = function(str) {
  return str.replace(/&([^;]+);/g, function(s, entity) {
    switch(entity) {
      case "amp":
        return "&";
      case "lt":
        return "<";
      case "gt":
        return ">";
      case "quot":
        return '"';
      default:
        if (entity.charAt(0) == "#") {
          var n = Number("0" + entity.substr(1));
          if (!isNaN(n)) {
            return String.fromCharCode(n);
          }
        }
        return s;
    }
  });
};
goog.string.HTML_ENTITY_PATTERN_ = /&([^;\s<&]+);?/g;
goog.string.whitespaceEscape = function(str, opt_xml) {
  return goog.string.newLineToBr(str.replace(/  /g, " &#160;"), opt_xml);
};
goog.string.preserveSpaces = function(str) {
  return str.replace(/(^|[\n ]) /g, "$1" + goog.string.Unicode.NBSP);
};
goog.string.stripQuotes = function(str, quoteChars) {
  var length = quoteChars.length;
  for (var i = 0; i < length; i++) {
    var quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);
    if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {
      return str.substring(1, str.length - 1);
    }
  }
  return str;
};
goog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {
  if (opt_protectEscapedCharacters) {
    str = goog.string.unescapeEntities(str);
  }
  if (str.length > chars) {
    str = str.substring(0, chars - 3) + "...";
  }
  if (opt_protectEscapedCharacters) {
    str = goog.string.htmlEscape(str);
  }
  return str;
};
goog.string.truncateMiddle = function(str, chars, opt_protectEscapedCharacters, opt_trailingChars) {
  if (opt_protectEscapedCharacters) {
    str = goog.string.unescapeEntities(str);
  }
  if (opt_trailingChars && str.length > chars) {
    if (opt_trailingChars > chars) {
      opt_trailingChars = chars;
    }
    var endPoint = str.length - opt_trailingChars;
    var startPoint = chars - opt_trailingChars;
    str = str.substring(0, startPoint) + "..." + str.substring(endPoint);
  } else {
    if (str.length > chars) {
      var half = Math.floor(chars / 2);
      var endPos = str.length - half;
      half += chars % 2;
      str = str.substring(0, half) + "..." + str.substring(endPos);
    }
  }
  if (opt_protectEscapedCharacters) {
    str = goog.string.htmlEscape(str);
  }
  return str;
};
goog.string.specialEscapeChars_ = {"\x00":"\\0", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\x0B", '"':'\\"', "\\":"\\\\", "<":"<"};
goog.string.jsEscapeCache_ = {"'":"\\'"};
goog.string.quote = function(s) {
  s = String(s);
  var sb = ['"'];
  for (var i = 0; i < s.length; i++) {
    var ch = s.charAt(i);
    var cc = ch.charCodeAt(0);
    sb[i + 1] = goog.string.specialEscapeChars_[ch] || (cc > 31 && cc < 127 ? ch : goog.string.escapeChar(ch));
  }
  sb.push('"');
  return sb.join("");
};
goog.string.escapeString = function(str) {
  var sb = [];
  for (var i = 0; i < str.length; i++) {
    sb[i] = goog.string.escapeChar(str.charAt(i));
  }
  return sb.join("");
};
goog.string.escapeChar = function(c) {
  if (c in goog.string.jsEscapeCache_) {
    return goog.string.jsEscapeCache_[c];
  }
  if (c in goog.string.specialEscapeChars_) {
    return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c];
  }
  var rv = c;
  var cc = c.charCodeAt(0);
  if (cc > 31 && cc < 127) {
    rv = c;
  } else {
    if (cc < 256) {
      rv = "\\x";
      if (cc < 16 || cc > 256) {
        rv += "0";
      }
    } else {
      rv = "\\u";
      if (cc < 4096) {
        rv += "0";
      }
    }
    rv += cc.toString(16).toUpperCase();
  }
  return goog.string.jsEscapeCache_[c] = rv;
};
goog.string.contains = function(str, subString) {
  return str.indexOf(subString) != -1;
};
goog.string.caseInsensitiveContains = function(str, subString) {
  return goog.string.contains(str.toLowerCase(), subString.toLowerCase());
};
goog.string.countOf = function(s, ss) {
  return s && ss ? s.split(ss).length - 1 : 0;
};
goog.string.removeAt = function(s, index, stringLength) {
  var resultStr = s;
  if (index >= 0 && index < s.length && stringLength > 0) {
    resultStr = s.substr(0, index) + s.substr(index + stringLength, s.length - index - stringLength);
  }
  return resultStr;
};
goog.string.remove = function(str, substr) {
  return str.replace(substr, "");
};
goog.string.removeAll = function(s, ss) {
  var re = new RegExp(goog.string.regExpEscape(ss), "g");
  return s.replace(re, "");
};
goog.string.replaceAll = function(s, ss, replacement) {
  var re = new RegExp(goog.string.regExpEscape(ss), "g");
  return s.replace(re, replacement.replace(/\$/g, "$$$$"));
};
goog.string.regExpEscape = function(s) {
  return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, "\\$1").replace(/\x08/g, "\\x08");
};
goog.string.repeat = String.prototype.repeat ? function(string, length) {
  return string.repeat(length);
} : function(string, length) {
  return (new Array(length + 1)).join(string);
};
goog.string.padNumber = function(num, length, opt_precision) {
  var s = goog.isDef(opt_precision) ? num.toFixed(opt_precision) : String(num);
  var index = s.indexOf(".");
  if (index == -1) {
    index = s.length;
  }
  return goog.string.repeat("0", Math.max(0, length - index)) + s;
};
goog.string.makeSafe = function(obj) {
  return obj == null ? "" : String(obj);
};
goog.string.buildString = function(var_args) {
  return Array.prototype.join.call(arguments, "");
};
goog.string.getRandomString = function() {
  var x = 2147483648;
  return Math.floor(Math.random() * x).toString(36) + Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);
};
goog.string.compareVersions = function(version1, version2) {
  var order = 0;
  var v1Subs = goog.string.trim(String(version1)).split(".");
  var v2Subs = goog.string.trim(String(version2)).split(".");
  var subCount = Math.max(v1Subs.length, v2Subs.length);
  for (var subIdx = 0; order == 0 && subIdx < subCount; subIdx++) {
    var v1Sub = v1Subs[subIdx] || "";
    var v2Sub = v2Subs[subIdx] || "";
    do {
      var v1Comp = /(\d*)(\D*)(.*)/.exec(v1Sub) || ["", "", "", ""];
      var v2Comp = /(\d*)(\D*)(.*)/.exec(v2Sub) || ["", "", "", ""];
      if (v1Comp[0].length == 0 && v2Comp[0].length == 0) {
        break;
      }
      var v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10);
      var v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);
      order = goog.string.compareElements_(v1CompNum, v2CompNum) || goog.string.compareElements_(v1Comp[2].length == 0, v2Comp[2].length == 0) || goog.string.compareElements_(v1Comp[2], v2Comp[2]);
      v1Sub = v1Comp[3];
      v2Sub = v2Comp[3];
    } while (order == 0);
  }
  return order;
};
goog.string.compareElements_ = function(left, right) {
  if (left < right) {
    return -1;
  } else {
    if (left > right) {
      return 1;
    }
  }
  return 0;
};
goog.string.hashCode = function(str) {
  var result = 0;
  for (var i = 0; i < str.length; ++i) {
    result = 31 * result + str.charCodeAt(i) >>> 0;
  }
  return result;
};
goog.string.uniqueStringCounter_ = Math.random() * 2147483648 | 0;
goog.string.createUniqueString = function() {
  return "goog_" + goog.string.uniqueStringCounter_++;
};
goog.string.toNumber = function(str) {
  var num = Number(str);
  if (num == 0 && goog.string.isEmptyOrWhitespace(str)) {
    return NaN;
  }
  return num;
};
goog.string.isLowerCamelCase = function(str) {
  return /^[a-z]+([A-Z][a-z]*)*$/.test(str);
};
goog.string.isUpperCamelCase = function(str) {
  return /^([A-Z][a-z]*)+$/.test(str);
};
goog.string.toCamelCase = function(str) {
  return String(str).replace(/\-([a-z])/g, function(all, match) {
    return match.toUpperCase();
  });
};
goog.string.toSelectorCase = function(str) {
  return String(str).replace(/([A-Z])/g, "-$1").toLowerCase();
};
goog.string.toTitleCase = function(str, opt_delimiters) {
  var delimiters = goog.isString(opt_delimiters) ? goog.string.regExpEscape(opt_delimiters) : "\\s";
  delimiters = delimiters ? "|[" + delimiters + "]+" : "";
  var regexp = new RegExp("(^" + delimiters + ")([a-z])", "g");
  return str.replace(regexp, function(all, p1, p2) {
    return p1 + p2.toUpperCase();
  });
};
goog.string.capitalize = function(str) {
  return String(str.charAt(0)).toUpperCase() + String(str.substr(1)).toLowerCase();
};
goog.string.parseInt = function(value) {
  if (isFinite(value)) {
    value = String(value);
  }
  if (goog.isString(value)) {
    return /^\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10);
  }
  return NaN;
};
goog.string.splitLimit = function(str, separator, limit) {
  var parts = str.split(separator);
  var returnVal = [];
  while (limit > 0 && parts.length) {
    returnVal.push(parts.shift());
    limit--;
  }
  if (parts.length) {
    returnVal.push(parts.join(separator));
  }
  return returnVal;
};
goog.string.lastComponent = function(str, separators) {
  if (!separators) {
    return str;
  } else {
    if (typeof separators == "string") {
      separators = [separators];
    }
  }
  var lastSeparatorIndex = -1;
  for (var i = 0; i < separators.length; i++) {
    if (separators[i] == "") {
      continue;
    }
    var currentSeparatorIndex = str.lastIndexOf(separators[i]);
    if (currentSeparatorIndex > lastSeparatorIndex) {
      lastSeparatorIndex = currentSeparatorIndex;
    }
  }
  if (lastSeparatorIndex == -1) {
    return str;
  }
  return str.slice(lastSeparatorIndex + 1);
};
goog.string.editDistance = function(a, b) {
  var v0 = [];
  var v1 = [];
  if (a == b) {
    return 0;
  }
  if (!a.length || !b.length) {
    return Math.max(a.length, b.length);
  }
  for (var i = 0; i < b.length + 1; i++) {
    v0[i] = i;
  }
  for (var i = 0; i < a.length; i++) {
    v1[0] = i + 1;
    for (var j = 0; j < b.length; j++) {
      var cost = Number(a[i] != b[j]);
      v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);
    }
    for (var j = 0; j < v0.length; j++) {
      v0[j] = v1[j];
    }
  }
  return v1[b.length];
};
goog.provide("goog.asserts");
goog.provide("goog.asserts.AssertionError");
goog.require("goog.debug.Error");
goog.require("goog.dom.NodeType");
goog.require("goog.string");
goog.define("goog.asserts.ENABLE_ASSERTS", goog.DEBUG);
goog.asserts.AssertionError = function(messagePattern, messageArgs) {
  messageArgs.unshift(messagePattern);
  goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
  messageArgs.shift();
  this.messagePattern = messagePattern;
};
goog.inherits(goog.asserts.AssertionError, goog.debug.Error);
goog.asserts.AssertionError.prototype.name = "AssertionError";
goog.asserts.DEFAULT_ERROR_HANDLER = function(e) {
  throw e;
};
goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER;
goog.asserts.doAssertFailure_ = function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
  var message = "Assertion failed";
  if (givenMessage) {
    message += ": " + givenMessage;
    var args = givenArgs;
  } else {
    if (defaultMessage) {
      message += ": " + defaultMessage;
      args = defaultArgs;
    }
  }
  var e = new goog.asserts.AssertionError("" + message, args || []);
  goog.asserts.errorHandler_(e);
};
goog.asserts.setErrorHandler = function(errorHandler) {
  if (goog.asserts.ENABLE_ASSERTS) {
    goog.asserts.errorHandler_ = errorHandler;
  }
};
goog.asserts.assert = function(condition, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !condition) {
    goog.asserts.doAssertFailure_("", null, opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return condition;
};
goog.asserts.fail = function(opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS) {
    goog.asserts.errorHandler_(new goog.asserts.AssertionError("Failure" + (opt_message ? ": " + opt_message : ""), Array.prototype.slice.call(arguments, 1)));
  }
};
goog.asserts.assertNumber = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
    goog.asserts.doAssertFailure_("Expected number but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return value;
};
goog.asserts.assertString = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
    goog.asserts.doAssertFailure_("Expected string but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return value;
};
goog.asserts.assertFunction = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
    goog.asserts.doAssertFailure_("Expected function but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return value;
};
goog.asserts.assertObject = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
    goog.asserts.doAssertFailure_("Expected object but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return value;
};
goog.asserts.assertArray = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
    goog.asserts.doAssertFailure_("Expected array but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return value;
};
goog.asserts.assertBoolean = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
    goog.asserts.doAssertFailure_("Expected boolean but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return value;
};
goog.asserts.assertElement = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) || value.nodeType != goog.dom.NodeType.ELEMENT)) {
    goog.asserts.doAssertFailure_("Expected Element but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return value;
};
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
    goog.asserts.doAssertFailure_("Expected instanceof %s but got %s.", [goog.asserts.getType_(type), goog.asserts.getType_(value)], opt_message, Array.prototype.slice.call(arguments, 3));
  }
  return value;
};
goog.asserts.assertObjectPrototypeIsIntact = function() {
  for (var key in Object.prototype) {
    goog.asserts.fail(key + " should not be enumerable in Object.prototype.");
  }
};
goog.asserts.getType_ = function(value) {
  if (value instanceof Function) {
    return value.displayName || value.name || "unknown type name";
  } else {
    if (value instanceof Object) {
      return value.constructor.displayName || value.constructor.name || Object.prototype.toString.call(value);
    } else {
      return value === null ? "null" : typeof value;
    }
  }
};
goog.provide("goog.array");
goog.require("goog.asserts");
goog.define("goog.NATIVE_ARRAY_PROTOTYPES", goog.TRUSTED_SITE);
goog.define("goog.array.ASSUME_NATIVE_FUNCTIONS", false);
goog.array.peek = function(array) {
  return array[array.length - 1];
};
goog.array.last = goog.array.peek;
goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ? function(arr, obj, opt_fromIndex) {
  goog.asserts.assert(arr.length != null);
  return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);
} : function(arr, obj, opt_fromIndex) {
  var fromIndex = opt_fromIndex == null ? 0 : opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex;
  if (goog.isString(arr)) {
    if (!goog.isString(obj) || obj.length != 1) {
      return -1;
    }
    return arr.indexOf(obj, fromIndex);
  }
  for (var i = fromIndex; i < arr.length; i++) {
    if (i in arr && arr[i] === obj) {
      return i;
    }
  }
  return -1;
};
goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ? function(arr, obj, opt_fromIndex) {
  goog.asserts.assert(arr.length != null);
  var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
  return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);
} : function(arr, obj, opt_fromIndex) {
  var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
  if (fromIndex < 0) {
    fromIndex = Math.max(0, arr.length + fromIndex);
  }
  if (goog.isString(arr)) {
    if (!goog.isString(obj) || obj.length != 1) {
      return -1;
    }
    return arr.lastIndexOf(obj, fromIndex);
  }
  for (var i = fromIndex; i >= 0; i--) {
    if (i in arr && arr[i] === obj) {
      return i;
    }
  }
  return -1;
};
goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ? function(arr, f, opt_obj) {
  goog.asserts.assert(arr.length != null);
  Array.prototype.forEach.call(arr, f, opt_obj);
} : function(arr, f, opt_obj) {
  var l = arr.length;
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = 0; i < l; i++) {
    if (i in arr2) {
      f.call(opt_obj, arr2[i], i, arr);
    }
  }
};
goog.array.forEachRight = function(arr, f, opt_obj) {
  var l = arr.length;
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = l - 1; i >= 0; --i) {
    if (i in arr2) {
      f.call(opt_obj, arr2[i], i, arr);
    }
  }
};
goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ? function(arr, f, opt_obj) {
  goog.asserts.assert(arr.length != null);
  return Array.prototype.filter.call(arr, f, opt_obj);
} : function(arr, f, opt_obj) {
  var l = arr.length;
  var res = [];
  var resLength = 0;
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = 0; i < l; i++) {
    if (i in arr2) {
      var val = arr2[i];
      if (f.call(opt_obj, val, i, arr)) {
        res[resLength++] = val;
      }
    }
  }
  return res;
};
goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ? function(arr, f, opt_obj) {
  goog.asserts.assert(arr.length != null);
  return Array.prototype.map.call(arr, f, opt_obj);
} : function(arr, f, opt_obj) {
  var l = arr.length;
  var res = new Array(l);
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = 0; i < l; i++) {
    if (i in arr2) {
      res[i] = f.call(opt_obj, arr2[i], i, arr);
    }
  }
  return res;
};
goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ? function(arr, f, val, opt_obj) {
  goog.asserts.assert(arr.length != null);
  if (opt_obj) {
    f = goog.bind(f, opt_obj);
  }
  return Array.prototype.reduce.call(arr, f, val);
} : function(arr, f, val, opt_obj) {
  var rval = val;
  goog.array.forEach(arr, function(val, index) {
    rval = f.call(opt_obj, rval, val, index, arr);
  });
  return rval;
};
goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ? function(arr, f, val, opt_obj) {
  goog.asserts.assert(arr.length != null);
  goog.asserts.assert(f != null);
  if (opt_obj) {
    f = goog.bind(f, opt_obj);
  }
  return Array.prototype.reduceRight.call(arr, f, val);
} : function(arr, f, val, opt_obj) {
  var rval = val;
  goog.array.forEachRight(arr, function(val, index) {
    rval = f.call(opt_obj, rval, val, index, arr);
  });
  return rval;
};
goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ? function(arr, f, opt_obj) {
  goog.asserts.assert(arr.length != null);
  return Array.prototype.some.call(arr, f, opt_obj);
} : function(arr, f, opt_obj) {
  var l = arr.length;
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = 0; i < l; i++) {
    if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
      return true;
    }
  }
  return false;
};
goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ? function(arr, f, opt_obj) {
  goog.asserts.assert(arr.length != null);
  return Array.prototype.every.call(arr, f, opt_obj);
} : function(arr, f, opt_obj) {
  var l = arr.length;
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = 0; i < l; i++) {
    if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {
      return false;
    }
  }
  return true;
};
goog.array.count = function(arr, f, opt_obj) {
  var count = 0;
  goog.array.forEach(arr, function(element, index, arr) {
    if (f.call(opt_obj, element, index, arr)) {
      ++count;
    }
  }, opt_obj);
  return count;
};
goog.array.find = function(arr, f, opt_obj) {
  var i = goog.array.findIndex(arr, f, opt_obj);
  return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
};
goog.array.findIndex = function(arr, f, opt_obj) {
  var l = arr.length;
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = 0; i < l; i++) {
    if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
      return i;
    }
  }
  return -1;
};
goog.array.findRight = function(arr, f, opt_obj) {
  var i = goog.array.findIndexRight(arr, f, opt_obj);
  return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
};
goog.array.findIndexRight = function(arr, f, opt_obj) {
  var l = arr.length;
  var arr2 = goog.isString(arr) ? arr.split("") : arr;
  for (var i = l - 1; i >= 0; i--) {
    if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
      return i;
    }
  }
  return -1;
};
goog.array.contains = function(arr, obj) {
  return goog.array.indexOf(arr, obj) >= 0;
};
goog.array.isEmpty = function(arr) {
  return arr.length == 0;
};
goog.array.clear = function(arr) {
  if (!goog.isArray(arr)) {
    for (var i = arr.length - 1; i >= 0; i--) {
      delete arr[i];
    }
  }
  arr.length = 0;
};
goog.array.insert = function(arr, obj) {
  if (!goog.array.contains(arr, obj)) {
    arr.push(obj);
  }
};
goog.array.insertAt = function(arr, obj, opt_i) {
  goog.array.splice(arr, opt_i, 0, obj);
};
goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {
  goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);
};
goog.array.insertBefore = function(arr, obj, opt_obj2) {
  var i;
  if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {
    arr.push(obj);
  } else {
    goog.array.insertAt(arr, obj, i);
  }
};
goog.array.remove = function(arr, obj) {
  var i = goog.array.indexOf(arr, obj);
  var rv;
  if (rv = i >= 0) {
    goog.array.removeAt(arr, i);
  }
  return rv;
};
goog.array.removeLast = function(arr, obj) {
  var i = goog.array.lastIndexOf(arr, obj);
  if (i >= 0) {
    goog.array.removeAt(arr, i);
    return true;
  }
  return false;
};
goog.array.removeAt = function(arr, i) {
  goog.asserts.assert(arr.length != null);
  return Array.prototype.splice.call(arr, i, 1).length == 1;
};
goog.array.removeIf = function(arr, f, opt_obj) {
  var i = goog.array.findIndex(arr, f, opt_obj);
  if (i >= 0) {
    goog.array.removeAt(arr, i);
    return true;
  }
  return false;
};
goog.array.removeAllIf = function(arr, f, opt_obj) {
  var removedCount = 0;
  goog.array.forEachRight(arr, function(val, index) {
    if (f.call(opt_obj, val, index, arr)) {
      if (goog.array.removeAt(arr, index)) {
        removedCount++;
      }
    }
  });
  return removedCount;
};
goog.array.concat = function(var_args) {
  return Array.prototype.concat.apply([], arguments);
};
goog.array.join = function(var_args) {
  return Array.prototype.concat.apply([], arguments);
};
goog.array.toArray = function(object) {
  var length = object.length;
  if (length > 0) {
    var rv = new Array(length);
    for (var i = 0; i < length; i++) {
      rv[i] = object[i];
    }
    return rv;
  }
  return [];
};
goog.array.clone = goog.array.toArray;
goog.array.extend = function(arr1, var_args) {
  for (var i = 1; i < arguments.length; i++) {
    var arr2 = arguments[i];
    if (goog.isArrayLike(arr2)) {
      var len1 = arr1.length || 0;
      var len2 = arr2.length || 0;
      arr1.length = len1 + len2;
      for (var j = 0; j < len2; j++) {
        arr1[len1 + j] = arr2[j];
      }
    } else {
      arr1.push(arr2);
    }
  }
};
goog.array.splice = function(arr, index, howMany, var_args) {
  goog.asserts.assert(arr.length != null);
  return Array.prototype.splice.apply(arr, goog.array.slice(arguments, 1));
};
goog.array.slice = function(arr, start, opt_end) {
  goog.asserts.assert(arr.length != null);
  if (arguments.length <= 2) {
    return Array.prototype.slice.call(arr, start);
  } else {
    return Array.prototype.slice.call(arr, start, opt_end);
  }
};
goog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) {
  var returnArray = opt_rv || arr;
  var defaultHashFn = function(item) {
    return goog.isObject(item) ? "o" + goog.getUid(item) : (typeof item).charAt(0) + item;
  };
  var hashFn = opt_hashFn || defaultHashFn;
  var seen = {}, cursorInsert = 0, cursorRead = 0;
  while (cursorRead < arr.length) {
    var current = arr[cursorRead++];
    var key = hashFn(current);
    if (!Object.prototype.hasOwnProperty.call(seen, key)) {
      seen[key] = true;
      returnArray[cursorInsert++] = current;
    }
  }
  returnArray.length = cursorInsert;
};
goog.array.binarySearch = function(arr, target, opt_compareFn) {
  return goog.array.binarySearch_(arr, opt_compareFn || goog.array.defaultCompare, false, target);
};
goog.array.binarySelect = function(arr, evaluator, opt_obj) {
  return goog.array.binarySearch_(arr, evaluator, true, undefined, opt_obj);
};
goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {
  var left = 0;
  var right = arr.length;
  var found;
  while (left < right) {
    var middle = left + right >> 1;
    var compareResult;
    if (isEvaluator) {
      compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);
    } else {
      compareResult = compareFn(opt_target, arr[middle]);
    }
    if (compareResult > 0) {
      left = middle + 1;
    } else {
      right = middle;
      found = !compareResult;
    }
  }
  return found ? left : ~left;
};
goog.array.sort = function(arr, opt_compareFn) {
  arr.sort(opt_compareFn || goog.array.defaultCompare);
};
goog.array.stableSort = function(arr, opt_compareFn) {
  var compArr = new Array(arr.length);
  for (var i = 0; i < arr.length; i++) {
    compArr[i] = {index:i, value:arr[i]};
  }
  var valueCompareFn = opt_compareFn || goog.array.defaultCompare;
  function stableCompareFn(obj1, obj2) {
    return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;
  }
  goog.array.sort(compArr, stableCompareFn);
  for (var i = 0; i < arr.length; i++) {
    arr[i] = compArr[i].value;
  }
};
goog.array.sortByKey = function(arr, keyFn, opt_compareFn) {
  var keyCompareFn = opt_compareFn || goog.array.defaultCompare;
  goog.array.sort(arr, function(a, b) {
    return keyCompareFn(keyFn(a), keyFn(b));
  });
};
goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {
  goog.array.sortByKey(arr, function(obj) {
    return obj[key];
  }, opt_compareFn);
};
goog.array.isSorted = function(arr, opt_compareFn, opt_strict) {
  var compare = opt_compareFn || goog.array.defaultCompare;
  for (var i = 1; i < arr.length; i++) {
    var compareResult = compare(arr[i - 1], arr[i]);
    if (compareResult > 0 || compareResult == 0 && opt_strict) {
      return false;
    }
  }
  return true;
};
goog.array.equals = function(arr1, arr2, opt_equalsFn) {
  if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length != arr2.length) {
    return false;
  }
  var l = arr1.length;
  var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
  for (var i = 0; i < l; i++) {
    if (!equalsFn(arr1[i], arr2[i])) {
      return false;
    }
  }
  return true;
};
goog.array.compare3 = function(arr1, arr2, opt_compareFn) {
  var compare = opt_compareFn || goog.array.defaultCompare;
  var l = Math.min(arr1.length, arr2.length);
  for (var i = 0; i < l; i++) {
    var result = compare(arr1[i], arr2[i]);
    if (result != 0) {
      return result;
    }
  }
  return goog.array.defaultCompare(arr1.length, arr2.length);
};
goog.array.defaultCompare = function(a, b) {
  return a > b ? 1 : a < b ? -1 : 0;
};
goog.array.inverseDefaultCompare = function(a, b) {
  return -goog.array.defaultCompare(a, b);
};
goog.array.defaultCompareEquality = function(a, b) {
  return a === b;
};
goog.array.binaryInsert = function(array, value, opt_compareFn) {
  var index = goog.array.binarySearch(array, value, opt_compareFn);
  if (index < 0) {
    goog.array.insertAt(array, value, -(index + 1));
    return true;
  }
  return false;
};
goog.array.binaryRemove = function(array, value, opt_compareFn) {
  var index = goog.array.binarySearch(array, value, opt_compareFn);
  return index >= 0 ? goog.array.removeAt(array, index) : false;
};
goog.array.bucket = function(array, sorter, opt_obj) {
  var buckets = {};
  for (var i = 0; i < array.length; i++) {
    var value = array[i];
    var key = sorter.call(opt_obj, value, i, array);
    if (goog.isDef(key)) {
      var bucket = buckets[key] || (buckets[key] = []);
      bucket.push(value);
    }
  }
  return buckets;
};
goog.array.toObject = function(arr, keyFunc, opt_obj) {
  var ret = {};
  goog.array.forEach(arr, function(element, index) {
    ret[keyFunc.call(opt_obj, element, index, arr)] = element;
  });
  return ret;
};
goog.array.range = function(startOrEnd, opt_end, opt_step) {
  var array = [];
  var start = 0;
  var end = startOrEnd;
  var step = opt_step || 1;
  if (opt_end !== undefined) {
    start = startOrEnd;
    end = opt_end;
  }
  if (step * (end - start) < 0) {
    return [];
  }
  if (step > 0) {
    for (var i = start; i < end; i += step) {
      array.push(i);
    }
  } else {
    for (var i = start; i > end; i += step) {
      array.push(i);
    }
  }
  return array;
};
goog.array.repeat = function(value, n) {
  var array = [];
  for (var i = 0; i < n; i++) {
    array[i] = value;
  }
  return array;
};
goog.array.flatten = function(var_args) {
  var CHUNK_SIZE = 8192;
  var result = [];
  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (goog.isArray(element)) {
      for (var c = 0; c < element.length; c += CHUNK_SIZE) {
        var chunk = goog.array.slice(element, c, c + CHUNK_SIZE);
        var recurseResult = goog.array.flatten.apply(null, chunk);
        for (var r = 0; r < recurseResult.length; r++) {
          result.push(recurseResult[r]);
        }
      }
    } else {
      result.push(element);
    }
  }
  return result;
};
goog.array.rotate = function(array, n) {
  goog.asserts.assert(array.length != null);
  if (array.length) {
    n %= array.length;
    if (n > 0) {
      Array.prototype.unshift.apply(array, array.splice(-n, n));
    } else {
      if (n < 0) {
        Array.prototype.push.apply(array, array.splice(0, -n));
      }
    }
  }
  return array;
};
goog.array.moveItem = function(arr, fromIndex, toIndex) {
  goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length);
  goog.asserts.assert(toIndex >= 0 && toIndex < arr.length);
  var removedItems = Array.prototype.splice.call(arr, fromIndex, 1);
  Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);
};
goog.array.zip = function(var_args) {
  if (!arguments.length) {
    return [];
  }
  var result = [];
  var minLen = arguments[0].length;
  for (var i = 1; i < arguments.length; i++) {
    if (arguments[i].length < minLen) {
      minLen = arguments[i].length;
    }
  }
  for (var i = 0; i < minLen; i++) {
    var value = [];
    for (var j = 0; j < arguments.length; j++) {
      value.push(arguments[j][i]);
    }
    result.push(value);
  }
  return result;
};
goog.array.shuffle = function(arr, opt_randFn) {
  var randFn = opt_randFn || Math.random;
  for (var i = arr.length - 1; i > 0; i--) {
    var j = Math.floor(randFn() * (i + 1));
    var tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
  }
};
goog.array.copyByIndex = function(arr, index_arr) {
  var result = [];
  goog.array.forEach(index_arr, function(index) {
    result.push(arr[index]);
  });
  return result;
};
goog.array.concatMap = function(arr, f, opt_obj) {
  return goog.array.concat.apply([], goog.array.map(arr, f, opt_obj));
};
goog.provide("goog.labs.userAgent.util");
goog.require("goog.string");
goog.labs.userAgent.util.getNativeUserAgentString_ = function() {
  var navigator = goog.labs.userAgent.util.getNavigator_();
  if (navigator) {
    var userAgent = navigator.userAgent;
    if (userAgent) {
      return userAgent;
    }
  }
  return "";
};
goog.labs.userAgent.util.getNavigator_ = function() {
  return goog.global.navigator;
};
goog.labs.userAgent.util.userAgent_ = goog.labs.userAgent.util.getNativeUserAgentString_();
goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {
  goog.labs.userAgent.util.userAgent_ = opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_();
};
goog.labs.userAgent.util.getUserAgent = function() {
  return goog.labs.userAgent.util.userAgent_;
};
goog.labs.userAgent.util.matchUserAgent = function(str) {
  var userAgent = goog.labs.userAgent.util.getUserAgent();
  return goog.string.contains(userAgent, str);
};
goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {
  var userAgent = goog.labs.userAgent.util.getUserAgent();
  return goog.string.caseInsensitiveContains(userAgent, str);
};
goog.labs.userAgent.util.extractVersionTuples = function(userAgent) {
  var versionRegExp = new RegExp("(\\w[\\w ]+)" + "/" + "([^\\s]+)" + "\\s*" + "(?:\\((.*?)\\))?", "g");
  var data = [];
  var match;
  while (match = versionRegExp.exec(userAgent)) {
    data.push([match[1], match[2], match[3] || undefined]);
  }
  return data;
};
goog.provide("goog.object");
goog.object.is = function(v, v2) {
  if (v === v2) {
    return v !== 0 || 1 / v === 1 / v2;
  }
  return v !== v && v2 !== v2;
};
goog.object.forEach = function(obj, f, opt_obj) {
  for (var key in obj) {
    f.call(opt_obj, obj[key], key, obj);
  }
};
goog.object.filter = function(obj, f, opt_obj) {
  var res = {};
  for (var key in obj) {
    if (f.call(opt_obj, obj[key], key, obj)) {
      res[key] = obj[key];
    }
  }
  return res;
};
goog.object.map = function(obj, f, opt_obj) {
  var res = {};
  for (var key in obj) {
    res[key] = f.call(opt_obj, obj[key], key, obj);
  }
  return res;
};
goog.object.some = function(obj, f, opt_obj) {
  for (var key in obj) {
    if (f.call(opt_obj, obj[key], key, obj)) {
      return true;
    }
  }
  return false;
};
goog.object.every = function(obj, f, opt_obj) {
  for (var key in obj) {
    if (!f.call(opt_obj, obj[key], key, obj)) {
      return false;
    }
  }
  return true;
};
goog.object.getCount = function(obj) {
  var rv = 0;
  for (var key in obj) {
    rv++;
  }
  return rv;
};
goog.object.getAnyKey = function(obj) {
  for (var key in obj) {
    return key;
  }
};
goog.object.getAnyValue = function(obj) {
  for (var key in obj) {
    return obj[key];
  }
};
goog.object.contains = function(obj, val) {
  return goog.object.containsValue(obj, val);
};
goog.object.getValues = function(obj) {
  var res = [];
  var i = 0;
  for (var key in obj) {
    res[i++] = obj[key];
  }
  return res;
};
goog.object.getKeys = function(obj) {
  var res = [];
  var i = 0;
  for (var key in obj) {
    res[i++] = key;
  }
  return res;
};
goog.object.getValueByKeys = function(obj, var_args) {
  var isArrayLike = goog.isArrayLike(var_args);
  var keys = isArrayLike ? var_args : arguments;
  for (var i = isArrayLike ? 0 : 1; i < keys.length; i++) {
    obj = obj[keys[i]];
    if (!goog.isDef(obj)) {
      break;
    }
  }
  return obj;
};
goog.object.containsKey = function(obj, key) {
  return obj !== null && key in obj;
};
goog.object.containsValue = function(obj, val) {
  for (var key in obj) {
    if (obj[key] == val) {
      return true;
    }
  }
  return false;
};
goog.object.findKey = function(obj, f, opt_this) {
  for (var key in obj) {
    if (f.call(opt_this, obj[key], key, obj)) {
      return key;
    }
  }
  return undefined;
};
goog.object.findValue = function(obj, f, opt_this) {
  var key = goog.object.findKey(obj, f, opt_this);
  return key && obj[key];
};
goog.object.isEmpty = function(obj) {
  for (var key in obj) {
    return false;
  }
  return true;
};
goog.object.clear = function(obj) {
  for (var i in obj) {
    delete obj[i];
  }
};
goog.object.remove = function(obj, key) {
  var rv;
  if (rv = key in obj) {
    delete obj[key];
  }
  return rv;
};
goog.object.add = function(obj, key, val) {
  if (obj !== null && key in obj) {
    throw Error('The object already contains the key "' + key + '"');
  }
  goog.object.set(obj, key, val);
};
goog.object.get = function(obj, key, opt_val) {
  if (obj !== null && key in obj) {
    return obj[key];
  }
  return opt_val;
};
goog.object.set = function(obj, key, value) {
  obj[key] = value;
};
goog.object.setIfUndefined = function(obj, key, value) {
  return key in obj ? obj[key] : obj[key] = value;
};
goog.object.setWithReturnValueIfNotSet = function(obj, key, f) {
  if (key in obj) {
    return obj[key];
  }
  var val = f();
  obj[key] = val;
  return val;
};
goog.object.equals = function(a, b) {
  for (var k in a) {
    if (!(k in b) || a[k] !== b[k]) {
      return false;
    }
  }
  for (var k in b) {
    if (!(k in a)) {
      return false;
    }
  }
  return true;
};
goog.object.clone = function(obj) {
  var res = {};
  for (var key in obj) {
    res[key] = obj[key];
  }
  return res;
};
goog.object.unsafeClone = function(obj) {
  var type = goog.typeOf(obj);
  if (type == "object" || type == "array") {
    if (goog.isFunction(obj.clone)) {
      return obj.clone();
    }
    var clone = type == "array" ? [] : {};
    for (var key in obj) {
      clone[key] = goog.object.unsafeClone(obj[key]);
    }
    return clone;
  }
  return obj;
};
goog.object.transpose = function(obj) {
  var transposed = {};
  for (var key in obj) {
    transposed[obj[key]] = key;
  }
  return transposed;
};
goog.object.PROTOTYPE_FIELDS_ = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"];
goog.object.extend = function(target, var_args) {
  var key, source;
  for (var i = 1; i < arguments.length; i++) {
    source = arguments[i];
    for (key in source) {
      target[key] = source[key];
    }
    for (var j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) {
      key = goog.object.PROTOTYPE_FIELDS_[j];
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        target[key] = source[key];
      }
    }
  }
};
goog.object.create = function(var_args) {
  var argLength = arguments.length;
  if (argLength == 1 && goog.isArray(arguments[0])) {
    return goog.object.create.apply(null, arguments[0]);
  }
  if (argLength % 2) {
    throw Error("Uneven number of arguments");
  }
  var rv = {};
  for (var i = 0; i < argLength; i += 2) {
    rv[arguments[i]] = arguments[i + 1];
  }
  return rv;
};
goog.object.createSet = function(var_args) {
  var argLength = arguments.length;
  if (argLength == 1 && goog.isArray(arguments[0])) {
    return goog.object.createSet.apply(null, arguments[0]);
  }
  var rv = {};
  for (var i = 0; i < argLength; i++) {
    rv[arguments[i]] = true;
  }
  return rv;
};
goog.object.createImmutableView = function(obj) {
  var result = obj;
  if (Object.isFrozen && !Object.isFrozen(obj)) {
    result = Object.create(obj);
    Object.freeze(result);
  }
  return result;
};
goog.object.isImmutableView = function(obj) {
  return !!Object.isFrozen && Object.isFrozen(obj);
};
goog.object.getAllPropertyNames = function(obj, opt_includeObjectPrototype, opt_includeFunctionPrototype) {
  if (!obj) {
    return [];
  }
  if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
    return goog.object.getKeys(obj);
  }
  var visitedSet = {};
  var proto = obj;
  while (proto && (proto !== Object.prototype || !!opt_includeObjectPrototype) && (proto !== Function.prototype || !!opt_includeFunctionPrototype)) {
    var names = Object.getOwnPropertyNames(proto);
    for (var i = 0; i < names.length; i++) {
      visitedSet[names[i]] = true;
    }
    proto = Object.getPrototypeOf(proto);
  }
  return goog.object.getKeys(visitedSet);
};
goog.provide("goog.labs.userAgent.browser");
goog.require("goog.array");
goog.require("goog.labs.userAgent.util");
goog.require("goog.object");
goog.require("goog.string");
goog.labs.userAgent.browser.matchOpera_ = function() {
  return goog.labs.userAgent.util.matchUserAgent("Opera");
};
goog.labs.userAgent.browser.matchIE_ = function() {
  return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE");
};
goog.labs.userAgent.browser.matchEdge_ = function() {
  return goog.labs.userAgent.util.matchUserAgent("Edge");
};
goog.labs.userAgent.browser.matchFirefox_ = function() {
  return goog.labs.userAgent.util.matchUserAgent("Firefox");
};
goog.labs.userAgent.browser.matchSafari_ = function() {
  return goog.labs.userAgent.util.matchUserAgent("Safari") && !(goog.labs.userAgent.browser.matchChrome_() || goog.labs.userAgent.browser.matchCoast_() || goog.labs.userAgent.browser.matchOpera_() || goog.labs.userAgent.browser.matchEdge_() || goog.labs.userAgent.browser.isSilk() || goog.labs.userAgent.util.matchUserAgent("Android"));
};
goog.labs.userAgent.browser.matchCoast_ = function() {
  return goog.labs.userAgent.util.matchUserAgent("Coast");
};
goog.labs.userAgent.browser.matchIosWebview_ = function() {
  return (goog.labs.userAgent.util.matchUserAgent("iPad") || goog.labs.userAgent.util.matchUserAgent("iPhone")) && !goog.labs.userAgent.browser.matchSafari_() && !goog.labs.userAgent.browser.matchChrome_() && !goog.labs.userAgent.browser.matchCoast_() && goog.labs.userAgent.util.matchUserAgent("AppleWebKit");
};
goog.labs.userAgent.browser.matchChrome_ = function() {
  return (goog.labs.userAgent.util.matchUserAgent("Chrome") || goog.labs.userAgent.util.matchUserAgent("CriOS")) && !goog.labs.userAgent.browser.matchEdge_();
};
goog.labs.userAgent.browser.matchAndroidBrowser_ = function() {
  return goog.labs.userAgent.util.matchUserAgent("Android") && !(goog.labs.userAgent.browser.isChrome() || goog.labs.userAgent.browser.isFirefox() || goog.labs.userAgent.browser.isOpera() || goog.labs.userAgent.browser.isSilk());
};
goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_;
goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_;
goog.labs.userAgent.browser.isEdge = goog.labs.userAgent.browser.matchEdge_;
goog.labs.userAgent.browser.isFirefox = goog.labs.userAgent.browser.matchFirefox_;
goog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_;
goog.labs.userAgent.browser.isCoast = goog.labs.userAgent.browser.matchCoast_;
goog.labs.userAgent.browser.isIosWebview = goog.labs.userAgent.browser.matchIosWebview_;
goog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_;
goog.labs.userAgent.browser.isAndroidBrowser = goog.labs.userAgent.browser.matchAndroidBrowser_;
goog.labs.userAgent.browser.isSilk = function() {
  return goog.labs.userAgent.util.matchUserAgent("Silk");
};
goog.labs.userAgent.browser.getVersion = function() {
  var userAgentString = goog.labs.userAgent.util.getUserAgent();
  if (goog.labs.userAgent.browser.isIE()) {
    return goog.labs.userAgent.browser.getIEVersion_(userAgentString);
  }
  var versionTuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString);
  var versionMap = {};
  goog.array.forEach(versionTuples, function(tuple) {
    var key = tuple[0];
    var value = tuple[1];
    versionMap[key] = value;
  });
  var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap);
  function lookUpValueWithKeys(keys) {
    var key = goog.array.find(keys, versionMapHasKey);
    return versionMap[key] || "";
  }
  if (goog.labs.userAgent.browser.isOpera()) {
    return lookUpValueWithKeys(["Version", "Opera"]);
  }
  if (goog.labs.userAgent.browser.isEdge()) {
    return lookUpValueWithKeys(["Edge"]);
  }
  if (goog.labs.userAgent.browser.isChrome()) {
    return lookUpValueWithKeys(["Chrome", "CriOS"]);
  }
  var tuple = versionTuples[2];
  return tuple && tuple[1] || "";
};
goog.labs.userAgent.browser.isVersionOrHigher = function(version) {
  return goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(), version) >= 0;
};
goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) {
  var rv = /rv: *([\d\.]*)/.exec(userAgent);
  if (rv && rv[1]) {
    return rv[1];
  }
  var version = "";
  var msie = /MSIE +([\d\.]+)/.exec(userAgent);
  if (msie && msie[1]) {
    var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent);
    if (msie[1] == "7.0") {
      if (tridentVersion && tridentVersion[1]) {
        switch(tridentVersion[1]) {
          case "4.0":
            version = "8.0";
            break;
          case "5.0":
            version = "9.0";
            break;
          case "6.0":
            version = "10.0";
            break;
          case "7.0":
            version = "11.0";
            break;
        }
      } else {
        version = "7.0";
      }
    } else {
      version = msie[1];
    }
  }
  return version;
};
goog.provide("goog.labs.userAgent.engine");
goog.require("goog.array");
goog.require("goog.labs.userAgent.util");
goog.require("goog.string");
goog.labs.userAgent.engine.isPresto = function() {
  return goog.labs.userAgent.util.matchUserAgent("Presto");
};
goog.labs.userAgent.engine.isTrident = function() {
  return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE");
};
goog.labs.userAgent.engine.isEdge = function() {
  return goog.labs.userAgent.util.matchUserAgent("Edge");
};
goog.labs.userAgent.engine.isWebKit = function() {
  return goog.labs.userAgent.util.matchUserAgentIgnoreCase("WebKit") && !goog.labs.userAgent.engine.isEdge();
};
goog.labs.userAgent.engine.isGecko = function() {
  return goog.labs.userAgent.util.matchUserAgent("Gecko") && !goog.labs.userAgent.engine.isWebKit() && !goog.labs.userAgent.engine.isTrident() && !goog.labs.userAgent.engine.isEdge();
};
goog.labs.userAgent.engine.getVersion = function() {
  var userAgentString = goog.labs.userAgent.util.getUserAgent();
  if (userAgentString) {
    var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString);
    var engineTuple = goog.labs.userAgent.engine.getEngineTuple_(tuples);
    if (engineTuple) {
      if (engineTuple[0] == "Gecko") {
        return goog.labs.userAgent.engine.getVersionForKey_(tuples, "Firefox");
      }
      return engineTuple[1];
    }
    var browserTuple = tuples[0];
    var info;
    if (browserTuple && (info = browserTuple[2])) {
      var match = /Trident\/([^\s;]+)/.exec(info);
      if (match) {
        return match[1];
      }
    }
  }
  return "";
};
goog.labs.userAgent.engine.getEngineTuple_ = function(tuples) {
  if (!goog.labs.userAgent.engine.isEdge()) {
    return tuples[1];
  }
  for (var i = 0; i < tuples.length; i++) {
    var tuple = tuples[i];
    if (tuple[0] == "Edge") {
      return tuple;
    }
  }
};
goog.labs.userAgent.engine.isVersionOrHigher = function(version) {
  return goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(), version) >= 0;
};
goog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) {
  var pair = goog.array.find(tuples, function(pair) {
    return key == pair[0];
  });
  return pair && pair[1] || "";
};
goog.provide("goog.labs.userAgent.platform");
goog.require("goog.labs.userAgent.util");
goog.require("goog.string");
goog.labs.userAgent.platform.isAndroid = function() {
  return goog.labs.userAgent.util.matchUserAgent("Android");
};
goog.labs.userAgent.platform.isIpod = function() {
  return goog.labs.userAgent.util.matchUserAgent("iPod");
};
goog.labs.userAgent.platform.isIphone = function() {
  return goog.labs.userAgent.util.matchUserAgent("iPhone") && !goog.labs.userAgent.util.matchUserAgent("iPod") && !goog.labs.userAgent.util.matchUserAgent("iPad");
};
goog.labs.userAgent.platform.isIpad = function() {
  return goog.labs.userAgent.util.matchUserAgent("iPad");
};
goog.labs.userAgent.platform.isIos = function() {
  return goog.labs.userAgent.platform.isIphone() || goog.labs.userAgent.platform.isIpad() || goog.labs.userAgent.platform.isIpod();
};
goog.labs.userAgent.platform.isMacintosh = function() {
  return goog.labs.userAgent.util.matchUserAgent("Macintosh");
};
goog.labs.userAgent.platform.isLinux = function() {
  return goog.labs.userAgent.util.matchUserAgent("Linux");
};
goog.labs.userAgent.platform.isWindows = function() {
  return goog.labs.userAgent.util.matchUserAgent("Windows");
};
goog.labs.userAgent.platform.isChromeOS = function() {
  return goog.labs.userAgent.util.matchUserAgent("CrOS");
};
goog.labs.userAgent.platform.getVersion = function() {
  var userAgentString = goog.labs.userAgent.util.getUserAgent();
  var version = "", re;
  if (goog.labs.userAgent.platform.isWindows()) {
    re = /Windows (?:NT|Phone) ([0-9.]+)/;
    var match = re.exec(userAgentString);
    if (match) {
      version = match[1];
    } else {
      version = "0.0";
    }
  } else {
    if (goog.labs.userAgent.platform.isIos()) {
      re = /(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/;
      var match = re.exec(userAgentString);
      version = match && match[1].replace(/_/g, ".");
    } else {
      if (goog.labs.userAgent.platform.isMacintosh()) {
        re = /Mac OS X ([0-9_.]+)/;
        var match = re.exec(userAgentString);
        version = match ? match[1].replace(/_/g, ".") : "10";
      } else {
        if (goog.labs.userAgent.platform.isAndroid()) {
          re = /Android\s+([^\);]+)(\)|;)/;
          var match = re.exec(userAgentString);
          version = match && match[1];
        } else {
          if (goog.labs.userAgent.platform.isChromeOS()) {
            re = /(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/;
            var match = re.exec(userAgentString);
            version = match && match[1];
          }
        }
      }
    }
  }
  return version || "";
};
goog.labs.userAgent.platform.isVersionOrHigher = function(version) {
  return goog.string.compareVersions(goog.labs.userAgent.platform.getVersion(), version) >= 0;
};
goog.provide("goog.reflect");
goog.reflect.object = function(type, object) {
  return object;
};
goog.reflect.objectProperty = function(prop, object) {
  return prop;
};
goog.reflect.sinkValue = function(x) {
  goog.reflect.sinkValue[" "](x);
  return x;
};
goog.reflect.sinkValue[" "] = goog.nullFunction;
goog.reflect.canAccessProperty = function(obj, prop) {
  try {
    goog.reflect.sinkValue(obj[prop]);
    return true;
  } catch (e) {
  }
  return false;
};
goog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) {
  var storedKey = opt_keyFn ? opt_keyFn(key) : key;
  if (Object.prototype.hasOwnProperty.call(cacheObj, storedKey)) {
    return cacheObj[storedKey];
  }
  return cacheObj[storedKey] = valueFn(key);
};
goog.provide("goog.userAgent");
goog.require("goog.labs.userAgent.browser");
goog.require("goog.labs.userAgent.engine");
goog.require("goog.labs.userAgent.platform");
goog.require("goog.labs.userAgent.util");
goog.require("goog.reflect");
goog.require("goog.string");
goog.define("goog.userAgent.ASSUME_IE", false);
goog.define("goog.userAgent.ASSUME_EDGE", false);
goog.define("goog.userAgent.ASSUME_GECKO", false);
goog.define("goog.userAgent.ASSUME_WEBKIT", false);
goog.define("goog.userAgent.ASSUME_MOBILE_WEBKIT", false);
goog.define("goog.userAgent.ASSUME_OPERA", false);
goog.define("goog.userAgent.ASSUME_ANY_VERSION", false);
goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE || goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO || goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_OPERA;
goog.userAgent.getUserAgentString = function() {
  return goog.labs.userAgent.util.getUserAgent();
};
goog.userAgent.getNavigator = function() {
  return goog.global["navigator"] || null;
};
goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_OPERA : goog.labs.userAgent.browser.isOpera();
goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_IE : goog.labs.userAgent.browser.isIE();
goog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_EDGE : goog.labs.userAgent.engine.isEdge();
goog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;
goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_GECKO : goog.labs.userAgent.engine.isGecko();
goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT : goog.labs.userAgent.engine.isWebKit();
goog.userAgent.isMobile_ = function() {
  return goog.userAgent.WEBKIT && goog.labs.userAgent.util.matchUserAgent("Mobile");
};
goog.userAgent.MOBILE = goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();
goog.userAgent.SAFARI = goog.userAgent.WEBKIT;
goog.userAgent.determinePlatform_ = function() {
  var navigator = goog.userAgent.getNavigator();
  return navigator && navigator.platform || "";
};
goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();
goog.define("goog.userAgent.ASSUME_MAC", false);
goog.define("goog.userAgent.ASSUME_WINDOWS", false);
goog.define("goog.userAgent.ASSUME_LINUX", false);
goog.define("goog.userAgent.ASSUME_X11", false);
goog.define("goog.userAgent.ASSUME_ANDROID", false);
goog.define("goog.userAgent.ASSUME_IPHONE", false);
goog.define("goog.userAgent.ASSUME_IPAD", false);
goog.define("goog.userAgent.ASSUME_IPOD", false);
goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC || goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX || goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID || goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD || goog.userAgent.ASSUME_IPOD;
goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_MAC : goog.labs.userAgent.platform.isMacintosh();
goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_WINDOWS : goog.labs.userAgent.platform.isWindows();
goog.userAgent.isLegacyLinux_ = function() {
  return goog.labs.userAgent.platform.isLinux() || goog.labs.userAgent.platform.isChromeOS();
};
goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_LINUX : goog.userAgent.isLegacyLinux_();
goog.userAgent.isX11_ = function() {
  var navigator = goog.userAgent.getNavigator();
  return !!navigator && goog.string.contains(navigator["appVersion"] || "", "X11");
};
goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_X11 : goog.userAgent.isX11_();
goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_ANDROID : goog.labs.userAgent.platform.isAndroid();
goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPHONE : goog.labs.userAgent.platform.isIphone();
goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPAD : goog.labs.userAgent.platform.isIpad();
goog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPOD : goog.labs.userAgent.platform.isIpod();
goog.userAgent.IOS = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD || goog.userAgent.ASSUME_IPOD : goog.labs.userAgent.platform.isIos();
goog.userAgent.determineVersion_ = function() {
  var version = "";
  var arr = goog.userAgent.getVersionRegexResult_();
  if (arr) {
    version = arr ? arr[1] : "";
  }
  if (goog.userAgent.IE) {
    var docMode = goog.userAgent.getDocumentMode_();
    if (docMode != null && docMode > parseFloat(version)) {
      return String(docMode);
    }
  }
  return version;
};
goog.userAgent.getVersionRegexResult_ = function() {
  var userAgent = goog.userAgent.getUserAgentString();
  if (goog.userAgent.GECKO) {
    return /rv\:([^\);]+)(\)|;)/.exec(userAgent);
  }
  if (goog.userAgent.EDGE) {
    return /Edge\/([\d\.]+)/.exec(userAgent);
  }
  if (goog.userAgent.IE) {
    return /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(userAgent);
  }
  if (goog.userAgent.WEBKIT) {
    return /WebKit\/(\S+)/.exec(userAgent);
  }
  if (goog.userAgent.OPERA) {
    return /(?:Version)[ \/]?(\S+)/.exec(userAgent);
  }
  return undefined;
};
goog.userAgent.getDocumentMode_ = function() {
  var doc = goog.global["document"];
  return doc ? doc["documentMode"] : undefined;
};
goog.userAgent.VERSION = goog.userAgent.determineVersion_();
goog.userAgent.compare = function(v1, v2) {
  return goog.string.compareVersions(v1, v2);
};
goog.userAgent.isVersionOrHigherCache_ = {};
goog.userAgent.isVersionOrHigher = function(version) {
  return goog.userAgent.ASSUME_ANY_VERSION || goog.reflect.cache(goog.userAgent.isVersionOrHigherCache_, version, function() {
    return goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0;
  });
};
goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;
goog.userAgent.isDocumentModeOrHigher = function(documentMode) {
  return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;
};
goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;
goog.userAgent.DOCUMENT_MODE = function() {
  var doc = goog.global["document"];
  var mode = goog.userAgent.getDocumentMode_();
  if (!doc || !goog.userAgent.IE) {
    return undefined;
  }
  return mode || (doc["compatMode"] == "CSS1Compat" ? parseInt(goog.userAgent.VERSION, 10) : 5);
}();
goog.provide("goog.debug");
goog.require("goog.array");
goog.require("goog.userAgent");
goog.define("goog.debug.LOGGING_ENABLED", goog.DEBUG);
goog.define("goog.debug.FORCE_SLOPPY_STACKS", false);
goog.debug.catchErrors = function(logFunc, opt_cancel, opt_target) {
  var target = opt_target || goog.global;
  var oldErrorHandler = target.onerror;
  var retVal = !!opt_cancel;
  if (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("535.3")) {
    retVal = !retVal;
  }
  target.onerror = function(message, url, line, opt_col, opt_error) {
    if (oldErrorHandler) {
      oldErrorHandler(message, url, line, opt_col, opt_error);
    }
    logFunc({message:message, fileName:url, line:line, col:opt_col, error:opt_error});
    return retVal;
  };
};
goog.debug.expose = function(obj, opt_showFn) {
  if (typeof obj == "undefined") {
    return "undefined";
  }
  if (obj == null) {
    return "NULL";
  }
  var str = [];
  for (var x in obj) {
    if (!opt_showFn && goog.isFunction(obj[x])) {
      continue;
    }
    var s = x + " = ";
    try {
      s += obj[x];
    } catch (e) {
      s += "*** " + e + " ***";
    }
    str.push(s);
  }
  return str.join("\n");
};
goog.debug.deepExpose = function(obj, opt_showFn) {
  var str = [];
  var uidsToCleanup = [];
  var ancestorUids = {};
  var helper = function(obj, space) {
    var nestspace = space + "  ";
    var indentMultiline = function(str) {
      return str.replace(/\n/g, "\n" + space);
    };
    try {
      if (!goog.isDef(obj)) {
        str.push("undefined");
      } else {
        if (goog.isNull(obj)) {
          str.push("NULL");
        } else {
          if (goog.isString(obj)) {
            str.push('"' + indentMultiline(obj) + '"');
          } else {
            if (goog.isFunction(obj)) {
              str.push(indentMultiline(String(obj)));
            } else {
              if (goog.isObject(obj)) {
                if (!goog.hasUid(obj)) {
                  uidsToCleanup.push(obj);
                }
                var uid = goog.getUid(obj);
                if (ancestorUids[uid]) {
                  str.push("*** reference loop detected (id=" + uid + ") ***");
                } else {
                  ancestorUids[uid] = true;
                  str.push("{");
                  for (var x in obj) {
                    if (!opt_showFn && goog.isFunction(obj[x])) {
                      continue;
                    }
                    str.push("\n");
                    str.push(nestspace);
                    str.push(x + " = ");
                    helper(obj[x], nestspace);
                  }
                  str.push("\n" + space + "}");
                  delete ancestorUids[uid];
                }
              } else {
                str.push(obj);
              }
            }
          }
        }
      }
    } catch (e) {
      str.push("*** " + e + " ***");
    }
  };
  helper(obj, "");
  for (var i = 0; i < uidsToCleanup.length; i++) {
    goog.removeUid(uidsToCleanup[i]);
  }
  return str.join("");
};
goog.debug.exposeArray = function(arr) {
  var str = [];
  for (var i = 0; i < arr.length; i++) {
    if (goog.isArray(arr[i])) {
      str.push(goog.debug.exposeArray(arr[i]));
    } else {
      str.push(arr[i]);
    }
  }
  return "[ " + str.join(", ") + " ]";
};
goog.debug.normalizeErrorObject = function(err) {
  var href = goog.getObjectByName("window.location.href");
  if (goog.isString(err)) {
    return {"message":err, "name":"Unknown error", "lineNumber":"Not available", "fileName":href, "stack":"Not available"};
  }
  var lineNumber, fileName;
  var threwError = false;
  try {
    lineNumber = err.lineNumber || err.line || "Not available";
  } catch (e) {
    lineNumber = "Not available";
    threwError = true;
  }
  try {
    fileName = err.fileName || err.filename || err.sourceURL || goog.global["$googDebugFname"] || href;
  } catch (e$1) {
    fileName = "Not available";
    threwError = true;
  }
  if (threwError || !err.lineNumber || !err.fileName || !err.stack || !err.message || !err.name) {
    return {"message":err.message || "Not available", "name":err.name || "UnknownError", "lineNumber":lineNumber, "fileName":fileName, "stack":err.stack || "Not available"};
  }
  return err;
};
goog.debug.enhanceError = function(err, opt_message) {
  var error;
  if (!(err instanceof Error)) {
    error = Error(err);
    if (Error.captureStackTrace) {
      Error.captureStackTrace(error, goog.debug.enhanceError);
    }
  } else {
    error = err;
  }
  if (!error.stack) {
    error.stack = goog.debug.getStacktrace(goog.debug.enhanceError);
  }
  if (opt_message) {
    var x = 0;
    while (error["message" + x]) {
      ++x;
    }
    error["message" + x] = String(opt_message);
  }
  return error;
};
goog.debug.getStacktraceSimple = function(opt_depth) {
  if (!goog.debug.FORCE_SLOPPY_STACKS) {
    var stack = goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple);
    if (stack) {
      return stack;
    }
  }
  var sb = [];
  var fn = arguments.callee.caller;
  var depth = 0;
  while (fn && (!opt_depth || depth < opt_depth)) {
    sb.push(goog.debug.getFunctionName(fn));
    sb.push("()\n");
    try {
      fn = fn.caller;
    } catch (e) {
      sb.push("[exception trying to get caller]\n");
      break;
    }
    depth++;
    if (depth >= goog.debug.MAX_STACK_DEPTH) {
      sb.push("[...long stack...]");
      break;
    }
  }
  if (opt_depth && depth >= opt_depth) {
    sb.push("[...reached max depth limit...]");
  } else {
    sb.push("[end]");
  }
  return sb.join("");
};
goog.debug.MAX_STACK_DEPTH = 50;
goog.debug.getNativeStackTrace_ = function(fn) {
  var tempErr = new Error;
  if (Error.captureStackTrace) {
    Error.captureStackTrace(tempErr, fn);
    return String(tempErr.stack);
  } else {
    try {
      throw tempErr;
    } catch (e) {
      tempErr = e;
    }
    var stack = tempErr.stack;
    if (stack) {
      return String(stack);
    }
  }
  return null;
};
goog.debug.getStacktrace = function(fn) {
  var stack;
  if (!goog.debug.FORCE_SLOPPY_STACKS) {
    var contextFn = fn || goog.debug.getStacktrace;
    stack = goog.debug.getNativeStackTrace_(contextFn);
  }
  if (!stack) {
    stack = goog.debug.getStacktraceHelper_(fn || arguments.callee.caller, []);
  }
  return stack;
};
goog.debug.getStacktraceHelper_ = function(fn, visited) {
  var sb = [];
  if (goog.array.contains(visited, fn)) {
    sb.push("[...circular reference...]");
  } else {
    if (fn && visited.length < goog.debug.MAX_STACK_DEPTH) {
      sb.push(goog.debug.getFunctionName(fn) + "(");
      var args = fn.arguments;
      for (var i = 0; args && i < args.length; i++) {
        if (i > 0) {
          sb.push(", ");
        }
        var argDesc;
        var arg = args[i];
        switch(typeof arg) {
          case "object":
            argDesc = arg ? "object" : "null";
            break;
          case "string":
            argDesc = arg;
            break;
          case "number":
            argDesc = String(arg);
            break;
          case "boolean":
            argDesc = arg ? "true" : "false";
            break;
          case "function":
            argDesc = goog.debug.getFunctionName(arg);
            argDesc = argDesc ? argDesc : "[fn]";
            break;
          case "undefined":
          default:
            argDesc = typeof arg;
            break;
        }
        if (argDesc.length > 40) {
          argDesc = argDesc.substr(0, 40) + "...";
        }
        sb.push(argDesc);
      }
      visited.push(fn);
      sb.push(")\n");
      try {
        sb.push(goog.debug.getStacktraceHelper_(fn.caller, visited));
      } catch (e) {
        sb.push("[exception trying to get caller]\n");
      }
    } else {
      if (fn) {
        sb.push("[...long stack...]");
      } else {
        sb.push("[end]");
      }
    }
  }
  return sb.join("");
};
goog.debug.setFunctionResolver = function(resolver) {
  goog.debug.fnNameResolver_ = resolver;
};
goog.debug.getFunctionName = function(fn) {
  if (goog.debug.fnNameCache_[fn]) {
    return goog.debug.fnNameCache_[fn];
  }
  if (goog.debug.fnNameResolver_) {
    var name = goog.debug.fnNameResolver_(fn);
    if (name) {
      goog.debug.fnNameCache_[fn] = name;
      return name;
    }
  }
  var functionSource = String(fn);
  if (!goog.debug.fnNameCache_[functionSource]) {
    var matches = /function ([^\(]+)/.exec(functionSource);
    if (matches) {
      var method = matches[1];
      goog.debug.fnNameCache_[functionSource] = method;
    } else {
      goog.debug.fnNameCache_[functionSource] = "[Anonymous]";
    }
  }
  return goog.debug.fnNameCache_[functionSource];
};
goog.debug.makeWhitespaceVisible = function(string) {
  return string.replace(/ /g, "[_]").replace(/\f/g, "[f]").replace(/\n/g, "[n]\n").replace(/\r/g, "[r]").replace(/\t/g, "[t]");
};
goog.debug.runtimeType = function(value) {
  if (value instanceof Function) {
    return value.displayName || value.name || "unknown type name";
  } else {
    if (value instanceof Object) {
      return value.constructor.displayName || value.constructor.name || Object.prototype.toString.call(value);
    } else {
      return value === null ? "null" : typeof value;
    }
  }
};
goog.debug.fnNameCache_ = {};
goog.debug.fnNameResolver_;
goog.provide("goog.debug.LogRecord");
goog.debug.LogRecord = function(level, msg, loggerName, opt_time, opt_sequenceNumber) {
  this.reset(level, msg, loggerName, opt_time, opt_sequenceNumber);
};
goog.debug.LogRecord.prototype.time_;
goog.debug.LogRecord.prototype.level_;
goog.debug.LogRecord.prototype.msg_;
goog.debug.LogRecord.prototype.loggerName_;
goog.debug.LogRecord.prototype.sequenceNumber_ = 0;
goog.debug.LogRecord.prototype.exception_ = null;
goog.define("goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS", true);
goog.debug.LogRecord.nextSequenceNumber_ = 0;
goog.debug.LogRecord.prototype.reset = function(level, msg, loggerName, opt_time, opt_sequenceNumber) {
  if (goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS) {
    this.sequenceNumber_ = typeof opt_sequenceNumber == "number" ? opt_sequenceNumber : goog.debug.LogRecord.nextSequenceNumber_++;
  }
  this.time_ = opt_time || goog.now();
  this.level_ = level;
  this.msg_ = msg;
  this.loggerName_ = loggerName;
  delete this.exception_;
};
goog.debug.LogRecord.prototype.getLoggerName = function() {
  return this.loggerName_;
};
goog.debug.LogRecord.prototype.getException = function() {
  return this.exception_;
};
goog.debug.LogRecord.prototype.setException = function(exception) {
  this.exception_ = exception;
};
goog.debug.LogRecord.prototype.setLoggerName = function(loggerName) {
  this.loggerName_ = loggerName;
};
goog.debug.LogRecord.prototype.getLevel = function() {
  return this.level_;
};
goog.debug.LogRecord.prototype.setLevel = function(level) {
  this.level_ = level;
};
goog.debug.LogRecord.prototype.getMessage = function() {
  return this.msg_;
};
goog.debug.LogRecord.prototype.setMessage = function(msg) {
  this.msg_ = msg;
};
goog.debug.LogRecord.prototype.getMillis = function() {
  return this.time_;
};
goog.debug.LogRecord.prototype.setMillis = function(time) {
  this.time_ = time;
};
goog.debug.LogRecord.prototype.getSequenceNumber = function() {
  return this.sequenceNumber_;
};
goog.provide("goog.debug.LogBuffer");
goog.require("goog.asserts");
goog.require("goog.debug.LogRecord");
goog.debug.LogBuffer = function() {
  goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(), "Cannot use goog.debug.LogBuffer without defining " + "goog.debug.LogBuffer.CAPACITY.");
  this.clear();
};
goog.debug.LogBuffer.getInstance = function() {
  if (!goog.debug.LogBuffer.instance_) {
    goog.debug.LogBuffer.instance_ = new goog.debug.LogBuffer;
  }
  return goog.debug.LogBuffer.instance_;
};
goog.define("goog.debug.LogBuffer.CAPACITY", 0);
goog.debug.LogBuffer.prototype.buffer_;
goog.debug.LogBuffer.prototype.curIndex_;
goog.debug.LogBuffer.prototype.isFull_;
goog.debug.LogBuffer.prototype.addRecord = function(level, msg, loggerName) {
  var curIndex = (this.curIndex_ + 1) % goog.debug.LogBuffer.CAPACITY;
  this.curIndex_ = curIndex;
  if (this.isFull_) {
    var ret = this.buffer_[curIndex];
    ret.reset(level, msg, loggerName);
    return ret;
  }
  this.isFull_ = curIndex == goog.debug.LogBuffer.CAPACITY - 1;
  return this.buffer_[curIndex] = new goog.debug.LogRecord(level, msg, loggerName);
};
goog.debug.LogBuffer.isBufferingEnabled = function() {
  return goog.debug.LogBuffer.CAPACITY > 0;
};
goog.debug.LogBuffer.prototype.clear = function() {
  this.buffer_ = new Array(goog.debug.LogBuffer.CAPACITY);
  this.curIndex_ = -1;
  this.isFull_ = false;
};
goog.debug.LogBuffer.prototype.forEachRecord = function(func) {
  var buffer = this.buffer_;
  if (!buffer[0]) {
    return;
  }
  var curIndex = this.curIndex_;
  var i = this.isFull_ ? curIndex : -1;
  do {
    i = (i + 1) % goog.debug.LogBuffer.CAPACITY;
    func(buffer[i]);
  } while (i != curIndex);
};
goog.provide("goog.debug.LogManager");
goog.provide("goog.debug.Loggable");
goog.provide("goog.debug.Logger");
goog.provide("goog.debug.Logger.Level");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.debug");
goog.require("goog.debug.LogBuffer");
goog.require("goog.debug.LogRecord");
goog.debug.Loggable;
goog.debug.Logger = function(name) {
  this.name_ = name;
  this.parent_ = null;
  this.level_ = null;
  this.children_ = null;
  this.handlers_ = null;
};
goog.debug.Logger.ROOT_LOGGER_NAME = "";
goog.define("goog.debug.Logger.ENABLE_HIERARCHY", true);
if (!goog.debug.Logger.ENABLE_HIERARCHY) {
  goog.debug.Logger.rootHandlers_ = [];
  goog.debug.Logger.rootLevel_;
}
goog.debug.Logger.Level = function(name, value) {
  this.name = name;
  this.value = value;
};
goog.debug.Logger.Level.prototype.toString = function() {
  return this.name;
};
goog.debug.Logger.Level.OFF = new goog.debug.Logger.Level("OFF", Infinity);
goog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level("SHOUT", 1200);
goog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level("SEVERE", 1000);
goog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level("WARNING", 900);
goog.debug.Logger.Level.INFO = new goog.debug.Logger.Level("INFO", 800);
goog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level("CONFIG", 700);
goog.debug.Logger.Level.FINE = new goog.debug.Logger.Level("FINE", 500);
goog.debug.Logger.Level.FINER = new goog.debug.Logger.Level("FINER", 400);
goog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level("FINEST", 300);
goog.debug.Logger.Level.ALL = new goog.debug.Logger.Level("ALL", 0);
goog.debug.Logger.Level.PREDEFINED_LEVELS = [goog.debug.Logger.Level.OFF, goog.debug.Logger.Level.SHOUT, goog.debug.Logger.Level.SEVERE, goog.debug.Logger.Level.WARNING, goog.debug.Logger.Level.INFO, goog.debug.Logger.Level.CONFIG, goog.debug.Logger.Level.FINE, goog.debug.Logger.Level.FINER, goog.debug.Logger.Level.FINEST, goog.debug.Logger.Level.ALL];
goog.debug.Logger.Level.predefinedLevelsCache_ = null;
goog.debug.Logger.Level.createPredefinedLevelsCache_ = function() {
  goog.debug.Logger.Level.predefinedLevelsCache_ = {};
  for (var i = 0, level; level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i]; i++) {
    goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level;
    goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level;
  }
};
goog.debug.Logger.Level.getPredefinedLevel = function(name) {
  if (!goog.debug.Logger.Level.predefinedLevelsCache_) {
    goog.debug.Logger.Level.createPredefinedLevelsCache_();
  }
  return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null;
};
goog.debug.Logger.Level.getPredefinedLevelByValue = function(value) {
  if (!goog.debug.Logger.Level.predefinedLevelsCache_) {
    goog.debug.Logger.Level.createPredefinedLevelsCache_();
  }
  if (value in goog.debug.Logger.Level.predefinedLevelsCache_) {
    return goog.debug.Logger.Level.predefinedLevelsCache_[value];
  }
  for (var i = 0; i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length; ++i) {
    var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];
    if (level.value <= value) {
      return level;
    }
  }
  return null;
};
goog.debug.Logger.getLogger = function(name) {
  return goog.debug.LogManager.getLogger(name);
};
goog.debug.Logger.logToProfilers = function(msg) {
  if (goog.global["console"]) {
    if (goog.global["console"]["timeStamp"]) {
      goog.global["console"]["timeStamp"](msg);
    } else {
      if (goog.global["console"]["markTimeline"]) {
        goog.global["console"]["markTimeline"](msg);
      }
    }
  }
  if (goog.global["msWriteProfilerMark"]) {
    goog.global["msWriteProfilerMark"](msg);
  }
};
goog.debug.Logger.prototype.getName = function() {
  return this.name_;
};
goog.debug.Logger.prototype.addHandler = function(handler) {
  if (goog.debug.LOGGING_ENABLED) {
    if (goog.debug.Logger.ENABLE_HIERARCHY) {
      if (!this.handlers_) {
        this.handlers_ = [];
      }
      this.handlers_.push(handler);
    } else {
      goog.asserts.assert(!this.name_, "Cannot call addHandler on a non-root logger when " + "goog.debug.Logger.ENABLE_HIERARCHY is false.");
      goog.debug.Logger.rootHandlers_.push(handler);
    }
  }
};
goog.debug.Logger.prototype.removeHandler = function(handler) {
  if (goog.debug.LOGGING_ENABLED) {
    var handlers = goog.debug.Logger.ENABLE_HIERARCHY ? this.handlers_ : goog.debug.Logger.rootHandlers_;
    return !!handlers && goog.array.remove(handlers, handler);
  } else {
    return false;
  }
};
goog.debug.Logger.prototype.getParent = function() {
  return this.parent_;
};
goog.debug.Logger.prototype.getChildren = function() {
  if (!this.children_) {
    this.children_ = {};
  }
  return this.children_;
};
goog.debug.Logger.prototype.setLevel = function(level) {
  if (goog.debug.LOGGING_ENABLED) {
    if (goog.debug.Logger.ENABLE_HIERARCHY) {
      this.level_ = level;
    } else {
      goog.asserts.assert(!this.name_, "Cannot call setLevel() on a non-root logger when " + "goog.debug.Logger.ENABLE_HIERARCHY is false.");
      goog.debug.Logger.rootLevel_ = level;
    }
  }
};
goog.debug.Logger.prototype.getLevel = function() {
  return goog.debug.LOGGING_ENABLED ? this.level_ : goog.debug.Logger.Level.OFF;
};
goog.debug.Logger.prototype.getEffectiveLevel = function() {
  if (!goog.debug.LOGGING_ENABLED) {
    return goog.debug.Logger.Level.OFF;
  }
  if (!goog.debug.Logger.ENABLE_HIERARCHY) {
    return goog.debug.Logger.rootLevel_;
  }
  if (this.level_) {
    return this.level_;
  }
  if (this.parent_) {
    return this.parent_.getEffectiveLevel();
  }
  goog.asserts.fail("Root logger has no level set.");
  return null;
};
goog.debug.Logger.prototype.isLoggable = function(level) {
  return goog.debug.LOGGING_ENABLED && level.value >= this.getEffectiveLevel().value;
};
goog.debug.Logger.prototype.log = function(level, msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED && this.isLoggable(level)) {
    if (goog.isFunction(msg)) {
      msg = msg();
    }
    this.doLogRecord_(this.getLogRecord(level, msg, opt_exception));
  }
};
goog.debug.Logger.prototype.getLogRecord = function(level, msg, opt_exception) {
  if (goog.debug.LogBuffer.isBufferingEnabled()) {
    var logRecord = goog.debug.LogBuffer.getInstance().addRecord(level, msg, this.name_);
  } else {
    logRecord = new goog.debug.LogRecord(level, String(msg), this.name_);
  }
  if (opt_exception) {
    logRecord.setException(opt_exception);
  }
  return logRecord;
};
goog.debug.Logger.prototype.shout = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.SHOUT, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.severe = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.warning = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.info = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.INFO, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.config = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.CONFIG, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.fine = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.FINE, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.finer = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.FINER, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.finest = function(msg, opt_exception) {
  if (goog.debug.LOGGING_ENABLED) {
    this.log(goog.debug.Logger.Level.FINEST, msg, opt_exception);
  }
};
goog.debug.Logger.prototype.logRecord = function(logRecord) {
  if (goog.debug.LOGGING_ENABLED && this.isLoggable(logRecord.getLevel())) {
    this.doLogRecord_(logRecord);
  }
};
goog.debug.Logger.prototype.doLogRecord_ = function(logRecord) {
  goog.debug.Logger.logToProfilers("log:" + logRecord.getMessage());
  if (goog.debug.Logger.ENABLE_HIERARCHY) {
    var target = this;
    while (target) {
      target.callPublish_(logRecord);
      target = target.getParent();
    }
  } else {
    for (var i = 0, handler; handler = goog.debug.Logger.rootHandlers_[i++];) {
      handler(logRecord);
    }
  }
};
goog.debug.Logger.prototype.callPublish_ = function(logRecord) {
  if (this.handlers_) {
    for (var i = 0, handler; handler = this.handlers_[i]; i++) {
      handler(logRecord);
    }
  }
};
goog.debug.Logger.prototype.setParent_ = function(parent) {
  this.parent_ = parent;
};
goog.debug.Logger.prototype.addChild_ = function(name, logger) {
  this.getChildren()[name] = logger;
};
goog.debug.LogManager = {};
goog.debug.LogManager.loggers_ = {};
goog.debug.LogManager.rootLogger_ = null;
goog.debug.LogManager.initialize = function() {
  if (!goog.debug.LogManager.rootLogger_) {
    goog.debug.LogManager.rootLogger_ = new goog.debug.Logger(goog.debug.Logger.ROOT_LOGGER_NAME);
    goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME] = goog.debug.LogManager.rootLogger_;
    goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG);
  }
};
goog.debug.LogManager.getLoggers = function() {
  return goog.debug.LogManager.loggers_;
};
goog.debug.LogManager.getRoot = function() {
  goog.debug.LogManager.initialize();
  return goog.debug.LogManager.rootLogger_;
};
goog.debug.LogManager.getLogger = function(name) {
  goog.debug.LogManager.initialize();
  var ret = goog.debug.LogManager.loggers_[name];
  return ret || goog.debug.LogManager.createLogger_(name);
};
goog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) {
  return function(info) {
    var logger = opt_logger || goog.debug.LogManager.getRoot();
    logger.severe("Error: " + info.message + " (" + info.fileName + " @ Line: " + info.line + ")");
  };
};
goog.debug.LogManager.createLogger_ = function(name) {
  var logger = new goog.debug.Logger(name);
  if (goog.debug.Logger.ENABLE_HIERARCHY) {
    var lastDotIndex = name.lastIndexOf(".");
    var parentName = name.substr(0, lastDotIndex);
    var leafName = name.substr(lastDotIndex + 1);
    var parentLogger = goog.debug.LogManager.getLogger(parentName);
    parentLogger.addChild_(leafName, logger);
    logger.setParent_(parentLogger);
  }
  goog.debug.LogManager.loggers_[name] = logger;
  return logger;
};
goog.provide("goog.dom.BrowserFeature");
goog.require("goog.userAgent");
goog.dom.BrowserFeature = {CAN_ADD_NAME_OR_TYPE_ATTRIBUTES:!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), CAN_USE_CHILDREN_ATTRIBUTE:!goog.userAgent.GECKO && !goog.userAgent.IE || goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9) || goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9.1"), CAN_USE_INNER_TEXT:goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9"), CAN_USE_PARENT_ELEMENT_PROPERTY:goog.userAgent.IE || goog.userAgent.OPERA || goog.userAgent.WEBKIT, 
INNER_HTML_NEEDS_SCOPED_ELEMENT:goog.userAgent.IE, LEGACY_IE_RANGES:goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)};
goog.provide("goog.dom.HtmlElement");
goog.dom.HtmlElement = function() {
};
goog.provide("goog.dom.TagName");
goog.require("goog.dom.HtmlElement");
goog.dom.TagName = function(tagName) {
  this.tagName_ = tagName;
};
goog.dom.TagName.prototype.toString = function() {
  return this.tagName_;
};
goog.dom.TagName.A = new goog.dom.TagName("A");
goog.dom.TagName.ABBR = new goog.dom.TagName("ABBR");
goog.dom.TagName.ACRONYM = new goog.dom.TagName("ACRONYM");
goog.dom.TagName.ADDRESS = new goog.dom.TagName("ADDRESS");
goog.dom.TagName.APPLET = new goog.dom.TagName("APPLET");
goog.dom.TagName.AREA = new goog.dom.TagName("AREA");
goog.dom.TagName.ARTICLE = new goog.dom.TagName("ARTICLE");
goog.dom.TagName.ASIDE = new goog.dom.TagName("ASIDE");
goog.dom.TagName.AUDIO = new goog.dom.TagName("AUDIO");
goog.dom.TagName.B = new goog.dom.TagName("B");
goog.dom.TagName.BASE = new goog.dom.TagName("BASE");
goog.dom.TagName.BASEFONT = new goog.dom.TagName("BASEFONT");
goog.dom.TagName.BDI = new goog.dom.TagName("BDI");
goog.dom.TagName.BDO = new goog.dom.TagName("BDO");
goog.dom.TagName.BIG = new goog.dom.TagName("BIG");
goog.dom.TagName.BLOCKQUOTE = new goog.dom.TagName("BLOCKQUOTE");
goog.dom.TagName.BODY = new goog.dom.TagName("BODY");
goog.dom.TagName.BR = new goog.dom.TagName("BR");
goog.dom.TagName.BUTTON = new goog.dom.TagName("BUTTON");
goog.dom.TagName.CANVAS = new goog.dom.TagName("CANVAS");
goog.dom.TagName.CAPTION = new goog.dom.TagName("CAPTION");
goog.dom.TagName.CENTER = new goog.dom.TagName("CENTER");
goog.dom.TagName.CITE = new goog.dom.TagName("CITE");
goog.dom.TagName.CODE = new goog.dom.TagName("CODE");
goog.dom.TagName.COL = new goog.dom.TagName("COL");
goog.dom.TagName.COLGROUP = new goog.dom.TagName("COLGROUP");
goog.dom.TagName.COMMAND = new goog.dom.TagName("COMMAND");
goog.dom.TagName.DATA = new goog.dom.TagName("DATA");
goog.dom.TagName.DATALIST = new goog.dom.TagName("DATALIST");
goog.dom.TagName.DD = new goog.dom.TagName("DD");
goog.dom.TagName.DEL = new goog.dom.TagName("DEL");
goog.dom.TagName.DETAILS = new goog.dom.TagName("DETAILS");
goog.dom.TagName.DFN = new goog.dom.TagName("DFN");
goog.dom.TagName.DIALOG = new goog.dom.TagName("DIALOG");
goog.dom.TagName.DIR = new goog.dom.TagName("DIR");
goog.dom.TagName.DIV = new goog.dom.TagName("DIV");
goog.dom.TagName.DL = new goog.dom.TagName("DL");
goog.dom.TagName.DT = new goog.dom.TagName("DT");
goog.dom.TagName.EM = new goog.dom.TagName("EM");
goog.dom.TagName.EMBED = new goog.dom.TagName("EMBED");
goog.dom.TagName.FIELDSET = new goog.dom.TagName("FIELDSET");
goog.dom.TagName.FIGCAPTION = new goog.dom.TagName("FIGCAPTION");
goog.dom.TagName.FIGURE = new goog.dom.TagName("FIGURE");
goog.dom.TagName.FONT = new goog.dom.TagName("FONT");
goog.dom.TagName.FOOTER = new goog.dom.TagName("FOOTER");
goog.dom.TagName.FORM = new goog.dom.TagName("FORM");
goog.dom.TagName.FRAME = new goog.dom.TagName("FRAME");
goog.dom.TagName.FRAMESET = new goog.dom.TagName("FRAMESET");
goog.dom.TagName.H1 = new goog.dom.TagName("H1");
goog.dom.TagName.H2 = new goog.dom.TagName("H2");
goog.dom.TagName.H3 = new goog.dom.TagName("H3");
goog.dom.TagName.H4 = new goog.dom.TagName("H4");
goog.dom.TagName.H5 = new goog.dom.TagName("H5");
goog.dom.TagName.H6 = new goog.dom.TagName("H6");
goog.dom.TagName.HEAD = new goog.dom.TagName("HEAD");
goog.dom.TagName.HEADER = new goog.dom.TagName("HEADER");
goog.dom.TagName.HGROUP = new goog.dom.TagName("HGROUP");
goog.dom.TagName.HR = new goog.dom.TagName("HR");
goog.dom.TagName.HTML = new goog.dom.TagName("HTML");
goog.dom.TagName.I = new goog.dom.TagName("I");
goog.dom.TagName.IFRAME = new goog.dom.TagName("IFRAME");
goog.dom.TagName.IMG = new goog.dom.TagName("IMG");
goog.dom.TagName.INPUT = new goog.dom.TagName("INPUT");
goog.dom.TagName.INS = new goog.dom.TagName("INS");
goog.dom.TagName.ISINDEX = new goog.dom.TagName("ISINDEX");
goog.dom.TagName.KBD = new goog.dom.TagName("KBD");
goog.dom.TagName.KEYGEN = new goog.dom.TagName("KEYGEN");
goog.dom.TagName.LABEL = new goog.dom.TagName("LABEL");
goog.dom.TagName.LEGEND = new goog.dom.TagName("LEGEND");
goog.dom.TagName.LI = new goog.dom.TagName("LI");
goog.dom.TagName.LINK = new goog.dom.TagName("LINK");
goog.dom.TagName.MAP = new goog.dom.TagName("MAP");
goog.dom.TagName.MARK = new goog.dom.TagName("MARK");
goog.dom.TagName.MATH = new goog.dom.TagName("MATH");
goog.dom.TagName.MENU = new goog.dom.TagName("MENU");
goog.dom.TagName.META = new goog.dom.TagName("META");
goog.dom.TagName.METER = new goog.dom.TagName("METER");
goog.dom.TagName.NAV = new goog.dom.TagName("NAV");
goog.dom.TagName.NOFRAMES = new goog.dom.TagName("NOFRAMES");
goog.dom.TagName.NOSCRIPT = new goog.dom.TagName("NOSCRIPT");
goog.dom.TagName.OBJECT = new goog.dom.TagName("OBJECT");
goog.dom.TagName.OL = new goog.dom.TagName("OL");
goog.dom.TagName.OPTGROUP = new goog.dom.TagName("OPTGROUP");
goog.dom.TagName.OPTION = new goog.dom.TagName("OPTION");
goog.dom.TagName.OUTPUT = new goog.dom.TagName("OUTPUT");
goog.dom.TagName.P = new goog.dom.TagName("P");
goog.dom.TagName.PARAM = new goog.dom.TagName("PARAM");
goog.dom.TagName.PRE = new goog.dom.TagName("PRE");
goog.dom.TagName.PROGRESS = new goog.dom.TagName("PROGRESS");
goog.dom.TagName.Q = new goog.dom.TagName("Q");
goog.dom.TagName.RP = new goog.dom.TagName("RP");
goog.dom.TagName.RT = new goog.dom.TagName("RT");
goog.dom.TagName.RUBY = new goog.dom.TagName("RUBY");
goog.dom.TagName.S = new goog.dom.TagName("S");
goog.dom.TagName.SAMP = new goog.dom.TagName("SAMP");
goog.dom.TagName.SCRIPT = new goog.dom.TagName("SCRIPT");
goog.dom.TagName.SECTION = new goog.dom.TagName("SECTION");
goog.dom.TagName.SELECT = new goog.dom.TagName("SELECT");
goog.dom.TagName.SMALL = new goog.dom.TagName("SMALL");
goog.dom.TagName.SOURCE = new goog.dom.TagName("SOURCE");
goog.dom.TagName.SPAN = new goog.dom.TagName("SPAN");
goog.dom.TagName.STRIKE = new goog.dom.TagName("STRIKE");
goog.dom.TagName.STRONG = new goog.dom.TagName("STRONG");
goog.dom.TagName.STYLE = new goog.dom.TagName("STYLE");
goog.dom.TagName.SUB = new goog.dom.TagName("SUB");
goog.dom.TagName.SUMMARY = new goog.dom.TagName("SUMMARY");
goog.dom.TagName.SUP = new goog.dom.TagName("SUP");
goog.dom.TagName.SVG = new goog.dom.TagName("SVG");
goog.dom.TagName.TABLE = new goog.dom.TagName("TABLE");
goog.dom.TagName.TBODY = new goog.dom.TagName("TBODY");
goog.dom.TagName.TD = new goog.dom.TagName("TD");
goog.dom.TagName.TEMPLATE = new goog.dom.TagName("TEMPLATE");
goog.dom.TagName.TEXTAREA = new goog.dom.TagName("TEXTAREA");
goog.dom.TagName.TFOOT = new goog.dom.TagName("TFOOT");
goog.dom.TagName.TH = new goog.dom.TagName("TH");
goog.dom.TagName.THEAD = new goog.dom.TagName("THEAD");
goog.dom.TagName.TIME = new goog.dom.TagName("TIME");
goog.dom.TagName.TITLE = new goog.dom.TagName("TITLE");
goog.dom.TagName.TR = new goog.dom.TagName("TR");
goog.dom.TagName.TRACK = new goog.dom.TagName("TRACK");
goog.dom.TagName.TT = new goog.dom.TagName("TT");
goog.dom.TagName.U = new goog.dom.TagName("U");
goog.dom.TagName.UL = new goog.dom.TagName("UL");
goog.dom.TagName.VAR = new goog.dom.TagName("VAR");
goog.dom.TagName.VIDEO = new goog.dom.TagName("VIDEO");
goog.dom.TagName.WBR = new goog.dom.TagName("WBR");
goog.provide("goog.dom.tags");
goog.require("goog.object");
goog.dom.tags.VOID_TAGS_ = goog.object.createSet("area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr");
goog.dom.tags.isVoidTag = function(tagName) {
  return goog.dom.tags.VOID_TAGS_[tagName] === true;
};
goog.provide("goog.string.TypedString");
goog.string.TypedString = function() {
};
goog.string.TypedString.prototype.implementsGoogStringTypedString;
goog.string.TypedString.prototype.getTypedStringValue;
goog.provide("goog.string.Const");
goog.require("goog.asserts");
goog.require("goog.string.TypedString");
goog.string.Const = function() {
  this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ = "";
  this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ = goog.string.Const.TYPE_MARKER_;
};
goog.string.Const.prototype.implementsGoogStringTypedString = true;
goog.string.Const.prototype.getTypedStringValue = function() {
  return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_;
};
goog.string.Const.prototype.toString = function() {
  return "Const{" + this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ + "}";
};
goog.string.Const.unwrap = function(stringConst) {
  if (stringConst instanceof goog.string.Const && stringConst.constructor === goog.string.Const && stringConst.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ === goog.string.Const.TYPE_MARKER_) {
    return stringConst.stringConstValueWithSecurityContract__googStringSecurityPrivate_;
  } else {
    goog.asserts.fail("expected object of type Const, got '" + stringConst + "'");
    return "type_error:Const";
  }
};
goog.string.Const.from = function(s) {
  return goog.string.Const.create__googStringSecurityPrivate_(s);
};
goog.string.Const.TYPE_MARKER_ = {};
goog.string.Const.create__googStringSecurityPrivate_ = function(s) {
  var stringConst = new goog.string.Const;
  stringConst.stringConstValueWithSecurityContract__googStringSecurityPrivate_ = s;
  return stringConst;
};
goog.string.Const.EMPTY = goog.string.Const.from("");
goog.provide("goog.html.SafeScript");
goog.require("goog.asserts");
goog.require("goog.string.Const");
goog.require("goog.string.TypedString");
goog.html.SafeScript = function() {
  this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = "";
  this.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
};
goog.html.SafeScript.prototype.implementsGoogStringTypedString = true;
goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
goog.html.SafeScript.fromConstant = function(script) {
  var scriptString = goog.string.Const.unwrap(script);
  if (scriptString.length === 0) {
    return goog.html.SafeScript.EMPTY;
  }
  return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(scriptString);
};
goog.html.SafeScript.prototype.getTypedStringValue = function() {
  return this.privateDoNotAccessOrElseSafeScriptWrappedValue_;
};
if (goog.DEBUG) {
  goog.html.SafeScript.prototype.toString = function() {
    return "SafeScript{" + this.privateDoNotAccessOrElseSafeScriptWrappedValue_ + "}";
  };
}
goog.html.SafeScript.unwrap = function(safeScript) {
  if (safeScript instanceof goog.html.SafeScript && safeScript.constructor === goog.html.SafeScript && safeScript.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
    return safeScript.privateDoNotAccessOrElseSafeScriptWrappedValue_;
  } else {
    goog.asserts.fail("expected object of type SafeScript, got '" + safeScript + "' of type " + goog.typeOf(safeScript));
    return "type_error:SafeScript";
  }
};
goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse = function(script) {
  return (new goog.html.SafeScript).initSecurityPrivateDoNotAccessOrElse_(script);
};
goog.html.SafeScript.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(script) {
  this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = script;
  return this;
};
goog.html.SafeScript.EMPTY = goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse("");
goog.provide("goog.html.SafeStyle");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.string");
goog.require("goog.string.Const");
goog.require("goog.string.TypedString");
goog.html.SafeStyle = function() {
  this.privateDoNotAccessOrElseSafeStyleWrappedValue_ = "";
  this.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
};
goog.html.SafeStyle.prototype.implementsGoogStringTypedString = true;
goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
goog.html.SafeStyle.fromConstant = function(style) {
  var styleString = goog.string.Const.unwrap(style);
  if (styleString.length === 0) {
    return goog.html.SafeStyle.EMPTY;
  }
  goog.html.SafeStyle.checkStyle_(styleString);
  goog.asserts.assert(goog.string.endsWith(styleString, ";"), "Last character of style string is not ';': " + styleString);
  goog.asserts.assert(goog.string.contains(styleString, ":"), "Style string must contain at least one ':', to " + 'specify a "name: value" pair: ' + styleString);
  return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(styleString);
};
goog.html.SafeStyle.checkStyle_ = function(style) {
  goog.asserts.assert(!/[<>]/.test(style), "Forbidden characters in style string: " + style);
};
goog.html.SafeStyle.prototype.getTypedStringValue = function() {
  return this.privateDoNotAccessOrElseSafeStyleWrappedValue_;
};
if (goog.DEBUG) {
  goog.html.SafeStyle.prototype.toString = function() {
    return "SafeStyle{" + this.privateDoNotAccessOrElseSafeStyleWrappedValue_ + "}";
  };
}
goog.html.SafeStyle.unwrap = function(safeStyle) {
  if (safeStyle instanceof goog.html.SafeStyle && safeStyle.constructor === goog.html.SafeStyle && safeStyle.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
    return safeStyle.privateDoNotAccessOrElseSafeStyleWrappedValue_;
  } else {
    goog.asserts.fail("expected object of type SafeStyle, got '" + safeStyle + "' of type " + goog.typeOf(safeStyle));
    return "type_error:SafeStyle";
  }
};
goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse = function(style) {
  return (new goog.html.SafeStyle).initSecurityPrivateDoNotAccessOrElse_(style);
};
goog.html.SafeStyle.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(style) {
  this.privateDoNotAccessOrElseSafeStyleWrappedValue_ = style;
  return this;
};
goog.html.SafeStyle.EMPTY = goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse("");
goog.html.SafeStyle.INNOCUOUS_STRING = "zClosurez";
goog.html.SafeStyle.PropertyMap;
goog.html.SafeStyle.create = function(map) {
  var style = "";
  for (var name in map) {
    if (!/^[-_a-zA-Z0-9]+$/.test(name)) {
      throw Error("Name allows only [-_a-zA-Z0-9], got: " + name);
    }
    var value = map[name];
    if (value == null) {
      continue;
    }
    if (value instanceof goog.string.Const) {
      value = goog.string.Const.unwrap(value);
      goog.asserts.assert(!/[{;}]/.test(value), "Value does not allow [{;}].");
    } else {
      if (!goog.html.SafeStyle.VALUE_RE_.test(value)) {
        goog.asserts.fail("String value allows only [-,.\"'%_!# a-zA-Z0-9], rgb() and " + "rgba(), got: " + value);
        value = goog.html.SafeStyle.INNOCUOUS_STRING;
      } else {
        if (!goog.html.SafeStyle.hasBalancedQuotes_(value)) {
          goog.asserts.fail("String value requires balanced quotes, got: " + value);
          value = goog.html.SafeStyle.INNOCUOUS_STRING;
        }
      }
    }
    style += name + ":" + value + ";";
  }
  if (!style) {
    return goog.html.SafeStyle.EMPTY;
  }
  goog.html.SafeStyle.checkStyle_(style);
  return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);
};
goog.html.SafeStyle.hasBalancedQuotes_ = function(value) {
  var outsideSingle = true;
  var outsideDouble = true;
  for (var i = 0; i < value.length; i++) {
    var c = value.charAt(i);
    if (c == "'" && outsideDouble) {
      outsideSingle = !outsideSingle;
    } else {
      if (c == '"' && outsideSingle) {
        outsideDouble = !outsideDouble;
      }
    }
  }
  return outsideSingle && outsideDouble;
};
goog.html.SafeStyle.VALUE_RE_ = /^([-,."'%_!# a-zA-Z0-9]+|(?:rgb|hsl)a?\([0-9.%, ]+\))$/;
goog.html.SafeStyle.concat = function(var_args) {
  var style = "";
  var addArgument = function(argument) {
    if (goog.isArray(argument)) {
      goog.array.forEach(argument, addArgument);
    } else {
      style += goog.html.SafeStyle.unwrap(argument);
    }
  };
  goog.array.forEach(arguments, addArgument);
  if (!style) {
    return goog.html.SafeStyle.EMPTY;
  }
  return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);
};
goog.provide("goog.html.SafeStyleSheet");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.string");
goog.require("goog.string.Const");
goog.require("goog.string.TypedString");
goog.html.SafeStyleSheet = function() {
  this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ = "";
  this.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
};
goog.html.SafeStyleSheet.prototype.implementsGoogStringTypedString = true;
goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
goog.html.SafeStyleSheet.concat = function(var_args) {
  var result = "";
  var addArgument = function(argument) {
    if (goog.isArray(argument)) {
      goog.array.forEach(argument, addArgument);
    } else {
      result += goog.html.SafeStyleSheet.unwrap(argument);
    }
  };
  goog.array.forEach(arguments, addArgument);
  return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(result);
};
goog.html.SafeStyleSheet.fromConstant = function(styleSheet) {
  var styleSheetString = goog.string.Const.unwrap(styleSheet);
  if (styleSheetString.length === 0) {
    return goog.html.SafeStyleSheet.EMPTY;
  }
  goog.asserts.assert(!goog.string.contains(styleSheetString, "<"), "Forbidden '<' character in style sheet string: " + styleSheetString);
  return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheetString);
};
goog.html.SafeStyleSheet.prototype.getTypedStringValue = function() {
  return this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;
};
if (goog.DEBUG) {
  goog.html.SafeStyleSheet.prototype.toString = function() {
    return "SafeStyleSheet{" + this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ + "}";
  };
}
goog.html.SafeStyleSheet.unwrap = function(safeStyleSheet) {
  if (safeStyleSheet instanceof goog.html.SafeStyleSheet && safeStyleSheet.constructor === goog.html.SafeStyleSheet && safeStyleSheet.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
    return safeStyleSheet.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;
  } else {
    goog.asserts.fail("expected object of type SafeStyleSheet, got '" + safeStyleSheet + "' of type " + goog.typeOf(safeStyleSheet));
    return "type_error:SafeStyleSheet";
  }
};
goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse = function(styleSheet) {
  return (new goog.html.SafeStyleSheet).initSecurityPrivateDoNotAccessOrElse_(styleSheet);
};
goog.html.SafeStyleSheet.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(styleSheet) {
  this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ = styleSheet;
  return this;
};
goog.html.SafeStyleSheet.EMPTY = goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse("");
goog.provide("goog.fs.url");
goog.fs.url.createObjectUrl = function(blob) {
  return goog.fs.url.getUrlObject_().createObjectURL(blob);
};
goog.fs.url.revokeObjectUrl = function(url) {
  goog.fs.url.getUrlObject_().revokeObjectURL(url);
};
goog.fs.url.UrlObject_;
goog.fs.url.getUrlObject_ = function() {
  var urlObject = goog.fs.url.findUrlObject_();
  if (urlObject != null) {
    return urlObject;
  } else {
    throw Error("This browser doesn't seem to support blob URLs");
  }
};
goog.fs.url.findUrlObject_ = function() {
  if (goog.isDef(goog.global.URL) && goog.isDef(goog.global.URL.createObjectURL)) {
    return goog.global.URL;
  } else {
    if (goog.isDef(goog.global.webkitURL) && goog.isDef(goog.global.webkitURL.createObjectURL)) {
      return goog.global.webkitURL;
    } else {
      if (goog.isDef(goog.global.createObjectURL)) {
        return goog.global;
      } else {
        return null;
      }
    }
  }
};
goog.fs.url.browserSupportsObjectUrls = function() {
  return goog.fs.url.findUrlObject_() != null;
};
goog.provide("goog.i18n.bidi");
goog.provide("goog.i18n.bidi.Dir");
goog.provide("goog.i18n.bidi.DirectionalString");
goog.provide("goog.i18n.bidi.Format");
goog.define("goog.i18n.bidi.FORCE_RTL", false);
goog.i18n.bidi.IS_RTL = goog.i18n.bidi.FORCE_RTL || (goog.LOCALE.substring(0, 2).toLowerCase() == "ar" || goog.LOCALE.substring(0, 2).toLowerCase() == "fa" || goog.LOCALE.substring(0, 2).toLowerCase() == "he" || goog.LOCALE.substring(0, 2).toLowerCase() == "iw" || goog.LOCALE.substring(0, 2).toLowerCase() == "ps" || goog.LOCALE.substring(0, 2).toLowerCase() == "sd" || goog.LOCALE.substring(0, 2).toLowerCase() == "ug" || goog.LOCALE.substring(0, 2).toLowerCase() == "ur" || goog.LOCALE.substring(0, 
2).toLowerCase() == "yi") && (goog.LOCALE.length == 2 || goog.LOCALE.substring(2, 3) == "-" || goog.LOCALE.substring(2, 3) == "_") || goog.LOCALE.length >= 3 && goog.LOCALE.substring(0, 3).toLowerCase() == "ckb" && (goog.LOCALE.length == 3 || goog.LOCALE.substring(3, 4) == "-" || goog.LOCALE.substring(3, 4) == "_");
goog.i18n.bidi.Format = {LRE:"\u202a", RLE:"\u202b", PDF:"\u202c", LRM:"\u200e", RLM:"\u200f"};
goog.i18n.bidi.Dir = {LTR:1, RTL:-1, NEUTRAL:0};
goog.i18n.bidi.RIGHT = "right";
goog.i18n.bidi.LEFT = "left";
goog.i18n.bidi.I18N_RIGHT = goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.LEFT : goog.i18n.bidi.RIGHT;
goog.i18n.bidi.I18N_LEFT = goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.RIGHT : goog.i18n.bidi.LEFT;
goog.i18n.bidi.toDir = function(givenDir, opt_noNeutral) {
  if (typeof givenDir == "number") {
    return givenDir > 0 ? goog.i18n.bidi.Dir.LTR : givenDir < 0 ? goog.i18n.bidi.Dir.RTL : opt_noNeutral ? null : goog.i18n.bidi.Dir.NEUTRAL;
  } else {
    if (givenDir == null) {
      return null;
    } else {
      return givenDir ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.LTR;
    }
  }
};
goog.i18n.bidi.ltrChars_ = "A-Za-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u0300-\u0590\u0800-\u1fff" + "\u200e\u2c00-\ufb1c\ufe00-\ufe6f\ufefd-\uffff";
goog.i18n.bidi.rtlChars_ = "\u0591-\u06ef\u06fa-\u07ff\u200f\ufb1d-\ufdff\ufe70-\ufefc";
goog.i18n.bidi.htmlSkipReg_ = /<[^>]*>|&[^;]+;/g;
goog.i18n.bidi.stripHtmlIfNeeded_ = function(str, opt_isStripNeeded) {
  return opt_isStripNeeded ? str.replace(goog.i18n.bidi.htmlSkipReg_, "") : str;
};
goog.i18n.bidi.rtlCharReg_ = new RegExp("[" + goog.i18n.bidi.rtlChars_ + "]");
goog.i18n.bidi.ltrCharReg_ = new RegExp("[" + goog.i18n.bidi.ltrChars_ + "]");
goog.i18n.bidi.hasAnyRtl = function(str, opt_isHtml) {
  return goog.i18n.bidi.rtlCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
};
goog.i18n.bidi.hasRtlChar = goog.i18n.bidi.hasAnyRtl;
goog.i18n.bidi.hasAnyLtr = function(str, opt_isHtml) {
  return goog.i18n.bidi.ltrCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
};
goog.i18n.bidi.ltrRe_ = new RegExp("^[" + goog.i18n.bidi.ltrChars_ + "]");
goog.i18n.bidi.rtlRe_ = new RegExp("^[" + goog.i18n.bidi.rtlChars_ + "]");
goog.i18n.bidi.isRtlChar = function(str) {
  return goog.i18n.bidi.rtlRe_.test(str);
};
goog.i18n.bidi.isLtrChar = function(str) {
  return goog.i18n.bidi.ltrRe_.test(str);
};
goog.i18n.bidi.isNeutralChar = function(str) {
  return !goog.i18n.bidi.isLtrChar(str) && !goog.i18n.bidi.isRtlChar(str);
};
goog.i18n.bidi.ltrDirCheckRe_ = new RegExp("^[^" + goog.i18n.bidi.rtlChars_ + "]*[" + goog.i18n.bidi.ltrChars_ + "]");
goog.i18n.bidi.rtlDirCheckRe_ = new RegExp("^[^" + goog.i18n.bidi.ltrChars_ + "]*[" + goog.i18n.bidi.rtlChars_ + "]");
goog.i18n.bidi.startsWithRtl = function(str, opt_isHtml) {
  return goog.i18n.bidi.rtlDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
};
goog.i18n.bidi.isRtlText = goog.i18n.bidi.startsWithRtl;
goog.i18n.bidi.startsWithLtr = function(str, opt_isHtml) {
  return goog.i18n.bidi.ltrDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
};
goog.i18n.bidi.isLtrText = goog.i18n.bidi.startsWithLtr;
goog.i18n.bidi.isRequiredLtrRe_ = /^http:\/\/.*/;
goog.i18n.bidi.isNeutralText = function(str, opt_isHtml) {
  str = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml);
  return goog.i18n.bidi.isRequiredLtrRe_.test(str) || !goog.i18n.bidi.hasAnyLtr(str) && !goog.i18n.bidi.hasAnyRtl(str);
};
goog.i18n.bidi.ltrExitDirCheckRe_ = new RegExp("[" + goog.i18n.bidi.ltrChars_ + "][^" + goog.i18n.bidi.rtlChars_ + "]*$");
goog.i18n.bidi.rtlExitDirCheckRe_ = new RegExp("[" + goog.i18n.bidi.rtlChars_ + "][^" + goog.i18n.bidi.ltrChars_ + "]*$");
goog.i18n.bidi.endsWithLtr = function(str, opt_isHtml) {
  return goog.i18n.bidi.ltrExitDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
};
goog.i18n.bidi.isLtrExitText = goog.i18n.bidi.endsWithLtr;
goog.i18n.bidi.endsWithRtl = function(str, opt_isHtml) {
  return goog.i18n.bidi.rtlExitDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
};
goog.i18n.bidi.isRtlExitText = goog.i18n.bidi.endsWithRtl;
goog.i18n.bidi.rtlLocalesRe_ = new RegExp("^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|" + ".*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))" + "(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)", "i");
goog.i18n.bidi.isRtlLanguage = function(lang) {
  return goog.i18n.bidi.rtlLocalesRe_.test(lang);
};
goog.i18n.bidi.bracketGuardTextRe_ = /(\(.*?\)+)|(\[.*?\]+)|(\{.*?\}+)|(<.*?>+)/g;
goog.i18n.bidi.guardBracketInText = function(s, opt_isRtlContext) {
  var useRtl = opt_isRtlContext === undefined ? goog.i18n.bidi.hasAnyRtl(s) : opt_isRtlContext;
  var mark = useRtl ? goog.i18n.bidi.Format.RLM : goog.i18n.bidi.Format.LRM;
  return s.replace(goog.i18n.bidi.bracketGuardTextRe_, mark + "$&" + mark);
};
goog.i18n.bidi.enforceRtlInHtml = function(html) {
  if (html.charAt(0) == "<") {
    return html.replace(/<\w+/, "$& dir=rtl");
  }
  return "\n<span dir=rtl>" + html + "</span>";
};
goog.i18n.bidi.enforceRtlInText = function(text) {
  return goog.i18n.bidi.Format.RLE + text + goog.i18n.bidi.Format.PDF;
};
goog.i18n.bidi.enforceLtrInHtml = function(html) {
  if (html.charAt(0) == "<") {
    return html.replace(/<\w+/, "$& dir=ltr");
  }
  return "\n<span dir=ltr>" + html + "</span>";
};
goog.i18n.bidi.enforceLtrInText = function(text) {
  return goog.i18n.bidi.Format.LRE + text + goog.i18n.bidi.Format.PDF;
};
goog.i18n.bidi.dimensionsRe_ = /:\s*([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)/g;
goog.i18n.bidi.leftRe_ = /left/gi;
goog.i18n.bidi.rightRe_ = /right/gi;
goog.i18n.bidi.tempRe_ = /%%%%/g;
goog.i18n.bidi.mirrorCSS = function(cssStr) {
  return cssStr.replace(goog.i18n.bidi.dimensionsRe_, ":$1 $4 $3 $2").replace(goog.i18n.bidi.leftRe_, "%%%%").replace(goog.i18n.bidi.rightRe_, goog.i18n.bidi.LEFT).replace(goog.i18n.bidi.tempRe_, goog.i18n.bidi.RIGHT);
};
goog.i18n.bidi.doubleQuoteSubstituteRe_ = /([\u0591-\u05f2])"/g;
goog.i18n.bidi.singleQuoteSubstituteRe_ = /([\u0591-\u05f2])'/g;
goog.i18n.bidi.normalizeHebrewQuote = function(str) {
  return str.replace(goog.i18n.bidi.doubleQuoteSubstituteRe_, "$1\u05f4").replace(goog.i18n.bidi.singleQuoteSubstituteRe_, "$1\u05f3");
};
goog.i18n.bidi.wordSeparatorRe_ = /\s+/;
goog.i18n.bidi.hasNumeralsRe_ = /[\d\u06f0-\u06f9]/;
goog.i18n.bidi.rtlDetectionThreshold_ = 0.40;
goog.i18n.bidi.estimateDirection = function(str, opt_isHtml) {
  var rtlCount = 0;
  var totalCount = 0;
  var hasWeaklyLtr = false;
  var tokens = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml).split(goog.i18n.bidi.wordSeparatorRe_);
  for (var i = 0; i < tokens.length; i++) {
    var token = tokens[i];
    if (goog.i18n.bidi.startsWithRtl(token)) {
      rtlCount++;
      totalCount++;
    } else {
      if (goog.i18n.bidi.isRequiredLtrRe_.test(token)) {
        hasWeaklyLtr = true;
      } else {
        if (goog.i18n.bidi.hasAnyLtr(token)) {
          totalCount++;
        } else {
          if (goog.i18n.bidi.hasNumeralsRe_.test(token)) {
            hasWeaklyLtr = true;
          }
        }
      }
    }
  }
  return totalCount == 0 ? hasWeaklyLtr ? goog.i18n.bidi.Dir.LTR : goog.i18n.bidi.Dir.NEUTRAL : rtlCount / totalCount > goog.i18n.bidi.rtlDetectionThreshold_ ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.LTR;
};
goog.i18n.bidi.detectRtlDirectionality = function(str, opt_isHtml) {
  return goog.i18n.bidi.estimateDirection(str, opt_isHtml) == goog.i18n.bidi.Dir.RTL;
};
goog.i18n.bidi.setElementDirAndAlign = function(element, dir) {
  if (element) {
    dir = goog.i18n.bidi.toDir(dir);
    if (dir) {
      element.style.textAlign = dir == goog.i18n.bidi.Dir.RTL ? goog.i18n.bidi.RIGHT : goog.i18n.bidi.LEFT;
      element.dir = dir == goog.i18n.bidi.Dir.RTL ? "rtl" : "ltr";
    }
  }
};
goog.i18n.bidi.setElementDirByTextDirectionality = function(element, text) {
  switch(goog.i18n.bidi.estimateDirection(text)) {
    case goog.i18n.bidi.Dir.LTR:
      element.dir = "ltr";
      break;
    case goog.i18n.bidi.Dir.RTL:
      element.dir = "rtl";
      break;
    default:
      element.removeAttribute("dir");
  }
};
goog.i18n.bidi.DirectionalString = function() {
};
goog.i18n.bidi.DirectionalString.prototype.implementsGoogI18nBidiDirectionalString;
goog.i18n.bidi.DirectionalString.prototype.getDirection;
goog.provide("goog.html.TrustedResourceUrl");
goog.require("goog.asserts");
goog.require("goog.i18n.bidi.Dir");
goog.require("goog.i18n.bidi.DirectionalString");
goog.require("goog.string.Const");
goog.require("goog.string.TypedString");
goog.html.TrustedResourceUrl = function() {
  this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ = "";
  this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
};
goog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString = true;
goog.html.TrustedResourceUrl.prototype.getTypedStringValue = function() {
  return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
};
goog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString = true;
goog.html.TrustedResourceUrl.prototype.getDirection = function() {
  return goog.i18n.bidi.Dir.LTR;
};
if (goog.DEBUG) {
  goog.html.TrustedResourceUrl.prototype.toString = function() {
    return "TrustedResourceUrl{" + this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ + "}";
  };
}
goog.html.TrustedResourceUrl.unwrap = function(trustedResourceUrl) {
  if (trustedResourceUrl instanceof goog.html.TrustedResourceUrl && trustedResourceUrl.constructor === goog.html.TrustedResourceUrl && trustedResourceUrl.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
    return trustedResourceUrl.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
  } else {
    goog.asserts.fail("expected object of type TrustedResourceUrl, got '" + trustedResourceUrl + "' of type " + goog.typeOf(trustedResourceUrl));
    return "type_error:TrustedResourceUrl";
  }
};
goog.html.TrustedResourceUrl.format = function(format, args) {
  var formatStr = goog.string.Const.unwrap(format);
  if (!goog.html.TrustedResourceUrl.BASE_URL_.test(formatStr)) {
    throw new Error("Invalid TrustedResourceUrl format: " + formatStr);
  }
  var result = formatStr.replace(goog.html.TrustedResourceUrl.FORMAT_MARKER_, function(match, id) {
    if (!Object.prototype.hasOwnProperty.call(args, id)) {
      throw new Error('Found marker, "' + id + '", in format string, "' + formatStr + '", but no valid label mapping found ' + "in args: " + JSON.stringify(args));
    }
    var arg = args[id];
    if (arg instanceof goog.string.Const) {
      return goog.string.Const.unwrap(arg);
    } else {
      return encodeURIComponent(String(arg));
    }
  });
  return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(result);
};
goog.html.TrustedResourceUrl.FORMAT_MARKER_ = /%{(\w+)}/g;
goog.html.TrustedResourceUrl.BASE_URL_ = /^(?:https:)?\/\/[0-9a-z.:[\]-]+\/|^\/[^\/\\]|^about:blank(#|$)/i;
goog.html.TrustedResourceUrl.fromConstant = function(url) {
  return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(url));
};
goog.html.TrustedResourceUrl.fromConstants = function(parts) {
  var unwrapped = "";
  for (var i = 0; i < parts.length; i++) {
    unwrapped += goog.string.Const.unwrap(parts[i]);
  }
  return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(unwrapped);
};
goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) {
  var trustedResourceUrl = new goog.html.TrustedResourceUrl;
  trustedResourceUrl.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ = url;
  return trustedResourceUrl;
};
goog.provide("goog.html.SafeUrl");
goog.require("goog.asserts");
goog.require("goog.fs.url");
goog.require("goog.html.TrustedResourceUrl");
goog.require("goog.i18n.bidi.Dir");
goog.require("goog.i18n.bidi.DirectionalString");
goog.require("goog.string");
goog.require("goog.string.Const");
goog.require("goog.string.TypedString");
goog.html.SafeUrl = function() {
  this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = "";
  this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
};
goog.html.SafeUrl.INNOCUOUS_STRING = "about:invalid#zClosurez";
goog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;
goog.html.SafeUrl.prototype.getTypedStringValue = function() {
  return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
};
goog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString = true;
goog.html.SafeUrl.prototype.getDirection = function() {
  return goog.i18n.bidi.Dir.LTR;
};
if (goog.DEBUG) {
  goog.html.SafeUrl.prototype.toString = function() {
    return "SafeUrl{" + this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ + "}";
  };
}
goog.html.SafeUrl.unwrap = function(safeUrl) {
  if (safeUrl instanceof goog.html.SafeUrl && safeUrl.constructor === goog.html.SafeUrl && safeUrl.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
    return safeUrl.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
  } else {
    goog.asserts.fail("expected object of type SafeUrl, got '" + safeUrl + "' of type " + goog.typeOf(safeUrl));
    return "type_error:SafeUrl";
  }
};
goog.html.SafeUrl.fromConstant = function(url) {
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(url));
};
goog.html.SAFE_MIME_TYPE_PATTERN_ = /^(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm))$/i;
goog.html.SafeUrl.fromBlob = function(blob) {
  var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ? goog.fs.url.createObjectUrl(blob) : goog.html.SafeUrl.INNOCUOUS_STRING;
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
};
goog.html.DATA_URL_PATTERN_ = /^data:([^;,]*);base64,[a-z0-9+\/]+=*$/i;
goog.html.SafeUrl.fromDataUrl = function(dataUrl) {
  var match = dataUrl.match(goog.html.DATA_URL_PATTERN_);
  var valid = match && goog.html.SAFE_MIME_TYPE_PATTERN_.test(match[1]);
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(valid ? dataUrl : goog.html.SafeUrl.INNOCUOUS_STRING);
};
goog.html.SafeUrl.fromTelUrl = function(telUrl) {
  if (!goog.string.caseInsensitiveStartsWith(telUrl, "tel:")) {
    telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;
  }
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(telUrl);
};
goog.html.SafeUrl.fromTrustedResourceUrl = function(trustedResourceUrl) {
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.html.TrustedResourceUrl.unwrap(trustedResourceUrl));
};
goog.html.SAFE_URL_PATTERN_ = /^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;
goog.html.SafeUrl.sanitize = function(url) {
  if (url instanceof goog.html.SafeUrl) {
    return url;
  } else {
    if (url.implementsGoogStringTypedString) {
      url = url.getTypedStringValue();
    } else {
      url = String(url);
    }
  }
  if (!goog.html.SAFE_URL_PATTERN_.test(url)) {
    url = goog.html.SafeUrl.INNOCUOUS_STRING;
  }
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
};
goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(url) {
  var safeUrl = new goog.html.SafeUrl;
  safeUrl.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = url;
  return safeUrl;
};
goog.html.SafeUrl.ABOUT_BLANK = goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse("about:blank");
goog.provide("goog.html.SafeHtml");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.dom.TagName");
goog.require("goog.dom.tags");
goog.require("goog.html.SafeScript");
goog.require("goog.html.SafeStyle");
goog.require("goog.html.SafeStyleSheet");
goog.require("goog.html.SafeUrl");
goog.require("goog.html.TrustedResourceUrl");
goog.require("goog.i18n.bidi.Dir");
goog.require("goog.i18n.bidi.DirectionalString");
goog.require("goog.labs.userAgent.browser");
goog.require("goog.object");
goog.require("goog.string");
goog.require("goog.string.Const");
goog.require("goog.string.TypedString");
goog.html.SafeHtml = function() {
  this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = "";
  this.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
  this.dir_ = null;
};
goog.html.SafeHtml.prototype.implementsGoogI18nBidiDirectionalString = true;
goog.html.SafeHtml.prototype.getDirection = function() {
  return this.dir_;
};
goog.html.SafeHtml.prototype.implementsGoogStringTypedString = true;
goog.html.SafeHtml.prototype.getTypedStringValue = function() {
  return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
};
if (goog.DEBUG) {
  goog.html.SafeHtml.prototype.toString = function() {
    return "SafeHtml{" + this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ + "}";
  };
}
goog.html.SafeHtml.unwrap = function(safeHtml) {
  if (safeHtml instanceof goog.html.SafeHtml && safeHtml.constructor === goog.html.SafeHtml && safeHtml.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
    return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
  } else {
    goog.asserts.fail("expected object of type SafeHtml, got '" + safeHtml + "' of type " + goog.typeOf(safeHtml));
    return "type_error:SafeHtml";
  }
};
goog.html.SafeHtml.TextOrHtml_;
goog.html.SafeHtml.htmlEscape = function(textOrHtml) {
  if (textOrHtml instanceof goog.html.SafeHtml) {
    return textOrHtml;
  }
  var dir = null;
  if (textOrHtml.implementsGoogI18nBidiDirectionalString) {
    dir = textOrHtml.getDirection();
  }
  var textAsString;
  if (textOrHtml.implementsGoogStringTypedString) {
    textAsString = textOrHtml.getTypedStringValue();
  } else {
    textAsString = String(textOrHtml);
  }
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.htmlEscape(textAsString), dir);
};
goog.html.SafeHtml.htmlEscapePreservingNewlines = function(textOrHtml) {
  if (textOrHtml instanceof goog.html.SafeHtml) {
    return textOrHtml;
  }
  var html = goog.html.SafeHtml.htmlEscape(textOrHtml);
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.newLineToBr(goog.html.SafeHtml.unwrap(html)), html.getDirection());
};
goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces = function(textOrHtml) {
  if (textOrHtml instanceof goog.html.SafeHtml) {
    return textOrHtml;
  }
  var html = goog.html.SafeHtml.htmlEscape(textOrHtml);
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.whitespaceEscape(goog.html.SafeHtml.unwrap(html)), html.getDirection());
};
goog.html.SafeHtml.from = goog.html.SafeHtml.htmlEscape;
goog.html.SafeHtml.VALID_NAMES_IN_TAG_ = /^[a-zA-Z0-9-]+$/;
goog.html.SafeHtml.URL_ATTRIBUTES_ = goog.object.createSet("action", "cite", "data", "formaction", "href", "manifest", "poster", "src");
goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_ = goog.object.createSet(goog.dom.TagName.APPLET, goog.dom.TagName.BASE, goog.dom.TagName.EMBED, goog.dom.TagName.IFRAME, goog.dom.TagName.LINK, goog.dom.TagName.MATH, goog.dom.TagName.META, goog.dom.TagName.OBJECT, goog.dom.TagName.SCRIPT, goog.dom.TagName.STYLE, goog.dom.TagName.SVG, goog.dom.TagName.TEMPLATE);
goog.html.SafeHtml.AttributeValue;
goog.html.SafeHtml.create = function(tagName, opt_attributes, opt_content) {
  goog.html.SafeHtml.verifyTagName(String(tagName));
  return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(String(tagName), opt_attributes, opt_content);
};
goog.html.SafeHtml.verifyTagName = function(tagName) {
  if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(tagName)) {
    throw Error("Invalid tag name <" + tagName + ">.");
  }
  if (tagName.toUpperCase() in goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_) {
    throw Error("Tag name <" + tagName + "> is not allowed for SafeHtml.");
  }
};
goog.html.SafeHtml.createIframe = function(opt_src, opt_srcdoc, opt_attributes, opt_content) {
  if (opt_src) {
    goog.html.TrustedResourceUrl.unwrap(opt_src);
  }
  var fixedAttributes = {};
  fixedAttributes["src"] = opt_src || null;
  fixedAttributes["srcdoc"] = opt_srcdoc && goog.html.SafeHtml.unwrap(opt_srcdoc);
  var defaultAttributes = {"sandbox":""};
  var attributes = goog.html.SafeHtml.combineAttributes(fixedAttributes, defaultAttributes, opt_attributes);
  return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("iframe", attributes, opt_content);
};
goog.html.SafeHtml.createSandboxIframe = function(opt_src, opt_srcdoc, opt_attributes, opt_content) {
  if (!goog.html.SafeHtml.canUseSandboxIframe()) {
    throw new Error("The browser does not support sandboxed iframes.");
  }
  var fixedAttributes = {};
  if (opt_src) {
    fixedAttributes["src"] = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(opt_src));
  } else {
    fixedAttributes["src"] = null;
  }
  fixedAttributes["srcdoc"] = opt_srcdoc || null;
  fixedAttributes["sandbox"] = "";
  var attributes = goog.html.SafeHtml.combineAttributes(fixedAttributes, {}, opt_attributes);
  return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("iframe", attributes, opt_content);
};
goog.html.SafeHtml.canUseSandboxIframe = function() {
  return goog.global["HTMLIFrameElement"] && "sandbox" in goog.global["HTMLIFrameElement"].prototype;
};
goog.html.SafeHtml.createScriptSrc = function(src, opt_attributes) {
  goog.html.TrustedResourceUrl.unwrap(src);
  var fixedAttributes = {"src":src};
  var defaultAttributes = {};
  var attributes = goog.html.SafeHtml.combineAttributes(fixedAttributes, defaultAttributes, opt_attributes);
  return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("script", attributes);
};
goog.html.SafeHtml.createScript = function(script, opt_attributes) {
  for (var attr in opt_attributes) {
    var attrLower = attr.toLowerCase();
    if (attrLower == "language" || attrLower == "src" || attrLower == "text" || attrLower == "type") {
      throw Error('Cannot set "' + attrLower + '" attribute');
    }
  }
  var content = "";
  script = goog.array.concat(script);
  for (var i = 0; i < script.length; i++) {
    content += goog.html.SafeScript.unwrap(script[i]);
  }
  var htmlContent = goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content, goog.i18n.bidi.Dir.NEUTRAL);
  return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("script", opt_attributes, htmlContent);
};
goog.html.SafeHtml.createStyle = function(styleSheet, opt_attributes) {
  var fixedAttributes = {"type":"text/css"};
  var defaultAttributes = {};
  var attributes = goog.html.SafeHtml.combineAttributes(fixedAttributes, defaultAttributes, opt_attributes);
  var content = "";
  styleSheet = goog.array.concat(styleSheet);
  for (var i = 0; i < styleSheet.length; i++) {
    content += goog.html.SafeStyleSheet.unwrap(styleSheet[i]);
  }
  var htmlContent = goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content, goog.i18n.bidi.Dir.NEUTRAL);
  return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("style", attributes, htmlContent);
};
goog.html.SafeHtml.createMetaRefresh = function(url, opt_secs) {
  var unwrappedUrl = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url));
  if (goog.labs.userAgent.browser.isIE() || goog.labs.userAgent.browser.isEdge()) {
    if (goog.string.contains(unwrappedUrl, ";")) {
      unwrappedUrl = "'" + unwrappedUrl.replace(/'/g, "%27") + "'";
    }
  }
  var attributes = {"http-equiv":"refresh", "content":(opt_secs || 0) + "; url=" + unwrappedUrl};
  return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("meta", attributes);
};
goog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) {
  if (value instanceof goog.string.Const) {
    value = goog.string.Const.unwrap(value);
  } else {
    if (name.toLowerCase() == "style") {
      value = goog.html.SafeHtml.getStyleValue_(value);
    } else {
      if (/^on/i.test(name)) {
        throw Error('Attribute "' + name + '" requires goog.string.Const value, "' + value + '" given.');
      } else {
        if (name.toLowerCase() in goog.html.SafeHtml.URL_ATTRIBUTES_) {
          if (value instanceof goog.html.TrustedResourceUrl) {
            value = goog.html.TrustedResourceUrl.unwrap(value);
          } else {
            if (value instanceof goog.html.SafeUrl) {
              value = goog.html.SafeUrl.unwrap(value);
            } else {
              if (goog.isString(value)) {
                value = goog.html.SafeUrl.sanitize(value).getTypedStringValue();
              } else {
                throw Error('Attribute "' + name + '" on tag "' + tagName + '" requires goog.html.SafeUrl, goog.string.Const, or string,' + ' value "' + value + '" given.');
              }
            }
          }
        }
      }
    }
  }
  if (value.implementsGoogStringTypedString) {
    value = value.getTypedStringValue();
  }
  goog.asserts.assert(goog.isString(value) || goog.isNumber(value), "String or number value expected, got " + typeof value + " with value: " + value);
  return name + '="' + goog.string.htmlEscape(String(value)) + '"';
};
goog.html.SafeHtml.getStyleValue_ = function(value) {
  if (!goog.isObject(value)) {
    throw Error('The "style" attribute requires goog.html.SafeStyle or map ' + "of style properties, " + typeof value + " given: " + value);
  }
  if (!(value instanceof goog.html.SafeStyle)) {
    value = goog.html.SafeStyle.create(value);
  }
  return goog.html.SafeStyle.unwrap(value);
};
goog.html.SafeHtml.createWithDir = function(dir, tagName, opt_attributes, opt_content) {
  var html = goog.html.SafeHtml.create(tagName, opt_attributes, opt_content);
  html.dir_ = dir;
  return html;
};
goog.html.SafeHtml.concat = function(var_args) {
  var dir = goog.i18n.bidi.Dir.NEUTRAL;
  var content = "";
  var addArgument = function(argument) {
    if (goog.isArray(argument)) {
      goog.array.forEach(argument, addArgument);
    } else {
      var html = goog.html.SafeHtml.htmlEscape(argument);
      content += goog.html.SafeHtml.unwrap(html);
      var htmlDir = html.getDirection();
      if (dir == goog.i18n.bidi.Dir.NEUTRAL) {
        dir = htmlDir;
      } else {
        if (htmlDir != goog.i18n.bidi.Dir.NEUTRAL && dir != htmlDir) {
          dir = null;
        }
      }
    }
  };
  goog.array.forEach(arguments, addArgument);
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(content, dir);
};
goog.html.SafeHtml.concatWithDir = function(dir, var_args) {
  var html = goog.html.SafeHtml.concat(goog.array.slice(arguments, 1));
  html.dir_ = dir;
  return html;
};
goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse = function(html, dir) {
  return (new goog.html.SafeHtml).initSecurityPrivateDoNotAccessOrElse_(html, dir);
};
goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(html, dir) {
  this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = html;
  this.dir_ = dir;
  return this;
};
goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = function(tagName, opt_attributes, opt_content) {
  var dir = null;
  var result = "<" + tagName;
  result += goog.html.SafeHtml.stringifyAttributes(tagName, opt_attributes);
  var content = opt_content;
  if (!goog.isDefAndNotNull(content)) {
    content = [];
  } else {
    if (!goog.isArray(content)) {
      content = [content];
    }
  }
  if (goog.dom.tags.isVoidTag(tagName.toLowerCase())) {
    goog.asserts.assert(!content.length, "Void tag <" + tagName + "> does not allow content.");
    result += ">";
  } else {
    var html = goog.html.SafeHtml.concat(content);
    result += ">" + goog.html.SafeHtml.unwrap(html) + "</" + tagName + ">";
    dir = html.getDirection();
  }
  var dirAttribute = opt_attributes && opt_attributes["dir"];
  if (dirAttribute) {
    if (/^(ltr|rtl|auto)$/i.test(dirAttribute)) {
      dir = goog.i18n.bidi.Dir.NEUTRAL;
    } else {
      dir = null;
    }
  }
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(result, dir);
};
goog.html.SafeHtml.stringifyAttributes = function(tagName, opt_attributes) {
  var result = "";
  if (opt_attributes) {
    for (var name in opt_attributes) {
      if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(name)) {
        throw Error('Invalid attribute name "' + name + '".');
      }
      var value = opt_attributes[name];
      if (!goog.isDefAndNotNull(value)) {
        continue;
      }
      result += " " + goog.html.SafeHtml.getAttrNameAndValue_(tagName, name, value);
    }
  }
  return result;
};
goog.html.SafeHtml.combineAttributes = function(fixedAttributes, defaultAttributes, opt_attributes) {
  var combinedAttributes = {};
  var name;
  for (name in fixedAttributes) {
    goog.asserts.assert(name.toLowerCase() == name, "Must be lower case");
    combinedAttributes[name] = fixedAttributes[name];
  }
  for (name in defaultAttributes) {
    goog.asserts.assert(name.toLowerCase() == name, "Must be lower case");
    combinedAttributes[name] = defaultAttributes[name];
  }
  for (name in opt_attributes) {
    var nameLower = name.toLowerCase();
    if (nameLower in fixedAttributes) {
      throw Error('Cannot override "' + nameLower + '" attribute, got "' + name + '" with value "' + opt_attributes[name] + '"');
    }
    if (nameLower in defaultAttributes) {
      delete combinedAttributes[nameLower];
    }
    combinedAttributes[name] = opt_attributes[name];
  }
  return combinedAttributes;
};
goog.html.SafeHtml.DOCTYPE_HTML = goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("<!DOCTYPE html>", goog.i18n.bidi.Dir.NEUTRAL);
goog.html.SafeHtml.EMPTY = goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("", goog.i18n.bidi.Dir.NEUTRAL);
goog.html.SafeHtml.BR = goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("<br>", goog.i18n.bidi.Dir.NEUTRAL);
goog.provide("goog.dom.safe");
goog.provide("goog.dom.safe.InsertAdjacentHtmlPosition");
goog.require("goog.asserts");
goog.require("goog.html.SafeHtml");
goog.require("goog.html.SafeScript");
goog.require("goog.html.SafeStyle");
goog.require("goog.html.SafeUrl");
goog.require("goog.html.TrustedResourceUrl");
goog.require("goog.string");
goog.require("goog.string.Const");
goog.dom.safe.InsertAdjacentHtmlPosition = {AFTERBEGIN:"afterbegin", AFTEREND:"afterend", BEFOREBEGIN:"beforebegin", BEFOREEND:"beforeend"};
goog.dom.safe.insertAdjacentHtml = function(node, position, html) {
  node.insertAdjacentHTML(position, goog.html.SafeHtml.unwrap(html));
};
goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_ = {"MATH":true, "SCRIPT":true, "STYLE":true, "SVG":true, "TEMPLATE":true};
goog.dom.safe.setInnerHtml = function(elem, html) {
  if (goog.asserts.ENABLE_ASSERTS) {
    var tagName = elem.tagName.toUpperCase();
    if (goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_[tagName]) {
      throw Error("goog.dom.safe.setInnerHtml cannot be used to set content of " + elem.tagName + ".");
    }
  }
  elem.innerHTML = goog.html.SafeHtml.unwrap(html);
};
goog.dom.safe.setOuterHtml = function(elem, html) {
  elem.outerHTML = goog.html.SafeHtml.unwrap(html);
};
goog.dom.safe.setStyle = function(elem, style) {
  elem.style.cssText = goog.html.SafeStyle.unwrap(style);
};
goog.dom.safe.documentWrite = function(doc, html) {
  doc.write(goog.html.SafeHtml.unwrap(html));
};
goog.dom.safe.setAnchorHref = function(anchor, url) {
  goog.dom.safe.assertIsHTMLAnchorElement_(anchor);
  var safeUrl;
  if (url instanceof goog.html.SafeUrl) {
    safeUrl = url;
  } else {
    safeUrl = goog.html.SafeUrl.sanitize(url);
  }
  anchor.href = goog.html.SafeUrl.unwrap(safeUrl);
};
goog.dom.safe.setImageSrc = function(imageElement, url) {
  goog.dom.safe.assertIsHTMLImageElement_(imageElement);
  var safeUrl;
  if (url instanceof goog.html.SafeUrl) {
    safeUrl = url;
  } else {
    safeUrl = goog.html.SafeUrl.sanitize(url);
  }
  imageElement.src = goog.html.SafeUrl.unwrap(safeUrl);
};
goog.dom.safe.setEmbedSrc = function(embed, url) {
  goog.dom.safe.assertIsHTMLEmbedElement_(embed);
  embed.src = goog.html.TrustedResourceUrl.unwrap(url);
};
goog.dom.safe.setFrameSrc = function(frame, url) {
  goog.dom.safe.assertIsHTMLFrameElement_(frame);
  frame.src = goog.html.TrustedResourceUrl.unwrap(url);
};
goog.dom.safe.setIframeSrc = function(iframe, url) {
  goog.dom.safe.assertIsHTMLIFrameElement_(iframe);
  iframe.src = goog.html.TrustedResourceUrl.unwrap(url);
};
goog.dom.safe.setIframeSrcdoc = function(iframe, html) {
  goog.dom.safe.assertIsHTMLIFrameElement_(iframe);
  iframe.srcdoc = goog.html.SafeHtml.unwrap(html);
};
goog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {
  goog.dom.safe.assertIsHTMLLinkElement_(link);
  link.rel = rel;
  if (goog.string.caseInsensitiveContains(rel, "stylesheet")) {
    goog.asserts.assert(url instanceof goog.html.TrustedResourceUrl, 'URL must be TrustedResourceUrl because "rel" contains "stylesheet"');
    link.href = goog.html.TrustedResourceUrl.unwrap(url);
  } else {
    if (url instanceof goog.html.TrustedResourceUrl) {
      link.href = goog.html.TrustedResourceUrl.unwrap(url);
    } else {
      if (url instanceof goog.html.SafeUrl) {
        link.href = goog.html.SafeUrl.unwrap(url);
      } else {
        link.href = goog.html.SafeUrl.sanitize(url).getTypedStringValue();
      }
    }
  }
};
goog.dom.safe.setObjectData = function(object, url) {
  goog.dom.safe.assertIsHTMLObjectElement_(object);
  object.data = goog.html.TrustedResourceUrl.unwrap(url);
};
goog.dom.safe.setScriptSrc = function(script, url) {
  goog.dom.safe.assertIsHTMLScriptElement_(script);
  script.src = goog.html.TrustedResourceUrl.unwrap(url);
};
goog.dom.safe.setScriptContent = function(script, content) {
  goog.dom.safe.assertIsHTMLScriptElement_(script);
  script.text = goog.html.SafeScript.unwrap(content);
};
goog.dom.safe.setLocationHref = function(loc, url) {
  goog.dom.safe.assertIsLocation_(loc);
  var safeUrl;
  if (url instanceof goog.html.SafeUrl) {
    safeUrl = url;
  } else {
    safeUrl = goog.html.SafeUrl.sanitize(url);
  }
  loc.href = goog.html.SafeUrl.unwrap(safeUrl);
};
goog.dom.safe.openInWindow = function(url, opt_openerWin, opt_name, opt_specs, opt_replace) {
  var safeUrl;
  if (url instanceof goog.html.SafeUrl) {
    safeUrl = url;
  } else {
    safeUrl = goog.html.SafeUrl.sanitize(url);
  }
  var win = opt_openerWin || window;
  return win.open(goog.html.SafeUrl.unwrap(safeUrl), opt_name ? goog.string.Const.unwrap(opt_name) : "", opt_specs, opt_replace);
};
goog.dom.safe.assertIsLocation_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof Location != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof Location || !(o instanceof Element)), "Argument is not a Location (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLAnchorElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLAnchorElement != "undefined" && typeof Location != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLAnchorElement || !(o instanceof Location || o instanceof Element)), "Argument is not a HTMLAnchorElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLLinkElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLLinkElement != "undefined" && typeof Location != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLLinkElement || !(o instanceof Location || o instanceof Element)), "Argument is not a HTMLLinkElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLImageElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLImageElement != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLImageElement || !(o instanceof Element)), "Argument is not a HTMLImageElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLEmbedElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLEmbedElement != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLEmbedElement || !(o instanceof Element)), "Argument is not a HTMLEmbedElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLFrameElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLFrameElement != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLFrameElement || !(o instanceof Element)), "Argument is not a HTMLFrameElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLIFrameElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLIFrameElement != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLIFrameElement || !(o instanceof Element)), "Argument is not a HTMLIFrameElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLObjectElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLObjectElement != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLObjectElement || !(o instanceof Element)), "Argument is not a HTMLObjectElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.assertIsHTMLScriptElement_ = function(o) {
  if (goog.asserts.ENABLE_ASSERTS && typeof HTMLScriptElement != "undefined" && typeof Element != "undefined") {
    goog.asserts.assert(o && (o instanceof HTMLScriptElement || !(o instanceof Element)), "Argument is not a HTMLScriptElement (or a non-Element mock); got: %s", goog.dom.safe.debugStringForType_(o));
  }
  return o;
};
goog.dom.safe.debugStringForType_ = function(value) {
  if (goog.isObject(value)) {
    return value.constructor.displayName || value.constructor.name || Object.prototype.toString.call(value);
  } else {
    return value === undefined ? "undefined" : value === null ? "null" : typeof value;
  }
};
goog.provide("goog.html.uncheckedconversions");
goog.require("goog.asserts");
goog.require("goog.html.SafeHtml");
goog.require("goog.html.SafeScript");
goog.require("goog.html.SafeStyle");
goog.require("goog.html.SafeStyleSheet");
goog.require("goog.html.SafeUrl");
goog.require("goog.html.TrustedResourceUrl");
goog.require("goog.string");
goog.require("goog.string.Const");
goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract = function(justification, html, opt_dir) {
  goog.asserts.assertString(goog.string.Const.unwrap(justification), "must provide justification");
  goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), "must provide non-empty justification");
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(html, opt_dir || null);
};
goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract = function(justification, script) {
  goog.asserts.assertString(goog.string.Const.unwrap(justification), "must provide justification");
  goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), "must provide non-empty justification");
  return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(script);
};
goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract = function(justification, style) {
  goog.asserts.assertString(goog.string.Const.unwrap(justification), "must provide justification");
  goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), "must provide non-empty justification");
  return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);
};
goog.html.uncheckedconversions.safeStyleSheetFromStringKnownToSatisfyTypeContract = function(justification, styleSheet) {
  goog.asserts.assertString(goog.string.Const.unwrap(justification), "must provide justification");
  goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), "must provide non-empty justification");
  return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet);
};
goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract = function(justification, url) {
  goog.asserts.assertString(goog.string.Const.unwrap(justification), "must provide justification");
  goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), "must provide non-empty justification");
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
};
goog.html.uncheckedconversions.trustedResourceUrlFromStringKnownToSatisfyTypeContract = function(justification, url) {
  goog.asserts.assertString(goog.string.Const.unwrap(justification), "must provide justification");
  goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), "must provide non-empty justification");
  return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);
};
goog.provide("goog.math");
goog.require("goog.array");
goog.require("goog.asserts");
goog.math.randomInt = function(a) {
  return Math.floor(Math.random() * a);
};
goog.math.uniformRandom = function(a, b) {
  return a + Math.random() * (b - a);
};
goog.math.clamp = function(value, min, max) {
  return Math.min(Math.max(value, min), max);
};
goog.math.modulo = function(a, b) {
  var r = a % b;
  return r * b < 0 ? r + b : r;
};
goog.math.lerp = function(a, b, x) {
  return a + x * (b - a);
};
goog.math.nearlyEquals = function(a, b, opt_tolerance) {
  return Math.abs(a - b) <= (opt_tolerance || 0.000001);
};
goog.math.standardAngle = function(angle) {
  return goog.math.modulo(angle, 360);
};
goog.math.standardAngleInRadians = function(angle) {
  return goog.math.modulo(angle, 2 * Math.PI);
};
goog.math.toRadians = function(angleDegrees) {
  return angleDegrees * Math.PI / 180;
};
goog.math.toDegrees = function(angleRadians) {
  return angleRadians * 180 / Math.PI;
};
goog.math.angleDx = function(degrees, radius) {
  return radius * Math.cos(goog.math.toRadians(degrees));
};
goog.math.angleDy = function(degrees, radius) {
  return radius * Math.sin(goog.math.toRadians(degrees));
};
goog.math.angle = function(x1, y1, x2, y2) {
  return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(y2 - y1, x2 - x1)));
};
goog.math.angleDifference = function(startAngle, endAngle) {
  var d = goog.math.standardAngle(endAngle) - goog.math.standardAngle(startAngle);
  if (d > 180) {
    d = d - 360;
  } else {
    if (d <= -180) {
      d = 360 + d;
    }
  }
  return d;
};
goog.math.sign = function(x) {
  if (x > 0) {
    return 1;
  }
  if (x < 0) {
    return -1;
  }
  return x;
};
goog.math.longestCommonSubsequence = function(array1, array2, opt_compareFn, opt_collectorFn) {
  var compare = opt_compareFn || function(a, b) {
    return a == b;
  };
  var collect = opt_collectorFn || function(i1, i2) {
    return array1[i1];
  };
  var length1 = array1.length;
  var length2 = array2.length;
  var arr = [];
  for (var i = 0; i < length1 + 1; i++) {
    arr[i] = [];
    arr[i][0] = 0;
  }
  for (var j = 0; j < length2 + 1; j++) {
    arr[0][j] = 0;
  }
  for (i = 1; i <= length1; i++) {
    for (j = 1; j <= length2; j++) {
      if (compare(array1[i - 1], array2[j - 1])) {
        arr[i][j] = arr[i - 1][j - 1] + 1;
      } else {
        arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]);
      }
    }
  }
  var result = [];
  var i = length1, j = length2;
  while (i > 0 && j > 0) {
    if (compare(array1[i - 1], array2[j - 1])) {
      result.unshift(collect(i - 1, j - 1));
      i--;
      j--;
    } else {
      if (arr[i - 1][j] > arr[i][j - 1]) {
        i--;
      } else {
        j--;
      }
    }
  }
  return result;
};
goog.math.sum = function(var_args) {
  return goog.array.reduce(arguments, function(sum, value) {
    return sum + value;
  }, 0);
};
goog.math.average = function(var_args) {
  return goog.math.sum.apply(null, arguments) / arguments.length;
};
goog.math.sampleVariance = function(var_args) {
  var sampleSize = arguments.length;
  if (sampleSize < 2) {
    return 0;
  }
  var mean = goog.math.average.apply(null, arguments);
  var variance = goog.math.sum.apply(null, goog.array.map(arguments, function(val) {
    return Math.pow(val - mean, 2);
  })) / (sampleSize - 1);
  return variance;
};
goog.math.standardDeviation = function(var_args) {
  return Math.sqrt(goog.math.sampleVariance.apply(null, arguments));
};
goog.math.isInt = function(num) {
  return isFinite(num) && num % 1 == 0;
};
goog.math.isFiniteNumber = function(num) {
  return isFinite(num);
};
goog.math.isNegativeZero = function(num) {
  return num == 0 && 1 / num < 0;
};
goog.math.log10Floor = function(num) {
  if (num > 0) {
    var x = Math.round(Math.log(num) * Math.LOG10E);
    return x - (parseFloat("1e" + x) > num ? 1 : 0);
  }
  return num == 0 ? -Infinity : NaN;
};
goog.math.safeFloor = function(num, opt_epsilon) {
  goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
  return Math.floor(num + (opt_epsilon || 2e-15));
};
goog.math.safeCeil = function(num, opt_epsilon) {
  goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
  return Math.ceil(num - (opt_epsilon || 2e-15));
};
goog.provide("goog.math.Coordinate");
goog.require("goog.math");
goog.math.Coordinate = function(opt_x, opt_y) {
  this.x = goog.isDef(opt_x) ? opt_x : 0;
  this.y = goog.isDef(opt_y) ? opt_y : 0;
};
goog.math.Coordinate.prototype.clone = function() {
  return new goog.math.Coordinate(this.x, this.y);
};
if (goog.DEBUG) {
  goog.math.Coordinate.prototype.toString = function() {
    return "(" + this.x + ", " + this.y + ")";
  };
}
goog.math.Coordinate.prototype.equals = function(other) {
  return other instanceof goog.math.Coordinate && goog.math.Coordinate.equals(this, other);
};
goog.math.Coordinate.equals = function(a, b) {
  if (a == b) {
    return true;
  }
  if (!a || !b) {
    return false;
  }
  return a.x == b.x && a.y == b.y;
};
goog.math.Coordinate.distance = function(a, b) {
  var dx = a.x - b.x;
  var dy = a.y - b.y;
  return Math.sqrt(dx * dx + dy * dy);
};
goog.math.Coordinate.magnitude = function(a) {
  return Math.sqrt(a.x * a.x + a.y * a.y);
};
goog.math.Coordinate.azimuth = function(a) {
  return goog.math.angle(0, 0, a.x, a.y);
};
goog.math.Coordinate.squaredDistance = function(a, b) {
  var dx = a.x - b.x;
  var dy = a.y - b.y;
  return dx * dx + dy * dy;
};
goog.math.Coordinate.difference = function(a, b) {
  return new goog.math.Coordinate(a.x - b.x, a.y - b.y);
};
goog.math.Coordinate.sum = function(a, b) {
  return new goog.math.Coordinate(a.x + b.x, a.y + b.y);
};
goog.math.Coordinate.prototype.ceil = function() {
  this.x = Math.ceil(this.x);
  this.y = Math.ceil(this.y);
  return this;
};
goog.math.Coordinate.prototype.floor = function() {
  this.x = Math.floor(this.x);
  this.y = Math.floor(this.y);
  return this;
};
goog.math.Coordinate.prototype.round = function() {
  this.x = Math.round(this.x);
  this.y = Math.round(this.y);
  return this;
};
goog.math.Coordinate.prototype.translate = function(tx, opt_ty) {
  if (tx instanceof goog.math.Coordinate) {
    this.x += tx.x;
    this.y += tx.y;
  } else {
    this.x += Number(tx);
    if (goog.isNumber(opt_ty)) {
      this.y += opt_ty;
    }
  }
  return this;
};
goog.math.Coordinate.prototype.scale = function(sx, opt_sy) {
  var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
  this.x *= sx;
  this.y *= sy;
  return this;
};
goog.math.Coordinate.prototype.rotateRadians = function(radians, opt_center) {
  var center = opt_center || new goog.math.Coordinate(0, 0);
  var x = this.x;
  var y = this.y;
  var cos = Math.cos(radians);
  var sin = Math.sin(radians);
  this.x = (x - center.x) * cos - (y - center.y) * sin + center.x;
  this.y = (x - center.x) * sin + (y - center.y) * cos + center.y;
};
goog.math.Coordinate.prototype.rotateDegrees = function(degrees, opt_center) {
  this.rotateRadians(goog.math.toRadians(degrees), opt_center);
};
goog.provide("goog.math.Size");
goog.math.Size = function(width, height) {
  this.width = width;
  this.height = height;
};
goog.math.Size.equals = function(a, b) {
  if (a == b) {
    return true;
  }
  if (!a || !b) {
    return false;
  }
  return a.width == b.width && a.height == b.height;
};
goog.math.Size.prototype.clone = function() {
  return new goog.math.Size(this.width, this.height);
};
if (goog.DEBUG) {
  goog.math.Size.prototype.toString = function() {
    return "(" + this.width + " x " + this.height + ")";
  };
}
goog.math.Size.prototype.getLongest = function() {
  return Math.max(this.width, this.height);
};
goog.math.Size.prototype.getShortest = function() {
  return Math.min(this.width, this.height);
};
goog.math.Size.prototype.area = function() {
  return this.width * this.height;
};
goog.math.Size.prototype.perimeter = function() {
  return (this.width + this.height) * 2;
};
goog.math.Size.prototype.aspectRatio = function() {
  return this.width / this.height;
};
goog.math.Size.prototype.isEmpty = function() {
  return !this.area();
};
goog.math.Size.prototype.ceil = function() {
  this.width = Math.ceil(this.width);
  this.height = Math.ceil(this.height);
  return this;
};
goog.math.Size.prototype.fitsInside = function(target) {
  return this.width <= target.width && this.height <= target.height;
};
goog.math.Size.prototype.floor = function() {
  this.width = Math.floor(this.width);
  this.height = Math.floor(this.height);
  return this;
};
goog.math.Size.prototype.round = function() {
  this.width = Math.round(this.width);
  this.height = Math.round(this.height);
  return this;
};
goog.math.Size.prototype.scale = function(sx, opt_sy) {
  var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
  this.width *= sx;
  this.height *= sy;
  return this;
};
goog.math.Size.prototype.scaleToCover = function(target) {
  var s = this.aspectRatio() <= target.aspectRatio() ? target.width / this.width : target.height / this.height;
  return this.scale(s);
};
goog.math.Size.prototype.scaleToFit = function(target) {
  var s = this.aspectRatio() > target.aspectRatio() ? target.width / this.width : target.height / this.height;
  return this.scale(s);
};
goog.provide("goog.dom");
goog.provide("goog.dom.Appendable");
goog.provide("goog.dom.DomHelper");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.dom.BrowserFeature");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagName");
goog.require("goog.dom.safe");
goog.require("goog.html.SafeHtml");
goog.require("goog.html.uncheckedconversions");
goog.require("goog.math.Coordinate");
goog.require("goog.math.Size");
goog.require("goog.object");
goog.require("goog.string");
goog.require("goog.string.Unicode");
goog.require("goog.userAgent");
goog.define("goog.dom.ASSUME_QUIRKS_MODE", false);
goog.define("goog.dom.ASSUME_STANDARDS_MODE", false);
goog.dom.COMPAT_MODE_KNOWN_ = goog.dom.ASSUME_QUIRKS_MODE || goog.dom.ASSUME_STANDARDS_MODE;
goog.dom.getDomHelper = function(opt_element) {
  return opt_element ? new goog.dom.DomHelper(goog.dom.getOwnerDocument(opt_element)) : goog.dom.defaultDomHelper_ || (goog.dom.defaultDomHelper_ = new goog.dom.DomHelper);
};
goog.dom.defaultDomHelper_;
goog.dom.getDocument = function() {
  return document;
};
goog.dom.getElement = function(element) {
  return goog.dom.getElementHelper_(document, element);
};
goog.dom.getElementHelper_ = function(doc, element) {
  return goog.isString(element) ? doc.getElementById(element) : element;
};
goog.dom.getRequiredElement = function(id) {
  return goog.dom.getRequiredElementHelper_(document, id);
};
goog.dom.getRequiredElementHelper_ = function(doc, id) {
  goog.asserts.assertString(id);
  var element = goog.dom.getElementHelper_(doc, id);
  element = goog.asserts.assertElement(element, "No element found with id: " + id);
  return element;
};
goog.dom.$ = goog.dom.getElement;
goog.dom.getElementsByTagName = function(tagName, opt_parent) {
  var parent = opt_parent || document;
  return parent.getElementsByTagName(String(tagName));
};
goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {
  return goog.dom.getElementsByTagNameAndClass_(document, opt_tag, opt_class, opt_el);
};
goog.dom.getElementsByClass = function(className, opt_el) {
  var parent = opt_el || document;
  if (goog.dom.canUseQuerySelector_(parent)) {
    return parent.querySelectorAll("." + className);
  }
  return goog.dom.getElementsByTagNameAndClass_(document, "*", className, opt_el);
};
goog.dom.getElementByClass = function(className, opt_el) {
  var parent = opt_el || document;
  var retVal = null;
  if (parent.getElementsByClassName) {
    retVal = parent.getElementsByClassName(className)[0];
  } else {
    if (goog.dom.canUseQuerySelector_(parent)) {
      retVal = parent.querySelector("." + className);
    } else {
      retVal = goog.dom.getElementsByTagNameAndClass_(document, "*", className, opt_el)[0];
    }
  }
  return retVal || null;
};
goog.dom.getRequiredElementByClass = function(className, opt_root) {
  var retValue = goog.dom.getElementByClass(className, opt_root);
  return goog.asserts.assert(retValue, "No element found with className: " + className);
};
goog.dom.canUseQuerySelector_ = function(parent) {
  return !!(parent.querySelectorAll && parent.querySelector);
};
goog.dom.getElementsByTagNameAndClass_ = function(doc, opt_tag, opt_class, opt_el) {
  var parent = opt_el || doc;
  var tagName = opt_tag && opt_tag != "*" ? String(opt_tag).toUpperCase() : "";
  if (goog.dom.canUseQuerySelector_(parent) && (tagName || opt_class)) {
    var query = tagName + (opt_class ? "." + opt_class : "");
    return parent.querySelectorAll(query);
  }
  if (opt_class && parent.getElementsByClassName) {
    var els = parent.getElementsByClassName(opt_class);
    if (tagName) {
      var arrayLike = {};
      var len = 0;
      for (var i = 0, el; el = els[i]; i++) {
        if (tagName == el.nodeName) {
          arrayLike[len++] = el;
        }
      }
      arrayLike.length = len;
      return arrayLike;
    } else {
      return els;
    }
  }
  var els = parent.getElementsByTagName(tagName || "*");
  if (opt_class) {
    var arrayLike = {};
    var len = 0;
    for (var i = 0, el; el = els[i]; i++) {
      var className = el.className;
      if (typeof className.split == "function" && goog.array.contains(className.split(/\s+/), opt_class)) {
        arrayLike[len++] = el;
      }
    }
    arrayLike.length = len;
    return arrayLike;
  } else {
    return els;
  }
};
goog.dom.$$ = goog.dom.getElementsByTagNameAndClass;
goog.dom.setProperties = function(element, properties) {
  goog.object.forEach(properties, function(val, key) {
    if (val && val.implementsGoogStringTypedString) {
      val = val.getTypedStringValue();
    }
    if (key == "style") {
      element.style.cssText = val;
    } else {
      if (key == "class") {
        element.className = val;
      } else {
        if (key == "for") {
          element.htmlFor = val;
        } else {
          if (goog.dom.DIRECT_ATTRIBUTE_MAP_.hasOwnProperty(key)) {
            element.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[key], val);
          } else {
            if (goog.string.startsWith(key, "aria-") || goog.string.startsWith(key, "data-")) {
              element.setAttribute(key, val);
            } else {
              element[key] = val;
            }
          }
        }
      }
    }
  });
};
goog.dom.DIRECT_ATTRIBUTE_MAP_ = {"cellpadding":"cellPadding", "cellspacing":"cellSpacing", "colspan":"colSpan", "frameborder":"frameBorder", "height":"height", "maxlength":"maxLength", "nonce":"nonce", "role":"role", "rowspan":"rowSpan", "type":"type", "usemap":"useMap", "valign":"vAlign", "width":"width"};
goog.dom.getViewportSize = function(opt_window) {
  return goog.dom.getViewportSize_(opt_window || window);
};
goog.dom.getViewportSize_ = function(win) {
  var doc = win.document;
  var el = goog.dom.isCss1CompatMode_(doc) ? doc.documentElement : doc.body;
  return new goog.math.Size(el.clientWidth, el.clientHeight);
};
goog.dom.getDocumentHeight = function() {
  return goog.dom.getDocumentHeight_(window);
};
goog.dom.getDocumentHeightForWindow = function(win) {
  return goog.dom.getDocumentHeight_(win);
};
goog.dom.getDocumentHeight_ = function(win) {
  var doc = win.document;
  var height = 0;
  if (doc) {
    var body = doc.body;
    var docEl = doc.documentElement;
    if (!(docEl && body)) {
      return 0;
    }
    var vh = goog.dom.getViewportSize_(win).height;
    if (goog.dom.isCss1CompatMode_(doc) && docEl.scrollHeight) {
      height = docEl.scrollHeight != vh ? docEl.scrollHeight : docEl.offsetHeight;
    } else {
      var sh = docEl.scrollHeight;
      var oh = docEl.offsetHeight;
      if (docEl.clientHeight != oh) {
        sh = body.scrollHeight;
        oh = body.offsetHeight;
      }
      if (sh > vh) {
        height = sh > oh ? sh : oh;
      } else {
        height = sh < oh ? sh : oh;
      }
    }
  }
  return height;
};
goog.dom.getPageScroll = function(opt_window) {
  var win = opt_window || goog.global || window;
  return goog.dom.getDomHelper(win.document).getDocumentScroll();
};
goog.dom.getDocumentScroll = function() {
  return goog.dom.getDocumentScroll_(document);
};
goog.dom.getDocumentScroll_ = function(doc) {
  var el = goog.dom.getDocumentScrollElement_(doc);
  var win = goog.dom.getWindow_(doc);
  if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher("10") && win.pageYOffset != el.scrollTop) {
    return new goog.math.Coordinate(el.scrollLeft, el.scrollTop);
  }
  return new goog.math.Coordinate(win.pageXOffset || el.scrollLeft, win.pageYOffset || el.scrollTop);
};
goog.dom.getDocumentScrollElement = function() {
  return goog.dom.getDocumentScrollElement_(document);
};
goog.dom.getDocumentScrollElement_ = function(doc) {
  if (doc.scrollingElement) {
    return doc.scrollingElement;
  }
  if (!goog.userAgent.WEBKIT && goog.dom.isCss1CompatMode_(doc)) {
    return doc.documentElement;
  }
  return doc.body || doc.documentElement;
};
goog.dom.getWindow = function(opt_doc) {
  return opt_doc ? goog.dom.getWindow_(opt_doc) : window;
};
goog.dom.getWindow_ = function(doc) {
  return doc.parentWindow || doc.defaultView;
};
goog.dom.createDom = function(tagName, opt_properties, var_args) {
  return goog.dom.createDom_(document, arguments);
};
goog.dom.createDom_ = function(doc, args) {
  var tagName = String(args[0]);
  var attributes = args[1];
  if (!goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES && attributes && (attributes.name || attributes.type)) {
    var tagNameArr = ["<", tagName];
    if (attributes.name) {
      tagNameArr.push(' name="', goog.string.htmlEscape(attributes.name), '"');
    }
    if (attributes.type) {
      tagNameArr.push(' type="', goog.string.htmlEscape(attributes.type), '"');
      var clone = {};
      goog.object.extend(clone, attributes);
      delete clone["type"];
      attributes = clone;
    }
    tagNameArr.push(">");
    tagName = tagNameArr.join("");
  }
  var element = doc.createElement(tagName);
  if (attributes) {
    if (goog.isString(attributes)) {
      element.className = attributes;
    } else {
      if (goog.isArray(attributes)) {
        element.className = attributes.join(" ");
      } else {
        goog.dom.setProperties(element, attributes);
      }
    }
  }
  if (args.length > 2) {
    goog.dom.append_(doc, element, args, 2);
  }
  return element;
};
goog.dom.append_ = function(doc, parent, args, startIndex) {
  function childHandler(child) {
    if (child) {
      parent.appendChild(goog.isString(child) ? doc.createTextNode(child) : child);
    }
  }
  for (var i = startIndex; i < args.length; i++) {
    var arg = args[i];
    if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) {
      goog.array.forEach(goog.dom.isNodeList(arg) ? goog.array.toArray(arg) : arg, childHandler);
    } else {
      childHandler(arg);
    }
  }
};
goog.dom.$dom = goog.dom.createDom;
goog.dom.createElement = function(name) {
  return goog.dom.createElement_(document, name);
};
goog.dom.createElement_ = function(doc, name) {
  return doc.createElement(String(name));
};
goog.dom.createTextNode = function(content) {
  return document.createTextNode(String(content));
};
goog.dom.createTable = function(rows, columns, opt_fillWithNbsp) {
  return goog.dom.createTable_(document, rows, columns, !!opt_fillWithNbsp);
};
goog.dom.createTable_ = function(doc, rows, columns, fillWithNbsp) {
  var table = goog.dom.createElement_(doc, goog.dom.TagName.TABLE);
  var tbody = table.appendChild(goog.dom.createElement_(doc, goog.dom.TagName.TBODY));
  for (var i = 0; i < rows; i++) {
    var tr = goog.dom.createElement_(doc, goog.dom.TagName.TR);
    for (var j = 0; j < columns; j++) {
      var td = goog.dom.createElement_(doc, goog.dom.TagName.TD);
      if (fillWithNbsp) {
        goog.dom.setTextContent(td, goog.string.Unicode.NBSP);
      }
      tr.appendChild(td);
    }
    tbody.appendChild(tr);
  }
  return table;
};
goog.dom.constHtmlToNode = function(var_args) {
  var stringArray = goog.array.map(arguments, goog.string.Const.unwrap);
  var safeHtml = goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract(goog.string.Const.from("Constant HTML string, that gets turned into a " + "Node later, so it will be automatically balanced."), stringArray.join(""));
  return goog.dom.safeHtmlToNode(safeHtml);
};
goog.dom.safeHtmlToNode = function(html) {
  return goog.dom.safeHtmlToNode_(document, html);
};
goog.dom.safeHtmlToNode_ = function(doc, html) {
  var tempDiv = goog.dom.createElement_(doc, goog.dom.TagName.DIV);
  if (goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT) {
    goog.dom.safe.setInnerHtml(tempDiv, goog.html.SafeHtml.concat(goog.html.SafeHtml.BR, html));
    tempDiv.removeChild(tempDiv.firstChild);
  } else {
    goog.dom.safe.setInnerHtml(tempDiv, html);
  }
  return goog.dom.childrenToNode_(doc, tempDiv);
};
goog.dom.childrenToNode_ = function(doc, tempDiv) {
  if (tempDiv.childNodes.length == 1) {
    return tempDiv.removeChild(tempDiv.firstChild);
  } else {
    var fragment = doc.createDocumentFragment();
    while (tempDiv.firstChild) {
      fragment.appendChild(tempDiv.firstChild);
    }
    return fragment;
  }
};
goog.dom.isCss1CompatMode = function() {
  return goog.dom.isCss1CompatMode_(document);
};
goog.dom.isCss1CompatMode_ = function(doc) {
  if (goog.dom.COMPAT_MODE_KNOWN_) {
    return goog.dom.ASSUME_STANDARDS_MODE;
  }
  return doc.compatMode == "CSS1Compat";
};
goog.dom.canHaveChildren = function(node) {
  if (node.nodeType != goog.dom.NodeType.ELEMENT) {
    return false;
  }
  switch(node.tagName) {
    case String(goog.dom.TagName.APPLET):
    case String(goog.dom.TagName.AREA):
    case String(goog.dom.TagName.BASE):
    case String(goog.dom.TagName.BR):
    case String(goog.dom.TagName.COL):
    case String(goog.dom.TagName.COMMAND):
    case String(goog.dom.TagName.EMBED):
    case String(goog.dom.TagName.FRAME):
    case String(goog.dom.TagName.HR):
    case String(goog.dom.TagName.IMG):
    case String(goog.dom.TagName.INPUT):
    case String(goog.dom.TagName.IFRAME):
    case String(goog.dom.TagName.ISINDEX):
    case String(goog.dom.TagName.KEYGEN):
    case String(goog.dom.TagName.LINK):
    case String(goog.dom.TagName.NOFRAMES):
    case String(goog.dom.TagName.NOSCRIPT):
    case String(goog.dom.TagName.META):
    case String(goog.dom.TagName.OBJECT):
    case String(goog.dom.TagName.PARAM):
    case String(goog.dom.TagName.SCRIPT):
    case String(goog.dom.TagName.SOURCE):
    case String(goog.dom.TagName.STYLE):
    case String(goog.dom.TagName.TRACK):
    case String(goog.dom.TagName.WBR):
      return false;
  }
  return true;
};
goog.dom.appendChild = function(parent, child) {
  parent.appendChild(child);
};
goog.dom.append = function(parent, var_args) {
  goog.dom.append_(goog.dom.getOwnerDocument(parent), parent, arguments, 1);
};
goog.dom.removeChildren = function(node) {
  var child;
  while (child = node.firstChild) {
    node.removeChild(child);
  }
};
goog.dom.insertSiblingBefore = function(newNode, refNode) {
  if (refNode.parentNode) {
    refNode.parentNode.insertBefore(newNode, refNode);
  }
};
goog.dom.insertSiblingAfter = function(newNode, refNode) {
  if (refNode.parentNode) {
    refNode.parentNode.insertBefore(newNode, refNode.nextSibling);
  }
};
goog.dom.insertChildAt = function(parent, child, index) {
  parent.insertBefore(child, parent.childNodes[index] || null);
};
goog.dom.removeNode = function(node) {
  return node && node.parentNode ? node.parentNode.removeChild(node) : null;
};
goog.dom.replaceNode = function(newNode, oldNode) {
  var parent = oldNode.parentNode;
  if (parent) {
    parent.replaceChild(newNode, oldNode);
  }
};
goog.dom.flattenElement = function(element) {
  var child, parent = element.parentNode;
  if (parent && parent.nodeType != goog.dom.NodeType.DOCUMENT_FRAGMENT) {
    if (element.removeNode) {
      return element.removeNode(false);
    } else {
      while (child = element.firstChild) {
        parent.insertBefore(child, element);
      }
      return goog.dom.removeNode(element);
    }
  }
};
goog.dom.getChildren = function(element) {
  if (goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE && element.children != undefined) {
    return element.children;
  }
  return goog.array.filter(element.childNodes, function(node) {
    return node.nodeType == goog.dom.NodeType.ELEMENT;
  });
};
goog.dom.getFirstElementChild = function(node) {
  if (goog.isDef(node.firstElementChild)) {
    return node.firstElementChild;
  }
  return goog.dom.getNextElementNode_(node.firstChild, true);
};
goog.dom.getLastElementChild = function(node) {
  if (goog.isDef(node.lastElementChild)) {
    return node.lastElementChild;
  }
  return goog.dom.getNextElementNode_(node.lastChild, false);
};
goog.dom.getNextElementSibling = function(node) {
  if (goog.isDef(node.nextElementSibling)) {
    return node.nextElementSibling;
  }
  return goog.dom.getNextElementNode_(node.nextSibling, true);
};
goog.dom.getPreviousElementSibling = function(node) {
  if (goog.isDef(node.previousElementSibling)) {
    return node.previousElementSibling;
  }
  return goog.dom.getNextElementNode_(node.previousSibling, false);
};
goog.dom.getNextElementNode_ = function(node, forward) {
  while (node && node.nodeType != goog.dom.NodeType.ELEMENT) {
    node = forward ? node.nextSibling : node.previousSibling;
  }
  return node;
};
goog.dom.getNextNode = function(node) {
  if (!node) {
    return null;
  }
  if (node.firstChild) {
    return node.firstChild;
  }
  while (node && !node.nextSibling) {
    node = node.parentNode;
  }
  return node ? node.nextSibling : null;
};
goog.dom.getPreviousNode = function(node) {
  if (!node) {
    return null;
  }
  if (!node.previousSibling) {
    return node.parentNode;
  }
  node = node.previousSibling;
  while (node && node.lastChild) {
    node = node.lastChild;
  }
  return node;
};
goog.dom.isNodeLike = function(obj) {
  return goog.isObject(obj) && obj.nodeType > 0;
};
goog.dom.isElement = function(obj) {
  return goog.isObject(obj) && obj.nodeType == goog.dom.NodeType.ELEMENT;
};
goog.dom.isWindow = function(obj) {
  return goog.isObject(obj) && obj["window"] == obj;
};
goog.dom.getParentElement = function(element) {
  var parent;
  if (goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY) {
    var isIe9 = goog.userAgent.IE && goog.userAgent.isVersionOrHigher("9") && !goog.userAgent.isVersionOrHigher("10");
    if (!(isIe9 && goog.global["SVGElement"] && element instanceof goog.global["SVGElement"])) {
      parent = element.parentElement;
      if (parent) {
        return parent;
      }
    }
  }
  parent = element.parentNode;
  return goog.dom.isElement(parent) ? parent : null;
};
goog.dom.contains = function(parent, descendant) {
  if (!parent || !descendant) {
    return false;
  }
  if (parent.contains && descendant.nodeType == goog.dom.NodeType.ELEMENT) {
    return parent == descendant || parent.contains(descendant);
  }
  if (typeof parent.compareDocumentPosition != "undefined") {
    return parent == descendant || Boolean(parent.compareDocumentPosition(descendant) & 16);
  }
  while (descendant && parent != descendant) {
    descendant = descendant.parentNode;
  }
  return descendant == parent;
};
goog.dom.compareNodeOrder = function(node1, node2) {
  if (node1 == node2) {
    return 0;
  }
  if (node1.compareDocumentPosition) {
    return node1.compareDocumentPosition(node2) & 2 ? 1 : -1;
  }
  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
    if (node1.nodeType == goog.dom.NodeType.DOCUMENT) {
      return -1;
    }
    if (node2.nodeType == goog.dom.NodeType.DOCUMENT) {
      return 1;
    }
  }
  if ("sourceIndex" in node1 || node1.parentNode && "sourceIndex" in node1.parentNode) {
    var isElement1 = node1.nodeType == goog.dom.NodeType.ELEMENT;
    var isElement2 = node2.nodeType == goog.dom.NodeType.ELEMENT;
    if (isElement1 && isElement2) {
      return node1.sourceIndex - node2.sourceIndex;
    } else {
      var parent1 = node1.parentNode;
      var parent2 = node2.parentNode;
      if (parent1 == parent2) {
        return goog.dom.compareSiblingOrder_(node1, node2);
      }
      if (!isElement1 && goog.dom.contains(parent1, node2)) {
        return -1 * goog.dom.compareParentsDescendantNodeIe_(node1, node2);
      }
      if (!isElement2 && goog.dom.contains(parent2, node1)) {
        return goog.dom.compareParentsDescendantNodeIe_(node2, node1);
      }
      return (isElement1 ? node1.sourceIndex : parent1.sourceIndex) - (isElement2 ? node2.sourceIndex : parent2.sourceIndex);
    }
  }
  var doc = goog.dom.getOwnerDocument(node1);
  var range1, range2;
  range1 = doc.createRange();
  range1.selectNode(node1);
  range1.collapse(true);
  range2 = doc.createRange();
  range2.selectNode(node2);
  range2.collapse(true);
  return range1.compareBoundaryPoints(goog.global["Range"].START_TO_END, range2);
};
goog.dom.compareParentsDescendantNodeIe_ = function(textNode, node) {
  var parent = textNode.parentNode;
  if (parent == node) {
    return -1;
  }
  var sibling = node;
  while (sibling.parentNode != parent) {
    sibling = sibling.parentNode;
  }
  return goog.dom.compareSiblingOrder_(sibling, textNode);
};
goog.dom.compareSiblingOrder_ = function(node1, node2) {
  var s = node2;
  while (s = s.previousSibling) {
    if (s == node1) {
      return -1;
    }
  }
  return 1;
};
goog.dom.findCommonAncestor = function(var_args) {
  var i, count = arguments.length;
  if (!count) {
    return null;
  } else {
    if (count == 1) {
      return arguments[0];
    }
  }
  var paths = [];
  var minLength = Infinity;
  for (i = 0; i < count; i++) {
    var ancestors = [];
    var node = arguments[i];
    while (node) {
      ancestors.unshift(node);
      node = node.parentNode;
    }
    paths.push(ancestors);
    minLength = Math.min(minLength, ancestors.length);
  }
  var output = null;
  for (i = 0; i < minLength; i++) {
    var first = paths[0][i];
    for (var j = 1; j < count; j++) {
      if (first != paths[j][i]) {
        return output;
      }
    }
    output = first;
  }
  return output;
};
goog.dom.getOwnerDocument = function(node) {
  goog.asserts.assert(node, "Node cannot be null or undefined.");
  return node.nodeType == goog.dom.NodeType.DOCUMENT ? node : node.ownerDocument || node.document;
};
goog.dom.getFrameContentDocument = function(frame) {
  return frame.contentDocument || frame.contentWindow.document;
};
goog.dom.getFrameContentWindow = function(frame) {
  try {
    return frame.contentWindow || (frame.contentDocument ? goog.dom.getWindow(frame.contentDocument) : null);
  } catch (e) {
  }
  return null;
};
goog.dom.setTextContent = function(node, text) {
  goog.asserts.assert(node != null, "goog.dom.setTextContent expects a non-null value for node");
  if ("textContent" in node) {
    node.textContent = text;
  } else {
    if (node.nodeType == goog.dom.NodeType.TEXT) {
      node.data = text;
    } else {
      if (node.firstChild && node.firstChild.nodeType == goog.dom.NodeType.TEXT) {
        while (node.lastChild != node.firstChild) {
          node.removeChild(node.lastChild);
        }
        node.firstChild.data = text;
      } else {
        goog.dom.removeChildren(node);
        var doc = goog.dom.getOwnerDocument(node);
        node.appendChild(doc.createTextNode(String(text)));
      }
    }
  }
};
goog.dom.getOuterHtml = function(element) {
  goog.asserts.assert(element !== null, "goog.dom.getOuterHtml expects a non-null value for element");
  if ("outerHTML" in element) {
    return element.outerHTML;
  } else {
    var doc = goog.dom.getOwnerDocument(element);
    var div = goog.dom.createElement_(doc, goog.dom.TagName.DIV);
    div.appendChild(element.cloneNode(true));
    return div.innerHTML;
  }
};
goog.dom.findNode = function(root, p) {
  var rv = [];
  var found = goog.dom.findNodes_(root, p, rv, true);
  return found ? rv[0] : undefined;
};
goog.dom.findNodes = function(root, p) {
  var rv = [];
  goog.dom.findNodes_(root, p, rv, false);
  return rv;
};
goog.dom.findNodes_ = function(root, p, rv, findOne) {
  if (root != null) {
    var child = root.firstChild;
    while (child) {
      if (p(child)) {
        rv.push(child);
        if (findOne) {
          return true;
        }
      }
      if (goog.dom.findNodes_(child, p, rv, findOne)) {
        return true;
      }
      child = child.nextSibling;
    }
  }
  return false;
};
goog.dom.TAGS_TO_IGNORE_ = {"SCRIPT":1, "STYLE":1, "HEAD":1, "IFRAME":1, "OBJECT":1};
goog.dom.PREDEFINED_TAG_VALUES_ = {"IMG":" ", "BR":"\n"};
goog.dom.isFocusableTabIndex = function(element) {
  return goog.dom.hasSpecifiedTabIndex_(element) && goog.dom.isTabIndexFocusable_(element);
};
goog.dom.setFocusableTabIndex = function(element, enable) {
  if (enable) {
    element.tabIndex = 0;
  } else {
    element.tabIndex = -1;
    element.removeAttribute("tabIndex");
  }
};
goog.dom.isFocusable = function(element) {
  var focusable;
  if (goog.dom.nativelySupportsFocus_(element)) {
    focusable = !element.disabled && (!goog.dom.hasSpecifiedTabIndex_(element) || goog.dom.isTabIndexFocusable_(element));
  } else {
    focusable = goog.dom.isFocusableTabIndex(element);
  }
  return focusable && goog.userAgent.IE ? goog.dom.hasNonZeroBoundingRect_(element) : focusable;
};
goog.dom.hasSpecifiedTabIndex_ = function(element) {
  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9")) {
    var attrNode = element.getAttributeNode("tabindex");
    return goog.isDefAndNotNull(attrNode) && attrNode.specified;
  } else {
    return element.hasAttribute("tabindex");
  }
};
goog.dom.isTabIndexFocusable_ = function(element) {
  var index = element.tabIndex;
  return goog.isNumber(index) && index >= 0 && index < 32768;
};
goog.dom.nativelySupportsFocus_ = function(element) {
  return element.tagName == goog.dom.TagName.A || element.tagName == goog.dom.TagName.INPUT || element.tagName == goog.dom.TagName.TEXTAREA || element.tagName == goog.dom.TagName.SELECT || element.tagName == goog.dom.TagName.BUTTON;
};
goog.dom.hasNonZeroBoundingRect_ = function(element) {
  var rect;
  if (!goog.isFunction(element["getBoundingClientRect"]) || goog.userAgent.IE && element.parentElement == null) {
    rect = {"height":element.offsetHeight, "width":element.offsetWidth};
  } else {
    rect = element.getBoundingClientRect();
  }
  return goog.isDefAndNotNull(rect) && rect.height > 0 && rect.width > 0;
};
goog.dom.getTextContent = function(node) {
  var textContent;
  if (goog.dom.BrowserFeature.CAN_USE_INNER_TEXT && node !== null && "innerText" in node) {
    textContent = goog.string.canonicalizeNewlines(node.innerText);
  } else {
    var buf = [];
    goog.dom.getTextContent_(node, buf, true);
    textContent = buf.join("");
  }
  textContent = textContent.replace(/ \xAD /g, " ").replace(/\xAD/g, "");
  textContent = textContent.replace(/\u200B/g, "");
  if (!goog.dom.BrowserFeature.CAN_USE_INNER_TEXT) {
    textContent = textContent.replace(/ +/g, " ");
  }
  if (textContent != " ") {
    textContent = textContent.replace(/^\s*/, "");
  }
  return textContent;
};
goog.dom.getRawTextContent = function(node) {
  var buf = [];
  goog.dom.getTextContent_(node, buf, false);
  return buf.join("");
};
goog.dom.getTextContent_ = function(node, buf, normalizeWhitespace) {
  if (node.nodeName in goog.dom.TAGS_TO_IGNORE_) {
  } else {
    if (node.nodeType == goog.dom.NodeType.TEXT) {
      if (normalizeWhitespace) {
        buf.push(String(node.nodeValue).replace(/(\r\n|\r|\n)/g, ""));
      } else {
        buf.push(node.nodeValue);
      }
    } else {
      if (node.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {
        buf.push(goog.dom.PREDEFINED_TAG_VALUES_[node.nodeName]);
      } else {
        var child = node.firstChild;
        while (child) {
          goog.dom.getTextContent_(child, buf, normalizeWhitespace);
          child = child.nextSibling;
        }
      }
    }
  }
};
goog.dom.getNodeTextLength = function(node) {
  return goog.dom.getTextContent(node).length;
};
goog.dom.getNodeTextOffset = function(node, opt_offsetParent) {
  var root = opt_offsetParent || goog.dom.getOwnerDocument(node).body;
  var buf = [];
  while (node && node != root) {
    var cur = node;
    while (cur = cur.previousSibling) {
      buf.unshift(goog.dom.getTextContent(cur));
    }
    node = node.parentNode;
  }
  return goog.string.trimLeft(buf.join("")).replace(/ +/g, " ").length;
};
goog.dom.getNodeAtOffset = function(parent, offset, opt_result) {
  var stack = [parent], pos = 0, cur = null;
  while (stack.length > 0 && pos < offset) {
    cur = stack.pop();
    if (cur.nodeName in goog.dom.TAGS_TO_IGNORE_) {
    } else {
      if (cur.nodeType == goog.dom.NodeType.TEXT) {
        var text = cur.nodeValue.replace(/(\r\n|\r|\n)/g, "").replace(/ +/g, " ");
        pos += text.length;
      } else {
        if (cur.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {
          pos += goog.dom.PREDEFINED_TAG_VALUES_[cur.nodeName].length;
        } else {
          for (var i = cur.childNodes.length - 1; i >= 0; i--) {
            stack.push(cur.childNodes[i]);
          }
        }
      }
    }
  }
  if (goog.isObject(opt_result)) {
    opt_result.remainder = cur ? cur.nodeValue.length + offset - pos - 1 : 0;
    opt_result.node = cur;
  }
  return cur;
};
goog.dom.isNodeList = function(val) {
  if (val && typeof val.length == "number") {
    if (goog.isObject(val)) {
      return typeof val.item == "function" || typeof val.item == "string";
    } else {
      if (goog.isFunction(val)) {
        return typeof val.item == "function";
      }
    }
  }
  return false;
};
goog.dom.getAncestorByTagNameAndClass = function(element, opt_tag, opt_class, opt_maxSearchSteps) {
  if (!opt_tag && !opt_class) {
    return null;
  }
  var tagName = opt_tag ? String(opt_tag).toUpperCase() : null;
  return goog.dom.getAncestor(element, function(node) {
    return (!tagName || node.nodeName == tagName) && (!opt_class || goog.isString(node.className) && goog.array.contains(node.className.split(/\s+/), opt_class));
  }, true, opt_maxSearchSteps);
};
goog.dom.getAncestorByClass = function(element, className, opt_maxSearchSteps) {
  return goog.dom.getAncestorByTagNameAndClass(element, null, className, opt_maxSearchSteps);
};
goog.dom.getAncestor = function(element, matcher, opt_includeNode, opt_maxSearchSteps) {
  if (element && !opt_includeNode) {
    element = element.parentNode;
  }
  var steps = 0;
  while (element && (opt_maxSearchSteps == null || steps <= opt_maxSearchSteps)) {
    goog.asserts.assert(element.name != "parentNode");
    if (matcher(element)) {
      return element;
    }
    element = element.parentNode;
    steps++;
  }
  return null;
};
goog.dom.getActiveElement = function(doc) {
  try {
    return doc && doc.activeElement;
  } catch (e) {
  }
  return null;
};
goog.dom.getPixelRatio = function() {
  var win = goog.dom.getWindow();
  if (goog.isDef(win.devicePixelRatio)) {
    return win.devicePixelRatio;
  } else {
    if (win.matchMedia) {
      return goog.dom.matchesPixelRatio_(3) || goog.dom.matchesPixelRatio_(2) || goog.dom.matchesPixelRatio_(1.5) || goog.dom.matchesPixelRatio_(1) || .75;
    }
  }
  return 1;
};
goog.dom.matchesPixelRatio_ = function(pixelRatio) {
  var win = goog.dom.getWindow();
  var dpiPerDppx = 96;
  var query = "(min-resolution: " + pixelRatio + "dppx)," + "(min--moz-device-pixel-ratio: " + pixelRatio + ")," + "(min-resolution: " + pixelRatio * dpiPerDppx + "dpi)";
  return win.matchMedia(query).matches ? pixelRatio : 0;
};
goog.dom.getCanvasContext2D = function(canvas) {
  return canvas.getContext("2d");
};
goog.dom.DomHelper = function(opt_document) {
  this.document_ = opt_document || goog.global.document || document;
};
goog.dom.DomHelper.prototype.getDomHelper = goog.dom.getDomHelper;
goog.dom.DomHelper.prototype.setDocument = function(document) {
  this.document_ = document;
};
goog.dom.DomHelper.prototype.getDocument = function() {
  return this.document_;
};
goog.dom.DomHelper.prototype.getElement = function(element) {
  return goog.dom.getElementHelper_(this.document_, element);
};
goog.dom.DomHelper.prototype.getRequiredElement = function(id) {
  return goog.dom.getRequiredElementHelper_(this.document_, id);
};
goog.dom.DomHelper.prototype.$ = goog.dom.DomHelper.prototype.getElement;
goog.dom.DomHelper.prototype.getElementsByTagName = function(tagName, opt_parent) {
  var parent = opt_parent || this.document_;
  return parent.getElementsByTagName(String(tagName));
};
goog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {
  return goog.dom.getElementsByTagNameAndClass_(this.document_, opt_tag, opt_class, opt_el);
};
goog.dom.DomHelper.prototype.getElementsByClass = function(className, opt_el) {
  var doc = opt_el || this.document_;
  return goog.dom.getElementsByClass(className, doc);
};
goog.dom.DomHelper.prototype.getElementByClass = function(className, opt_el) {
  var doc = opt_el || this.document_;
  return goog.dom.getElementByClass(className, doc);
};
goog.dom.DomHelper.prototype.getRequiredElementByClass = function(className, opt_root) {
  var root = opt_root || this.document_;
  return goog.dom.getRequiredElementByClass(className, root);
};
goog.dom.DomHelper.prototype.$$ = goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;
goog.dom.DomHelper.prototype.setProperties = goog.dom.setProperties;
goog.dom.DomHelper.prototype.getViewportSize = function(opt_window) {
  return goog.dom.getViewportSize(opt_window || this.getWindow());
};
goog.dom.DomHelper.prototype.getDocumentHeight = function() {
  return goog.dom.getDocumentHeight_(this.getWindow());
};
goog.dom.Appendable;
goog.dom.DomHelper.prototype.createDom = function(tagName, opt_attributes, var_args) {
  return goog.dom.createDom_(this.document_, arguments);
};
goog.dom.DomHelper.prototype.$dom = goog.dom.DomHelper.prototype.createDom;
goog.dom.DomHelper.prototype.createElement = function(name) {
  return goog.dom.createElement_(this.document_, name);
};
goog.dom.DomHelper.prototype.createTextNode = function(content) {
  return this.document_.createTextNode(String(content));
};
goog.dom.DomHelper.prototype.createTable = function(rows, columns, opt_fillWithNbsp) {
  return goog.dom.createTable_(this.document_, rows, columns, !!opt_fillWithNbsp);
};
goog.dom.DomHelper.prototype.safeHtmlToNode = function(html) {
  return goog.dom.safeHtmlToNode_(this.document_, html);
};
goog.dom.DomHelper.prototype.isCss1CompatMode = function() {
  return goog.dom.isCss1CompatMode_(this.document_);
};
goog.dom.DomHelper.prototype.getWindow = function() {
  return goog.dom.getWindow_(this.document_);
};
goog.dom.DomHelper.prototype.getDocumentScrollElement = function() {
  return goog.dom.getDocumentScrollElement_(this.document_);
};
goog.dom.DomHelper.prototype.getDocumentScroll = function() {
  return goog.dom.getDocumentScroll_(this.document_);
};
goog.dom.DomHelper.prototype.getActiveElement = function(opt_doc) {
  return goog.dom.getActiveElement(opt_doc || this.document_);
};
goog.dom.DomHelper.prototype.appendChild = goog.dom.appendChild;
goog.dom.DomHelper.prototype.append = goog.dom.append;
goog.dom.DomHelper.prototype.canHaveChildren = goog.dom.canHaveChildren;
goog.dom.DomHelper.prototype.removeChildren = goog.dom.removeChildren;
goog.dom.DomHelper.prototype.insertSiblingBefore = goog.dom.insertSiblingBefore;
goog.dom.DomHelper.prototype.insertSiblingAfter = goog.dom.insertSiblingAfter;
goog.dom.DomHelper.prototype.insertChildAt = goog.dom.insertChildAt;
goog.dom.DomHelper.prototype.removeNode = goog.dom.removeNode;
goog.dom.DomHelper.prototype.replaceNode = goog.dom.replaceNode;
goog.dom.DomHelper.prototype.flattenElement = goog.dom.flattenElement;
goog.dom.DomHelper.prototype.getChildren = goog.dom.getChildren;
goog.dom.DomHelper.prototype.getFirstElementChild = goog.dom.getFirstElementChild;
goog.dom.DomHelper.prototype.getLastElementChild = goog.dom.getLastElementChild;
goog.dom.DomHelper.prototype.getNextElementSibling = goog.dom.getNextElementSibling;
goog.dom.DomHelper.prototype.getPreviousElementSibling = goog.dom.getPreviousElementSibling;
goog.dom.DomHelper.prototype.getNextNode = goog.dom.getNextNode;
goog.dom.DomHelper.prototype.getPreviousNode = goog.dom.getPreviousNode;
goog.dom.DomHelper.prototype.isNodeLike = goog.dom.isNodeLike;
goog.dom.DomHelper.prototype.isElement = goog.dom.isElement;
goog.dom.DomHelper.prototype.isWindow = goog.dom.isWindow;
goog.dom.DomHelper.prototype.getParentElement = goog.dom.getParentElement;
goog.dom.DomHelper.prototype.contains = goog.dom.contains;
goog.dom.DomHelper.prototype.compareNodeOrder = goog.dom.compareNodeOrder;
goog.dom.DomHelper.prototype.findCommonAncestor = goog.dom.findCommonAncestor;
goog.dom.DomHelper.prototype.getOwnerDocument = goog.dom.getOwnerDocument;
goog.dom.DomHelper.prototype.getFrameContentDocument = goog.dom.getFrameContentDocument;
goog.dom.DomHelper.prototype.getFrameContentWindow = goog.dom.getFrameContentWindow;
goog.dom.DomHelper.prototype.setTextContent = goog.dom.setTextContent;
goog.dom.DomHelper.prototype.getOuterHtml = goog.dom.getOuterHtml;
goog.dom.DomHelper.prototype.findNode = goog.dom.findNode;
goog.dom.DomHelper.prototype.findNodes = goog.dom.findNodes;
goog.dom.DomHelper.prototype.isFocusableTabIndex = goog.dom.isFocusableTabIndex;
goog.dom.DomHelper.prototype.setFocusableTabIndex = goog.dom.setFocusableTabIndex;
goog.dom.DomHelper.prototype.isFocusable = goog.dom.isFocusable;
goog.dom.DomHelper.prototype.getTextContent = goog.dom.getTextContent;
goog.dom.DomHelper.prototype.getNodeTextLength = goog.dom.getNodeTextLength;
goog.dom.DomHelper.prototype.getNodeTextOffset = goog.dom.getNodeTextOffset;
goog.dom.DomHelper.prototype.getNodeAtOffset = goog.dom.getNodeAtOffset;
goog.dom.DomHelper.prototype.isNodeList = goog.dom.isNodeList;
goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass = goog.dom.getAncestorByTagNameAndClass;
goog.dom.DomHelper.prototype.getAncestorByClass = goog.dom.getAncestorByClass;
goog.dom.DomHelper.prototype.getAncestor = goog.dom.getAncestor;
goog.dom.DomHelper.prototype.getCanvasContext2D = goog.dom.getCanvasContext2D;
goog.provide("goog.dom.classlist");
goog.require("goog.array");
goog.define("goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST", false);
goog.dom.classlist.get = function(element) {
  if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) {
    return element.classList;
  }
  var className = element.className;
  return goog.isString(className) && className.match(/\S+/g) || [];
};
goog.dom.classlist.set = function(element, className) {
  element.className = className;
};
goog.dom.classlist.contains = function(element, className) {
  if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) {
    return element.classList.contains(className);
  }
  return goog.array.contains(goog.dom.classlist.get(element), className);
};
goog.dom.classlist.add = function(element, className) {
  if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) {
    element.classList.add(className);
    return;
  }
  if (!goog.dom.classlist.contains(element, className)) {
    element.className += element.className.length > 0 ? " " + className : className;
  }
};
goog.dom.classlist.addAll = function(element, classesToAdd) {
  if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) {
    goog.array.forEach(classesToAdd, function(className) {
      goog.dom.classlist.add(element, className);
    });
    return;
  }
  var classMap = {};
  goog.array.forEach(goog.dom.classlist.get(element), function(className) {
    classMap[className] = true;
  });
  goog.array.forEach(classesToAdd, function(className) {
    classMap[className] = true;
  });
  element.className = "";
  for (var className in classMap) {
    element.className += element.className.length > 0 ? " " + className : className;
  }
};
goog.dom.classlist.remove = function(element, className) {
  if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) {
    element.classList.remove(className);
    return;
  }
  if (goog.dom.classlist.contains(element, className)) {
    element.className = goog.array.filter(goog.dom.classlist.get(element), function(c) {
      return c != className;
    }).join(" ");
  }
};
goog.dom.classlist.removeAll = function(element, classesToRemove) {
  if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) {
    goog.array.forEach(classesToRemove, function(className) {
      goog.dom.classlist.remove(element, className);
    });
    return;
  }
  element.className = goog.array.filter(goog.dom.classlist.get(element), function(className) {
    return !goog.array.contains(classesToRemove, className);
  }).join(" ");
};
goog.dom.classlist.enable = function(element, className, enabled) {
  if (enabled) {
    goog.dom.classlist.add(element, className);
  } else {
    goog.dom.classlist.remove(element, className);
  }
};
goog.dom.classlist.enableAll = function(element, classesToEnable, enabled) {
  var f = enabled ? goog.dom.classlist.addAll : goog.dom.classlist.removeAll;
  f(element, classesToEnable);
};
goog.dom.classlist.swap = function(element, fromClass, toClass) {
  if (goog.dom.classlist.contains(element, fromClass)) {
    goog.dom.classlist.remove(element, fromClass);
    goog.dom.classlist.add(element, toClass);
    return true;
  }
  return false;
};
goog.dom.classlist.toggle = function(element, className) {
  var add = !goog.dom.classlist.contains(element, className);
  goog.dom.classlist.enable(element, className, add);
  return add;
};
goog.dom.classlist.addRemove = function(element, classToRemove, classToAdd) {
  goog.dom.classlist.remove(element, classToRemove);
  goog.dom.classlist.add(element, classToAdd);
};
goog.provide("goog.dom.vendor");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.dom.vendor.getVendorJsPrefix = function() {
  if (goog.userAgent.WEBKIT) {
    return "Webkit";
  } else {
    if (goog.userAgent.GECKO) {
      return "Moz";
    } else {
      if (goog.userAgent.IE) {
        return "ms";
      } else {
        if (goog.userAgent.OPERA) {
          return "O";
        }
      }
    }
  }
  return null;
};
goog.dom.vendor.getVendorPrefix = function() {
  if (goog.userAgent.WEBKIT) {
    return "-webkit";
  } else {
    if (goog.userAgent.GECKO) {
      return "-moz";
    } else {
      if (goog.userAgent.IE) {
        return "-ms";
      } else {
        if (goog.userAgent.OPERA) {
          return "-o";
        }
      }
    }
  }
  return null;
};
goog.dom.vendor.getPrefixedPropertyName = function(propertyName, opt_object) {
  if (opt_object && propertyName in opt_object) {
    return propertyName;
  }
  var prefix = goog.dom.vendor.getVendorJsPrefix();
  if (prefix) {
    prefix = prefix.toLowerCase();
    var prefixedPropertyName = prefix + goog.string.toTitleCase(propertyName);
    return !goog.isDef(opt_object) || prefixedPropertyName in opt_object ? prefixedPropertyName : null;
  }
  return null;
};
goog.dom.vendor.getPrefixedEventType = function(eventType) {
  var prefix = goog.dom.vendor.getVendorJsPrefix() || "";
  return (prefix + eventType).toLowerCase();
};
goog.provide("goog.html.legacyconversions");
goog.require("goog.html.SafeHtml");
goog.require("goog.html.SafeStyle");
goog.require("goog.html.SafeStyleSheet");
goog.require("goog.html.SafeUrl");
goog.require("goog.html.TrustedResourceUrl");
goog.html.legacyconversions.safeHtmlFromString = function(html) {
  goog.html.legacyconversions.reportCallback_();
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(html, null);
};
goog.html.legacyconversions.safeStyleFromString = function(style) {
  goog.html.legacyconversions.reportCallback_();
  return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(style);
};
goog.html.legacyconversions.safeStyleSheetFromString = function(styleSheet) {
  goog.html.legacyconversions.reportCallback_();
  return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet);
};
goog.html.legacyconversions.safeUrlFromString = function(url) {
  goog.html.legacyconversions.reportCallback_();
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
};
goog.html.legacyconversions.trustedResourceUrlFromString = function(url) {
  goog.html.legacyconversions.reportCallback_();
  return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);
};
goog.html.legacyconversions.reportCallback_ = goog.nullFunction;
goog.html.legacyconversions.setReportCallback = function(callback) {
  goog.html.legacyconversions.reportCallback_ = callback;
};
goog.provide("goog.math.Box");
goog.require("goog.asserts");
goog.require("goog.math.Coordinate");
goog.math.Box = function(top, right, bottom, left) {
  this.top = top;
  this.right = right;
  this.bottom = bottom;
  this.left = left;
};
goog.math.Box.boundingBox = function(var_args) {
  var box = new goog.math.Box(arguments[0].y, arguments[0].x, arguments[0].y, arguments[0].x);
  for (var i = 1; i < arguments.length; i++) {
    box.expandToIncludeCoordinate(arguments[i]);
  }
  return box;
};
goog.math.Box.prototype.getWidth = function() {
  return this.right - this.left;
};
goog.math.Box.prototype.getHeight = function() {
  return this.bottom - this.top;
};
goog.math.Box.prototype.clone = function() {
  return new goog.math.Box(this.top, this.right, this.bottom, this.left);
};
if (goog.DEBUG) {
  goog.math.Box.prototype.toString = function() {
    return "(" + this.top + "t, " + this.right + "r, " + this.bottom + "b, " + this.left + "l)";
  };
}
goog.math.Box.prototype.contains = function(other) {
  return goog.math.Box.contains(this, other);
};
goog.math.Box.prototype.expand = function(top, opt_right, opt_bottom, opt_left) {
  if (goog.isObject(top)) {
    this.top -= top.top;
    this.right += top.right;
    this.bottom += top.bottom;
    this.left -= top.left;
  } else {
    this.top -= top;
    this.right += Number(opt_right);
    this.bottom += Number(opt_bottom);
    this.left -= Number(opt_left);
  }
  return this;
};
goog.math.Box.prototype.expandToInclude = function(box) {
  this.left = Math.min(this.left, box.left);
  this.top = Math.min(this.top, box.top);
  this.right = Math.max(this.right, box.right);
  this.bottom = Math.max(this.bottom, box.bottom);
};
goog.math.Box.prototype.expandToIncludeCoordinate = function(coord) {
  this.top = Math.min(this.top, coord.y);
  this.right = Math.max(this.right, coord.x);
  this.bottom = Math.max(this.bottom, coord.y);
  this.left = Math.min(this.left, coord.x);
};
goog.math.Box.equals = function(a, b) {
  if (a == b) {
    return true;
  }
  if (!a || !b) {
    return false;
  }
  return a.top == b.top && a.right == b.right && a.bottom == b.bottom && a.left == b.left;
};
goog.math.Box.contains = function(box, other) {
  if (!box || !other) {
    return false;
  }
  if (other instanceof goog.math.Box) {
    return other.left >= box.left && other.right <= box.right && other.top >= box.top && other.bottom <= box.bottom;
  }
  return other.x >= box.left && other.x <= box.right && other.y >= box.top && other.y <= box.bottom;
};
goog.math.Box.relativePositionX = function(box, coord) {
  if (coord.x < box.left) {
    return coord.x - box.left;
  } else {
    if (coord.x > box.right) {
      return coord.x - box.right;
    }
  }
  return 0;
};
goog.math.Box.relativePositionY = function(box, coord) {
  if (coord.y < box.top) {
    return coord.y - box.top;
  } else {
    if (coord.y > box.bottom) {
      return coord.y - box.bottom;
    }
  }
  return 0;
};
goog.math.Box.distance = function(box, coord) {
  var x = goog.math.Box.relativePositionX(box, coord);
  var y = goog.math.Box.relativePositionY(box, coord);
  return Math.sqrt(x * x + y * y);
};
goog.math.Box.intersects = function(a, b) {
  return a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom;
};
goog.math.Box.intersectsWithPadding = function(a, b, padding) {
  return a.left <= b.right + padding && b.left <= a.right + padding && a.top <= b.bottom + padding && b.top <= a.bottom + padding;
};
goog.math.Box.prototype.ceil = function() {
  this.top = Math.ceil(this.top);
  this.right = Math.ceil(this.right);
  this.bottom = Math.ceil(this.bottom);
  this.left = Math.ceil(this.left);
  return this;
};
goog.math.Box.prototype.floor = function() {
  this.top = Math.floor(this.top);
  this.right = Math.floor(this.right);
  this.bottom = Math.floor(this.bottom);
  this.left = Math.floor(this.left);
  return this;
};
goog.math.Box.prototype.round = function() {
  this.top = Math.round(this.top);
  this.right = Math.round(this.right);
  this.bottom = Math.round(this.bottom);
  this.left = Math.round(this.left);
  return this;
};
goog.math.Box.prototype.translate = function(tx, opt_ty) {
  if (tx instanceof goog.math.Coordinate) {
    this.left += tx.x;
    this.right += tx.x;
    this.top += tx.y;
    this.bottom += tx.y;
  } else {
    goog.asserts.assertNumber(tx);
    this.left += tx;
    this.right += tx;
    if (goog.isNumber(opt_ty)) {
      this.top += opt_ty;
      this.bottom += opt_ty;
    }
  }
  return this;
};
goog.math.Box.prototype.scale = function(sx, opt_sy) {
  var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
  this.left *= sx;
  this.right *= sx;
  this.top *= sy;
  this.bottom *= sy;
  return this;
};
goog.provide("goog.math.IRect");
goog.math.IRect = function() {
};
goog.math.IRect.prototype.left;
goog.math.IRect.prototype.top;
goog.math.IRect.prototype.width;
goog.math.IRect.prototype.height;
goog.provide("goog.math.Rect");
goog.require("goog.asserts");
goog.require("goog.math.Box");
goog.require("goog.math.Coordinate");
goog.require("goog.math.IRect");
goog.require("goog.math.Size");
goog.math.Rect = function(x, y, w, h) {
  this.left = x;
  this.top = y;
  this.width = w;
  this.height = h;
};
goog.math.Rect.prototype.clone = function() {
  return new goog.math.Rect(this.left, this.top, this.width, this.height);
};
goog.math.Rect.prototype.toBox = function() {
  var right = this.left + this.width;
  var bottom = this.top + this.height;
  return new goog.math.Box(this.top, right, bottom, this.left);
};
goog.math.Rect.createFromPositionAndSize = function(position, size) {
  return new goog.math.Rect(position.x, position.y, size.width, size.height);
};
goog.math.Rect.createFromBox = function(box) {
  return new goog.math.Rect(box.left, box.top, box.right - box.left, box.bottom - box.top);
};
if (goog.DEBUG) {
  goog.math.Rect.prototype.toString = function() {
    return "(" + this.left + ", " + this.top + " - " + this.width + "w x " + this.height + "h)";
  };
}
goog.math.Rect.equals = function(a, b) {
  if (a == b) {
    return true;
  }
  if (!a || !b) {
    return false;
  }
  return a.left == b.left && a.width == b.width && a.top == b.top && a.height == b.height;
};
goog.math.Rect.prototype.intersection = function(rect) {
  var x0 = Math.max(this.left, rect.left);
  var x1 = Math.min(this.left + this.width, rect.left + rect.width);
  if (x0 <= x1) {
    var y0 = Math.max(this.top, rect.top);
    var y1 = Math.min(this.top + this.height, rect.top + rect.height);
    if (y0 <= y1) {
      this.left = x0;
      this.top = y0;
      this.width = x1 - x0;
      this.height = y1 - y0;
      return true;
    }
  }
  return false;
};
goog.math.Rect.intersection = function(a, b) {
  var x0 = Math.max(a.left, b.left);
  var x1 = Math.min(a.left + a.width, b.left + b.width);
  if (x0 <= x1) {
    var y0 = Math.max(a.top, b.top);
    var y1 = Math.min(a.top + a.height, b.top + b.height);
    if (y0 <= y1) {
      return new goog.math.Rect(x0, y0, x1 - x0, y1 - y0);
    }
  }
  return null;
};
goog.math.Rect.intersects = function(a, b) {
  return a.left <= b.left + b.width && b.left <= a.left + a.width && a.top <= b.top + b.height && b.top <= a.top + a.height;
};
goog.math.Rect.prototype.intersects = function(rect) {
  return goog.math.Rect.intersects(this, rect);
};
goog.math.Rect.difference = function(a, b) {
  var intersection = goog.math.Rect.intersection(a, b);
  if (!intersection || !intersection.height || !intersection.width) {
    return [a.clone()];
  }
  var result = [];
  var top = a.top;
  var height = a.height;
  var ar = a.left + a.width;
  var ab = a.top + a.height;
  var br = b.left + b.width;
  var bb = b.top + b.height;
  if (b.top > a.top) {
    result.push(new goog.math.Rect(a.left, a.top, a.width, b.top - a.top));
    top = b.top;
    height -= b.top - a.top;
  }
  if (bb < ab) {
    result.push(new goog.math.Rect(a.left, bb, a.width, ab - bb));
    height = bb - top;
  }
  if (b.left > a.left) {
    result.push(new goog.math.Rect(a.left, top, b.left - a.left, height));
  }
  if (br < ar) {
    result.push(new goog.math.Rect(br, top, ar - br, height));
  }
  return result;
};
goog.math.Rect.prototype.difference = function(rect) {
  return goog.math.Rect.difference(this, rect);
};
goog.math.Rect.prototype.boundingRect = function(rect) {
  var right = Math.max(this.left + this.width, rect.left + rect.width);
  var bottom = Math.max(this.top + this.height, rect.top + rect.height);
  this.left = Math.min(this.left, rect.left);
  this.top = Math.min(this.top, rect.top);
  this.width = right - this.left;
  this.height = bottom - this.top;
};
goog.math.Rect.boundingRect = function(a, b) {
  if (!a || !b) {
    return null;
  }
  var newRect = new goog.math.Rect(a.left, a.top, a.width, a.height);
  newRect.boundingRect(b);
  return newRect;
};
goog.math.Rect.prototype.contains = function(another) {
  if (another instanceof goog.math.Coordinate) {
    return another.x >= this.left && another.x <= this.left + this.width && another.y >= this.top && another.y <= this.top + this.height;
  } else {
    return this.left <= another.left && this.left + this.width >= another.left + another.width && this.top <= another.top && this.top + this.height >= another.top + another.height;
  }
};
goog.math.Rect.prototype.squaredDistance = function(point) {
  var dx = point.x < this.left ? this.left - point.x : Math.max(point.x - (this.left + this.width), 0);
  var dy = point.y < this.top ? this.top - point.y : Math.max(point.y - (this.top + this.height), 0);
  return dx * dx + dy * dy;
};
goog.math.Rect.prototype.distance = function(point) {
  return Math.sqrt(this.squaredDistance(point));
};
goog.math.Rect.prototype.getSize = function() {
  return new goog.math.Size(this.width, this.height);
};
goog.math.Rect.prototype.getTopLeft = function() {
  return new goog.math.Coordinate(this.left, this.top);
};
goog.math.Rect.prototype.getCenter = function() {
  return new goog.math.Coordinate(this.left + this.width / 2, this.top + this.height / 2);
};
goog.math.Rect.prototype.getBottomRight = function() {
  return new goog.math.Coordinate(this.left + this.width, this.top + this.height);
};
goog.math.Rect.prototype.ceil = function() {
  this.left = Math.ceil(this.left);
  this.top = Math.ceil(this.top);
  this.width = Math.ceil(this.width);
  this.height = Math.ceil(this.height);
  return this;
};
goog.math.Rect.prototype.floor = function() {
  this.left = Math.floor(this.left);
  this.top = Math.floor(this.top);
  this.width = Math.floor(this.width);
  this.height = Math.floor(this.height);
  return this;
};
goog.math.Rect.prototype.round = function() {
  this.left = Math.round(this.left);
  this.top = Math.round(this.top);
  this.width = Math.round(this.width);
  this.height = Math.round(this.height);
  return this;
};
goog.math.Rect.prototype.translate = function(tx, opt_ty) {
  if (tx instanceof goog.math.Coordinate) {
    this.left += tx.x;
    this.top += tx.y;
  } else {
    this.left += goog.asserts.assertNumber(tx);
    if (goog.isNumber(opt_ty)) {
      this.top += opt_ty;
    }
  }
  return this;
};
goog.math.Rect.prototype.scale = function(sx, opt_sy) {
  var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
  this.left *= sx;
  this.width *= sx;
  this.top *= sy;
  this.height *= sy;
  return this;
};
goog.provide("goog.style");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagName");
goog.require("goog.dom.vendor");
goog.require("goog.html.SafeStyleSheet");
goog.require("goog.html.legacyconversions");
goog.require("goog.math.Box");
goog.require("goog.math.Coordinate");
goog.require("goog.math.Rect");
goog.require("goog.math.Size");
goog.require("goog.object");
goog.require("goog.reflect");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.forwardDeclare("goog.events.Event");
goog.style.setStyle = function(element, style, opt_value) {
  if (goog.isString(style)) {
    goog.style.setStyle_(element, opt_value, style);
  } else {
    for (var key in style) {
      goog.style.setStyle_(element, style[key], key);
    }
  }
};
goog.style.setStyle_ = function(element, value, style) {
  var propertyName = goog.style.getVendorJsStyleName_(element, style);
  if (propertyName) {
    element.style[propertyName] = value;
  }
};
goog.style.styleNameCache_ = {};
goog.style.getVendorJsStyleName_ = function(element, style) {
  var propertyName = goog.style.styleNameCache_[style];
  if (!propertyName) {
    var camelStyle = goog.string.toCamelCase(style);
    propertyName = camelStyle;
    if (element.style[camelStyle] === undefined) {
      var prefixedStyle = goog.dom.vendor.getVendorJsPrefix() + goog.string.toTitleCase(camelStyle);
      if (element.style[prefixedStyle] !== undefined) {
        propertyName = prefixedStyle;
      }
    }
    goog.style.styleNameCache_[style] = propertyName;
  }
  return propertyName;
};
goog.style.getVendorStyleName_ = function(element, style) {
  var camelStyle = goog.string.toCamelCase(style);
  if (element.style[camelStyle] === undefined) {
    var prefixedStyle = goog.dom.vendor.getVendorJsPrefix() + goog.string.toTitleCase(camelStyle);
    if (element.style[prefixedStyle] !== undefined) {
      return goog.dom.vendor.getVendorPrefix() + "-" + style;
    }
  }
  return style;
};
goog.style.getStyle = function(element, property) {
  var styleValue = element.style[goog.string.toCamelCase(property)];
  if (typeof styleValue !== "undefined") {
    return styleValue;
  }
  return element.style[goog.style.getVendorJsStyleName_(element, property)] || "";
};
goog.style.getComputedStyle = function(element, property) {
  var doc = goog.dom.getOwnerDocument(element);
  if (doc.defaultView && doc.defaultView.getComputedStyle) {
    var styles = doc.defaultView.getComputedStyle(element, null);
    if (styles) {
      return styles[property] || styles.getPropertyValue(property) || "";
    }
  }
  return "";
};
goog.style.getCascadedStyle = function(element, style) {
  return element.currentStyle ? element.currentStyle[style] : null;
};
goog.style.getStyle_ = function(element, style) {
  return goog.style.getComputedStyle(element, style) || goog.style.getCascadedStyle(element, style) || element.style && element.style[style];
};
goog.style.getComputedBoxSizing = function(element) {
  return goog.style.getStyle_(element, "boxSizing") || goog.style.getStyle_(element, "MozBoxSizing") || goog.style.getStyle_(element, "WebkitBoxSizing") || null;
};
goog.style.getComputedPosition = function(element) {
  return goog.style.getStyle_(element, "position");
};
goog.style.getBackgroundColor = function(element) {
  return goog.style.getStyle_(element, "backgroundColor");
};
goog.style.getComputedOverflowX = function(element) {
  return goog.style.getStyle_(element, "overflowX");
};
goog.style.getComputedOverflowY = function(element) {
  return goog.style.getStyle_(element, "overflowY");
};
goog.style.getComputedZIndex = function(element) {
  return goog.style.getStyle_(element, "zIndex");
};
goog.style.getComputedTextAlign = function(element) {
  return goog.style.getStyle_(element, "textAlign");
};
goog.style.getComputedCursor = function(element) {
  return goog.style.getStyle_(element, "cursor");
};
goog.style.getComputedTransform = function(element) {
  var property = goog.style.getVendorStyleName_(element, "transform");
  return goog.style.getStyle_(element, property) || goog.style.getStyle_(element, "transform");
};
goog.style.setPosition = function(el, arg1, opt_arg2) {
  var x, y;
  if (arg1 instanceof goog.math.Coordinate) {
    x = arg1.x;
    y = arg1.y;
  } else {
    x = arg1;
    y = opt_arg2;
  }
  el.style.left = goog.style.getPixelStyleValue_(x, false);
  el.style.top = goog.style.getPixelStyleValue_(y, false);
};
goog.style.getPosition = function(element) {
  return new goog.math.Coordinate(element.offsetLeft, element.offsetTop);
};
goog.style.getClientViewportElement = function(opt_node) {
  var doc;
  if (opt_node) {
    doc = goog.dom.getOwnerDocument(opt_node);
  } else {
    doc = goog.dom.getDocument();
  }
  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9) && !goog.dom.getDomHelper(doc).isCss1CompatMode()) {
    return doc.body;
  }
  return doc.documentElement;
};
goog.style.getViewportPageOffset = function(doc) {
  var body = doc.body;
  var documentElement = doc.documentElement;
  var scrollLeft = body.scrollLeft || documentElement.scrollLeft;
  var scrollTop = body.scrollTop || documentElement.scrollTop;
  return new goog.math.Coordinate(scrollLeft, scrollTop);
};
goog.style.getBoundingClientRect_ = function(el) {
  var rect;
  try {
    rect = el.getBoundingClientRect();
  } catch (e) {
    return {"left":0, "top":0, "right":0, "bottom":0};
  }
  if (goog.userAgent.IE && el.ownerDocument.body) {
    var doc = el.ownerDocument;
    rect.left -= doc.documentElement.clientLeft + doc.body.clientLeft;
    rect.top -= doc.documentElement.clientTop + doc.body.clientTop;
  }
  return rect;
};
goog.style.getOffsetParent = function(element) {
  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(8)) {
    goog.asserts.assert(element && "offsetParent" in element);
    return element.offsetParent;
  }
  var doc = goog.dom.getOwnerDocument(element);
  var positionStyle = goog.style.getStyle_(element, "position");
  var skipStatic = positionStyle == "fixed" || positionStyle == "absolute";
  for (var parent = element.parentNode; parent && parent != doc; parent = parent.parentNode) {
    if (parent.nodeType == goog.dom.NodeType.DOCUMENT_FRAGMENT && parent.host) {
      parent = parent.host;
    }
    positionStyle = goog.style.getStyle_(parent, "position");
    skipStatic = skipStatic && positionStyle == "static" && parent != doc.documentElement && parent != doc.body;
    if (!skipStatic && (parent.scrollWidth > parent.clientWidth || parent.scrollHeight > parent.clientHeight || positionStyle == "fixed" || positionStyle == "absolute" || positionStyle == "relative")) {
      return parent;
    }
  }
  return null;
};
goog.style.getVisibleRectForElement = function(element) {
  var visibleRect = new goog.math.Box(0, Infinity, Infinity, 0);
  var dom = goog.dom.getDomHelper(element);
  var body = dom.getDocument().body;
  var documentElement = dom.getDocument().documentElement;
  var scrollEl = dom.getDocumentScrollElement();
  for (var el = element; el = goog.style.getOffsetParent(el);) {
    if ((!goog.userAgent.IE || el.clientWidth != 0) && (!goog.userAgent.WEBKIT || el.clientHeight != 0 || el != body) && (el != body && el != documentElement && goog.style.getStyle_(el, "overflow") != "visible")) {
      var pos = goog.style.getPageOffset(el);
      var client = goog.style.getClientLeftTop(el);
      pos.x += client.x;
      pos.y += client.y;
      visibleRect.top = Math.max(visibleRect.top, pos.y);
      visibleRect.right = Math.min(visibleRect.right, pos.x + el.clientWidth);
      visibleRect.bottom = Math.min(visibleRect.bottom, pos.y + el.clientHeight);
      visibleRect.left = Math.max(visibleRect.left, pos.x);
    }
  }
  var scrollX = scrollEl.scrollLeft, scrollY = scrollEl.scrollTop;
  visibleRect.left = Math.max(visibleRect.left, scrollX);
  visibleRect.top = Math.max(visibleRect.top, scrollY);
  var winSize = dom.getViewportSize();
  visibleRect.right = Math.min(visibleRect.right, scrollX + winSize.width);
  visibleRect.bottom = Math.min(visibleRect.bottom, scrollY + winSize.height);
  return visibleRect.top >= 0 && visibleRect.left >= 0 && visibleRect.bottom > visibleRect.top && visibleRect.right > visibleRect.left ? visibleRect : null;
};
goog.style.getContainerOffsetToScrollInto = function(element, opt_container, opt_center) {
  var container = opt_container || goog.dom.getDocumentScrollElement();
  var elementPos = goog.style.getPageOffset(element);
  var containerPos = goog.style.getPageOffset(container);
  var containerBorder = goog.style.getBorderBox(container);
  if (container == goog.dom.getDocumentScrollElement()) {
    var relX = elementPos.x - container.scrollLeft;
    var relY = elementPos.y - container.scrollTop;
    if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) {
      relX += containerBorder.left;
      relY += containerBorder.top;
    }
  } else {
    var relX = elementPos.x - containerPos.x - containerBorder.left;
    var relY = elementPos.y - containerPos.y - containerBorder.top;
  }
  var elementSize = goog.style.getSizeWithDisplay_(element);
  var spaceX = container.clientWidth - elementSize.width;
  var spaceY = container.clientHeight - elementSize.height;
  var scrollLeft = container.scrollLeft;
  var scrollTop = container.scrollTop;
  if (opt_center) {
    scrollLeft += relX - spaceX / 2;
    scrollTop += relY - spaceY / 2;
  } else {
    scrollLeft += Math.min(relX, Math.max(relX - spaceX, 0));
    scrollTop += Math.min(relY, Math.max(relY - spaceY, 0));
  }
  return new goog.math.Coordinate(scrollLeft, scrollTop);
};
goog.style.scrollIntoContainerView = function(element, opt_container, opt_center) {
  var container = opt_container || goog.dom.getDocumentScrollElement();
  var offset = goog.style.getContainerOffsetToScrollInto(element, container, opt_center);
  container.scrollLeft = offset.x;
  container.scrollTop = offset.y;
};
goog.style.getClientLeftTop = function(el) {
  return new goog.math.Coordinate(el.clientLeft, el.clientTop);
};
goog.style.getPageOffset = function(el) {
  var doc = goog.dom.getOwnerDocument(el);
  goog.asserts.assertObject(el, "Parameter is required");
  var pos = new goog.math.Coordinate(0, 0);
  var viewportElement = goog.style.getClientViewportElement(doc);
  if (el == viewportElement) {
    return pos;
  }
  var box = goog.style.getBoundingClientRect_(el);
  var scrollCoord = goog.dom.getDomHelper(doc).getDocumentScroll();
  pos.x = box.left + scrollCoord.x;
  pos.y = box.top + scrollCoord.y;
  return pos;
};
goog.style.getPageOffsetLeft = function(el) {
  return goog.style.getPageOffset(el).x;
};
goog.style.getPageOffsetTop = function(el) {
  return goog.style.getPageOffset(el).y;
};
goog.style.getFramedPageOffset = function(el, relativeWin) {
  var position = new goog.math.Coordinate(0, 0);
  var currentWin = goog.dom.getWindow(goog.dom.getOwnerDocument(el));
  if (!goog.reflect.canAccessProperty(currentWin, "parent")) {
    return position;
  }
  var currentEl = el;
  do {
    var offset = currentWin == relativeWin ? goog.style.getPageOffset(currentEl) : goog.style.getClientPositionForElement_(goog.asserts.assert(currentEl));
    position.x += offset.x;
    position.y += offset.y;
  } while (currentWin && currentWin != relativeWin && currentWin != currentWin.parent && (currentEl = currentWin.frameElement) && (currentWin = currentWin.parent));
  return position;
};
goog.style.translateRectForAnotherFrame = function(rect, origBase, newBase) {
  if (origBase.getDocument() != newBase.getDocument()) {
    var body = origBase.getDocument().body;
    var pos = goog.style.getFramedPageOffset(body, newBase.getWindow());
    pos = goog.math.Coordinate.difference(pos, goog.style.getPageOffset(body));
    if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9) && !origBase.isCss1CompatMode()) {
      pos = goog.math.Coordinate.difference(pos, origBase.getDocumentScroll());
    }
    rect.left += pos.x;
    rect.top += pos.y;
  }
};
goog.style.getRelativePosition = function(a, b) {
  var ap = goog.style.getClientPosition(a);
  var bp = goog.style.getClientPosition(b);
  return new goog.math.Coordinate(ap.x - bp.x, ap.y - bp.y);
};
goog.style.getClientPositionForElement_ = function(el) {
  var box = goog.style.getBoundingClientRect_(el);
  return new goog.math.Coordinate(box.left, box.top);
};
goog.style.getClientPosition = function(el) {
  goog.asserts.assert(el);
  if (el.nodeType == goog.dom.NodeType.ELEMENT) {
    return goog.style.getClientPositionForElement_(el);
  } else {
    var targetEvent = el.changedTouches ? el.changedTouches[0] : el;
    return new goog.math.Coordinate(targetEvent.clientX, targetEvent.clientY);
  }
};
goog.style.setPageOffset = function(el, x, opt_y) {
  var cur = goog.style.getPageOffset(el);
  if (x instanceof goog.math.Coordinate) {
    opt_y = x.y;
    x = x.x;
  }
  var dx = goog.asserts.assertNumber(x) - cur.x;
  var dy = Number(opt_y) - cur.y;
  goog.style.setPosition(el, el.offsetLeft + dx, el.offsetTop + dy);
};
goog.style.setSize = function(element, w, opt_h) {
  var h;
  if (w instanceof goog.math.Size) {
    h = w.height;
    w = w.width;
  } else {
    if (opt_h == undefined) {
      throw Error("missing height argument");
    }
    h = opt_h;
  }
  goog.style.setWidth(element, w);
  goog.style.setHeight(element, h);
};
goog.style.getPixelStyleValue_ = function(value, round) {
  if (typeof value == "number") {
    value = (round ? Math.round(value) : value) + "px";
  }
  return value;
};
goog.style.setHeight = function(element, height) {
  element.style.height = goog.style.getPixelStyleValue_(height, true);
};
goog.style.setWidth = function(element, width) {
  element.style.width = goog.style.getPixelStyleValue_(width, true);
};
goog.style.getSize = function(element) {
  return goog.style.evaluateWithTemporaryDisplay_(goog.style.getSizeWithDisplay_, element);
};
goog.style.evaluateWithTemporaryDisplay_ = function(fn, element) {
  if (goog.style.getStyle_(element, "display") != "none") {
    return fn(element);
  }
  var style = element.style;
  var originalDisplay = style.display;
  var originalVisibility = style.visibility;
  var originalPosition = style.position;
  style.visibility = "hidden";
  style.position = "absolute";
  style.display = "inline";
  var retVal = fn(element);
  style.display = originalDisplay;
  style.position = originalPosition;
  style.visibility = originalVisibility;
  return retVal;
};
goog.style.getSizeWithDisplay_ = function(element) {
  var offsetWidth = element.offsetWidth;
  var offsetHeight = element.offsetHeight;
  var webkitOffsetsZero = goog.userAgent.WEBKIT && !offsetWidth && !offsetHeight;
  if ((!goog.isDef(offsetWidth) || webkitOffsetsZero) && element.getBoundingClientRect) {
    var clientRect = goog.style.getBoundingClientRect_(element);
    return new goog.math.Size(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
  }
  return new goog.math.Size(offsetWidth, offsetHeight);
};
goog.style.getTransformedSize = function(element) {
  if (!element.getBoundingClientRect) {
    return null;
  }
  var clientRect = goog.style.evaluateWithTemporaryDisplay_(goog.style.getBoundingClientRect_, element);
  return new goog.math.Size(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
};
goog.style.getBounds = function(element) {
  var o = goog.style.getPageOffset(element);
  var s = goog.style.getSize(element);
  return new goog.math.Rect(o.x, o.y, s.width, s.height);
};
goog.style.toCamelCase = function(selector) {
  return goog.string.toCamelCase(String(selector));
};
goog.style.toSelectorCase = function(selector) {
  return goog.string.toSelectorCase(selector);
};
goog.style.getOpacity = function(el) {
  goog.asserts.assert(el);
  var style = el.style;
  var result = "";
  if ("opacity" in style) {
    result = style.opacity;
  } else {
    if ("MozOpacity" in style) {
      result = style.MozOpacity;
    } else {
      if ("filter" in style) {
        var match = style.filter.match(/alpha\(opacity=([\d.]+)\)/);
        if (match) {
          result = String(match[1] / 100);
        }
      }
    }
  }
  return result == "" ? result : Number(result);
};
goog.style.setOpacity = function(el, alpha) {
  goog.asserts.assert(el);
  var style = el.style;
  if ("opacity" in style) {
    style.opacity = alpha;
  } else {
    if ("MozOpacity" in style) {
      style.MozOpacity = alpha;
    } else {
      if ("filter" in style) {
        if (alpha === "") {
          style.filter = "";
        } else {
          style.filter = "alpha(opacity=" + Number(alpha) * 100 + ")";
        }
      }
    }
  }
};
goog.style.setTransparentBackgroundImage = function(el, src) {
  var style = el.style;
  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("8")) {
    style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(" + 'src="' + src + '", sizingMethod="crop")';
  } else {
    style.backgroundImage = "url(" + src + ")";
    style.backgroundPosition = "top left";
    style.backgroundRepeat = "no-repeat";
  }
};
goog.style.clearTransparentBackgroundImage = function(el) {
  var style = el.style;
  if ("filter" in style) {
    style.filter = "";
  } else {
    style.backgroundImage = "none";
  }
};
goog.style.showElement = function(el, display) {
  goog.style.setElementShown(el, display);
};
goog.style.setElementShown = function(el, isShown) {
  el.style.display = isShown ? "" : "none";
};
goog.style.isElementShown = function(el) {
  return el.style.display != "none";
};
goog.style.installStyles = function(stylesString, opt_node) {
  return goog.style.installSafeStyleSheet(goog.html.legacyconversions.safeStyleSheetFromString(stylesString), opt_node);
};
goog.style.installSafeStyleSheet = function(safeStyleSheet, opt_node) {
  var dh = goog.dom.getDomHelper(opt_node);
  var styleSheet = null;
  var doc = dh.getDocument();
  if (goog.userAgent.IE && doc.createStyleSheet) {
    styleSheet = doc.createStyleSheet();
    goog.style.setSafeStyleSheet(styleSheet, safeStyleSheet);
  } else {
    var head = dh.getElementsByTagNameAndClass(goog.dom.TagName.HEAD)[0];
    if (!head) {
      var body = dh.getElementsByTagNameAndClass(goog.dom.TagName.BODY)[0];
      head = dh.createDom(goog.dom.TagName.HEAD);
      body.parentNode.insertBefore(head, body);
    }
    styleSheet = dh.createDom(goog.dom.TagName.STYLE);
    goog.style.setSafeStyleSheet(styleSheet, safeStyleSheet);
    dh.appendChild(head, styleSheet);
  }
  return styleSheet;
};
goog.style.uninstallStyles = function(styleSheet) {
  var node = styleSheet.ownerNode || styleSheet.owningElement || styleSheet;
  goog.dom.removeNode(node);
};
goog.style.setStyles = function(element, stylesString) {
  goog.style.setSafeStyleSheet(element, goog.html.legacyconversions.safeStyleSheetFromString(stylesString));
};
goog.style.setSafeStyleSheet = function(element, safeStyleSheet) {
  var stylesString = goog.html.SafeStyleSheet.unwrap(safeStyleSheet);
  if (goog.userAgent.IE && goog.isDef(element.cssText)) {
    element.cssText = stylesString;
  } else {
    element.innerHTML = stylesString;
  }
};
goog.style.setPreWrap = function(el) {
  var style = el.style;
  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("8")) {
    style.whiteSpace = "pre";
    style.wordWrap = "break-word";
  } else {
    if (goog.userAgent.GECKO) {
      style.whiteSpace = "-moz-pre-wrap";
    } else {
      style.whiteSpace = "pre-wrap";
    }
  }
};
goog.style.setInlineBlock = function(el) {
  var style = el.style;
  style.position = "relative";
  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("8")) {
    style.zoom = "1";
    style.display = "inline";
  } else {
    style.display = "inline-block";
  }
};
goog.style.isRightToLeft = function(el) {
  return "rtl" == goog.style.getStyle_(el, "direction");
};
goog.style.unselectableStyle_ = goog.userAgent.GECKO ? "MozUserSelect" : goog.userAgent.WEBKIT || goog.userAgent.EDGE ? "WebkitUserSelect" : null;
goog.style.isUnselectable = function(el) {
  if (goog.style.unselectableStyle_) {
    return el.style[goog.style.unselectableStyle_].toLowerCase() == "none";
  } else {
    if (goog.userAgent.IE || goog.userAgent.OPERA) {
      return el.getAttribute("unselectable") == "on";
    }
  }
  return false;
};
goog.style.setUnselectable = function(el, unselectable, opt_noRecurse) {
  var descendants = !opt_noRecurse ? el.getElementsByTagName("*") : null;
  var name = goog.style.unselectableStyle_;
  if (name) {
    var value = unselectable ? "none" : "";
    if (el.style) {
      el.style[name] = value;
    }
    if (descendants) {
      for (var i = 0, descendant; descendant = descendants[i]; i++) {
        if (descendant.style) {
          descendant.style[name] = value;
        }
      }
    }
  } else {
    if (goog.userAgent.IE || goog.userAgent.OPERA) {
      var value = unselectable ? "on" : "";
      el.setAttribute("unselectable", value);
      if (descendants) {
        for (var i = 0, descendant; descendant = descendants[i]; i++) {
          descendant.setAttribute("unselectable", value);
        }
      }
    }
  }
};
goog.style.getBorderBoxSize = function(element) {
  return new goog.math.Size(element.offsetWidth, element.offsetHeight);
};
goog.style.setBorderBoxSize = function(element, size) {
  var doc = goog.dom.getOwnerDocument(element);
  var isCss1CompatMode = goog.dom.getDomHelper(doc).isCss1CompatMode();
  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("10") && (!isCss1CompatMode || !goog.userAgent.isVersionOrHigher("8"))) {
    var style = element.style;
    if (isCss1CompatMode) {
      var paddingBox = goog.style.getPaddingBox(element);
      var borderBox = goog.style.getBorderBox(element);
      style.pixelWidth = size.width - borderBox.left - paddingBox.left - paddingBox.right - borderBox.right;
      style.pixelHeight = size.height - borderBox.top - paddingBox.top - paddingBox.bottom - borderBox.bottom;
    } else {
      style.pixelWidth = size.width;
      style.pixelHeight = size.height;
    }
  } else {
    goog.style.setBoxSizingSize_(element, size, "border-box");
  }
};
goog.style.getContentBoxSize = function(element) {
  var doc = goog.dom.getOwnerDocument(element);
  var ieCurrentStyle = goog.userAgent.IE && element.currentStyle;
  if (ieCurrentStyle && goog.dom.getDomHelper(doc).isCss1CompatMode() && ieCurrentStyle.width != "auto" && ieCurrentStyle.height != "auto" && !ieCurrentStyle.boxSizing) {
    var width = goog.style.getIePixelValue_(element, ieCurrentStyle.width, "width", "pixelWidth");
    var height = goog.style.getIePixelValue_(element, ieCurrentStyle.height, "height", "pixelHeight");
    return new goog.math.Size(width, height);
  } else {
    var borderBoxSize = goog.style.getBorderBoxSize(element);
    var paddingBox = goog.style.getPaddingBox(element);
    var borderBox = goog.style.getBorderBox(element);
    return new goog.math.Size(borderBoxSize.width - borderBox.left - paddingBox.left - paddingBox.right - borderBox.right, borderBoxSize.height - borderBox.top - paddingBox.top - paddingBox.bottom - borderBox.bottom);
  }
};
goog.style.setContentBoxSize = function(element, size) {
  var doc = goog.dom.getOwnerDocument(element);
  var isCss1CompatMode = goog.dom.getDomHelper(doc).isCss1CompatMode();
  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("10") && (!isCss1CompatMode || !goog.userAgent.isVersionOrHigher("8"))) {
    var style = element.style;
    if (isCss1CompatMode) {
      style.pixelWidth = size.width;
      style.pixelHeight = size.height;
    } else {
      var paddingBox = goog.style.getPaddingBox(element);
      var borderBox = goog.style.getBorderBox(element);
      style.pixelWidth = size.width + borderBox.left + paddingBox.left + paddingBox.right + borderBox.right;
      style.pixelHeight = size.height + borderBox.top + paddingBox.top + paddingBox.bottom + borderBox.bottom;
    }
  } else {
    goog.style.setBoxSizingSize_(element, size, "content-box");
  }
};
goog.style.setBoxSizingSize_ = function(element, size, boxSizing) {
  var style = element.style;
  if (goog.userAgent.GECKO) {
    style.MozBoxSizing = boxSizing;
  } else {
    if (goog.userAgent.WEBKIT) {
      style.WebkitBoxSizing = boxSizing;
    } else {
      style.boxSizing = boxSizing;
    }
  }
  style.width = Math.max(size.width, 0) + "px";
  style.height = Math.max(size.height, 0) + "px";
};
goog.style.getIePixelValue_ = function(element, value, name, pixelName) {
  if (/^\d+px?$/.test(value)) {
    return parseInt(value, 10);
  } else {
    var oldStyleValue = element.style[name];
    var oldRuntimeValue = element.runtimeStyle[name];
    element.runtimeStyle[name] = element.currentStyle[name];
    element.style[name] = value;
    var pixelValue = element.style[pixelName];
    element.style[name] = oldStyleValue;
    element.runtimeStyle[name] = oldRuntimeValue;
    return +pixelValue;
  }
};
goog.style.getIePixelDistance_ = function(element, propName) {
  var value = goog.style.getCascadedStyle(element, propName);
  return value ? goog.style.getIePixelValue_(element, value, "left", "pixelLeft") : 0;
};
goog.style.getBox_ = function(element, stylePrefix) {
  if (goog.userAgent.IE) {
    var left = goog.style.getIePixelDistance_(element, stylePrefix + "Left");
    var right = goog.style.getIePixelDistance_(element, stylePrefix + "Right");
    var top = goog.style.getIePixelDistance_(element, stylePrefix + "Top");
    var bottom = goog.style.getIePixelDistance_(element, stylePrefix + "Bottom");
    return new goog.math.Box(top, right, bottom, left);
  } else {
    var left = goog.style.getComputedStyle(element, stylePrefix + "Left");
    var right = goog.style.getComputedStyle(element, stylePrefix + "Right");
    var top = goog.style.getComputedStyle(element, stylePrefix + "Top");
    var bottom = goog.style.getComputedStyle(element, stylePrefix + "Bottom");
    return new goog.math.Box(parseFloat(top), parseFloat(right), parseFloat(bottom), parseFloat(left));
  }
};
goog.style.getPaddingBox = function(element) {
  return goog.style.getBox_(element, "padding");
};
goog.style.getMarginBox = function(element) {
  return goog.style.getBox_(element, "margin");
};
goog.style.ieBorderWidthKeywords_ = {"thin":2, "medium":4, "thick":6};
goog.style.getIePixelBorder_ = function(element, prop) {
  if (goog.style.getCascadedStyle(element, prop + "Style") == "none") {
    return 0;
  }
  var width = goog.style.getCascadedStyle(element, prop + "Width");
  if (width in goog.style.ieBorderWidthKeywords_) {
    return goog.style.ieBorderWidthKeywords_[width];
  }
  return goog.style.getIePixelValue_(element, width, "left", "pixelLeft");
};
goog.style.getBorderBox = function(element) {
  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
    var left = goog.style.getIePixelBorder_(element, "borderLeft");
    var right = goog.style.getIePixelBorder_(element, "borderRight");
    var top = goog.style.getIePixelBorder_(element, "borderTop");
    var bottom = goog.style.getIePixelBorder_(element, "borderBottom");
    return new goog.math.Box(top, right, bottom, left);
  } else {
    var left = goog.style.getComputedStyle(element, "borderLeftWidth");
    var right = goog.style.getComputedStyle(element, "borderRightWidth");
    var top = goog.style.getComputedStyle(element, "borderTopWidth");
    var bottom = goog.style.getComputedStyle(element, "borderBottomWidth");
    return new goog.math.Box(parseFloat(top), parseFloat(right), parseFloat(bottom), parseFloat(left));
  }
};
goog.style.getFontFamily = function(el) {
  var doc = goog.dom.getOwnerDocument(el);
  var font = "";
  if (doc.body.createTextRange && goog.dom.contains(doc, el)) {
    var range = doc.body.createTextRange();
    range.moveToElementText(el);
    try {
      font = range.queryCommandValue("FontName");
    } catch (e) {
      font = "";
    }
  }
  if (!font) {
    font = goog.style.getStyle_(el, "fontFamily");
  }
  var fontsArray = font.split(",");
  if (fontsArray.length > 1) {
    font = fontsArray[0];
  }
  return goog.string.stripQuotes(font, "\"'");
};
goog.style.lengthUnitRegex_ = /[^\d]+$/;
goog.style.getLengthUnits = function(value) {
  var units = value.match(goog.style.lengthUnitRegex_);
  return units && units[0] || null;
};
goog.style.ABSOLUTE_CSS_LENGTH_UNITS_ = {"cm":1, "in":1, "mm":1, "pc":1, "pt":1};
goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_ = {"em":1, "ex":1};
goog.style.getFontSize = function(el) {
  var fontSize = goog.style.getStyle_(el, "fontSize");
  var sizeUnits = goog.style.getLengthUnits(fontSize);
  if (fontSize && "px" == sizeUnits) {
    return parseInt(fontSize, 10);
  }
  if (goog.userAgent.IE) {
    if (String(sizeUnits) in goog.style.ABSOLUTE_CSS_LENGTH_UNITS_) {
      return goog.style.getIePixelValue_(el, fontSize, "left", "pixelLeft");
    } else {
      if (el.parentNode && el.parentNode.nodeType == goog.dom.NodeType.ELEMENT && String(sizeUnits) in goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_) {
        var parentElement = el.parentNode;
        var parentSize = goog.style.getStyle_(parentElement, "fontSize");
        return goog.style.getIePixelValue_(parentElement, fontSize == parentSize ? "1em" : fontSize, "left", "pixelLeft");
      }
    }
  }
  var sizeElement = goog.dom.createDom(goog.dom.TagName.SPAN, {"style":"visibility:hidden;position:absolute;" + "line-height:0;padding:0;margin:0;border:0;height:1em;"});
  goog.dom.appendChild(el, sizeElement);
  fontSize = sizeElement.offsetHeight;
  goog.dom.removeNode(sizeElement);
  return fontSize;
};
goog.style.parseStyleAttribute = function(value) {
  var result = {};
  goog.array.forEach(value.split(/\s*;\s*/), function(pair) {
    var keyValue = pair.match(/\s*([\w-]+)\s*\:(.+)/);
    if (keyValue) {
      var styleName = keyValue[1];
      var styleValue = goog.string.trim(keyValue[2]);
      result[goog.string.toCamelCase(styleName.toLowerCase())] = styleValue;
    }
  });
  return result;
};
goog.style.toStyleAttribute = function(obj) {
  var buffer = [];
  goog.object.forEach(obj, function(value, key) {
    buffer.push(goog.string.toSelectorCase(key), ":", value, ";");
  });
  return buffer.join("");
};
goog.style.setFloat = function(el, value) {
  el.style[goog.userAgent.IE ? "styleFloat" : "cssFloat"] = value;
};
goog.style.getFloat = function(el) {
  return el.style[goog.userAgent.IE ? "styleFloat" : "cssFloat"] || "";
};
goog.style.getScrollbarWidth = function(opt_className) {
  var outerDiv = goog.dom.createElement(goog.dom.TagName.DIV);
  if (opt_className) {
    outerDiv.className = opt_className;
  }
  outerDiv.style.cssText = "overflow:auto;" + "position:absolute;top:0;width:100px;height:100px";
  var innerDiv = goog.dom.createElement(goog.dom.TagName.DIV);
  goog.style.setSize(innerDiv, "200px", "200px");
  outerDiv.appendChild(innerDiv);
  goog.dom.appendChild(goog.dom.getDocument().body, outerDiv);
  var width = outerDiv.offsetWidth - outerDiv.clientWidth;
  goog.dom.removeNode(outerDiv);
  return width;
};
goog.style.MATRIX_TRANSLATION_REGEX_ = new RegExp("matrix\\([0-9\\.\\-]+, [0-9\\.\\-]+, " + "[0-9\\.\\-]+, [0-9\\.\\-]+, " + "([0-9\\.\\-]+)p?x?, ([0-9\\.\\-]+)p?x?\\)");
goog.style.getCssTranslation = function(element) {
  var transform = goog.style.getComputedTransform(element);
  if (!transform) {
    return new goog.math.Coordinate(0, 0);
  }
  var matches = transform.match(goog.style.MATRIX_TRANSLATION_REGEX_);
  if (!matches) {
    return new goog.math.Coordinate(0, 0);
  }
  return new goog.math.Coordinate(parseFloat(matches[1]), parseFloat(matches[2]));
};
goog.provide("goog.editor.Command");
goog.editor.Command = {UNDO:"+undo", REDO:"+redo", LINK:"+link", FORMAT_BLOCK:"+formatBlock", INDENT:"+indent", OUTDENT:"+outdent", REMOVE_FORMAT:"+removeFormat", STRIKE_THROUGH:"+strikeThrough", HORIZONTAL_RULE:"+insertHorizontalRule", SUBSCRIPT:"+subscript", SUPERSCRIPT:"+superscript", UNDERLINE:"+underline", BOLD:"+bold", ITALIC:"+italic", FONT_SIZE:"+fontSize", FONT_FACE:"+fontName", FONT_COLOR:"+foreColor", EMOTICON:"+emoticon", EQUATION:"+equation", BACKGROUND_COLOR:"+backColor", ORDERED_LIST:"+insertOrderedList", 
UNORDERED_LIST:"+insertUnorderedList", TABLE:"+table", JUSTIFY_CENTER:"+justifyCenter", JUSTIFY_FULL:"+justifyFull", JUSTIFY_RIGHT:"+justifyRight", JUSTIFY_LEFT:"+justifyLeft", BLOCKQUOTE:"+BLOCKQUOTE", DIR_LTR:"ltr", DIR_RTL:"rtl", IMAGE:"image", EDIT_HTML:"editHtml", UPDATE_LINK_BUBBLE:"updateLinkBubble", DEFAULT_TAG:"+defaultTag", CLEAR_LOREM:"clearlorem", UPDATE_LOREM:"updatelorem", USING_LOREM:"usinglorem", MODAL_LINK_EDITOR:"link"};
goog.provide("goog.debug.EntryPointMonitor");
goog.provide("goog.debug.entryPointRegistry");
goog.require("goog.asserts");
goog.debug.EntryPointMonitor = function() {
};
goog.debug.EntryPointMonitor.prototype.wrap;
goog.debug.EntryPointMonitor.prototype.unwrap;
goog.debug.entryPointRegistry.refList_ = [];
goog.debug.entryPointRegistry.monitors_ = [];
goog.debug.entryPointRegistry.monitorsMayExist_ = false;
goog.debug.entryPointRegistry.register = function(callback) {
  goog.debug.entryPointRegistry.refList_[goog.debug.entryPointRegistry.refList_.length] = callback;
  if (goog.debug.entryPointRegistry.monitorsMayExist_) {
    var monitors = goog.debug.entryPointRegistry.monitors_;
    for (var i = 0; i < monitors.length; i++) {
      callback(goog.bind(monitors[i].wrap, monitors[i]));
    }
  }
};
goog.debug.entryPointRegistry.monitorAll = function(monitor) {
  goog.debug.entryPointRegistry.monitorsMayExist_ = true;
  var transformer = goog.bind(monitor.wrap, monitor);
  for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
    goog.debug.entryPointRegistry.refList_[i](transformer);
  }
  goog.debug.entryPointRegistry.monitors_.push(monitor);
};
goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) {
  var monitors = goog.debug.entryPointRegistry.monitors_;
  goog.asserts.assert(monitor == monitors[monitors.length - 1], "Only the most recent monitor can be unwrapped.");
  var transformer = goog.bind(monitor.unwrap, monitor);
  for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
    goog.debug.entryPointRegistry.refList_[i](transformer);
  }
  monitors.length--;
};
goog.provide("goog.events.BrowserFeature");
goog.require("goog.userAgent");
goog.events.BrowserFeature = {HAS_W3C_BUTTON:!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), HAS_W3C_EVENT_SUPPORT:!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), SET_KEY_CODE_TO_PREVENT_DEFAULT:goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9"), HAS_NAVIGATOR_ONLINE_PROPERTY:!goog.userAgent.WEBKIT || goog.userAgent.isVersionOrHigher("528"), HAS_HTML5_NETWORK_EVENT_SUPPORT:goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9b") || goog.userAgent.IE && 
goog.userAgent.isVersionOrHigher("8") || goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher("9.5") || goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher("528"), HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher("8") || goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9"), TOUCH_ENABLED:"ontouchstart" in goog.global || !!(goog.global["document"] && document.documentElement && "ontouchstart" in document.documentElement) || !!(goog.global["navigator"] && 
goog.global["navigator"]["msMaxTouchPoints"])};
goog.provide("goog.disposable.IDisposable");
goog.disposable.IDisposable = function() {
};
goog.disposable.IDisposable.prototype.dispose = goog.abstractMethod;
goog.disposable.IDisposable.prototype.isDisposed = goog.abstractMethod;
goog.provide("goog.Disposable");
goog.provide("goog.dispose");
goog.provide("goog.disposeAll");
goog.require("goog.disposable.IDisposable");
goog.Disposable = function() {
  this.creationStack;
  if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
    if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {
      this.creationStack = (new Error).stack;
    }
    goog.Disposable.instances_[goog.getUid(this)] = this;
  }
  this.disposed_ = this.disposed_;
  this.onDisposeCallbacks_ = this.onDisposeCallbacks_;
};
goog.Disposable.MonitoringMode = {OFF:0, PERMANENT:1, INTERACTIVE:2};
goog.define("goog.Disposable.MONITORING_MODE", 0);
goog.define("goog.Disposable.INCLUDE_STACK_ON_CREATION", true);
goog.Disposable.instances_ = {};
goog.Disposable.getUndisposedObjects = function() {
  var ret = [];
  for (var id in goog.Disposable.instances_) {
    if (goog.Disposable.instances_.hasOwnProperty(id)) {
      ret.push(goog.Disposable.instances_[Number(id)]);
    }
  }
  return ret;
};
goog.Disposable.clearUndisposedObjects = function() {
  goog.Disposable.instances_ = {};
};
goog.Disposable.prototype.disposed_ = false;
goog.Disposable.prototype.onDisposeCallbacks_;
goog.Disposable.prototype.isDisposed = function() {
  return this.disposed_;
};
goog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;
goog.Disposable.prototype.dispose = function() {
  if (!this.disposed_) {
    this.disposed_ = true;
    this.disposeInternal();
    if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
      var uid = goog.getUid(this);
      if (goog.Disposable.MONITORING_MODE == goog.Disposable.MonitoringMode.PERMANENT && !goog.Disposable.instances_.hasOwnProperty(uid)) {
        throw Error(this + " did not call the goog.Disposable base " + "constructor or was disposed of after a clearUndisposedObjects " + "call");
      }
      delete goog.Disposable.instances_[uid];
    }
  }
};
goog.Disposable.prototype.registerDisposable = function(disposable) {
  this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));
};
goog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {
  if (this.disposed_) {
    goog.isDef(opt_scope) ? callback.call(opt_scope) : callback();
    return;
  }
  if (!this.onDisposeCallbacks_) {
    this.onDisposeCallbacks_ = [];
  }
  this.onDisposeCallbacks_.push(goog.isDef(opt_scope) ? goog.bind(callback, opt_scope) : callback);
};
goog.Disposable.prototype.disposeInternal = function() {
  if (this.onDisposeCallbacks_) {
    while (this.onDisposeCallbacks_.length) {
      this.onDisposeCallbacks_.shift()();
    }
  }
};
goog.Disposable.isDisposed = function(obj) {
  if (obj && typeof obj.isDisposed == "function") {
    return obj.isDisposed();
  }
  return false;
};
goog.dispose = function(obj) {
  if (obj && typeof obj.dispose == "function") {
    obj.dispose();
  }
};
goog.disposeAll = function(var_args) {
  for (var i = 0, len = arguments.length; i < len; ++i) {
    var disposable = arguments[i];
    if (goog.isArrayLike(disposable)) {
      goog.disposeAll.apply(null, disposable);
    } else {
      goog.dispose(disposable);
    }
  }
};
goog.provide("goog.events.EventId");
goog.events.EventId = function(eventId) {
  this.id = eventId;
};
goog.events.EventId.prototype.toString = function() {
  return this.id;
};
goog.provide("goog.events.Event");
goog.provide("goog.events.EventLike");
goog.require("goog.Disposable");
goog.require("goog.events.EventId");
goog.events.EventLike;
goog.events.Event = function(type, opt_target) {
  this.type = type instanceof goog.events.EventId ? String(type) : type;
  this.target = opt_target;
  this.currentTarget = this.target;
  this.propagationStopped_ = false;
  this.defaultPrevented = false;
  this.returnValue_ = true;
};
goog.events.Event.prototype.stopPropagation = function() {
  this.propagationStopped_ = true;
};
goog.events.Event.prototype.preventDefault = function() {
  this.defaultPrevented = true;
  this.returnValue_ = false;
};
goog.events.Event.stopPropagation = function(e) {
  e.stopPropagation();
};
goog.events.Event.preventDefault = function(e) {
  e.preventDefault();
};
goog.provide("goog.events.EventType");
goog.require("goog.userAgent");
goog.events.getVendorPrefixedName_ = function(eventName) {
  return goog.userAgent.WEBKIT ? "webkit" + eventName : goog.userAgent.OPERA ? "o" + eventName.toLowerCase() : eventName.toLowerCase();
};
goog.events.EventType = {CLICK:"click", RIGHTCLICK:"rightclick", DBLCLICK:"dblclick", MOUSEDOWN:"mousedown", MOUSEUP:"mouseup", MOUSEOVER:"mouseover", MOUSEOUT:"mouseout", MOUSEMOVE:"mousemove", MOUSEENTER:"mouseenter", MOUSELEAVE:"mouseleave", SELECTIONCHANGE:"selectionchange", SELECTSTART:"selectstart", WHEEL:"wheel", KEYPRESS:"keypress", KEYDOWN:"keydown", KEYUP:"keyup", BLUR:"blur", FOCUS:"focus", DEACTIVATE:"deactivate", FOCUSIN:goog.userAgent.IE ? "focusin" : "DOMFocusIn", FOCUSOUT:goog.userAgent.IE ? 
"focusout" : "DOMFocusOut", CHANGE:"change", RESET:"reset", SELECT:"select", SUBMIT:"submit", INPUT:"input", PROPERTYCHANGE:"propertychange", DRAGSTART:"dragstart", DRAG:"drag", DRAGENTER:"dragenter", DRAGOVER:"dragover", DRAGLEAVE:"dragleave", DROP:"drop", DRAGEND:"dragend", TOUCHSTART:"touchstart", TOUCHMOVE:"touchmove", TOUCHEND:"touchend", TOUCHCANCEL:"touchcancel", BEFOREUNLOAD:"beforeunload", CONSOLEMESSAGE:"consolemessage", CONTEXTMENU:"contextmenu", DEVICEMOTION:"devicemotion", DEVICEORIENTATION:"deviceorientation", 
DOMCONTENTLOADED:"DOMContentLoaded", ERROR:"error", HELP:"help", LOAD:"load", LOSECAPTURE:"losecapture", ORIENTATIONCHANGE:"orientationchange", READYSTATECHANGE:"readystatechange", RESIZE:"resize", SCROLL:"scroll", UNLOAD:"unload", CANPLAY:"canplay", CANPLAYTHROUGH:"canplaythrough", DURATIONCHANGE:"durationchange", EMPTIED:"emptied", ENDED:"ended", LOADEDDATA:"loadeddata", LOADEDMETADATA:"loadedmetadata", PAUSE:"pause", PLAY:"play", PLAYING:"playing", RATECHANGE:"ratechange", SEEKED:"seeked", SEEKING:"seeking", 
STALLED:"stalled", SUSPEND:"suspend", TIMEUPDATE:"timeupdate", VOLUMECHANGE:"volumechange", WAITING:"waiting", SOURCEOPEN:"sourceopen", SOURCEENDED:"sourceended", SOURCECLOSED:"sourceclosed", ABORT:"abort", UPDATE:"update", UPDATESTART:"updatestart", UPDATEEND:"updateend", HASHCHANGE:"hashchange", PAGEHIDE:"pagehide", PAGESHOW:"pageshow", POPSTATE:"popstate", COPY:"copy", PASTE:"paste", CUT:"cut", BEFORECOPY:"beforecopy", BEFORECUT:"beforecut", BEFOREPASTE:"beforepaste", ONLINE:"online", OFFLINE:"offline", 
MESSAGE:"message", CONNECT:"connect", INSTALL:"install", ACTIVATE:"activate", FETCH:"fetch", FOREIGNFETCH:"foreignfetch", MESSAGEERROR:"messageerror", STATECHANGE:"statechange", UPDATEFOUND:"updatefound", CONTROLLERCHANGE:"controllerchange", ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"), ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"), ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"), TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"), 
POINTERDOWN:"pointerdown", POINTERUP:"pointerup", POINTERCANCEL:"pointercancel", POINTERMOVE:"pointermove", POINTEROVER:"pointerover", POINTEROUT:"pointerout", POINTERENTER:"pointerenter", POINTERLEAVE:"pointerleave", GOTPOINTERCAPTURE:"gotpointercapture", LOSTPOINTERCAPTURE:"lostpointercapture", MSGESTURECHANGE:"MSGestureChange", MSGESTUREEND:"MSGestureEnd", MSGESTUREHOLD:"MSGestureHold", MSGESTURESTART:"MSGestureStart", MSGESTURETAP:"MSGestureTap", MSGOTPOINTERCAPTURE:"MSGotPointerCapture", MSINERTIASTART:"MSInertiaStart", 
MSLOSTPOINTERCAPTURE:"MSLostPointerCapture", MSPOINTERCANCEL:"MSPointerCancel", MSPOINTERDOWN:"MSPointerDown", MSPOINTERENTER:"MSPointerEnter", MSPOINTERHOVER:"MSPointerHover", MSPOINTERLEAVE:"MSPointerLeave", MSPOINTERMOVE:"MSPointerMove", MSPOINTEROUT:"MSPointerOut", MSPOINTEROVER:"MSPointerOver", MSPOINTERUP:"MSPointerUp", TEXT:"text", TEXTINPUT:goog.userAgent.IE ? "textinput" : "textInput", COMPOSITIONSTART:"compositionstart", COMPOSITIONUPDATE:"compositionupdate", COMPOSITIONEND:"compositionend", 
BEFOREINPUT:"beforeinput", EXIT:"exit", LOADABORT:"loadabort", LOADCOMMIT:"loadcommit", LOADREDIRECT:"loadredirect", LOADSTART:"loadstart", LOADSTOP:"loadstop", RESPONSIVE:"responsive", SIZECHANGED:"sizechanged", UNRESPONSIVE:"unresponsive", VISIBILITYCHANGE:"visibilitychange", STORAGE:"storage", DOMSUBTREEMODIFIED:"DOMSubtreeModified", DOMNODEINSERTED:"DOMNodeInserted", DOMNODEREMOVED:"DOMNodeRemoved", DOMNODEREMOVEDFROMDOCUMENT:"DOMNodeRemovedFromDocument", DOMNODEINSERTEDINTODOCUMENT:"DOMNodeInsertedIntoDocument", 
DOMATTRMODIFIED:"DOMAttrModified", DOMCHARACTERDATAMODIFIED:"DOMCharacterDataModified", BEFOREPRINT:"beforeprint", AFTERPRINT:"afterprint"};
goog.provide("goog.events.BrowserEvent");
goog.provide("goog.events.BrowserEvent.MouseButton");
goog.require("goog.events.BrowserFeature");
goog.require("goog.events.Event");
goog.require("goog.events.EventType");
goog.require("goog.reflect");
goog.require("goog.userAgent");
goog.events.BrowserEvent = function(opt_e, opt_currentTarget) {
  goog.events.BrowserEvent.base(this, "constructor", opt_e ? opt_e.type : "");
  this.target = null;
  this.currentTarget = null;
  this.relatedTarget = null;
  this.offsetX = 0;
  this.offsetY = 0;
  this.clientX = 0;
  this.clientY = 0;
  this.screenX = 0;
  this.screenY = 0;
  this.button = 0;
  this.key = "";
  this.keyCode = 0;
  this.charCode = 0;
  this.ctrlKey = false;
  this.altKey = false;
  this.shiftKey = false;
  this.metaKey = false;
  this.state = null;
  this.platformModifierKey = false;
  this.event_ = null;
  if (opt_e) {
    this.init(opt_e, opt_currentTarget);
  }
};
goog.inherits(goog.events.BrowserEvent, goog.events.Event);
goog.events.BrowserEvent.MouseButton = {LEFT:0, MIDDLE:1, RIGHT:2};
goog.events.BrowserEvent.IEButtonMap = [1, 4, 2];
goog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) {
  var type = this.type = e.type;
  var relevantTouch = e.changedTouches ? e.changedTouches[0] : null;
  this.target = e.target || e.srcElement;
  this.currentTarget = opt_currentTarget;
  var relatedTarget = e.relatedTarget;
  if (relatedTarget) {
    if (goog.userAgent.GECKO) {
      if (!goog.reflect.canAccessProperty(relatedTarget, "nodeName")) {
        relatedTarget = null;
      }
    }
  } else {
    if (type == goog.events.EventType.MOUSEOVER) {
      relatedTarget = e.fromElement;
    } else {
      if (type == goog.events.EventType.MOUSEOUT) {
        relatedTarget = e.toElement;
      }
    }
  }
  this.relatedTarget = relatedTarget;
  if (!goog.isNull(relevantTouch)) {
    this.clientX = relevantTouch.clientX !== undefined ? relevantTouch.clientX : relevantTouch.pageX;
    this.clientY = relevantTouch.clientY !== undefined ? relevantTouch.clientY : relevantTouch.pageY;
    this.screenX = relevantTouch.screenX || 0;
    this.screenY = relevantTouch.screenY || 0;
  } else {
    this.offsetX = goog.userAgent.WEBKIT || e.offsetX !== undefined ? e.offsetX : e.layerX;
    this.offsetY = goog.userAgent.WEBKIT || e.offsetY !== undefined ? e.offsetY : e.layerY;
    this.clientX = e.clientX !== undefined ? e.clientX : e.pageX;
    this.clientY = e.clientY !== undefined ? e.clientY : e.pageY;
    this.screenX = e.screenX || 0;
    this.screenY = e.screenY || 0;
  }
  this.button = e.button;
  this.keyCode = e.keyCode || 0;
  this.key = e.key || "";
  this.charCode = e.charCode || (type == "keypress" ? e.keyCode : 0);
  this.ctrlKey = e.ctrlKey;
  this.altKey = e.altKey;
  this.shiftKey = e.shiftKey;
  this.metaKey = e.metaKey;
  this.platformModifierKey = goog.userAgent.MAC ? e.metaKey : e.ctrlKey;
  this.state = e.state;
  this.event_ = e;
  if (e.defaultPrevented) {
    this.preventDefault();
  }
};
goog.events.BrowserEvent.prototype.isButton = function(button) {
  if (!goog.events.BrowserFeature.HAS_W3C_BUTTON) {
    if (this.type == "click") {
      return button == goog.events.BrowserEvent.MouseButton.LEFT;
    } else {
      return !!(this.event_.button & goog.events.BrowserEvent.IEButtonMap[button]);
    }
  } else {
    return this.event_.button == button;
  }
};
goog.events.BrowserEvent.prototype.isMouseActionButton = function() {
  return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) && !(goog.userAgent.WEBKIT && goog.userAgent.MAC && this.ctrlKey);
};
goog.events.BrowserEvent.prototype.stopPropagation = function() {
  goog.events.BrowserEvent.superClass_.stopPropagation.call(this);
  if (this.event_.stopPropagation) {
    this.event_.stopPropagation();
  } else {
    this.event_.cancelBubble = true;
  }
};
goog.events.BrowserEvent.prototype.preventDefault = function() {
  goog.events.BrowserEvent.superClass_.preventDefault.call(this);
  var be = this.event_;
  if (!be.preventDefault) {
    be.returnValue = false;
    if (goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) {
      try {
        var VK_F1 = 112;
        var VK_F12 = 123;
        if (be.ctrlKey || be.keyCode >= VK_F1 && be.keyCode <= VK_F12) {
          be.keyCode = -1;
        }
      } catch (ex) {
      }
    }
  } else {
    be.preventDefault();
  }
};
goog.events.BrowserEvent.prototype.getBrowserEvent = function() {
  return this.event_;
};
goog.provide("goog.events.Listenable");
goog.provide("goog.events.ListenableKey");
goog.require("goog.events.EventId");
goog.forwardDeclare("goog.events.EventLike");
goog.forwardDeclare("goog.events.EventTarget");
goog.events.Listenable = function() {
};
goog.events.Listenable.IMPLEMENTED_BY_PROP = "closure_listenable_" + (Math.random() * 1e6 | 0);
goog.events.Listenable.addImplementation = function(cls) {
  cls.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = true;
};
goog.events.Listenable.isImplementedBy = function(obj) {
  return !!(obj && obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]);
};
goog.events.Listenable.prototype.listen;
goog.events.Listenable.prototype.listenOnce;
goog.events.Listenable.prototype.unlisten;
goog.events.Listenable.prototype.unlistenByKey;
goog.events.Listenable.prototype.dispatchEvent;
goog.events.Listenable.prototype.removeAllListeners;
goog.events.Listenable.prototype.getParentEventTarget;
goog.events.Listenable.prototype.fireListeners;
goog.events.Listenable.prototype.getListeners;
goog.events.Listenable.prototype.getListener;
goog.events.Listenable.prototype.hasListener;
goog.events.ListenableKey = function() {
};
goog.events.ListenableKey.counter_ = 0;
goog.events.ListenableKey.reserveKey = function() {
  return ++goog.events.ListenableKey.counter_;
};
goog.events.ListenableKey.prototype.src;
goog.events.ListenableKey.prototype.type;
goog.events.ListenableKey.prototype.listener;
goog.events.ListenableKey.prototype.capture;
goog.events.ListenableKey.prototype.handler;
goog.events.ListenableKey.prototype.key;
goog.provide("goog.events.Listener");
goog.require("goog.events.ListenableKey");
goog.events.Listener = function(listener, proxy, src, type, capture, opt_handler) {
  if (goog.events.Listener.ENABLE_MONITORING) {
    this.creationStack = (new Error).stack;
  }
  this.listener = listener;
  this.proxy = proxy;
  this.src = src;
  this.type = type;
  this.capture = !!capture;
  this.handler = opt_handler;
  this.key = goog.events.ListenableKey.reserveKey();
  this.callOnce = false;
  this.removed = false;
};
goog.define("goog.events.Listener.ENABLE_MONITORING", false);
goog.events.Listener.prototype.creationStack;
goog.events.Listener.prototype.markAsRemoved = function() {
  this.removed = true;
  this.listener = null;
  this.proxy = null;
  this.src = null;
  this.handler = null;
};
goog.provide("goog.events.ListenerMap");
goog.require("goog.array");
goog.require("goog.events.Listener");
goog.require("goog.object");
goog.events.ListenerMap = function(src) {
  this.src = src;
  this.listeners = {};
  this.typeCount_ = 0;
};
goog.events.ListenerMap.prototype.getTypeCount = function() {
  return this.typeCount_;
};
goog.events.ListenerMap.prototype.getListenerCount = function() {
  var count = 0;
  for (var type in this.listeners) {
    count += this.listeners[type].length;
  }
  return count;
};
goog.events.ListenerMap.prototype.add = function(type, listener, callOnce, opt_useCapture, opt_listenerScope) {
  var typeStr = type.toString();
  var listenerArray = this.listeners[typeStr];
  if (!listenerArray) {
    listenerArray = this.listeners[typeStr] = [];
    this.typeCount_++;
  }
  var listenerObj;
  var index = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, opt_useCapture, opt_listenerScope);
  if (index > -1) {
    listenerObj = listenerArray[index];
    if (!callOnce) {
      listenerObj.callOnce = false;
    }
  } else {
    listenerObj = new goog.events.Listener(listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope);
    listenerObj.callOnce = callOnce;
    listenerArray.push(listenerObj);
  }
  return listenerObj;
};
goog.events.ListenerMap.prototype.remove = function(type, listener, opt_useCapture, opt_listenerScope) {
  var typeStr = type.toString();
  if (!(typeStr in this.listeners)) {
    return false;
  }
  var listenerArray = this.listeners[typeStr];
  var index = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, opt_useCapture, opt_listenerScope);
  if (index > -1) {
    var listenerObj = listenerArray[index];
    listenerObj.markAsRemoved();
    goog.array.removeAt(listenerArray, index);
    if (listenerArray.length == 0) {
      delete this.listeners[typeStr];
      this.typeCount_--;
    }
    return true;
  }
  return false;
};
goog.events.ListenerMap.prototype.removeByKey = function(listener) {
  var type = listener.type;
  if (!(type in this.listeners)) {
    return false;
  }
  var removed = goog.array.remove(this.listeners[type], listener);
  if (removed) {
    listener.markAsRemoved();
    if (this.listeners[type].length == 0) {
      delete this.listeners[type];
      this.typeCount_--;
    }
  }
  return removed;
};
goog.events.ListenerMap.prototype.removeAll = function(opt_type) {
  var typeStr = opt_type && opt_type.toString();
  var count = 0;
  for (var type in this.listeners) {
    if (!typeStr || type == typeStr) {
      var listenerArray = this.listeners[type];
      for (var i = 0; i < listenerArray.length; i++) {
        ++count;
        listenerArray[i].markAsRemoved();
      }
      delete this.listeners[type];
      this.typeCount_--;
    }
  }
  return count;
};
goog.events.ListenerMap.prototype.getListeners = function(type, capture) {
  var listenerArray = this.listeners[type.toString()];
  var rv = [];
  if (listenerArray) {
    for (var i = 0; i < listenerArray.length; ++i) {
      var listenerObj = listenerArray[i];
      if (listenerObj.capture == capture) {
        rv.push(listenerObj);
      }
    }
  }
  return rv;
};
goog.events.ListenerMap.prototype.getListener = function(type, listener, capture, opt_listenerScope) {
  var listenerArray = this.listeners[type.toString()];
  var i = -1;
  if (listenerArray) {
    i = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, capture, opt_listenerScope);
  }
  return i > -1 ? listenerArray[i] : null;
};
goog.events.ListenerMap.prototype.hasListener = function(opt_type, opt_capture) {
  var hasType = goog.isDef(opt_type);
  var typeStr = hasType ? opt_type.toString() : "";
  var hasCapture = goog.isDef(opt_capture);
  return goog.object.some(this.listeners, function(listenerArray, type) {
    for (var i = 0; i < listenerArray.length; ++i) {
      if ((!hasType || listenerArray[i].type == typeStr) && (!hasCapture || listenerArray[i].capture == opt_capture)) {
        return true;
      }
    }
    return false;
  });
};
goog.events.ListenerMap.findListenerIndex_ = function(listenerArray, listener, opt_useCapture, opt_listenerScope) {
  for (var i = 0; i < listenerArray.length; ++i) {
    var listenerObj = listenerArray[i];
    if (!listenerObj.removed && listenerObj.listener == listener && listenerObj.capture == !!opt_useCapture && listenerObj.handler == opt_listenerScope) {
      return i;
    }
  }
  return -1;
};
goog.provide("goog.events");
goog.provide("goog.events.CaptureSimulationMode");
goog.provide("goog.events.Key");
goog.provide("goog.events.ListenableType");
goog.require("goog.asserts");
goog.require("goog.debug.entryPointRegistry");
goog.require("goog.events.BrowserEvent");
goog.require("goog.events.BrowserFeature");
goog.require("goog.events.Listenable");
goog.require("goog.events.ListenerMap");
goog.forwardDeclare("goog.debug.ErrorHandler");
goog.forwardDeclare("goog.events.EventWrapper");
goog.events.Key;
goog.events.ListenableType;
goog.events.LISTENER_MAP_PROP_ = "closure_lm_" + (Math.random() * 1e6 | 0);
goog.events.onString_ = "on";
goog.events.onStringMap_ = {};
goog.events.CaptureSimulationMode = {OFF_AND_FAIL:0, OFF_AND_SILENT:1, ON:2};
goog.define("goog.events.CAPTURE_SIMULATION_MODE", 2);
goog.events.listenerCountEstimate_ = 0;
goog.events.listen = function(src, type, listener, opt_capt, opt_handler) {
  if (goog.isArray(type)) {
    for (var i = 0; i < type.length; i++) {
      goog.events.listen(src, type[i], listener, opt_capt, opt_handler);
    }
    return null;
  }
  listener = goog.events.wrapListener(listener);
  if (goog.events.Listenable.isImplementedBy(src)) {
    return src.listen(type, listener, opt_capt, opt_handler);
  } else {
    return goog.events.listen_(src, type, listener, false, opt_capt, opt_handler);
  }
};
goog.events.listen_ = function(src, type, listener, callOnce, opt_capt, opt_handler) {
  if (!type) {
    throw Error("Invalid event type");
  }
  var capture = !!opt_capt;
  if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {
    if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.OFF_AND_FAIL) {
      goog.asserts.fail("Can not register capture listener in IE8-.");
      return null;
    } else {
      if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.OFF_AND_SILENT) {
        return null;
      }
    }
  }
  var listenerMap = goog.events.getListenerMap_(src);
  if (!listenerMap) {
    src[goog.events.LISTENER_MAP_PROP_] = listenerMap = new goog.events.ListenerMap(src);
  }
  var listenerObj = listenerMap.add(type, listener, callOnce, opt_capt, opt_handler);
  if (listenerObj.proxy) {
    return listenerObj;
  }
  var proxy = goog.events.getProxy();
  listenerObj.proxy = proxy;
  proxy.src = src;
  proxy.listener = listenerObj;
  if (src.addEventListener) {
    src.addEventListener(type.toString(), proxy, capture);
  } else {
    if (src.attachEvent) {
      src.attachEvent(goog.events.getOnString_(type.toString()), proxy);
    } else {
      throw Error("addEventListener and attachEvent are unavailable.");
    }
  }
  goog.events.listenerCountEstimate_++;
  return listenerObj;
};
goog.events.getProxy = function() {
  var proxyCallbackFunction = goog.events.handleBrowserEvent_;
  var f = goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? function(eventObject) {
    return proxyCallbackFunction.call(f.src, f.listener, eventObject);
  } : function(eventObject) {
    var v = proxyCallbackFunction.call(f.src, f.listener, eventObject);
    if (!v) {
      return v;
    }
  };
  return f;
};
goog.events.listenOnce = function(src, type, listener, opt_capt, opt_handler) {
  if (goog.isArray(type)) {
    for (var i = 0; i < type.length; i++) {
      goog.events.listenOnce(src, type[i], listener, opt_capt, opt_handler);
    }
    return null;
  }
  listener = goog.events.wrapListener(listener);
  if (goog.events.Listenable.isImplementedBy(src)) {
    return src.listenOnce(type, listener, opt_capt, opt_handler);
  } else {
    return goog.events.listen_(src, type, listener, true, opt_capt, opt_handler);
  }
};
goog.events.listenWithWrapper = function(src, wrapper, listener, opt_capt, opt_handler) {
  wrapper.listen(src, listener, opt_capt, opt_handler);
};
goog.events.unlisten = function(src, type, listener, opt_capt, opt_handler) {
  if (goog.isArray(type)) {
    for (var i = 0; i < type.length; i++) {
      goog.events.unlisten(src, type[i], listener, opt_capt, opt_handler);
    }
    return null;
  }
  listener = goog.events.wrapListener(listener);
  if (goog.events.Listenable.isImplementedBy(src)) {
    return src.unlisten(type, listener, opt_capt, opt_handler);
  }
  if (!src) {
    return false;
  }
  var capture = !!opt_capt;
  var listenerMap = goog.events.getListenerMap_(src);
  if (listenerMap) {
    var listenerObj = listenerMap.getListener(type, listener, capture, opt_handler);
    if (listenerObj) {
      return goog.events.unlistenByKey(listenerObj);
    }
  }
  return false;
};
goog.events.unlistenByKey = function(key) {
  if (goog.isNumber(key)) {
    return false;
  }
  var listener = key;
  if (!listener || listener.removed) {
    return false;
  }
  var src = listener.src;
  if (goog.events.Listenable.isImplementedBy(src)) {
    return src.unlistenByKey(listener);
  }
  var type = listener.type;
  var proxy = listener.proxy;
  if (src.removeEventListener) {
    src.removeEventListener(type, proxy, listener.capture);
  } else {
    if (src.detachEvent) {
      src.detachEvent(goog.events.getOnString_(type), proxy);
    }
  }
  goog.events.listenerCountEstimate_--;
  var listenerMap = goog.events.getListenerMap_(src);
  if (listenerMap) {
    listenerMap.removeByKey(listener);
    if (listenerMap.getTypeCount() == 0) {
      listenerMap.src = null;
      src[goog.events.LISTENER_MAP_PROP_] = null;
    }
  } else {
    listener.markAsRemoved();
  }
  return true;
};
goog.events.unlistenWithWrapper = function(src, wrapper, listener, opt_capt, opt_handler) {
  wrapper.unlisten(src, listener, opt_capt, opt_handler);
};
goog.events.removeAll = function(obj, opt_type) {
  if (!obj) {
    return 0;
  }
  if (goog.events.Listenable.isImplementedBy(obj)) {
    return obj.removeAllListeners(opt_type);
  }
  var listenerMap = goog.events.getListenerMap_(obj);
  if (!listenerMap) {
    return 0;
  }
  var count = 0;
  var typeStr = opt_type && opt_type.toString();
  for (var type in listenerMap.listeners) {
    if (!typeStr || type == typeStr) {
      var listeners = listenerMap.listeners[type].concat();
      for (var i = 0; i < listeners.length; ++i) {
        if (goog.events.unlistenByKey(listeners[i])) {
          ++count;
        }
      }
    }
  }
  return count;
};
goog.events.getListeners = function(obj, type, capture) {
  if (goog.events.Listenable.isImplementedBy(obj)) {
    return obj.getListeners(type, capture);
  } else {
    if (!obj) {
      return [];
    }
    var listenerMap = goog.events.getListenerMap_(obj);
    return listenerMap ? listenerMap.getListeners(type, capture) : [];
  }
};
goog.events.getListener = function(src, type, listener, opt_capt, opt_handler) {
  type = type;
  listener = goog.events.wrapListener(listener);
  var capture = !!opt_capt;
  if (goog.events.Listenable.isImplementedBy(src)) {
    return src.getListener(type, listener, capture, opt_handler);
  }
  if (!src) {
    return null;
  }
  var listenerMap = goog.events.getListenerMap_(src);
  if (listenerMap) {
    return listenerMap.getListener(type, listener, capture, opt_handler);
  }
  return null;
};
goog.events.hasListener = function(obj, opt_type, opt_capture) {
  if (goog.events.Listenable.isImplementedBy(obj)) {
    return obj.hasListener(opt_type, opt_capture);
  }
  var listenerMap = goog.events.getListenerMap_(obj);
  return !!listenerMap && listenerMap.hasListener(opt_type, opt_capture);
};
goog.events.expose = function(e) {
  var str = [];
  for (var key in e) {
    if (e[key] && e[key].id) {
      str.push(key + " = " + e[key] + " (" + e[key].id + ")");
    } else {
      str.push(key + " = " + e[key]);
    }
  }
  return str.join("\n");
};
goog.events.getOnString_ = function(type) {
  if (type in goog.events.onStringMap_) {
    return goog.events.onStringMap_[type];
  }
  return goog.events.onStringMap_[type] = goog.events.onString_ + type;
};
goog.events.fireListeners = function(obj, type, capture, eventObject) {
  if (goog.events.Listenable.isImplementedBy(obj)) {
    return obj.fireListeners(type, capture, eventObject);
  }
  return goog.events.fireListeners_(obj, type, capture, eventObject);
};
goog.events.fireListeners_ = function(obj, type, capture, eventObject) {
  var retval = true;
  var listenerMap = goog.events.getListenerMap_(obj);
  if (listenerMap) {
    var listenerArray = listenerMap.listeners[type.toString()];
    if (listenerArray) {
      listenerArray = listenerArray.concat();
      for (var i = 0; i < listenerArray.length; i++) {
        var listener = listenerArray[i];
        if (listener && listener.capture == capture && !listener.removed) {
          var result = goog.events.fireListener(listener, eventObject);
          retval = retval && result !== false;
        }
      }
    }
  }
  return retval;
};
goog.events.fireListener = function(listener, eventObject) {
  var listenerFn = listener.listener;
  var listenerHandler = listener.handler || listener.src;
  if (listener.callOnce) {
    goog.events.unlistenByKey(listener);
  }
  return listenerFn.call(listenerHandler, eventObject);
};
goog.events.getTotalListenerCount = function() {
  return goog.events.listenerCountEstimate_;
};
goog.events.dispatchEvent = function(src, e) {
  goog.asserts.assert(goog.events.Listenable.isImplementedBy(src), "Can not use goog.events.dispatchEvent with " + "non-goog.events.Listenable instance.");
  return src.dispatchEvent(e);
};
goog.events.protectBrowserEventEntryPoint = function(errorHandler) {
  goog.events.handleBrowserEvent_ = errorHandler.protectEntryPoint(goog.events.handleBrowserEvent_);
};
goog.events.handleBrowserEvent_ = function(listener, opt_evt) {
  if (listener.removed) {
    return true;
  }
  if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {
    var ieEvent = opt_evt || goog.getObjectByName("window.event");
    var evt = new goog.events.BrowserEvent(ieEvent, this);
    var retval = true;
    if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.ON) {
      if (!goog.events.isMarkedIeEvent_(ieEvent)) {
        goog.events.markIeEvent_(ieEvent);
        var ancestors = [];
        for (var parent = evt.currentTarget; parent; parent = parent.parentNode) {
          ancestors.push(parent);
        }
        var type = listener.type;
        for (var i = ancestors.length - 1; !evt.propagationStopped_ && i >= 0; i--) {
          evt.currentTarget = ancestors[i];
          var result = goog.events.fireListeners_(ancestors[i], type, true, evt);
          retval = retval && result;
        }
        for (var i = 0; !evt.propagationStopped_ && i < ancestors.length; i++) {
          evt.currentTarget = ancestors[i];
          var result = goog.events.fireListeners_(ancestors[i], type, false, evt);
          retval = retval && result;
        }
      }
    } else {
      retval = goog.events.fireListener(listener, evt);
    }
    return retval;
  }
  return goog.events.fireListener(listener, new goog.events.BrowserEvent(opt_evt, this));
};
goog.events.markIeEvent_ = function(e) {
  var useReturnValue = false;
  if (e.keyCode == 0) {
    try {
      e.keyCode = -1;
      return;
    } catch (ex) {
      useReturnValue = true;
    }
  }
  if (useReturnValue || e.returnValue == undefined) {
    e.returnValue = true;
  }
};
goog.events.isMarkedIeEvent_ = function(e) {
  return e.keyCode < 0 || e.returnValue != undefined;
};
goog.events.uniqueIdCounter_ = 0;
goog.events.getUniqueId = function(identifier) {
  return identifier + "_" + goog.events.uniqueIdCounter_++;
};
goog.events.getListenerMap_ = function(src) {
  var listenerMap = src[goog.events.LISTENER_MAP_PROP_];
  return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null;
};
goog.events.LISTENER_WRAPPER_PROP_ = "__closure_events_fn_" + (Math.random() * 1e9 >>> 0);
goog.events.wrapListener = function(listener) {
  goog.asserts.assert(listener, "Listener can not be null.");
  if (goog.isFunction(listener)) {
    return listener;
  }
  goog.asserts.assert(listener.handleEvent, "An object listener must have handleEvent method.");
  if (!listener[goog.events.LISTENER_WRAPPER_PROP_]) {
    listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) {
      return listener.handleEvent(e);
    };
  }
  return listener[goog.events.LISTENER_WRAPPER_PROP_];
};
goog.debug.entryPointRegistry.register(function(transformer) {
  goog.events.handleBrowserEvent_ = transformer(goog.events.handleBrowserEvent_);
});
goog.provide("uno.api.celogger");
goog.require("goog.debug.Logger");
(function() {
  var celogger = uno && uno.api && (uno.api.celogger || {});
  var log = goog && goog.debug && (goog.debug.Logger.getLogger("uno.api.celogger") || {config:console.log.bind(console), info:console.log.bind(console)});
  celogger.wrap = function(EN) {
    celogger.EN = {setup:EN.setup.bind(EN), cleanup:EN.cleanup.bind(EN), execCommand:EN.execCommand.bind(EN), queryCommandEnabled:EN.queryCommandEnabled.bind(EN), queryCommandValue:EN.queryCommandValue.bind(EN), queryCommandState:EN.queryCommandState.bind(EN), notify:EN.notify.bind(EN)};
    EN.setup = function(opt) {
      var obj = typeof opt === "string" ? JSON.parse(opt) : opt;
      log.config("EN.setup(" + JSON.stringify(obj, null, 2) + ")");
      var result = celogger.EN.setup(opt);
      log.info("EN.setup returning: " + result + "\n\n\n");
      return result;
    };
    EN.cleanup = function() {
      log.info("EN.cleanup()");
      var result = celogger.EN.cleanup();
      log.info("EN.cleanup returning: " + result + "\n\n\n");
      return result;
    };
    EN.execCommand = function(command, value, options) {
      logCommand("EN.execCommand", command, value, options);
      var result = celogger.EN.execCommand(command, value, options);
      log.info("EN.execCommand '" + command + "' returning: " + result + "\n\n\n");
      return result;
    };
    EN.queryCommandEnabled = function(command, options) {
      logCommand("EN.queryCommandEnabled", command, options);
      var result = celogger.EN.queryCommandEnabled(command, options);
      log.info("EN.queryCommandEnabled '" + command + "' returning: " + result + "\n\n\n");
      return result;
    };
    EN.queryCommandValue = function(command, options) {
      logCommand("EN.queryCommandValue", command, options);
      var result = celogger.EN.queryCommandValue(command, options);
      log.info("EN.queryCommandValue '" + command + "' returning: " + result + "\n\n\n");
      return result;
    };
    EN.queryCommandState = function(command, options) {
      logCommand("EN.queryCommandState", command, options);
      var result = celogger.EN.queryCommandState(command, options);
      log.info("EN.queryCommandState '" + command + "' returning: " + result + "\n\n\n");
      return result;
    };
    EN.notify = function(name, info) {
      log.info("NOTIFICATION : " + name + (goog.isDef(info) ? " : " + JSON.stringify(info, null, 2) : "") + "\n\n\n");
      return celogger.EN.notify(name, info);
    };
  };
  function logCommand(method, command, value, options) {
    var message = method + "('" + command + "'";
    if (value === undefined) {
      message += options === undefined ? "" : ", undefined, " + options;
    } else {
      if (value && typeof value === "object") {
        value = JSON.stringify(value, null, 2);
      } else {
        if (typeof value === "string" && !/^[\{\[]/.test(value) && !/^(true|false|[\.0-9]+)$/.test(value)) {
          value = "'" + value.replace(/'/g, "\\'") + "'";
        }
      }
      if (options && typeof options === "object") {
        options = JSON.stringify(options, null, 2);
      }
      message += ", " + value + (options === undefined ? "" : ", " + options);
    }
    message += ")";
    log.info(message);
  }
})();
goog.provide("uno.Auth");
goog.require("goog.debug.Logger");
(function() {
  var log = goog.debug.Logger.getLogger("uno.Auth");
  var Auth = uno.Auth = function(options) {
    this.router = options.router;
    this.providers = {};
  };
  Auth.ERROR_CODE_NO_AUTH = 2001;
  Auth.ERROR_CODE_INVALID_AUTH = 2002;
  Auth.ERROR_CODE_NETWORK_ERROR = 2003;
  Auth.ERROR_CODE_UNKNOWN = 2004;
  Auth.prototype.getTokenAsync = function(providerName, refresh, askUserForPermission) {
    var provider = this.providers[providerName] || this.addProvider(providerName);
    if (refresh) {
      provider.token = null;
    }
    if (provider.token) {
      return Promise.resolve(provider.token);
    }
    if (provider.request) {
      return provider.request;
    }
    provider.request = this.router.toHostAsync("requestAuth", {serviceName:provider.name, refresh:!!refresh, askUserForPermission:!!askUserForPermission}).then(function(response) {
      provider.request = null;
      provider.token = response.token;
      provider.lastRefreshed = response.lastRefreshed;
      provider.lastErrorCode = provider.errorCode;
      provider.errorCode = response.errorCode;
      if (response.errorCode) {
        var err = new Error("Auth Error");
        err.provider = providerName;
        err.errorCode = response.errorCode;
        throw err;
      } else {
        return response.token;
      }
    }).catch(function(error) {
      provider.request = null;
      provider.errorCode = error.errorCode;
      throw error;
    });
    return provider.request;
  };
  Auth.prototype.getLastErrorCode = function(providerName) {
    var provider = this.providers[providerName];
    return provider && provider.lastErrorCode;
  };
  Auth.prototype.addProvider = function(name) {
    this.providers[name] = {name:name, request:null, token:null, lastErrorCode:null, errorCode:null, lastRefreshed:null};
    return this.providers[name];
  };
})();
goog.provide("uno.Cache");
goog.require("goog.debug.Logger");
(function() {
  var log = goog.debug.Logger.getLogger("uno.Cache");
  var Cache = uno.Cache = function(options) {
    this.router = options.router;
    this.diskEnabled = false;
    this.memCache = {};
  };
  Cache.prototype.readMem = function(key) {
    return this.memCache[key];
  };
  Cache.prototype.writeMem = function(key, value) {
    this.memCache[key] = value;
  };
  Cache.prototype.readDiskAsync = function(key) {
    if (this.diskEnabled) {
      return this.router.toHostAsync("getFromCache", {href:key}).then(function(result) {
        return result.data ? result.data.data || result.data : result.data;
      });
    }
    return Promise.resolve();
  };
  Cache.prototype.writeDisk = function(key, value) {
    if (this.diskEnabled) {
      this.router.toHostAsync("saveInCache", {href:key, data:value});
    }
  };
  Cache.prototype.write = function(key, value) {
    this.writeMem(key, value);
    this.writeDisk(key, value);
  };
  Cache.prototype.enableDisk = function() {
    this.diskEnabled = true;
  };
  Cache.prototype.disableDisk = function() {
    this.diskEnabled = false;
  };
})();
goog.provide("uno.debug");
(function() {
  window.__timers__ = [];
  window.start = function(name) {
    if (!DEBUG) {
      return;
    }
    console.log(pad(__timers__.length) + "%c [START TIMER] [%s]", "color: #aaa;", name);
    __timers__.push({name:name, time:performance.now()});
  };
  window.stop = function(name) {
    if (!DEBUG) {
      return;
    }
    var timer = __timers__.pop() || {};
    if (timer.name !== name) {
      console.warn('Timer name "' + name + '" did not match "' + timer.name + '"! Are you missing a call to start or stop?');
    }
    var duration = performance.now() - timer.time;
    var color = duration < 0.5 ? "#aaa" : duration < 50 ? "green" : duration < 500 ? "darkorange" : "red";
    console.log(pad(__timers__.length) + "%c [%c%s sec%c] [%s]", "color: " + color + ";", "color: " + color + ";font-weight: bold;", format(duration), "color: " + color + ";", timer.name);
  };
  function pad(depth) {
    var padding = "";
    for (var i = 0; i < depth; i++) {
      padding += "\t";
    }
    return padding;
  }
  function format(num) {
    var text = (num / 1000).toFixed(3);
    return text.length === 5 ? "  " + text : text.length === 6 ? " " + text : text;
  }
})();
goog.provide("goog.dom.classes");
goog.require("goog.array");
goog.dom.classes.set = function(element, className) {
  element.className = className;
};
goog.dom.classes.get = function(element) {
  var className = element.className;
  return goog.isString(className) && className.match(/\S+/g) || [];
};
goog.dom.classes.add = function(element, var_args) {
  var classes = goog.dom.classes.get(element);
  var args = goog.array.slice(arguments, 1);
  var expectedCount = classes.length + args.length;
  goog.dom.classes.add_(classes, args);
  goog.dom.classes.set(element, classes.join(" "));
  return classes.length == expectedCount;
};
goog.dom.classes.remove = function(element, var_args) {
  var classes = goog.dom.classes.get(element);
  var args = goog.array.slice(arguments, 1);
  var newClasses = goog.dom.classes.getDifference_(classes, args);
  goog.dom.classes.set(element, newClasses.join(" "));
  return newClasses.length == classes.length - args.length;
};
goog.dom.classes.add_ = function(classes, args) {
  for (var i = 0; i < args.length; i++) {
    if (!goog.array.contains(classes, args[i])) {
      classes.push(args[i]);
    }
  }
};
goog.dom.classes.getDifference_ = function(arr1, arr2) {
  return goog.array.filter(arr1, function(item) {
    return !goog.array.contains(arr2, item);
  });
};
goog.dom.classes.swap = function(element, fromClass, toClass) {
  var classes = goog.dom.classes.get(element);
  var removed = false;
  for (var i = 0; i < classes.length; i++) {
    if (classes[i] == fromClass) {
      goog.array.splice(classes, i--, 1);
      removed = true;
    }
  }
  if (removed) {
    classes.push(toClass);
    goog.dom.classes.set(element, classes.join(" "));
  }
  return removed;
};
goog.dom.classes.addRemove = function(element, classesToRemove, classesToAdd) {
  var classes = goog.dom.classes.get(element);
  if (goog.isString(classesToRemove)) {
    goog.array.remove(classes, classesToRemove);
  } else {
    if (goog.isArray(classesToRemove)) {
      classes = goog.dom.classes.getDifference_(classes, classesToRemove);
    }
  }
  if (goog.isString(classesToAdd) && !goog.array.contains(classes, classesToAdd)) {
    classes.push(classesToAdd);
  } else {
    if (goog.isArray(classesToAdd)) {
      goog.dom.classes.add_(classes, classesToAdd);
    }
  }
  goog.dom.classes.set(element, classes.join(" "));
};
goog.dom.classes.has = function(element, className) {
  return goog.array.contains(goog.dom.classes.get(element), className);
};
goog.dom.classes.enable = function(element, className, enabled) {
  if (enabled) {
    goog.dom.classes.add(element, className);
  } else {
    goog.dom.classes.remove(element, className);
  }
};
goog.dom.classes.toggle = function(element, className) {
  var add = !goog.dom.classes.has(element, className);
  goog.dom.classes.enable(element, className, add);
  return add;
};
goog.provide("goog.log");
goog.provide("goog.log.Level");
goog.provide("goog.log.LogRecord");
goog.provide("goog.log.Logger");
goog.require("goog.debug");
goog.require("goog.debug.LogManager");
goog.require("goog.debug.LogRecord");
goog.require("goog.debug.Logger");
goog.define("goog.log.ENABLED", goog.debug.LOGGING_ENABLED);
goog.log.ROOT_LOGGER_NAME = goog.debug.Logger.ROOT_LOGGER_NAME;
goog.log.Logger = goog.debug.Logger;
goog.log.Level = goog.debug.Logger.Level;
goog.log.LogRecord = goog.debug.LogRecord;
goog.log.getLogger = function(name, opt_level) {
  if (goog.log.ENABLED) {
    var logger = goog.debug.LogManager.getLogger(name);
    if (opt_level && logger) {
      logger.setLevel(opt_level);
    }
    return logger;
  } else {
    return null;
  }
};
goog.log.addHandler = function(logger, handler) {
  if (goog.log.ENABLED && logger) {
    logger.addHandler(handler);
  }
};
goog.log.removeHandler = function(logger, handler) {
  if (goog.log.ENABLED && logger) {
    return logger.removeHandler(handler);
  } else {
    return false;
  }
};
goog.log.log = function(logger, level, msg, opt_exception) {
  if (goog.log.ENABLED && logger) {
    logger.log(level, msg, opt_exception);
  }
};
goog.log.error = function(logger, msg, opt_exception) {
  if (goog.log.ENABLED && logger) {
    logger.severe(msg, opt_exception);
  }
};
goog.log.warning = function(logger, msg, opt_exception) {
  if (goog.log.ENABLED && logger) {
    logger.warning(msg, opt_exception);
  }
};
goog.log.info = function(logger, msg, opt_exception) {
  if (goog.log.ENABLED && logger) {
    logger.info(msg, opt_exception);
  }
};
goog.log.fine = function(logger, msg, opt_exception) {
  if (goog.log.ENABLED && logger) {
    logger.fine(msg, opt_exception);
  }
};
goog.provide("goog.dom.SavedRange");
goog.require("goog.Disposable");
goog.require("goog.log");
goog.dom.SavedRange = function() {
  goog.Disposable.call(this);
};
goog.inherits(goog.dom.SavedRange, goog.Disposable);
goog.dom.SavedRange.logger_ = goog.log.getLogger("goog.dom.SavedRange");
goog.dom.SavedRange.prototype.restore = function(opt_stayAlive) {
  if (this.isDisposed()) {
    goog.log.error(goog.dom.SavedRange.logger_, "Disposed SavedRange objects cannot be restored.");
  }
  var range = this.restoreInternal();
  if (!opt_stayAlive) {
    this.dispose();
  }
  return range;
};
goog.dom.SavedRange.prototype.restoreInternal = goog.abstractMethod;
goog.provide("goog.dom.SavedCaretRange");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.SavedRange");
goog.require("goog.dom.TagName");
goog.require("goog.string");
goog.dom.SavedCaretRange = function(range) {
  goog.dom.SavedRange.call(this);
  this.startCaretId_ = goog.string.createUniqueString();
  this.endCaretId_ = goog.string.createUniqueString();
  this.reversed_ = range.isReversed();
  this.dom_ = goog.dom.getDomHelper(range.getDocument());
  range.surroundWithNodes(this.createCaret_(true), this.createCaret_(false));
};
goog.inherits(goog.dom.SavedCaretRange, goog.dom.SavedRange);
goog.dom.SavedCaretRange.prototype.toAbstractRange = function() {
  var range = null;
  var startCaret = this.getCaret(true);
  var endCaret = this.getCaret(false);
  if (startCaret && endCaret) {
    range = goog.dom.Range.createFromNodes(startCaret, 0, endCaret, 0);
  }
  return range;
};
goog.dom.SavedCaretRange.prototype.getCaret = function(start) {
  return this.dom_.getElement(start ? this.startCaretId_ : this.endCaretId_);
};
goog.dom.SavedCaretRange.prototype.removeCarets = function(opt_range) {
  goog.dom.removeNode(this.getCaret(true));
  goog.dom.removeNode(this.getCaret(false));
  return opt_range;
};
goog.dom.SavedCaretRange.prototype.setRestorationDocument = function(doc) {
  this.dom_.setDocument(doc);
};
goog.dom.SavedCaretRange.prototype.restoreInternal = function() {
  var range = null;
  var anchorCaret = this.getCaret(!this.reversed_);
  var focusCaret = this.getCaret(this.reversed_);
  if (anchorCaret && focusCaret) {
    var anchorNode = anchorCaret.parentNode;
    var anchorOffset = goog.array.indexOf(anchorNode.childNodes, anchorCaret);
    var focusNode = focusCaret.parentNode;
    var focusOffset = goog.array.indexOf(focusNode.childNodes, focusCaret);
    if (focusNode == anchorNode) {
      if (this.reversed_) {
        anchorOffset--;
      } else {
        focusOffset--;
      }
    }
    range = goog.dom.Range.createFromNodes(anchorNode, anchorOffset, focusNode, focusOffset);
    range = this.removeCarets(range);
    range.select();
  } else {
    this.removeCarets();
  }
  return range;
};
goog.dom.SavedCaretRange.prototype.disposeInternal = function() {
  this.removeCarets();
  this.dom_ = null;
};
goog.dom.SavedCaretRange.prototype.createCaret_ = function(start) {
  return this.dom_.createDom(goog.dom.TagName.SPAN, {"id":start ? this.startCaretId_ : this.endCaretId_});
};
goog.dom.SavedCaretRange.CARET_REGEX = /<span\s+id="?goog_\d+"?><\/span>/ig;
goog.dom.SavedCaretRange.htmlEqual = function(str1, str2) {
  return str1 == str2 || str1.replace(goog.dom.SavedCaretRange.CARET_REGEX, "") == str2.replace(goog.dom.SavedCaretRange.CARET_REGEX, "");
};
goog.provide("goog.functions");
goog.functions.constant = function(retValue) {
  return function() {
    return retValue;
  };
};
goog.functions.FALSE = goog.functions.constant(false);
goog.functions.TRUE = goog.functions.constant(true);
goog.functions.NULL = goog.functions.constant(null);
goog.functions.identity = function(opt_returnValue, var_args) {
  return opt_returnValue;
};
goog.functions.error = function(message) {
  return function() {
    throw Error(message);
  };
};
goog.functions.fail = function(err) {
  return function() {
    throw err;
  };
};
goog.functions.lock = function(f, opt_numArgs) {
  opt_numArgs = opt_numArgs || 0;
  return function() {
    return f.apply(this, Array.prototype.slice.call(arguments, 0, opt_numArgs));
  };
};
goog.functions.nth = function(n) {
  return function() {
    return arguments[n];
  };
};
goog.functions.partialRight = function(fn, var_args) {
  var rightArgs = Array.prototype.slice.call(arguments, 1);
  return function() {
    var newArgs = Array.prototype.slice.call(arguments);
    newArgs.push.apply(newArgs, rightArgs);
    return fn.apply(this, newArgs);
  };
};
goog.functions.withReturnValue = function(f, retValue) {
  return goog.functions.sequence(f, goog.functions.constant(retValue));
};
goog.functions.equalTo = function(value, opt_useLooseComparison) {
  return function(other) {
    return opt_useLooseComparison ? value == other : value === other;
  };
};
goog.functions.compose = function(fn, var_args) {
  var functions = arguments;
  var length = functions.length;
  return function() {
    var result;
    if (length) {
      result = functions[length - 1].apply(this, arguments);
    }
    for (var i = length - 2; i >= 0; i--) {
      result = functions[i].call(this, result);
    }
    return result;
  };
};
goog.functions.sequence = function(var_args) {
  var functions = arguments;
  var length = functions.length;
  return function() {
    var result;
    for (var i = 0; i < length; i++) {
      result = functions[i].apply(this, arguments);
    }
    return result;
  };
};
goog.functions.and = function(var_args) {
  var functions = arguments;
  var length = functions.length;
  return function() {
    for (var i = 0; i < length; i++) {
      if (!functions[i].apply(this, arguments)) {
        return false;
      }
    }
    return true;
  };
};
goog.functions.or = function(var_args) {
  var functions = arguments;
  var length = functions.length;
  return function() {
    for (var i = 0; i < length; i++) {
      if (functions[i].apply(this, arguments)) {
        return true;
      }
    }
    return false;
  };
};
goog.functions.not = function(f) {
  return function() {
    return !f.apply(this, arguments);
  };
};
goog.functions.create = function(constructor, var_args) {
  var temp = function() {
  };
  temp.prototype = constructor.prototype;
  var obj = new temp;
  constructor.apply(obj, Array.prototype.slice.call(arguments, 1));
  return obj;
};
goog.define("goog.functions.CACHE_RETURN_VALUE", true);
goog.functions.cacheReturnValue = function(fn) {
  var called = false;
  var value;
  return function() {
    if (!goog.functions.CACHE_RETURN_VALUE) {
      return fn();
    }
    if (!called) {
      value = fn();
      called = true;
    }
    return value;
  };
};
goog.functions.once = function(f) {
  var inner = f;
  return function() {
    if (inner) {
      var tmp = inner;
      inner = null;
      tmp();
    }
  };
};
goog.functions.debounce = function(f, interval, opt_scope) {
  var timeout = 0;
  return function(var_args) {
    goog.global.clearTimeout(timeout);
    var args = arguments;
    timeout = goog.global.setTimeout(function() {
      f.apply(opt_scope, args);
    }, interval);
  };
};
goog.functions.throttle = function(f, interval, opt_scope) {
  var timeout = 0;
  var shouldFire = false;
  var args = [];
  var handleTimeout = function() {
    timeout = 0;
    if (shouldFire) {
      shouldFire = false;
      fire();
    }
  };
  var fire = function() {
    timeout = goog.global.setTimeout(handleTimeout, interval);
    f.apply(opt_scope, args);
  };
  return function(var_args) {
    args = arguments;
    if (!timeout) {
      fire();
    } else {
      shouldFire = true;
    }
  };
};
goog.functions.rateLimit = function(f, interval, opt_scope) {
  var timeout = 0;
  var handleTimeout = function() {
    timeout = 0;
  };
  return function(var_args) {
    if (!timeout) {
      timeout = goog.global.setTimeout(handleTimeout, interval);
      f.apply(opt_scope, arguments);
    }
  };
};
goog.provide("goog.iter");
goog.provide("goog.iter.Iterable");
goog.provide("goog.iter.Iterator");
goog.provide("goog.iter.StopIteration");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.functions");
goog.require("goog.math");
goog.iter.Iterable;
goog.iter.StopIteration = "StopIteration" in goog.global ? goog.global["StopIteration"] : {message:"StopIteration", stack:""};
goog.iter.Iterator = function() {
};
goog.iter.Iterator.prototype.next = function() {
  throw goog.iter.StopIteration;
};
goog.iter.Iterator.prototype.__iterator__ = function(opt_keys) {
  return this;
};
goog.iter.toIterator = function(iterable) {
  if (iterable instanceof goog.iter.Iterator) {
    return iterable;
  }
  if (typeof iterable.__iterator__ == "function") {
    return iterable.__iterator__(false);
  }
  if (goog.isArrayLike(iterable)) {
    var i = 0;
    var newIter = new goog.iter.Iterator;
    newIter.next = function() {
      while (true) {
        if (i >= iterable.length) {
          throw goog.iter.StopIteration;
        }
        if (!(i in iterable)) {
          i++;
          continue;
        }
        return iterable[i++];
      }
    };
    return newIter;
  }
  throw Error("Not implemented");
};
goog.iter.forEach = function(iterable, f, opt_obj) {
  if (goog.isArrayLike(iterable)) {
    try {
      goog.array.forEach(iterable, f, opt_obj);
    } catch (ex) {
      if (ex !== goog.iter.StopIteration) {
        throw ex;
      }
    }
  } else {
    iterable = goog.iter.toIterator(iterable);
    try {
      while (true) {
        f.call(opt_obj, iterable.next(), undefined, iterable);
      }
    } catch (ex$2) {
      if (ex$2 !== goog.iter.StopIteration) {
        throw ex$2;
      }
    }
  }
};
goog.iter.filter = function(iterable, f, opt_obj) {
  var iterator = goog.iter.toIterator(iterable);
  var newIter = new goog.iter.Iterator;
  newIter.next = function() {
    while (true) {
      var val = iterator.next();
      if (f.call(opt_obj, val, undefined, iterator)) {
        return val;
      }
    }
  };
  return newIter;
};
goog.iter.filterFalse = function(iterable, f, opt_obj) {
  return goog.iter.filter(iterable, goog.functions.not(f), opt_obj);
};
goog.iter.range = function(startOrStop, opt_stop, opt_step) {
  var start = 0;
  var stop = startOrStop;
  var step = opt_step || 1;
  if (arguments.length > 1) {
    start = startOrStop;
    stop = opt_stop;
  }
  if (step == 0) {
    throw Error("Range step argument must not be zero");
  }
  var newIter = new goog.iter.Iterator;
  newIter.next = function() {
    if (step > 0 && start >= stop || step < 0 && start <= stop) {
      throw goog.iter.StopIteration;
    }
    var rv = start;
    start += step;
    return rv;
  };
  return newIter;
};
goog.iter.join = function(iterable, deliminator) {
  return goog.iter.toArray(iterable).join(deliminator);
};
goog.iter.map = function(iterable, f, opt_obj) {
  var iterator = goog.iter.toIterator(iterable);
  var newIter = new goog.iter.Iterator;
  newIter.next = function() {
    var val = iterator.next();
    return f.call(opt_obj, val, undefined, iterator);
  };
  return newIter;
};
goog.iter.reduce = function(iterable, f, val, opt_obj) {
  var rval = val;
  goog.iter.forEach(iterable, function(val) {
    rval = f.call(opt_obj, rval, val);
  });
  return rval;
};
goog.iter.some = function(iterable, f, opt_obj) {
  iterable = goog.iter.toIterator(iterable);
  try {
    while (true) {
      if (f.call(opt_obj, iterable.next(), undefined, iterable)) {
        return true;
      }
    }
  } catch (ex) {
    if (ex !== goog.iter.StopIteration) {
      throw ex;
    }
  }
  return false;
};
goog.iter.every = function(iterable, f, opt_obj) {
  iterable = goog.iter.toIterator(iterable);
  try {
    while (true) {
      if (!f.call(opt_obj, iterable.next(), undefined, iterable)) {
        return false;
      }
    }
  } catch (ex) {
    if (ex !== goog.iter.StopIteration) {
      throw ex;
    }
  }
  return true;
};
goog.iter.chain = function(var_args) {
  return goog.iter.chainFromIterable(arguments);
};
goog.iter.chainFromIterable = function(iterable) {
  var iterator = goog.iter.toIterator(iterable);
  var iter = new goog.iter.Iterator;
  var current = null;
  iter.next = function() {
    while (true) {
      if (current == null) {
        var it = iterator.next();
        current = goog.iter.toIterator(it);
      }
      try {
        return current.next();
      } catch (ex) {
        if (ex !== goog.iter.StopIteration) {
          throw ex;
        }
        current = null;
      }
    }
  };
  return iter;
};
goog.iter.dropWhile = function(iterable, f, opt_obj) {
  var iterator = goog.iter.toIterator(iterable);
  var newIter = new goog.iter.Iterator;
  var dropping = true;
  newIter.next = function() {
    while (true) {
      var val = iterator.next();
      if (dropping && f.call(opt_obj, val, undefined, iterator)) {
        continue;
      } else {
        dropping = false;
      }
      return val;
    }
  };
  return newIter;
};
goog.iter.takeWhile = function(iterable, f, opt_obj) {
  var iterator = goog.iter.toIterator(iterable);
  var iter = new goog.iter.Iterator;
  iter.next = function() {
    var val = iterator.next();
    if (f.call(opt_obj, val, undefined, iterator)) {
      return val;
    }
    throw goog.iter.StopIteration;
  };
  return iter;
};
goog.iter.toArray = function(iterable) {
  if (goog.isArrayLike(iterable)) {
    return goog.array.toArray(iterable);
  }
  iterable = goog.iter.toIterator(iterable);
  var array = [];
  goog.iter.forEach(iterable, function(val) {
    array.push(val);
  });
  return array;
};
goog.iter.equals = function(iterable1, iterable2, opt_equalsFn) {
  var fillValue = {};
  var pairs = goog.iter.zipLongest(fillValue, iterable1, iterable2);
  var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
  return goog.iter.every(pairs, function(pair) {
    return equalsFn(pair[0], pair[1]);
  });
};
goog.iter.nextOrValue = function(iterable, defaultValue) {
  try {
    return goog.iter.toIterator(iterable).next();
  } catch (e) {
    if (e != goog.iter.StopIteration) {
      throw e;
    }
    return defaultValue;
  }
};
goog.iter.product = function(var_args) {
  var someArrayEmpty = goog.array.some(arguments, function(arr) {
    return !arr.length;
  });
  if (someArrayEmpty || !arguments.length) {
    return new goog.iter.Iterator;
  }
  var iter = new goog.iter.Iterator;
  var arrays = arguments;
  var indicies = goog.array.repeat(0, arrays.length);
  iter.next = function() {
    if (indicies) {
      var retVal = goog.array.map(indicies, function(valueIndex, arrayIndex) {
        return arrays[arrayIndex][valueIndex];
      });
      for (var i = indicies.length - 1; i >= 0; i--) {
        goog.asserts.assert(indicies);
        if (indicies[i] < arrays[i].length - 1) {
          indicies[i]++;
          break;
        }
        if (i == 0) {
          indicies = null;
          break;
        }
        indicies[i] = 0;
      }
      return retVal;
    }
    throw goog.iter.StopIteration;
  };
  return iter;
};
goog.iter.cycle = function(iterable) {
  var baseIterator = goog.iter.toIterator(iterable);
  var cache = [];
  var cacheIndex = 0;
  var iter = new goog.iter.Iterator;
  var useCache = false;
  iter.next = function() {
    var returnElement = null;
    if (!useCache) {
      try {
        returnElement = baseIterator.next();
        cache.push(returnElement);
        return returnElement;
      } catch (e) {
        if (e != goog.iter.StopIteration || goog.array.isEmpty(cache)) {
          throw e;
        }
        useCache = true;
      }
    }
    returnElement = cache[cacheIndex];
    cacheIndex = (cacheIndex + 1) % cache.length;
    return returnElement;
  };
  return iter;
};
goog.iter.count = function(opt_start, opt_step) {
  var counter = opt_start || 0;
  var step = goog.isDef(opt_step) ? opt_step : 1;
  var iter = new goog.iter.Iterator;
  iter.next = function() {
    var returnValue = counter;
    counter += step;
    return returnValue;
  };
  return iter;
};
goog.iter.repeat = function(value) {
  var iter = new goog.iter.Iterator;
  iter.next = goog.functions.constant(value);
  return iter;
};
goog.iter.accumulate = function(iterable) {
  var iterator = goog.iter.toIterator(iterable);
  var total = 0;
  var iter = new goog.iter.Iterator;
  iter.next = function() {
    total += iterator.next();
    return total;
  };
  return iter;
};
goog.iter.zip = function(var_args) {
  var args = arguments;
  var iter = new goog.iter.Iterator;
  if (args.length > 0) {
    var iterators = goog.array.map(args, goog.iter.toIterator);
    iter.next = function() {
      var arr = goog.array.map(iterators, function(it) {
        return it.next();
      });
      return arr;
    };
  }
  return iter;
};
goog.iter.zipLongest = function(fillValue, var_args) {
  var args = goog.array.slice(arguments, 1);
  var iter = new goog.iter.Iterator;
  if (args.length > 0) {
    var iterators = goog.array.map(args, goog.iter.toIterator);
    iter.next = function() {
      var iteratorsHaveValues = false;
      var arr = goog.array.map(iterators, function(it) {
        var returnValue;
        try {
          returnValue = it.next();
          iteratorsHaveValues = true;
        } catch (ex) {
          if (ex !== goog.iter.StopIteration) {
            throw ex;
          }
          returnValue = fillValue;
        }
        return returnValue;
      });
      if (!iteratorsHaveValues) {
        throw goog.iter.StopIteration;
      }
      return arr;
    };
  }
  return iter;
};
goog.iter.compress = function(iterable, selectors) {
  var selectorIterator = goog.iter.toIterator(selectors);
  return goog.iter.filter(iterable, function() {
    return !!selectorIterator.next();
  });
};
goog.iter.GroupByIterator_ = function(iterable, opt_keyFunc) {
  this.iterator = goog.iter.toIterator(iterable);
  this.keyFunc = opt_keyFunc || goog.functions.identity;
  this.targetKey;
  this.currentKey;
  this.currentValue;
};
goog.inherits(goog.iter.GroupByIterator_, goog.iter.Iterator);
goog.iter.GroupByIterator_.prototype.next = function() {
  while (this.currentKey == this.targetKey) {
    this.currentValue = this.iterator.next();
    this.currentKey = this.keyFunc(this.currentValue);
  }
  this.targetKey = this.currentKey;
  return [this.currentKey, this.groupItems_(this.targetKey)];
};
goog.iter.GroupByIterator_.prototype.groupItems_ = function(targetKey) {
  var arr = [];
  while (this.currentKey == targetKey) {
    arr.push(this.currentValue);
    try {
      this.currentValue = this.iterator.next();
    } catch (ex) {
      if (ex !== goog.iter.StopIteration) {
        throw ex;
      }
      break;
    }
    this.currentKey = this.keyFunc(this.currentValue);
  }
  return arr;
};
goog.iter.groupBy = function(iterable, opt_keyFunc) {
  return new goog.iter.GroupByIterator_(iterable, opt_keyFunc);
};
goog.iter.starMap = function(iterable, f, opt_obj) {
  var iterator = goog.iter.toIterator(iterable);
  var iter = new goog.iter.Iterator;
  iter.next = function() {
    var args = goog.iter.toArray(iterator.next());
    return f.apply(opt_obj, goog.array.concat(args, undefined, iterator));
  };
  return iter;
};
goog.iter.tee = function(iterable, opt_num) {
  var iterator = goog.iter.toIterator(iterable);
  var num = goog.isNumber(opt_num) ? opt_num : 2;
  var buffers = goog.array.map(goog.array.range(num), function() {
    return [];
  });
  var addNextIteratorValueToBuffers = function() {
    var val = iterator.next();
    goog.array.forEach(buffers, function(buffer) {
      buffer.push(val);
    });
  };
  var createIterator = function(buffer) {
    var iter = new goog.iter.Iterator;
    iter.next = function() {
      if (goog.array.isEmpty(buffer)) {
        addNextIteratorValueToBuffers();
      }
      goog.asserts.assert(!goog.array.isEmpty(buffer));
      return buffer.shift();
    };
    return iter;
  };
  return goog.array.map(buffers, createIterator);
};
goog.iter.enumerate = function(iterable, opt_start) {
  return goog.iter.zip(goog.iter.count(opt_start), iterable);
};
goog.iter.limit = function(iterable, limitSize) {
  goog.asserts.assert(goog.math.isInt(limitSize) && limitSize >= 0);
  var iterator = goog.iter.toIterator(iterable);
  var iter = new goog.iter.Iterator;
  var remaining = limitSize;
  iter.next = function() {
    if (remaining-- > 0) {
      return iterator.next();
    }
    throw goog.iter.StopIteration;
  };
  return iter;
};
goog.iter.consume = function(iterable, count) {
  goog.asserts.assert(goog.math.isInt(count) && count >= 0);
  var iterator = goog.iter.toIterator(iterable);
  while (count-- > 0) {
    goog.iter.nextOrValue(iterator, null);
  }
  return iterator;
};
goog.iter.slice = function(iterable, start, opt_end) {
  goog.asserts.assert(goog.math.isInt(start) && start >= 0);
  var iterator = goog.iter.consume(iterable, start);
  if (goog.isNumber(opt_end)) {
    goog.asserts.assert(goog.math.isInt(opt_end) && opt_end >= start);
    iterator = goog.iter.limit(iterator, opt_end - start);
  }
  return iterator;
};
goog.iter.hasDuplicates_ = function(arr) {
  var deduped = [];
  goog.array.removeDuplicates(arr, deduped);
  return arr.length != deduped.length;
};
goog.iter.permutations = function(iterable, opt_length) {
  var elements = goog.iter.toArray(iterable);
  var length = goog.isNumber(opt_length) ? opt_length : elements.length;
  var sets = goog.array.repeat(elements, length);
  var product = goog.iter.product.apply(undefined, sets);
  return goog.iter.filter(product, function(arr) {
    return !goog.iter.hasDuplicates_(arr);
  });
};
goog.iter.combinations = function(iterable, length) {
  var elements = goog.iter.toArray(iterable);
  var indexes = goog.iter.range(elements.length);
  var indexIterator = goog.iter.permutations(indexes, length);
  var sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) {
    return goog.array.isSorted(arr);
  });
  var iter = new goog.iter.Iterator;
  function getIndexFromElements(index) {
    return elements[index];
  }
  iter.next = function() {
    return goog.array.map(sortedIndexIterator.next(), getIndexFromElements);
  };
  return iter;
};
goog.iter.combinationsWithReplacement = function(iterable, length) {
  var elements = goog.iter.toArray(iterable);
  var indexes = goog.array.range(elements.length);
  var sets = goog.array.repeat(indexes, length);
  var indexIterator = goog.iter.product.apply(undefined, sets);
  var sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) {
    return goog.array.isSorted(arr);
  });
  var iter = new goog.iter.Iterator;
  function getIndexFromElements(index) {
    return elements[index];
  }
  iter.next = function() {
    return goog.array.map(sortedIndexIterator.next(), getIndexFromElements);
  };
  return iter;
};
goog.provide("goog.dom.TagIterator");
goog.provide("goog.dom.TagWalkType");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.iter.Iterator");
goog.require("goog.iter.StopIteration");
goog.dom.TagWalkType = {START_TAG:1, OTHER:0, END_TAG:-1};
goog.dom.TagIterator = function(opt_node, opt_reversed, opt_unconstrained, opt_tagType, opt_depth) {
  this.reversed = !!opt_reversed;
  this.node = null;
  this.tagType = goog.dom.TagWalkType.OTHER;
  this.depth;
  this.started_ = false;
  this.constrained = !opt_unconstrained;
  if (opt_node) {
    this.setPosition(opt_node, opt_tagType);
  }
  this.depth = opt_depth != undefined ? opt_depth : this.tagType || 0;
  if (this.reversed) {
    this.depth *= -1;
  }
};
goog.inherits(goog.dom.TagIterator, goog.iter.Iterator);
goog.dom.TagIterator.prototype.setPosition = function(node, opt_tagType, opt_depth) {
  this.node = node;
  if (node) {
    if (goog.isNumber(opt_tagType)) {
      this.tagType = opt_tagType;
    } else {
      this.tagType = this.node.nodeType != goog.dom.NodeType.ELEMENT ? goog.dom.TagWalkType.OTHER : this.reversed ? goog.dom.TagWalkType.END_TAG : goog.dom.TagWalkType.START_TAG;
    }
  }
  if (goog.isNumber(opt_depth)) {
    this.depth = opt_depth;
  }
};
goog.dom.TagIterator.prototype.copyFrom = function(other) {
  this.node = other.node;
  this.tagType = other.tagType;
  this.depth = other.depth;
  this.reversed = other.reversed;
  this.constrained = other.constrained;
};
goog.dom.TagIterator.prototype.clone = function() {
  return new goog.dom.TagIterator(this.node, this.reversed, !this.constrained, this.tagType, this.depth);
};
goog.dom.TagIterator.prototype.skipTag = function() {
  var check = this.reversed ? goog.dom.TagWalkType.END_TAG : goog.dom.TagWalkType.START_TAG;
  if (this.tagType == check) {
    this.tagType = check * -1;
    this.depth += this.tagType * (this.reversed ? -1 : 1);
  }
};
goog.dom.TagIterator.prototype.restartTag = function() {
  var check = this.reversed ? goog.dom.TagWalkType.START_TAG : goog.dom.TagWalkType.END_TAG;
  if (this.tagType == check) {
    this.tagType = check * -1;
    this.depth += this.tagType * (this.reversed ? -1 : 1);
  }
};
goog.dom.TagIterator.prototype.next = function() {
  var node;
  if (this.started_) {
    if (!this.node || this.constrained && this.depth == 0) {
      throw goog.iter.StopIteration;
    }
    node = this.node;
    var startType = this.reversed ? goog.dom.TagWalkType.END_TAG : goog.dom.TagWalkType.START_TAG;
    if (this.tagType == startType) {
      var child = this.reversed ? node.lastChild : node.firstChild;
      if (child) {
        this.setPosition(child);
      } else {
        this.setPosition(node, startType * -1);
      }
    } else {
      var sibling = this.reversed ? node.previousSibling : node.nextSibling;
      if (sibling) {
        this.setPosition(sibling);
      } else {
        this.setPosition(node.parentNode, startType * -1);
      }
    }
    this.depth += this.tagType * (this.reversed ? -1 : 1);
  } else {
    this.started_ = true;
  }
  node = this.node;
  if (!this.node) {
    throw goog.iter.StopIteration;
  }
  return node;
};
goog.dom.TagIterator.prototype.isStarted = function() {
  return this.started_;
};
goog.dom.TagIterator.prototype.isStartTag = function() {
  return this.tagType == goog.dom.TagWalkType.START_TAG;
};
goog.dom.TagIterator.prototype.isEndTag = function() {
  return this.tagType == goog.dom.TagWalkType.END_TAG;
};
goog.dom.TagIterator.prototype.isNonElement = function() {
  return this.tagType == goog.dom.TagWalkType.OTHER;
};
goog.dom.TagIterator.prototype.equals = function(other) {
  return other.node == this.node && (!this.node || other.tagType == this.tagType);
};
goog.dom.TagIterator.prototype.splice = function(var_args) {
  var node = this.node;
  this.restartTag();
  this.reversed = !this.reversed;
  goog.dom.TagIterator.prototype.next.call(this);
  this.reversed = !this.reversed;
  var arr = goog.isArrayLike(arguments[0]) ? arguments[0] : arguments;
  for (var i = arr.length - 1; i >= 0; i--) {
    goog.dom.insertSiblingAfter(arr[i], node);
  }
  goog.dom.removeNode(node);
};
goog.provide("goog.dom.AbstractRange");
goog.provide("goog.dom.RangeIterator");
goog.provide("goog.dom.RangeType");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.SavedCaretRange");
goog.require("goog.dom.TagIterator");
goog.require("goog.userAgent");
goog.dom.RangeType = {TEXT:"text", CONTROL:"control", MULTI:"mutli"};
goog.dom.AbstractRange = function() {
};
goog.dom.AbstractRange.getBrowserSelectionForWindow = function(win) {
  if (win.getSelection) {
    return win.getSelection();
  } else {
    var doc = win.document;
    var sel = doc.selection;
    if (sel) {
      try {
        var range = sel.createRange();
        if (range.parentElement) {
          if (range.parentElement().document != doc) {
            return null;
          }
        } else {
          if (!range.length || range.item(0).document != doc) {
            return null;
          }
        }
      } catch (e) {
        return null;
      }
      return sel;
    }
    return null;
  }
};
goog.dom.AbstractRange.isNativeControlRange = function(range) {
  return !!range && !!range.addElement;
};
goog.dom.AbstractRange.prototype.clone = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getType = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getBrowserRangeObject = goog.abstractMethod;
goog.dom.AbstractRange.prototype.setBrowserRangeObject = function(nativeRange) {
  return false;
};
goog.dom.AbstractRange.prototype.getTextRangeCount = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getTextRange = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getTextRanges = function() {
  var output = [];
  for (var i = 0, len = this.getTextRangeCount(); i < len; i++) {
    output.push(this.getTextRange(i));
  }
  return output;
};
goog.dom.AbstractRange.prototype.getContainer = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getContainerElement = function() {
  var node = this.getContainer();
  return node.nodeType == goog.dom.NodeType.ELEMENT ? node : node.parentNode;
};
goog.dom.AbstractRange.prototype.getStartNode = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getStartOffset = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getStartPosition = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getEndNode = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getEndOffset = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getEndPosition = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getAnchorNode = function() {
  return this.isReversed() ? this.getEndNode() : this.getStartNode();
};
goog.dom.AbstractRange.prototype.getAnchorOffset = function() {
  return this.isReversed() ? this.getEndOffset() : this.getStartOffset();
};
goog.dom.AbstractRange.prototype.getFocusNode = function() {
  return this.isReversed() ? this.getStartNode() : this.getEndNode();
};
goog.dom.AbstractRange.prototype.getFocusOffset = function() {
  return this.isReversed() ? this.getStartOffset() : this.getEndOffset();
};
goog.dom.AbstractRange.prototype.isReversed = function() {
  return false;
};
goog.dom.AbstractRange.prototype.getDocument = function() {
  return goog.dom.getOwnerDocument(goog.userAgent.IE ? this.getContainer() : this.getStartNode());
};
goog.dom.AbstractRange.prototype.getWindow = function() {
  return goog.dom.getWindow(this.getDocument());
};
goog.dom.AbstractRange.prototype.containsRange = goog.abstractMethod;
goog.dom.AbstractRange.prototype.containsNode = goog.abstractMethod;
goog.dom.AbstractRange.prototype.isRangeInDocument = goog.abstractMethod;
goog.dom.AbstractRange.prototype.isCollapsed = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getText = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getHtmlFragment = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getValidHtml = goog.abstractMethod;
goog.dom.AbstractRange.prototype.getPastableHtml = goog.abstractMethod;
goog.dom.AbstractRange.prototype.__iterator__ = goog.abstractMethod;
goog.dom.AbstractRange.prototype.select = goog.abstractMethod;
goog.dom.AbstractRange.prototype.removeContents = goog.abstractMethod;
goog.dom.AbstractRange.prototype.insertNode = goog.abstractMethod;
goog.dom.AbstractRange.prototype.replaceContentsWithNode = function(node) {
  if (!this.isCollapsed()) {
    this.removeContents();
  }
  return this.insertNode(node, true);
};
goog.dom.AbstractRange.prototype.surroundWithNodes = goog.abstractMethod;
goog.dom.AbstractRange.prototype.saveUsingDom = goog.abstractMethod;
goog.dom.AbstractRange.prototype.saveUsingCarets = function() {
  return this.getStartNode() && this.getEndNode() ? new goog.dom.SavedCaretRange(this) : null;
};
goog.dom.AbstractRange.prototype.collapse = goog.abstractMethod;
goog.dom.RangeIterator = function(node, opt_reverse) {
  goog.dom.TagIterator.call(this, node, opt_reverse, true);
};
goog.inherits(goog.dom.RangeIterator, goog.dom.TagIterator);
goog.dom.RangeIterator.prototype.getStartTextOffset = goog.abstractMethod;
goog.dom.RangeIterator.prototype.getEndTextOffset = goog.abstractMethod;
goog.dom.RangeIterator.prototype.getStartNode = goog.abstractMethod;
goog.dom.RangeIterator.prototype.getEndNode = goog.abstractMethod;
goog.dom.RangeIterator.prototype.isLast = goog.abstractMethod;
goog.provide("goog.dom.TextRangeIterator");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.RangeIterator");
goog.require("goog.dom.TagName");
goog.require("goog.iter.StopIteration");
goog.dom.TextRangeIterator = function(startNode, startOffset, endNode, endOffset, opt_reverse) {
  this.startNode_ = null;
  this.endNode_ = null;
  this.startOffset_ = 0;
  this.endOffset_ = 0;
  var goNext;
  if (startNode) {
    this.startNode_ = startNode;
    this.startOffset_ = startOffset;
    this.endNode_ = endNode;
    this.endOffset_ = endOffset;
    if (startNode.nodeType == goog.dom.NodeType.ELEMENT && startNode.tagName != goog.dom.TagName.BR) {
      var startChildren = startNode.childNodes;
      var candidate = startChildren[startOffset];
      if (candidate) {
        this.startNode_ = candidate;
        this.startOffset_ = 0;
      } else {
        if (startChildren.length) {
          this.startNode_ = goog.array.peek(startChildren);
        }
        goNext = true;
      }
    }
    if (endNode.nodeType == goog.dom.NodeType.ELEMENT) {
      this.endNode_ = endNode.childNodes[endOffset];
      if (this.endNode_) {
        this.endOffset_ = 0;
      } else {
        this.endNode_ = endNode;
      }
    }
  }
  goog.dom.TextRangeIterator.base(this, "constructor", opt_reverse ? this.endNode_ : this.startNode_, opt_reverse);
  if (goNext) {
    try {
      this.next();
    } catch (e) {
      if (e != goog.iter.StopIteration) {
        throw e;
      }
    }
  }
};
goog.inherits(goog.dom.TextRangeIterator, goog.dom.RangeIterator);
goog.dom.TextRangeIterator.prototype.getStartTextOffset = function() {
  return this.node.nodeType != goog.dom.NodeType.TEXT ? -1 : this.node == this.startNode_ ? this.startOffset_ : 0;
};
goog.dom.TextRangeIterator.prototype.getEndTextOffset = function() {
  return this.node.nodeType != goog.dom.NodeType.TEXT ? -1 : this.node == this.endNode_ ? this.endOffset_ : this.node.nodeValue.length;
};
goog.dom.TextRangeIterator.prototype.getStartNode = function() {
  return this.startNode_;
};
goog.dom.TextRangeIterator.prototype.setStartNode = function(node) {
  if (!this.isStarted()) {
    this.setPosition(node);
  }
  this.startNode_ = node;
  this.startOffset_ = 0;
};
goog.dom.TextRangeIterator.prototype.getEndNode = function() {
  return this.endNode_;
};
goog.dom.TextRangeIterator.prototype.setEndNode = function(node) {
  this.endNode_ = node;
  this.endOffset_ = 0;
};
goog.dom.TextRangeIterator.prototype.isLast = function() {
  return this.isStarted() && this.node == this.endNode_ && (!this.endOffset_ || !this.isStartTag());
};
goog.dom.TextRangeIterator.prototype.next = function() {
  if (this.isLast()) {
    throw goog.iter.StopIteration;
  }
  return goog.dom.TextRangeIterator.superClass_.next.call(this);
};
goog.dom.TextRangeIterator.prototype.skipTag = function() {
  goog.dom.TextRangeIterator.superClass_.skipTag.apply(this);
  if (goog.dom.contains(this.node, this.endNode_)) {
    throw goog.iter.StopIteration;
  }
};
goog.dom.TextRangeIterator.prototype.copyFrom = function(other) {
  this.startNode_ = other.startNode_;
  this.endNode_ = other.endNode_;
  this.startOffset_ = other.startOffset_;
  this.endOffset_ = other.endOffset_;
  this.isReversed_ = other.isReversed_;
  goog.dom.TextRangeIterator.superClass_.copyFrom.call(this, other);
};
goog.dom.TextRangeIterator.prototype.clone = function() {
  var copy = new goog.dom.TextRangeIterator(this.startNode_, this.startOffset_, this.endNode_, this.endOffset_, this.isReversed_);
  copy.copyFrom(this);
  return copy;
};
goog.provide("goog.dom.RangeEndpoint");
goog.dom.RangeEndpoint = {START:1, END:0};
goog.provide("goog.string.StringBuffer");
goog.string.StringBuffer = function(opt_a1, var_args) {
  if (opt_a1 != null) {
    this.append.apply(this, arguments);
  }
};
goog.string.StringBuffer.prototype.buffer_ = "";
goog.string.StringBuffer.prototype.set = function(s) {
  this.buffer_ = "" + s;
};
goog.string.StringBuffer.prototype.append = function(a1, opt_a2, var_args) {
  this.buffer_ += String(a1);
  if (opt_a2 != null) {
    for (var i = 1; i < arguments.length; i++) {
      this.buffer_ += arguments[i];
    }
  }
  return this;
};
goog.string.StringBuffer.prototype.clear = function() {
  this.buffer_ = "";
};
goog.string.StringBuffer.prototype.getLength = function() {
  return this.buffer_.length;
};
goog.string.StringBuffer.prototype.toString = function() {
  return this.buffer_;
};
goog.provide("goog.dom.browserrange.AbstractRange");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.RangeEndpoint");
goog.require("goog.dom.TagName");
goog.require("goog.dom.TextRangeIterator");
goog.require("goog.iter");
goog.require("goog.math.Coordinate");
goog.require("goog.string");
goog.require("goog.string.StringBuffer");
goog.require("goog.userAgent");
goog.dom.browserrange.AbstractRange = function() {
};
goog.dom.browserrange.AbstractRange.prototype.clone = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getBrowserRange = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getContainer = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getStartNode = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getStartOffset = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getStartPosition = function() {
  return this.getPosition_(true);
};
goog.dom.browserrange.AbstractRange.prototype.getEndNode = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getEndOffset = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getEndPosition = function() {
  return this.getPosition_(false);
};
goog.dom.browserrange.AbstractRange.prototype.getPosition_ = function(start) {
  goog.asserts.assert(this.range_.getClientRects, "Getting selection coordinates is not supported.");
  var rects = this.range_.getClientRects();
  if (rects.length) {
    var r = start ? rects[0] : goog.array.peek(rects);
    return new goog.math.Coordinate(start ? r.left : r.right, start ? r.top : r.bottom);
  }
  return null;
};
goog.dom.browserrange.AbstractRange.prototype.compareBrowserRangeEndpoints = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.containsRange = function(abstractRange, opt_allowPartial) {
  var checkPartial = opt_allowPartial && !abstractRange.isCollapsed();
  var range = abstractRange.getBrowserRange();
  var start = goog.dom.RangeEndpoint.START, end = goog.dom.RangeEndpoint.END;
  try {
    if (checkPartial) {
      return this.compareBrowserRangeEndpoints(range, end, start) >= 0 && this.compareBrowserRangeEndpoints(range, start, end) <= 0;
    } else {
      return this.compareBrowserRangeEndpoints(range, end, end) >= 0 && this.compareBrowserRangeEndpoints(range, start, start) <= 0;
    }
  } catch (e) {
    if (!goog.userAgent.IE) {
      throw e;
    }
    return false;
  }
};
goog.dom.browserrange.AbstractRange.prototype.containsNode = function(node, opt_allowPartial) {
  return this.containsRange(goog.dom.browserrange.createRangeFromNodeContents(node), opt_allowPartial);
};
goog.dom.browserrange.AbstractRange.prototype.isCollapsed = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getText = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.getHtmlFragment = function() {
  var output = new goog.string.StringBuffer;
  goog.iter.forEach(this, function(node, ignore, it) {
    if (node.nodeType == goog.dom.NodeType.TEXT) {
      output.append(goog.string.htmlEscape(node.nodeValue.substring(it.getStartTextOffset(), it.getEndTextOffset())));
    } else {
      if (node.nodeType == goog.dom.NodeType.ELEMENT) {
        if (it.isEndTag()) {
          if (goog.dom.canHaveChildren(node)) {
            output.append("</" + node.tagName + ">");
          }
        } else {
          var shallow = node.cloneNode(false);
          var html = goog.dom.getOuterHtml(shallow);
          if (goog.userAgent.IE && node.tagName == goog.dom.TagName.LI) {
            output.append(html);
          } else {
            var index = html.lastIndexOf("<");
            output.append(index ? html.substr(0, index) : html);
          }
        }
      }
    }
  }, this);
  return output.toString();
};
goog.dom.browserrange.AbstractRange.prototype.getValidHtml = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.__iterator__ = function(opt_keys) {
  return new goog.dom.TextRangeIterator(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset());
};
goog.dom.browserrange.AbstractRange.prototype.select = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.removeContents = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.surroundContents = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.insertNode = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.surroundWithNodes = goog.abstractMethod;
goog.dom.browserrange.AbstractRange.prototype.collapse = goog.abstractMethod;
goog.provide("goog.dom.browserrange.W3cRange");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.RangeEndpoint");
goog.require("goog.dom.TagName");
goog.require("goog.dom.browserrange.AbstractRange");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.dom.browserrange.W3cRange = function(range) {
  this.range_ = range;
};
goog.inherits(goog.dom.browserrange.W3cRange, goog.dom.browserrange.AbstractRange);
goog.dom.browserrange.W3cRange.getBrowserRangeForNode = function(node) {
  var nodeRange = goog.dom.getOwnerDocument(node).createRange();
  if (node.nodeType == goog.dom.NodeType.TEXT) {
    nodeRange.setStart(node, 0);
    nodeRange.setEnd(node, node.length);
  } else {
    if (!goog.dom.browserrange.canContainRangeEndpoint(node)) {
      var rangeParent = node.parentNode;
      var rangeStartOffset = goog.array.indexOf(rangeParent.childNodes, node);
      nodeRange.setStart(rangeParent, rangeStartOffset);
      nodeRange.setEnd(rangeParent, rangeStartOffset + 1);
    } else {
      var tempNode, leaf = node;
      while ((tempNode = leaf.firstChild) && goog.dom.browserrange.canContainRangeEndpoint(tempNode)) {
        leaf = tempNode;
      }
      nodeRange.setStart(leaf, 0);
      leaf = node;
      while ((tempNode = leaf.lastChild) && goog.dom.browserrange.canContainRangeEndpoint(tempNode)) {
        leaf = tempNode;
      }
      nodeRange.setEnd(leaf, leaf.nodeType == goog.dom.NodeType.ELEMENT ? leaf.childNodes.length : leaf.length);
    }
  }
  return nodeRange;
};
goog.dom.browserrange.W3cRange.getBrowserRangeForNodes = function(startNode, startOffset, endNode, endOffset) {
  var nodeRange = goog.dom.getOwnerDocument(startNode).createRange();
  nodeRange.setStart(startNode, startOffset);
  nodeRange.setEnd(endNode, endOffset);
  return nodeRange;
};
goog.dom.browserrange.W3cRange.createFromNodeContents = function(node) {
  return new goog.dom.browserrange.W3cRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNode(node));
};
goog.dom.browserrange.W3cRange.createFromNodes = function(startNode, startOffset, endNode, endOffset) {
  return new goog.dom.browserrange.W3cRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNodes(startNode, startOffset, endNode, endOffset));
};
goog.dom.browserrange.W3cRange.prototype.clone = function() {
  return new this.constructor(this.range_.cloneRange());
};
goog.dom.browserrange.W3cRange.prototype.getBrowserRange = function() {
  return this.range_;
};
goog.dom.browserrange.W3cRange.prototype.getContainer = function() {
  return this.range_.commonAncestorContainer;
};
goog.dom.browserrange.W3cRange.prototype.getStartNode = function() {
  return this.range_.startContainer;
};
goog.dom.browserrange.W3cRange.prototype.getStartOffset = function() {
  return this.range_.startOffset;
};
goog.dom.browserrange.W3cRange.prototype.getEndNode = function() {
  return this.range_.endContainer;
};
goog.dom.browserrange.W3cRange.prototype.getEndOffset = function() {
  return this.range_.endOffset;
};
goog.dom.browserrange.W3cRange.prototype.compareBrowserRangeEndpoints = function(range, thisEndpoint, otherEndpoint) {
  return this.range_.compareBoundaryPoints(otherEndpoint == goog.dom.RangeEndpoint.START ? thisEndpoint == goog.dom.RangeEndpoint.START ? goog.global["Range"].START_TO_START : goog.global["Range"].START_TO_END : thisEndpoint == goog.dom.RangeEndpoint.START ? goog.global["Range"].END_TO_START : goog.global["Range"].END_TO_END, range);
};
goog.dom.browserrange.W3cRange.prototype.isCollapsed = function() {
  return this.range_.collapsed;
};
goog.dom.browserrange.W3cRange.prototype.getText = function() {
  return this.range_.toString();
};
goog.dom.browserrange.W3cRange.prototype.getValidHtml = function() {
  var div = goog.dom.getDomHelper(this.range_.startContainer).createDom(goog.dom.TagName.DIV);
  div.appendChild(this.range_.cloneContents());
  var result = div.innerHTML;
  if (goog.string.startsWith(result, "<") || !this.isCollapsed() && !goog.string.contains(result, "<")) {
    return result;
  }
  var container = this.getContainer();
  container = container.nodeType == goog.dom.NodeType.ELEMENT ? container : container.parentNode;
  var html = goog.dom.getOuterHtml(container.cloneNode(false));
  return html.replace(">", ">" + result);
};
goog.dom.browserrange.W3cRange.prototype.select = function(reverse) {
  var win = goog.dom.getWindow(goog.dom.getOwnerDocument(this.getStartNode()));
  this.selectInternal(win.getSelection(), reverse);
};
goog.dom.browserrange.W3cRange.prototype.selectInternal = function(selection, reverse) {
  selection.removeAllRanges();
  selection.addRange(this.range_);
};
goog.dom.browserrange.W3cRange.prototype.removeContents = function() {
  var range = this.range_;
  range.extractContents();
  if (range.startContainer.hasChildNodes()) {
    var rangeStartContainer = range.startContainer.childNodes[range.startOffset];
    if (rangeStartContainer) {
      var rangePrevious = rangeStartContainer.previousSibling;
      if (goog.dom.getRawTextContent(rangeStartContainer) == "") {
        goog.dom.removeNode(rangeStartContainer);
      }
      if (rangePrevious && goog.dom.getRawTextContent(rangePrevious) == "") {
        goog.dom.removeNode(rangePrevious);
      }
    }
  }
  if (goog.userAgent.EDGE_OR_IE) {
    var startNode = this.getStartNode();
    var startOffset = this.getStartOffset();
    var endNode = this.getEndNode();
    var endOffset = this.getEndOffset();
    var sibling = startNode.nextSibling;
    if (startNode == endNode && startNode.parentNode && startNode.nodeType == goog.dom.NodeType.TEXT && sibling && sibling.nodeType == goog.dom.NodeType.TEXT) {
      startNode.nodeValue += sibling.nodeValue;
      goog.dom.removeNode(sibling);
      range.setStart(startNode, startOffset);
      range.setEnd(endNode, endOffset);
    }
  }
};
goog.dom.browserrange.W3cRange.prototype.surroundContents = function(element) {
  this.range_.surroundContents(element);
  return element;
};
goog.dom.browserrange.W3cRange.prototype.insertNode = function(node, before) {
  var range = this.range_.cloneRange();
  range.collapse(before);
  range.insertNode(node);
  range.detach();
  return node;
};
goog.dom.browserrange.W3cRange.prototype.surroundWithNodes = function(startNode, endNode) {
  var win = goog.dom.getWindow(goog.dom.getOwnerDocument(this.getStartNode()));
  var selectionRange = goog.dom.Range.createFromWindow(win);
  if (selectionRange) {
    var sNode = selectionRange.getStartNode();
    var eNode = selectionRange.getEndNode();
    var sOffset = selectionRange.getStartOffset();
    var eOffset = selectionRange.getEndOffset();
  }
  var clone1 = this.range_.cloneRange();
  var clone2 = this.range_.cloneRange();
  clone1.collapse(false);
  clone2.collapse(true);
  clone1.insertNode(endNode);
  clone2.insertNode(startNode);
  clone1.detach();
  clone2.detach();
  if (selectionRange) {
    var isInsertedNode = function(n) {
      return n == startNode || n == endNode;
    };
    if (sNode.nodeType == goog.dom.NodeType.TEXT) {
      while (sOffset > sNode.length) {
        sOffset -= sNode.length;
        do {
          sNode = sNode.nextSibling;
        } while (isInsertedNode(sNode));
      }
    }
    if (eNode.nodeType == goog.dom.NodeType.TEXT) {
      while (eOffset > eNode.length) {
        eOffset -= eNode.length;
        do {
          eNode = eNode.nextSibling;
        } while (isInsertedNode(eNode));
      }
    }
    goog.dom.Range.createFromNodes(sNode, sOffset, eNode, eOffset).select();
  }
};
goog.dom.browserrange.W3cRange.prototype.collapse = function(toStart) {
  this.range_.collapse(toStart);
};
goog.provide("goog.dom.browserrange.GeckoRange");
goog.require("goog.dom.browserrange.W3cRange");
goog.dom.browserrange.GeckoRange = function(range) {
  goog.dom.browserrange.W3cRange.call(this, range);
};
goog.inherits(goog.dom.browserrange.GeckoRange, goog.dom.browserrange.W3cRange);
goog.dom.browserrange.GeckoRange.createFromNodeContents = function(node) {
  return new goog.dom.browserrange.GeckoRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNode(node));
};
goog.dom.browserrange.GeckoRange.createFromNodes = function(startNode, startOffset, endNode, endOffset) {
  return new goog.dom.browserrange.GeckoRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNodes(startNode, startOffset, endNode, endOffset));
};
goog.dom.browserrange.GeckoRange.prototype.selectInternal = function(selection, reversed) {
  if (!reversed || this.isCollapsed()) {
    goog.dom.browserrange.GeckoRange.base(this, "selectInternal", selection, reversed);
  } else {
    selection.collapse(this.getEndNode(), this.getEndOffset());
    selection.extend(this.getStartNode(), this.getStartOffset());
  }
};
goog.provide("goog.dom.browserrange.IeRange");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.RangeEndpoint");
goog.require("goog.dom.TagName");
goog.require("goog.dom.browserrange.AbstractRange");
goog.require("goog.log");
goog.require("goog.string");
goog.dom.browserrange.IeRange = function(range, doc) {
  this.parentNode_ = null;
  this.startNode_ = null;
  this.endNode_ = null;
  this.startOffset_ = -1;
  this.endOffset_ = -1;
  this.range_ = range;
  this.doc_ = doc;
};
goog.inherits(goog.dom.browserrange.IeRange, goog.dom.browserrange.AbstractRange);
goog.dom.browserrange.IeRange.logger_ = goog.log.getLogger("goog.dom.browserrange.IeRange");
goog.dom.browserrange.IeRange.getBrowserRangeForNode_ = function(node) {
  var nodeRange = goog.dom.getOwnerDocument(node).body.createTextRange();
  if (node.nodeType == goog.dom.NodeType.ELEMENT) {
    nodeRange.moveToElementText(node);
    if (goog.dom.browserrange.canContainRangeEndpoint(node) && !node.childNodes.length) {
      nodeRange.collapse(false);
    }
  } else {
    var offset = 0;
    var sibling = node;
    while (sibling = sibling.previousSibling) {
      var nodeType = sibling.nodeType;
      if (nodeType == goog.dom.NodeType.TEXT) {
        offset += sibling.length;
      } else {
        if (nodeType == goog.dom.NodeType.ELEMENT) {
          nodeRange.moveToElementText(sibling);
          break;
        }
      }
    }
    if (!sibling) {
      nodeRange.moveToElementText(node.parentNode);
    }
    nodeRange.collapse(!sibling);
    if (offset) {
      nodeRange.move("character", offset);
    }
    nodeRange.moveEnd("character", node.length);
  }
  return nodeRange;
};
goog.dom.browserrange.IeRange.getBrowserRangeForNodes_ = function(startNode, startOffset, endNode, endOffset) {
  var child, collapse = false;
  if (startNode.nodeType == goog.dom.NodeType.ELEMENT) {
    if (startOffset > startNode.childNodes.length) {
      goog.log.error(goog.dom.browserrange.IeRange.logger_, "Cannot have startOffset > startNode child count");
    }
    child = startNode.childNodes[startOffset];
    collapse = !child;
    startNode = child || startNode.lastChild || startNode;
    startOffset = 0;
  }
  var leftRange = goog.dom.browserrange.IeRange.getBrowserRangeForNode_(startNode);
  if (startOffset) {
    leftRange.move("character", startOffset);
  }
  if (startNode == endNode && startOffset == endOffset) {
    leftRange.collapse(true);
    return leftRange;
  }
  if (collapse) {
    leftRange.collapse(false);
  }
  collapse = false;
  if (endNode.nodeType == goog.dom.NodeType.ELEMENT) {
    if (endOffset > endNode.childNodes.length) {
      goog.log.error(goog.dom.browserrange.IeRange.logger_, "Cannot have endOffset > endNode child count");
    }
    child = endNode.childNodes[endOffset];
    endNode = child || endNode.lastChild || endNode;
    endOffset = 0;
    collapse = !child;
  }
  var rightRange = goog.dom.browserrange.IeRange.getBrowserRangeForNode_(endNode);
  rightRange.collapse(!collapse);
  if (endOffset) {
    rightRange.moveEnd("character", endOffset);
  }
  leftRange.setEndPoint("EndToEnd", rightRange);
  return leftRange;
};
goog.dom.browserrange.IeRange.createFromNodeContents = function(node) {
  var range = new goog.dom.browserrange.IeRange(goog.dom.browserrange.IeRange.getBrowserRangeForNode_(node), goog.dom.getOwnerDocument(node));
  if (!goog.dom.browserrange.canContainRangeEndpoint(node)) {
    range.startNode_ = range.endNode_ = range.parentNode_ = node.parentNode;
    range.startOffset_ = goog.array.indexOf(range.parentNode_.childNodes, node);
    range.endOffset_ = range.startOffset_ + 1;
  } else {
    var tempNode, leaf = node;
    while ((tempNode = leaf.firstChild) && goog.dom.browserrange.canContainRangeEndpoint(tempNode)) {
      leaf = tempNode;
    }
    range.startNode_ = leaf;
    range.startOffset_ = 0;
    leaf = node;
    while ((tempNode = leaf.lastChild) && goog.dom.browserrange.canContainRangeEndpoint(tempNode)) {
      leaf = tempNode;
    }
    range.endNode_ = leaf;
    range.endOffset_ = leaf.nodeType == goog.dom.NodeType.ELEMENT ? leaf.childNodes.length : leaf.length;
    range.parentNode_ = node;
  }
  return range;
};
goog.dom.browserrange.IeRange.createFromNodes = function(startNode, startOffset, endNode, endOffset) {
  var range = new goog.dom.browserrange.IeRange(goog.dom.browserrange.IeRange.getBrowserRangeForNodes_(startNode, startOffset, endNode, endOffset), goog.dom.getOwnerDocument(startNode));
  range.startNode_ = startNode;
  range.startOffset_ = startOffset;
  range.endNode_ = endNode;
  range.endOffset_ = endOffset;
  return range;
};
goog.dom.browserrange.IeRange.prototype.clone = function() {
  var range = new goog.dom.browserrange.IeRange(this.range_.duplicate(), this.doc_);
  range.parentNode_ = this.parentNode_;
  range.startNode_ = this.startNode_;
  range.endNode_ = this.endNode_;
  return range;
};
goog.dom.browserrange.IeRange.prototype.getBrowserRange = function() {
  return this.range_;
};
goog.dom.browserrange.IeRange.prototype.clearCachedValues_ = function() {
  this.parentNode_ = this.startNode_ = this.endNode_ = null;
  this.startOffset_ = this.endOffset_ = -1;
};
goog.dom.browserrange.IeRange.prototype.getContainer = function() {
  if (!this.parentNode_) {
    var selectText = this.range_.text;
    var range = this.range_.duplicate();
    var rightTrimmedSelectText = selectText.replace(/ +$/, "");
    var numSpacesAtEnd = selectText.length - rightTrimmedSelectText.length;
    if (numSpacesAtEnd) {
      range.moveEnd("character", -numSpacesAtEnd);
    }
    var parent = range.parentElement();
    var htmlText = range.htmlText;
    var htmlTextLen = goog.string.stripNewlines(htmlText).length;
    if (this.isCollapsed() && htmlTextLen > 0) {
      return this.parentNode_ = parent;
    }
    while (htmlTextLen > goog.string.stripNewlines(parent.outerHTML).length) {
      parent = parent.parentNode;
    }
    while (parent.childNodes.length == 1 && parent.innerText == goog.dom.browserrange.IeRange.getNodeText_(parent.firstChild)) {
      if (!goog.dom.browserrange.canContainRangeEndpoint(parent.firstChild)) {
        break;
      }
      parent = parent.firstChild;
    }
    if (selectText.length == 0) {
      parent = this.findDeepestContainer_(parent);
    }
    this.parentNode_ = parent;
  }
  return this.parentNode_;
};
goog.dom.browserrange.IeRange.prototype.findDeepestContainer_ = function(node) {
  var childNodes = node.childNodes;
  for (var i = 0, len = childNodes.length; i < len; i++) {
    var child = childNodes[i];
    if (goog.dom.browserrange.canContainRangeEndpoint(child)) {
      var childRange = goog.dom.browserrange.IeRange.getBrowserRangeForNode_(child);
      var start = goog.dom.RangeEndpoint.START;
      var end = goog.dom.RangeEndpoint.END;
      var isChildRangeErratic = childRange.htmlText != child.outerHTML;
      var isNativeInRangeErratic = this.isCollapsed() && isChildRangeErratic;
      var inChildRange = isNativeInRangeErratic ? this.compareBrowserRangeEndpoints(childRange, start, start) >= 0 && this.compareBrowserRangeEndpoints(childRange, start, end) <= 0 : this.range_.inRange(childRange);
      if (inChildRange) {
        return this.findDeepestContainer_(child);
      }
    }
  }
  return node;
};
goog.dom.browserrange.IeRange.prototype.getStartNode = function() {
  if (!this.startNode_) {
    this.startNode_ = this.getEndpointNode_(goog.dom.RangeEndpoint.START);
    if (this.isCollapsed()) {
      this.endNode_ = this.startNode_;
    }
  }
  return this.startNode_;
};
goog.dom.browserrange.IeRange.prototype.getStartOffset = function() {
  if (this.startOffset_ < 0) {
    this.startOffset_ = this.getOffset_(goog.dom.RangeEndpoint.START);
    if (this.isCollapsed()) {
      this.endOffset_ = this.startOffset_;
    }
  }
  return this.startOffset_;
};
goog.dom.browserrange.IeRange.prototype.getEndNode = function() {
  if (this.isCollapsed()) {
    return this.getStartNode();
  }
  if (!this.endNode_) {
    this.endNode_ = this.getEndpointNode_(goog.dom.RangeEndpoint.END);
  }
  return this.endNode_;
};
goog.dom.browserrange.IeRange.prototype.getEndOffset = function() {
  if (this.isCollapsed()) {
    return this.getStartOffset();
  }
  if (this.endOffset_ < 0) {
    this.endOffset_ = this.getOffset_(goog.dom.RangeEndpoint.END);
    if (this.isCollapsed()) {
      this.startOffset_ = this.endOffset_;
    }
  }
  return this.endOffset_;
};
goog.dom.browserrange.IeRange.prototype.compareBrowserRangeEndpoints = function(range, thisEndpoint, otherEndpoint) {
  return this.range_.compareEndPoints((thisEndpoint == goog.dom.RangeEndpoint.START ? "Start" : "End") + "To" + (otherEndpoint == goog.dom.RangeEndpoint.START ? "Start" : "End"), range);
};
goog.dom.browserrange.IeRange.prototype.getEndpointNode_ = function(endpoint, opt_node) {
  var node = opt_node || this.getContainer();
  if (!node || !node.firstChild) {
    return node;
  }
  var start = goog.dom.RangeEndpoint.START, end = goog.dom.RangeEndpoint.END;
  var isStartEndpoint = endpoint == start;
  for (var j = 0, length = node.childNodes.length; j < length; j++) {
    var i = isStartEndpoint ? j : length - j - 1;
    var child = node.childNodes[i];
    var childRange;
    try {
      childRange = goog.dom.browserrange.createRangeFromNodeContents(child);
    } catch (e) {
      continue;
    }
    var ieRange = childRange.getBrowserRange();
    if (this.isCollapsed()) {
      if (!goog.dom.browserrange.canContainRangeEndpoint(child)) {
        if (this.compareBrowserRangeEndpoints(ieRange, start, start) == 0) {
          this.startOffset_ = this.endOffset_ = i;
          return node;
        }
      } else {
        if (childRange.containsRange(this)) {
          return this.getEndpointNode_(endpoint, child);
        }
      }
    } else {
      if (this.containsRange(childRange)) {
        if (!goog.dom.browserrange.canContainRangeEndpoint(child)) {
          if (isStartEndpoint) {
            this.startOffset_ = i;
          } else {
            this.endOffset_ = i + 1;
          }
          return node;
        }
        return this.getEndpointNode_(endpoint, child);
      } else {
        if (this.compareBrowserRangeEndpoints(ieRange, start, end) < 0 && this.compareBrowserRangeEndpoints(ieRange, end, start) > 0) {
          return this.getEndpointNode_(endpoint, child);
        }
      }
    }
  }
  return node;
};
goog.dom.browserrange.IeRange.prototype.compareNodeEndpoints_ = function(node, thisEndpoint, otherEndpoint) {
  return this.range_.compareEndPoints((thisEndpoint == goog.dom.RangeEndpoint.START ? "Start" : "End") + "To" + (otherEndpoint == goog.dom.RangeEndpoint.START ? "Start" : "End"), goog.dom.browserrange.createRangeFromNodeContents(node).getBrowserRange());
};
goog.dom.browserrange.IeRange.prototype.getOffset_ = function(endpoint, opt_container) {
  var isStartEndpoint = endpoint == goog.dom.RangeEndpoint.START;
  var container = opt_container || (isStartEndpoint ? this.getStartNode() : this.getEndNode());
  if (container.nodeType == goog.dom.NodeType.ELEMENT) {
    var children = container.childNodes;
    var len = children.length;
    var edge = isStartEndpoint ? 0 : len - 1;
    var sign = isStartEndpoint ? 1 : -1;
    for (var i = edge; i >= 0 && i < len; i += sign) {
      var child = children[i];
      if (goog.dom.browserrange.canContainRangeEndpoint(child)) {
        continue;
      }
      var endPointCompare = this.compareNodeEndpoints_(child, endpoint, endpoint);
      if (endPointCompare == 0) {
        return isStartEndpoint ? i : i + 1;
      }
    }
    return i == -1 ? 0 : i;
  } else {
    var range = this.range_.duplicate();
    var nodeRange = goog.dom.browserrange.IeRange.getBrowserRangeForNode_(container);
    range.setEndPoint(isStartEndpoint ? "EndToEnd" : "StartToStart", nodeRange);
    var rangeLength = range.text.length;
    return isStartEndpoint ? container.length - rangeLength : rangeLength;
  }
};
goog.dom.browserrange.IeRange.getNodeText_ = function(node) {
  return node.nodeType == goog.dom.NodeType.TEXT ? node.nodeValue : node.innerText;
};
goog.dom.browserrange.IeRange.prototype.isRangeInDocument = function() {
  var range = this.doc_.body.createTextRange();
  range.moveToElementText(this.doc_.body);
  return this.containsRange(new goog.dom.browserrange.IeRange(range, this.doc_), true);
};
goog.dom.browserrange.IeRange.prototype.isCollapsed = function() {
  return this.range_.compareEndPoints("StartToEnd", this.range_) == 0;
};
goog.dom.browserrange.IeRange.prototype.getText = function() {
  return this.range_.text;
};
goog.dom.browserrange.IeRange.prototype.getValidHtml = function() {
  return this.range_.htmlText;
};
goog.dom.browserrange.IeRange.prototype.select = function(opt_reverse) {
  this.range_.select();
};
goog.dom.browserrange.IeRange.prototype.removeContents = function() {
  if (!this.isCollapsed() && this.range_.htmlText) {
    var startNode = this.getStartNode();
    var endNode = this.getEndNode();
    var oldText = this.range_.text;
    var clone = this.range_.duplicate();
    clone.moveStart("character", 1);
    clone.moveStart("character", -1);
    if (clone.text == oldText) {
      this.range_ = clone;
    }
    this.range_.text = "";
    this.clearCachedValues_();
    var newStartNode = this.getStartNode();
    var newStartOffset = this.getStartOffset();
    try {
      var sibling = startNode.nextSibling;
      if (startNode == endNode && startNode.parentNode && startNode.nodeType == goog.dom.NodeType.TEXT && sibling && sibling.nodeType == goog.dom.NodeType.TEXT) {
        startNode.nodeValue += sibling.nodeValue;
        goog.dom.removeNode(sibling);
        this.range_ = goog.dom.browserrange.IeRange.getBrowserRangeForNode_(newStartNode);
        this.range_.move("character", newStartOffset);
        this.clearCachedValues_();
      }
    } catch (e) {
    }
  }
};
goog.dom.browserrange.IeRange.getDomHelper_ = function(range) {
  return goog.dom.getDomHelper(range.parentElement());
};
goog.dom.browserrange.IeRange.pasteElement_ = function(range, element, opt_domHelper) {
  opt_domHelper = opt_domHelper || goog.dom.browserrange.IeRange.getDomHelper_(range);
  var id;
  var originalId = id = element.id;
  if (!id) {
    id = element.id = goog.string.createUniqueString();
  }
  range.pasteHTML(element.outerHTML);
  element = opt_domHelper.getElement(id);
  if (element) {
    if (!originalId) {
      element.removeAttribute("id");
    }
  }
  return element;
};
goog.dom.browserrange.IeRange.prototype.surroundContents = function(element) {
  goog.dom.removeNode(element);
  element.innerHTML = this.range_.htmlText;
  element = goog.dom.browserrange.IeRange.pasteElement_(this.range_, element);
  if (element) {
    this.range_.moveToElementText(element);
  }
  this.clearCachedValues_();
  return element;
};
goog.dom.browserrange.IeRange.insertNode_ = function(clone, node, before, opt_domHelper) {
  opt_domHelper = opt_domHelper || goog.dom.browserrange.IeRange.getDomHelper_(clone);
  var isNonElement;
  if (node.nodeType != goog.dom.NodeType.ELEMENT) {
    isNonElement = true;
    node = opt_domHelper.createDom(goog.dom.TagName.DIV, null, node);
  }
  clone.collapse(before);
  node = goog.dom.browserrange.IeRange.pasteElement_(clone, node, opt_domHelper);
  if (isNonElement) {
    var newNonElement = node.firstChild;
    opt_domHelper.flattenElement(node);
    node = newNonElement;
  }
  return node;
};
goog.dom.browserrange.IeRange.prototype.insertNode = function(node, before) {
  var output = goog.dom.browserrange.IeRange.insertNode_(this.range_.duplicate(), node, before);
  this.clearCachedValues_();
  return output;
};
goog.dom.browserrange.IeRange.prototype.surroundWithNodes = function(startNode, endNode) {
  var clone1 = this.range_.duplicate();
  var clone2 = this.range_.duplicate();
  goog.dom.browserrange.IeRange.insertNode_(clone1, startNode, true);
  goog.dom.browserrange.IeRange.insertNode_(clone2, endNode, false);
  this.clearCachedValues_();
};
goog.dom.browserrange.IeRange.prototype.collapse = function(toStart) {
  this.range_.collapse(toStart);
  if (toStart) {
    this.endNode_ = this.startNode_;
    this.endOffset_ = this.startOffset_;
  } else {
    this.startNode_ = this.endNode_;
    this.startOffset_ = this.endOffset_;
  }
};
goog.provide("goog.dom.browserrange.OperaRange");
goog.require("goog.dom.browserrange.W3cRange");
goog.dom.browserrange.OperaRange = function(range) {
  goog.dom.browserrange.W3cRange.call(this, range);
};
goog.inherits(goog.dom.browserrange.OperaRange, goog.dom.browserrange.W3cRange);
goog.dom.browserrange.OperaRange.createFromNodeContents = function(node) {
  return new goog.dom.browserrange.OperaRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNode(node));
};
goog.dom.browserrange.OperaRange.createFromNodes = function(startNode, startOffset, endNode, endOffset) {
  return new goog.dom.browserrange.OperaRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNodes(startNode, startOffset, endNode, endOffset));
};
goog.dom.browserrange.OperaRange.prototype.selectInternal = function(selection, reversed) {
  selection.collapse(this.getStartNode(), this.getStartOffset());
  if (this.getEndNode() != this.getStartNode() || this.getEndOffset() != this.getStartOffset()) {
    selection.extend(this.getEndNode(), this.getEndOffset());
  }
  if (selection.rangeCount == 0) {
    selection.addRange(this.range_);
  }
};
goog.provide("goog.dom.browserrange.WebKitRange");
goog.require("goog.dom.RangeEndpoint");
goog.require("goog.dom.browserrange.W3cRange");
goog.require("goog.userAgent");
goog.dom.browserrange.WebKitRange = function(range) {
  goog.dom.browserrange.W3cRange.call(this, range);
};
goog.inherits(goog.dom.browserrange.WebKitRange, goog.dom.browserrange.W3cRange);
goog.dom.browserrange.WebKitRange.createFromNodeContents = function(node) {
  return new goog.dom.browserrange.WebKitRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNode(node));
};
goog.dom.browserrange.WebKitRange.createFromNodes = function(startNode, startOffset, endNode, endOffset) {
  return new goog.dom.browserrange.WebKitRange(goog.dom.browserrange.W3cRange.getBrowserRangeForNodes(startNode, startOffset, endNode, endOffset));
};
goog.dom.browserrange.WebKitRange.prototype.compareBrowserRangeEndpoints = function(range, thisEndpoint, otherEndpoint) {
  if (goog.userAgent.isVersionOrHigher("528")) {
    return goog.dom.browserrange.WebKitRange.superClass_.compareBrowserRangeEndpoints.call(this, range, thisEndpoint, otherEndpoint);
  }
  return this.range_.compareBoundaryPoints(otherEndpoint == goog.dom.RangeEndpoint.START ? thisEndpoint == goog.dom.RangeEndpoint.START ? goog.global["Range"].START_TO_START : goog.global["Range"].END_TO_START : thisEndpoint == goog.dom.RangeEndpoint.START ? goog.global["Range"].START_TO_END : goog.global["Range"].END_TO_END, range);
};
goog.dom.browserrange.WebKitRange.prototype.selectInternal = function(selection, reversed) {
  if (reversed) {
    selection.setBaseAndExtent(this.getEndNode(), this.getEndOffset(), this.getStartNode(), this.getStartOffset());
  } else {
    selection.setBaseAndExtent(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset());
  }
};
goog.provide("goog.dom.browserrange");
goog.provide("goog.dom.browserrange.Error");
goog.require("goog.dom");
goog.require("goog.dom.BrowserFeature");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.browserrange.GeckoRange");
goog.require("goog.dom.browserrange.IeRange");
goog.require("goog.dom.browserrange.OperaRange");
goog.require("goog.dom.browserrange.W3cRange");
goog.require("goog.dom.browserrange.WebKitRange");
goog.require("goog.userAgent");
goog.dom.browserrange.Error = {NOT_IMPLEMENTED:"Not Implemented"};
goog.dom.browserrange.createRange = function(range) {
  if (goog.dom.BrowserFeature.LEGACY_IE_RANGES) {
    return new goog.dom.browserrange.IeRange(range, goog.dom.getOwnerDocument(range.parentElement()));
  } else {
    if (goog.userAgent.WEBKIT) {
      return new goog.dom.browserrange.WebKitRange(range);
    } else {
      if (goog.userAgent.GECKO) {
        return new goog.dom.browserrange.GeckoRange(range);
      } else {
        if (goog.userAgent.OPERA) {
          return new goog.dom.browserrange.OperaRange(range);
        } else {
          return new goog.dom.browserrange.W3cRange(range);
        }
      }
    }
  }
};
goog.dom.browserrange.createRangeFromNodeContents = function(node) {
  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
    return goog.dom.browserrange.IeRange.createFromNodeContents(node);
  } else {
    if (goog.userAgent.WEBKIT) {
      return goog.dom.browserrange.WebKitRange.createFromNodeContents(node);
    } else {
      if (goog.userAgent.GECKO) {
        return goog.dom.browserrange.GeckoRange.createFromNodeContents(node);
      } else {
        if (goog.userAgent.OPERA) {
          return goog.dom.browserrange.OperaRange.createFromNodeContents(node);
        } else {
          return goog.dom.browserrange.W3cRange.createFromNodeContents(node);
        }
      }
    }
  }
};
goog.dom.browserrange.createRangeFromNodes = function(startNode, startOffset, endNode, endOffset) {
  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
    return goog.dom.browserrange.IeRange.createFromNodes(startNode, startOffset, endNode, endOffset);
  } else {
    if (goog.userAgent.WEBKIT) {
      return goog.dom.browserrange.WebKitRange.createFromNodes(startNode, startOffset, endNode, endOffset);
    } else {
      if (goog.userAgent.GECKO) {
        return goog.dom.browserrange.GeckoRange.createFromNodes(startNode, startOffset, endNode, endOffset);
      } else {
        if (goog.userAgent.OPERA) {
          return goog.dom.browserrange.OperaRange.createFromNodes(startNode, startOffset, endNode, endOffset);
        } else {
          return goog.dom.browserrange.W3cRange.createFromNodes(startNode, startOffset, endNode, endOffset);
        }
      }
    }
  }
};
goog.dom.browserrange.canContainRangeEndpoint = function(node) {
  return goog.dom.canHaveChildren(node) || node.nodeType == goog.dom.NodeType.TEXT;
};
goog.provide("goog.dom.TextRange");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.AbstractRange");
goog.require("goog.dom.RangeType");
goog.require("goog.dom.SavedRange");
goog.require("goog.dom.TagName");
goog.require("goog.dom.TextRangeIterator");
goog.require("goog.dom.browserrange");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.dom.TextRange = function() {
  this.browserRangeWrapper_ = null;
  this.startNode_ = null;
  this.startOffset_ = null;
  this.endNode_ = null;
  this.endOffset_ = null;
  this.isReversed_ = false;
};
goog.inherits(goog.dom.TextRange, goog.dom.AbstractRange);
goog.dom.TextRange.createFromBrowserRange = function(range, opt_isReversed) {
  return goog.dom.TextRange.createFromBrowserRangeWrapper_(goog.dom.browserrange.createRange(range), opt_isReversed);
};
goog.dom.TextRange.createFromBrowserRangeWrapper_ = function(browserRange, opt_isReversed) {
  var range = new goog.dom.TextRange;
  range.browserRangeWrapper_ = browserRange;
  range.isReversed_ = !!opt_isReversed;
  return range;
};
goog.dom.TextRange.createFromNodeContents = function(node, opt_isReversed) {
  return goog.dom.TextRange.createFromBrowserRangeWrapper_(goog.dom.browserrange.createRangeFromNodeContents(node), opt_isReversed);
};
goog.dom.TextRange.createFromNodes = function(anchorNode, anchorOffset, focusNode, focusOffset) {
  var range = new goog.dom.TextRange;
  range.isReversed_ = goog.dom.Range.isReversed(anchorNode, anchorOffset, focusNode, focusOffset);
  if (goog.dom.isElement(anchorNode) && !goog.dom.canHaveChildren(anchorNode)) {
    var parent = anchorNode.parentNode;
    anchorOffset = goog.array.indexOf(parent.childNodes, anchorNode);
    anchorNode = parent;
  }
  if (goog.dom.isElement(focusNode) && !goog.dom.canHaveChildren(focusNode)) {
    var parent = focusNode.parentNode;
    focusOffset = goog.array.indexOf(parent.childNodes, focusNode);
    focusNode = parent;
  }
  if (range.isReversed_) {
    range.startNode_ = focusNode;
    range.startOffset_ = focusOffset;
    range.endNode_ = anchorNode;
    range.endOffset_ = anchorOffset;
  } else {
    range.startNode_ = anchorNode;
    range.startOffset_ = anchorOffset;
    range.endNode_ = focusNode;
    range.endOffset_ = focusOffset;
  }
  return range;
};
goog.dom.TextRange.prototype.clone = function() {
  var range = new goog.dom.TextRange;
  range.browserRangeWrapper_ = this.browserRangeWrapper_ && this.browserRangeWrapper_.clone();
  range.startNode_ = this.startNode_;
  range.startOffset_ = this.startOffset_;
  range.endNode_ = this.endNode_;
  range.endOffset_ = this.endOffset_;
  range.isReversed_ = this.isReversed_;
  return range;
};
goog.dom.TextRange.prototype.getType = function() {
  return goog.dom.RangeType.TEXT;
};
goog.dom.TextRange.prototype.getBrowserRangeObject = function() {
  return this.getBrowserRangeWrapper_().getBrowserRange();
};
goog.dom.TextRange.prototype.setBrowserRangeObject = function(nativeRange) {
  if (goog.dom.AbstractRange.isNativeControlRange(nativeRange)) {
    return false;
  }
  this.browserRangeWrapper_ = goog.dom.browserrange.createRange(nativeRange);
  this.clearCachedValues_();
  return true;
};
goog.dom.TextRange.prototype.clearCachedValues_ = function() {
  this.startNode_ = this.startOffset_ = this.endNode_ = this.endOffset_ = null;
};
goog.dom.TextRange.prototype.getTextRangeCount = function() {
  return 1;
};
goog.dom.TextRange.prototype.getTextRange = function(i) {
  return this;
};
goog.dom.TextRange.prototype.getBrowserRangeWrapper_ = function() {
  return this.browserRangeWrapper_ || (this.browserRangeWrapper_ = goog.dom.browserrange.createRangeFromNodes(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset()));
};
goog.dom.TextRange.prototype.getContainer = function() {
  return this.getBrowserRangeWrapper_().getContainer();
};
goog.dom.TextRange.prototype.getStartNode = function() {
  return this.startNode_ || (this.startNode_ = this.getBrowserRangeWrapper_().getStartNode());
};
goog.dom.TextRange.prototype.getStartOffset = function() {
  return this.startOffset_ != null ? this.startOffset_ : this.startOffset_ = this.getBrowserRangeWrapper_().getStartOffset();
};
goog.dom.TextRange.prototype.getStartPosition = function() {
  return this.getBrowserRangeWrapper_().getStartPosition();
};
goog.dom.TextRange.prototype.getEndNode = function() {
  return this.endNode_ || (this.endNode_ = this.getBrowserRangeWrapper_().getEndNode());
};
goog.dom.TextRange.prototype.getEndOffset = function() {
  return this.endOffset_ != null ? this.endOffset_ : this.endOffset_ = this.getBrowserRangeWrapper_().getEndOffset();
};
goog.dom.TextRange.prototype.getEndPosition = function() {
  return this.getBrowserRangeWrapper_().getEndPosition();
};
goog.dom.TextRange.prototype.moveToNodes = function(startNode, startOffset, endNode, endOffset, isReversed) {
  this.startNode_ = startNode;
  this.startOffset_ = startOffset;
  this.endNode_ = endNode;
  this.endOffset_ = endOffset;
  this.isReversed_ = isReversed;
  this.browserRangeWrapper_ = null;
};
goog.dom.TextRange.prototype.isReversed = function() {
  return this.isReversed_;
};
goog.dom.TextRange.prototype.containsRange = function(otherRange, opt_allowPartial) {
  var otherRangeType = otherRange.getType();
  if (otherRangeType == goog.dom.RangeType.TEXT) {
    return this.getBrowserRangeWrapper_().containsRange(otherRange.getBrowserRangeWrapper_(), opt_allowPartial);
  } else {
    if (otherRangeType == goog.dom.RangeType.CONTROL) {
      var elements = otherRange.getElements();
      var fn = opt_allowPartial ? goog.array.some : goog.array.every;
      return fn(elements, function(el) {
        return this.containsNode(el, opt_allowPartial);
      }, this);
    }
  }
  return false;
};
goog.dom.TextRange.prototype.containsNode = function(node, opt_allowPartial) {
  return this.containsRange(goog.dom.TextRange.createFromNodeContents(node), opt_allowPartial);
};
goog.dom.TextRange.isAttachedNode = function(node) {
  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
    var returnValue = false;
    try {
      returnValue = node.parentNode;
    } catch (e) {
    }
    return !!returnValue;
  } else {
    return goog.dom.contains(node.ownerDocument.body, node);
  }
};
goog.dom.TextRange.prototype.isRangeInDocument = function() {
  return (!this.startNode_ || goog.dom.TextRange.isAttachedNode(this.startNode_)) && (!this.endNode_ || goog.dom.TextRange.isAttachedNode(this.endNode_)) && (!(goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) || this.getBrowserRangeWrapper_().isRangeInDocument());
};
goog.dom.TextRange.prototype.isCollapsed = function() {
  return this.getBrowserRangeWrapper_().isCollapsed();
};
goog.dom.TextRange.prototype.getText = function() {
  return this.getBrowserRangeWrapper_().getText();
};
goog.dom.TextRange.prototype.getHtmlFragment = function() {
  return this.getBrowserRangeWrapper_().getHtmlFragment();
};
goog.dom.TextRange.prototype.getValidHtml = function() {
  return this.getBrowserRangeWrapper_().getValidHtml();
};
goog.dom.TextRange.prototype.getPastableHtml = function() {
  var html = this.getValidHtml();
  if (html.match(/^\s*<td\b/i)) {
    html = "<table><tbody><tr>" + html + "</tr></tbody></table>";
  } else {
    if (html.match(/^\s*<tr\b/i)) {
      html = "<table><tbody>" + html + "</tbody></table>";
    } else {
      if (html.match(/^\s*<tbody\b/i)) {
        html = "<table>" + html + "</table>";
      } else {
        if (html.match(/^\s*<li\b/i)) {
          var container = this.getContainer();
          var tagType = goog.dom.TagName.UL;
          while (container) {
            if (container.tagName == goog.dom.TagName.OL) {
              tagType = goog.dom.TagName.OL;
              break;
            } else {
              if (container.tagName == goog.dom.TagName.UL) {
                break;
              }
            }
            container = container.parentNode;
          }
          html = goog.string.buildString("<", tagType, ">", html, "</", tagType, ">");
        }
      }
    }
  }
  return html;
};
goog.dom.TextRange.prototype.__iterator__ = function(opt_keys) {
  return new goog.dom.TextRangeIterator(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset());
};
goog.dom.TextRange.prototype.select = function() {
  this.getBrowserRangeWrapper_().select(this.isReversed_);
};
goog.dom.TextRange.prototype.removeContents = function() {
  this.getBrowserRangeWrapper_().removeContents();
  this.clearCachedValues_();
};
goog.dom.TextRange.prototype.surroundContents = function(element) {
  var output = this.getBrowserRangeWrapper_().surroundContents(element);
  this.clearCachedValues_();
  return output;
};
goog.dom.TextRange.prototype.insertNode = function(node, before) {
  var output = this.getBrowserRangeWrapper_().insertNode(node, before);
  this.clearCachedValues_();
  return output;
};
goog.dom.TextRange.prototype.surroundWithNodes = function(startNode, endNode) {
  this.getBrowserRangeWrapper_().surroundWithNodes(startNode, endNode);
  this.clearCachedValues_();
};
goog.dom.TextRange.prototype.saveUsingDom = function() {
  return new goog.dom.DomSavedTextRange_(this);
};
goog.dom.TextRange.prototype.collapse = function(toAnchor) {
  var toStart = this.isReversed() ? !toAnchor : toAnchor;
  if (this.browserRangeWrapper_) {
    this.browserRangeWrapper_.collapse(toStart);
  }
  if (toStart) {
    this.endNode_ = this.startNode_;
    this.endOffset_ = this.startOffset_;
  } else {
    this.startNode_ = this.endNode_;
    this.startOffset_ = this.endOffset_;
  }
  this.isReversed_ = false;
};
goog.dom.DomSavedTextRange_ = function(range) {
  goog.dom.DomSavedTextRange_.base(this, "constructor");
  this.anchorNode_ = range.getAnchorNode();
  this.anchorOffset_ = range.getAnchorOffset();
  this.focusNode_ = range.getFocusNode();
  this.focusOffset_ = range.getFocusOffset();
};
goog.inherits(goog.dom.DomSavedTextRange_, goog.dom.SavedRange);
goog.dom.DomSavedTextRange_.prototype.restoreInternal = function() {
  return goog.dom.Range.createFromNodes(this.anchorNode_, this.anchorOffset_, this.focusNode_, this.focusOffset_);
};
goog.dom.DomSavedTextRange_.prototype.disposeInternal = function() {
  goog.dom.DomSavedTextRange_.superClass_.disposeInternal.call(this);
  this.anchorNode_ = null;
  this.focusNode_ = null;
};
goog.provide("goog.dom.AbstractMultiRange");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.AbstractRange");
goog.require("goog.dom.TextRange");
goog.dom.AbstractMultiRange = function() {
};
goog.inherits(goog.dom.AbstractMultiRange, goog.dom.AbstractRange);
goog.dom.AbstractMultiRange.prototype.containsRange = function(otherRange, opt_allowPartial) {
  var ranges = this.getTextRanges();
  var otherRanges = otherRange.getTextRanges();
  var fn = opt_allowPartial ? goog.array.some : goog.array.every;
  return fn(otherRanges, function(otherRange) {
    return goog.array.some(ranges, function(range) {
      return range.containsRange(otherRange, opt_allowPartial);
    });
  });
};
goog.dom.AbstractMultiRange.prototype.containsNode = function(node, opt_allowPartial) {
  return this.containsRange(goog.dom.TextRange.createFromNodeContents(node), opt_allowPartial);
};
goog.dom.AbstractMultiRange.prototype.insertNode = function(node, before) {
  if (before) {
    goog.dom.insertSiblingBefore(node, this.getStartNode());
  } else {
    goog.dom.insertSiblingAfter(node, this.getEndNode());
  }
  return node;
};
goog.dom.AbstractMultiRange.prototype.surroundWithNodes = function(startNode, endNode) {
  this.insertNode(startNode, true);
  this.insertNode(endNode, false);
};
goog.provide("goog.dom.ControlRange");
goog.provide("goog.dom.ControlRangeIterator");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.AbstractMultiRange");
goog.require("goog.dom.AbstractRange");
goog.require("goog.dom.RangeIterator");
goog.require("goog.dom.RangeType");
goog.require("goog.dom.SavedRange");
goog.require("goog.dom.TagWalkType");
goog.require("goog.dom.TextRange");
goog.require("goog.iter.StopIteration");
goog.require("goog.userAgent");
goog.dom.ControlRange = function() {
  this.range_ = null;
  this.elements_ = null;
  this.sortedElements_ = null;
};
goog.inherits(goog.dom.ControlRange, goog.dom.AbstractMultiRange);
goog.dom.ControlRange.createFromBrowserRange = function(controlRange) {
  var range = new goog.dom.ControlRange;
  range.range_ = controlRange;
  return range;
};
goog.dom.ControlRange.createFromElements = function(var_args) {
  var range = goog.dom.getOwnerDocument(arguments[0]).body.createControlRange();
  for (var i = 0, len = arguments.length; i < len; i++) {
    range.addElement(arguments[i]);
  }
  return goog.dom.ControlRange.createFromBrowserRange(range);
};
goog.dom.ControlRange.prototype.clearCachedValues_ = function() {
  this.elements_ = null;
  this.sortedElements_ = null;
};
goog.dom.ControlRange.prototype.clone = function() {
  return goog.dom.ControlRange.createFromElements.apply(this, this.getElements());
};
goog.dom.ControlRange.prototype.getType = function() {
  return goog.dom.RangeType.CONTROL;
};
goog.dom.ControlRange.prototype.getBrowserRangeObject = function() {
  return this.range_ || document.body.createControlRange();
};
goog.dom.ControlRange.prototype.setBrowserRangeObject = function(nativeRange) {
  if (!goog.dom.AbstractRange.isNativeControlRange(nativeRange)) {
    return false;
  }
  this.range_ = nativeRange;
  return true;
};
goog.dom.ControlRange.prototype.getTextRangeCount = function() {
  return this.range_ ? this.range_.length : 0;
};
goog.dom.ControlRange.prototype.getTextRange = function(i) {
  return goog.dom.TextRange.createFromNodeContents(this.range_.item(i));
};
goog.dom.ControlRange.prototype.getContainer = function() {
  return goog.dom.findCommonAncestor.apply(null, this.getElements());
};
goog.dom.ControlRange.prototype.getStartNode = function() {
  return this.getSortedElements()[0];
};
goog.dom.ControlRange.prototype.getStartOffset = function() {
  return 0;
};
goog.dom.ControlRange.prototype.getEndNode = function() {
  var sorted = this.getSortedElements();
  var startsLast = goog.array.peek(sorted);
  return goog.array.find(sorted, function(el) {
    return goog.dom.contains(el, startsLast);
  });
};
goog.dom.ControlRange.prototype.getEndOffset = function() {
  return this.getEndNode().childNodes.length;
};
goog.dom.ControlRange.prototype.getElements = function() {
  if (!this.elements_) {
    this.elements_ = [];
    if (this.range_) {
      for (var i = 0; i < this.range_.length; i++) {
        this.elements_.push(this.range_.item(i));
      }
    }
  }
  return this.elements_;
};
goog.dom.ControlRange.prototype.getSortedElements = function() {
  if (!this.sortedElements_) {
    this.sortedElements_ = this.getElements().concat();
    this.sortedElements_.sort(function(a, b) {
      return a.sourceIndex - b.sourceIndex;
    });
  }
  return this.sortedElements_;
};
goog.dom.ControlRange.prototype.isRangeInDocument = function() {
  var returnValue = false;
  try {
    returnValue = goog.array.every(this.getElements(), function(element) {
      return goog.userAgent.IE ? !!element.parentNode : goog.dom.contains(element.ownerDocument.body, element);
    });
  } catch (e) {
  }
  return returnValue;
};
goog.dom.ControlRange.prototype.isCollapsed = function() {
  return !this.range_ || !this.range_.length;
};
goog.dom.ControlRange.prototype.getText = function() {
  return "";
};
goog.dom.ControlRange.prototype.getHtmlFragment = function() {
  return goog.array.map(this.getSortedElements(), goog.dom.getOuterHtml).join("");
};
goog.dom.ControlRange.prototype.getValidHtml = function() {
  return this.getHtmlFragment();
};
goog.dom.ControlRange.prototype.getPastableHtml = goog.dom.ControlRange.prototype.getValidHtml;
goog.dom.ControlRange.prototype.__iterator__ = function(opt_keys) {
  return new goog.dom.ControlRangeIterator(this);
};
goog.dom.ControlRange.prototype.select = function() {
  if (this.range_) {
    this.range_.select();
  }
};
goog.dom.ControlRange.prototype.removeContents = function() {
  if (this.range_) {
    var nodes = [];
    for (var i = 0, len = this.range_.length; i < len; i++) {
      nodes.push(this.range_.item(i));
    }
    goog.array.forEach(nodes, goog.dom.removeNode);
    this.collapse(false);
  }
};
goog.dom.ControlRange.prototype.replaceContentsWithNode = function(node) {
  var result = this.insertNode(node, true);
  if (!this.isCollapsed()) {
    this.removeContents();
  }
  return result;
};
goog.dom.ControlRange.prototype.saveUsingDom = function() {
  return new goog.dom.DomSavedControlRange_(this);
};
goog.dom.ControlRange.prototype.collapse = function(toAnchor) {
  this.range_ = null;
  this.clearCachedValues_();
};
goog.dom.DomSavedControlRange_ = function(range) {
  this.elements_ = range.getElements();
};
goog.inherits(goog.dom.DomSavedControlRange_, goog.dom.SavedRange);
goog.dom.DomSavedControlRange_.prototype.restoreInternal = function() {
  var doc = this.elements_.length ? goog.dom.getOwnerDocument(this.elements_[0]) : document;
  var controlRange = doc.body.createControlRange();
  for (var i = 0, len = this.elements_.length; i < len; i++) {
    controlRange.addElement(this.elements_[i]);
  }
  return goog.dom.ControlRange.createFromBrowserRange(controlRange);
};
goog.dom.DomSavedControlRange_.prototype.disposeInternal = function() {
  goog.dom.DomSavedControlRange_.superClass_.disposeInternal.call(this);
  delete this.elements_;
};
goog.dom.ControlRangeIterator = function(range) {
  this.startNode_ = null;
  this.endNode_ = null;
  this.elements_ = null;
  if (range) {
    this.elements_ = range.getSortedElements();
    this.startNode_ = this.elements_.shift();
    this.endNode_ = goog.array.peek(this.elements_) || this.startNode_;
  }
  goog.dom.ControlRangeIterator.base(this, "constructor", this.startNode_, false);
};
goog.inherits(goog.dom.ControlRangeIterator, goog.dom.RangeIterator);
goog.dom.ControlRangeIterator.prototype.getStartTextOffset = function() {
  return 0;
};
goog.dom.ControlRangeIterator.prototype.getEndTextOffset = function() {
  return 0;
};
goog.dom.ControlRangeIterator.prototype.getStartNode = function() {
  return this.startNode_;
};
goog.dom.ControlRangeIterator.prototype.getEndNode = function() {
  return this.endNode_;
};
goog.dom.ControlRangeIterator.prototype.isLast = function() {
  return !this.depth && !this.elements_.length;
};
goog.dom.ControlRangeIterator.prototype.next = function() {
  if (this.isLast()) {
    throw goog.iter.StopIteration;
  } else {
    if (!this.depth) {
      var el = this.elements_.shift();
      this.setPosition(el, goog.dom.TagWalkType.START_TAG, goog.dom.TagWalkType.START_TAG);
      return el;
    }
  }
  return goog.dom.ControlRangeIterator.superClass_.next.call(this);
};
goog.dom.ControlRangeIterator.prototype.copyFrom = function(other) {
  this.elements_ = other.elements_;
  this.startNode_ = other.startNode_;
  this.endNode_ = other.endNode_;
  goog.dom.ControlRangeIterator.superClass_.copyFrom.call(this, other);
};
goog.dom.ControlRangeIterator.prototype.clone = function() {
  var copy = new goog.dom.ControlRangeIterator(null);
  copy.copyFrom(this);
  return copy;
};
goog.provide("goog.dom.MultiRange");
goog.provide("goog.dom.MultiRangeIterator");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.AbstractMultiRange");
goog.require("goog.dom.AbstractRange");
goog.require("goog.dom.RangeIterator");
goog.require("goog.dom.RangeType");
goog.require("goog.dom.SavedRange");
goog.require("goog.dom.TextRange");
goog.require("goog.iter");
goog.require("goog.iter.StopIteration");
goog.require("goog.log");
goog.dom.MultiRange = function() {
  this.logger_ = goog.log.getLogger("goog.dom.MultiRange");
  this.browserRanges_ = [];
  this.ranges_ = [];
  this.sortedRanges_ = null;
  this.container_ = null;
};
goog.inherits(goog.dom.MultiRange, goog.dom.AbstractMultiRange);
goog.dom.MultiRange.createFromBrowserSelection = function(selection) {
  var range = new goog.dom.MultiRange;
  for (var i = 0, len = selection.rangeCount; i < len; i++) {
    range.browserRanges_.push(selection.getRangeAt(i));
  }
  return range;
};
goog.dom.MultiRange.createFromBrowserRanges = function(browserRanges) {
  var range = new goog.dom.MultiRange;
  range.browserRanges_ = goog.array.clone(browserRanges);
  return range;
};
goog.dom.MultiRange.createFromTextRanges = function(textRanges) {
  var range = new goog.dom.MultiRange;
  range.ranges_ = textRanges;
  range.browserRanges_ = goog.array.map(textRanges, function(range) {
    return range.getBrowserRangeObject();
  });
  return range;
};
goog.dom.MultiRange.prototype.clearCachedValues_ = function() {
  this.ranges_ = [];
  this.sortedRanges_ = null;
  this.container_ = null;
};
goog.dom.MultiRange.prototype.clone = function() {
  return goog.dom.MultiRange.createFromBrowserRanges(this.browserRanges_);
};
goog.dom.MultiRange.prototype.getType = function() {
  return goog.dom.RangeType.MULTI;
};
goog.dom.MultiRange.prototype.getBrowserRangeObject = function() {
  if (this.browserRanges_.length > 1) {
    goog.log.warning(this.logger_, "getBrowserRangeObject called on MultiRange with more than 1 range");
  }
  return this.browserRanges_[0];
};
goog.dom.MultiRange.prototype.setBrowserRangeObject = function(nativeRange) {
  return false;
};
goog.dom.MultiRange.prototype.getTextRangeCount = function() {
  return this.browserRanges_.length;
};
goog.dom.MultiRange.prototype.getTextRange = function(i) {
  if (!this.ranges_[i]) {
    this.ranges_[i] = goog.dom.TextRange.createFromBrowserRange(this.browserRanges_[i]);
  }
  return this.ranges_[i];
};
goog.dom.MultiRange.prototype.getContainer = function() {
  if (!this.container_) {
    var nodes = [];
    for (var i = 0, len = this.getTextRangeCount(); i < len; i++) {
      nodes.push(this.getTextRange(i).getContainer());
    }
    this.container_ = goog.dom.findCommonAncestor.apply(null, nodes);
  }
  return this.container_;
};
goog.dom.MultiRange.prototype.getSortedRanges = function() {
  if (!this.sortedRanges_) {
    this.sortedRanges_ = this.getTextRanges();
    this.sortedRanges_.sort(function(a, b) {
      var aStartNode = a.getStartNode();
      var aStartOffset = a.getStartOffset();
      var bStartNode = b.getStartNode();
      var bStartOffset = b.getStartOffset();
      if (aStartNode == bStartNode && aStartOffset == bStartOffset) {
        return 0;
      }
      return goog.dom.Range.isReversed(aStartNode, aStartOffset, bStartNode, bStartOffset) ? 1 : -1;
    });
  }
  return this.sortedRanges_;
};
goog.dom.MultiRange.prototype.getStartNode = function() {
  return this.getSortedRanges()[0].getStartNode();
};
goog.dom.MultiRange.prototype.getStartOffset = function() {
  return this.getSortedRanges()[0].getStartOffset();
};
goog.dom.MultiRange.prototype.getEndNode = function() {
  return goog.array.peek(this.getSortedRanges()).getEndNode();
};
goog.dom.MultiRange.prototype.getEndOffset = function() {
  return goog.array.peek(this.getSortedRanges()).getEndOffset();
};
goog.dom.MultiRange.prototype.isRangeInDocument = function() {
  return goog.array.every(this.getTextRanges(), function(range) {
    return range.isRangeInDocument();
  });
};
goog.dom.MultiRange.prototype.isCollapsed = function() {
  return this.browserRanges_.length == 0 || this.browserRanges_.length == 1 && this.getTextRange(0).isCollapsed();
};
goog.dom.MultiRange.prototype.getText = function() {
  return goog.array.map(this.getTextRanges(), function(range) {
    return range.getText();
  }).join("");
};
goog.dom.MultiRange.prototype.getHtmlFragment = function() {
  return this.getValidHtml();
};
goog.dom.MultiRange.prototype.getValidHtml = function() {
  return goog.array.map(this.getTextRanges(), function(range) {
    return range.getValidHtml();
  }).join("");
};
goog.dom.MultiRange.prototype.getPastableHtml = function() {
  return this.getValidHtml();
};
goog.dom.MultiRange.prototype.__iterator__ = function(opt_keys) {
  return new goog.dom.MultiRangeIterator(this);
};
goog.dom.MultiRange.prototype.select = function() {
  var selection = goog.dom.AbstractRange.getBrowserSelectionForWindow(this.getWindow());
  selection.removeAllRanges();
  for (var i = 0, len = this.getTextRangeCount(); i < len; i++) {
    selection.addRange(this.getTextRange(i).getBrowserRangeObject());
  }
};
goog.dom.MultiRange.prototype.removeContents = function() {
  goog.array.forEach(this.getTextRanges(), function(range) {
    range.removeContents();
  });
};
goog.dom.MultiRange.prototype.saveUsingDom = function() {
  return new goog.dom.DomSavedMultiRange_(this);
};
goog.dom.MultiRange.prototype.collapse = function(toAnchor) {
  if (!this.isCollapsed()) {
    var range = toAnchor ? this.getTextRange(0) : this.getTextRange(this.getTextRangeCount() - 1);
    this.clearCachedValues_();
    range.collapse(toAnchor);
    this.ranges_ = [range];
    this.sortedRanges_ = [range];
    this.browserRanges_ = [range.getBrowserRangeObject()];
  }
};
goog.dom.DomSavedMultiRange_ = function(range) {
  this.savedRanges_ = goog.array.map(range.getTextRanges(), function(range) {
    return range.saveUsingDom();
  });
};
goog.inherits(goog.dom.DomSavedMultiRange_, goog.dom.SavedRange);
goog.dom.DomSavedMultiRange_.prototype.restoreInternal = function() {
  var ranges = goog.array.map(this.savedRanges_, function(savedRange) {
    return savedRange.restore();
  });
  return goog.dom.MultiRange.createFromTextRanges(ranges);
};
goog.dom.DomSavedMultiRange_.prototype.disposeInternal = function() {
  goog.dom.DomSavedMultiRange_.superClass_.disposeInternal.call(this);
  goog.array.forEach(this.savedRanges_, function(savedRange) {
    savedRange.dispose();
  });
  delete this.savedRanges_;
};
goog.dom.MultiRangeIterator = function(range) {
  this.iterators_ = null;
  this.currentIdx_ = 0;
  if (range) {
    this.iterators_ = goog.array.map(range.getSortedRanges(), function(r) {
      return goog.iter.toIterator(r);
    });
  }
  goog.dom.MultiRangeIterator.base(this, "constructor", range ? this.getStartNode() : null, false);
};
goog.inherits(goog.dom.MultiRangeIterator, goog.dom.RangeIterator);
goog.dom.MultiRangeIterator.prototype.getStartTextOffset = function() {
  return this.iterators_[this.currentIdx_].getStartTextOffset();
};
goog.dom.MultiRangeIterator.prototype.getEndTextOffset = function() {
  return this.iterators_[this.currentIdx_].getEndTextOffset();
};
goog.dom.MultiRangeIterator.prototype.getStartNode = function() {
  return this.iterators_[0].getStartNode();
};
goog.dom.MultiRangeIterator.prototype.getEndNode = function() {
  return goog.array.peek(this.iterators_).getEndNode();
};
goog.dom.MultiRangeIterator.prototype.isLast = function() {
  return this.iterators_[this.currentIdx_].isLast();
};
goog.dom.MultiRangeIterator.prototype.next = function() {
  try {
    var it = this.iterators_[this.currentIdx_];
    var next = it.next();
    this.setPosition(it.node, it.tagType, it.depth);
    return next;
  } catch (ex) {
    if (ex !== goog.iter.StopIteration || this.iterators_.length - 1 == this.currentIdx_) {
      throw ex;
    } else {
      this.currentIdx_++;
      return this.next();
    }
  }
};
goog.dom.MultiRangeIterator.prototype.copyFrom = function(other) {
  this.iterators_ = goog.array.clone(other.iterators_);
  goog.dom.MultiRangeIterator.superClass_.copyFrom.call(this, other);
};
goog.dom.MultiRangeIterator.prototype.clone = function() {
  var copy = new goog.dom.MultiRangeIterator(null);
  copy.copyFrom(this);
  return copy;
};
goog.provide("goog.dom.Range");
goog.require("goog.dom");
goog.require("goog.dom.AbstractRange");
goog.require("goog.dom.BrowserFeature");
goog.require("goog.dom.ControlRange");
goog.require("goog.dom.MultiRange");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TextRange");
goog.dom.Range.createFromWindow = function(opt_win) {
  var sel = goog.dom.AbstractRange.getBrowserSelectionForWindow(opt_win || window);
  return sel && goog.dom.Range.createFromBrowserSelection(sel);
};
goog.dom.Range.createFromBrowserSelection = function(selection) {
  var range;
  var isReversed = false;
  if (selection.createRange) {
    try {
      range = selection.createRange();
    } catch (e) {
      return null;
    }
  } else {
    if (selection.rangeCount) {
      if (selection.rangeCount > 1) {
        return goog.dom.MultiRange.createFromBrowserSelection(selection);
      } else {
        range = selection.getRangeAt(0);
        isReversed = goog.dom.Range.isReversed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);
      }
    } else {
      return null;
    }
  }
  return goog.dom.Range.createFromBrowserRange(range, isReversed);
};
goog.dom.Range.createFromBrowserRange = function(range, opt_isReversed) {
  return goog.dom.AbstractRange.isNativeControlRange(range) ? goog.dom.ControlRange.createFromBrowserRange(range) : goog.dom.TextRange.createFromBrowserRange(range, opt_isReversed);
};
goog.dom.Range.createFromNodeContents = function(node, opt_isReversed) {
  return goog.dom.TextRange.createFromNodeContents(node, opt_isReversed);
};
goog.dom.Range.createCaret = function(node, offset) {
  return goog.dom.TextRange.createFromNodes(node, offset, node, offset);
};
goog.dom.Range.createFromNodes = function(anchorNode, anchorOffset, focusNode, focusOffset) {
  return goog.dom.TextRange.createFromNodes(anchorNode, anchorOffset, focusNode, focusOffset);
};
goog.dom.Range.clearSelection = function(opt_win) {
  var sel = goog.dom.AbstractRange.getBrowserSelectionForWindow(opt_win || window);
  if (!sel) {
    return;
  }
  if (sel.empty) {
    try {
      sel.empty();
    } catch (e) {
    }
  } else {
    try {
      sel.removeAllRanges();
    } catch (e$3) {
    }
  }
};
goog.dom.Range.hasSelection = function(opt_win) {
  var sel = goog.dom.AbstractRange.getBrowserSelectionForWindow(opt_win || window);
  return !!sel && (goog.dom.BrowserFeature.LEGACY_IE_RANGES ? sel.type != "None" : !!sel.rangeCount);
};
goog.dom.Range.isReversed = function(anchorNode, anchorOffset, focusNode, focusOffset) {
  if (anchorNode == focusNode) {
    return focusOffset < anchorOffset;
  }
  var child;
  if (anchorNode.nodeType == goog.dom.NodeType.ELEMENT && anchorOffset) {
    child = anchorNode.childNodes[anchorOffset];
    if (child) {
      anchorNode = child;
      anchorOffset = 0;
    } else {
      if (goog.dom.contains(anchorNode, focusNode)) {
        return true;
      }
    }
  }
  if (focusNode.nodeType == goog.dom.NodeType.ELEMENT && focusOffset) {
    child = focusNode.childNodes[focusOffset];
    if (child) {
      focusNode = child;
      focusOffset = 0;
    } else {
      if (goog.dom.contains(focusNode, anchorNode)) {
        return false;
      }
    }
  }
  return (goog.dom.compareNodeOrder(anchorNode, focusNode) || anchorOffset - focusOffset) > 0;
};
goog.provide("goog.a11y.aria.Role");
goog.a11y.aria.Role = {ALERT:"alert", ALERTDIALOG:"alertdialog", APPLICATION:"application", ARTICLE:"article", BANNER:"banner", BUTTON:"button", CHECKBOX:"checkbox", COLUMNHEADER:"columnheader", COMBOBOX:"combobox", COMPLEMENTARY:"complementary", CONTENTINFO:"contentinfo", DEFINITION:"definition", DIALOG:"dialog", DIRECTORY:"directory", DOCUMENT:"document", FORM:"form", GRID:"grid", GRIDCELL:"gridcell", GROUP:"group", HEADING:"heading", IMG:"img", LINK:"link", LIST:"list", LISTBOX:"listbox", LISTITEM:"listitem", 
LOG:"log", MAIN:"main", MARQUEE:"marquee", MATH:"math", MENU:"menu", MENUBAR:"menubar", MENU_ITEM:"menuitem", MENU_ITEM_CHECKBOX:"menuitemcheckbox", MENU_ITEM_RADIO:"menuitemradio", NAVIGATION:"navigation", NOTE:"note", OPTION:"option", PRESENTATION:"presentation", PROGRESSBAR:"progressbar", RADIO:"radio", RADIOGROUP:"radiogroup", REGION:"region", ROW:"row", ROWGROUP:"rowgroup", ROWHEADER:"rowheader", SCROLLBAR:"scrollbar", SEARCH:"search", SEPARATOR:"separator", SLIDER:"slider", SPINBUTTON:"spinbutton", 
STATUS:"status", TAB:"tab", TAB_LIST:"tablist", TAB_PANEL:"tabpanel", TEXTBOX:"textbox", TEXTINFO:"textinfo", TIMER:"timer", TOOLBAR:"toolbar", TOOLTIP:"tooltip", TREE:"tree", TREEGRID:"treegrid", TREEITEM:"treeitem"};
goog.provide("goog.a11y.aria.AutoCompleteValues");
goog.provide("goog.a11y.aria.CheckedValues");
goog.provide("goog.a11y.aria.DropEffectValues");
goog.provide("goog.a11y.aria.ExpandedValues");
goog.provide("goog.a11y.aria.GrabbedValues");
goog.provide("goog.a11y.aria.InvalidValues");
goog.provide("goog.a11y.aria.LivePriority");
goog.provide("goog.a11y.aria.OrientationValues");
goog.provide("goog.a11y.aria.PressedValues");
goog.provide("goog.a11y.aria.RelevantValues");
goog.provide("goog.a11y.aria.SelectedValues");
goog.provide("goog.a11y.aria.SortValues");
goog.provide("goog.a11y.aria.State");
goog.a11y.aria.State = {ACTIVEDESCENDANT:"activedescendant", ATOMIC:"atomic", AUTOCOMPLETE:"autocomplete", BUSY:"busy", CHECKED:"checked", CONTROLS:"controls", DESCRIBEDBY:"describedby", DISABLED:"disabled", DROPEFFECT:"dropeffect", EXPANDED:"expanded", FLOWTO:"flowto", GRABBED:"grabbed", HASPOPUP:"haspopup", HIDDEN:"hidden", INVALID:"invalid", LABEL:"label", LABELLEDBY:"labelledby", LEVEL:"level", LIVE:"live", MULTILINE:"multiline", MULTISELECTABLE:"multiselectable", ORIENTATION:"orientation", OWNS:"owns", 
POSINSET:"posinset", PRESSED:"pressed", READONLY:"readonly", RELEVANT:"relevant", REQUIRED:"required", SELECTED:"selected", SETSIZE:"setsize", SORT:"sort", VALUEMAX:"valuemax", VALUEMIN:"valuemin", VALUENOW:"valuenow", VALUETEXT:"valuetext"};
goog.a11y.aria.AutoCompleteValues = {INLINE:"inline", LIST:"list", BOTH:"both", NONE:"none"};
goog.a11y.aria.DropEffectValues = {COPY:"copy", MOVE:"move", LINK:"link", EXECUTE:"execute", POPUP:"popup", NONE:"none"};
goog.a11y.aria.LivePriority = {OFF:"off", POLITE:"polite", ASSERTIVE:"assertive"};
goog.a11y.aria.OrientationValues = {VERTICAL:"vertical", HORIZONTAL:"horizontal"};
goog.a11y.aria.RelevantValues = {ADDITIONS:"additions", REMOVALS:"removals", TEXT:"text", ALL:"all"};
goog.a11y.aria.SortValues = {ASCENDING:"ascending", DESCENDING:"descending", NONE:"none", OTHER:"other"};
goog.a11y.aria.CheckedValues = {TRUE:"true", FALSE:"false", MIXED:"mixed", UNDEFINED:"undefined"};
goog.a11y.aria.ExpandedValues = {TRUE:"true", FALSE:"false", UNDEFINED:"undefined"};
goog.a11y.aria.GrabbedValues = {TRUE:"true", FALSE:"false", UNDEFINED:"undefined"};
goog.a11y.aria.InvalidValues = {FALSE:"false", TRUE:"true", GRAMMAR:"grammar", SPELLING:"spelling"};
goog.a11y.aria.PressedValues = {TRUE:"true", FALSE:"false", MIXED:"mixed", UNDEFINED:"undefined"};
goog.a11y.aria.SelectedValues = {TRUE:"true", FALSE:"false", UNDEFINED:"undefined"};
goog.provide("goog.a11y.aria.datatables");
goog.require("goog.a11y.aria.State");
goog.require("goog.object");
goog.a11y.aria.DefaultStateValueMap_;
goog.a11y.aria.datatables.getDefaultValuesMap = function() {
  if (!goog.a11y.aria.DefaultStateValueMap_) {
    goog.a11y.aria.DefaultStateValueMap_ = goog.object.create(goog.a11y.aria.State.ATOMIC, false, goog.a11y.aria.State.AUTOCOMPLETE, "none", goog.a11y.aria.State.DROPEFFECT, "none", goog.a11y.aria.State.HASPOPUP, false, goog.a11y.aria.State.LIVE, "off", goog.a11y.aria.State.MULTILINE, false, goog.a11y.aria.State.MULTISELECTABLE, false, goog.a11y.aria.State.ORIENTATION, "vertical", goog.a11y.aria.State.READONLY, false, goog.a11y.aria.State.RELEVANT, "additions text", goog.a11y.aria.State.REQUIRED, 
    false, goog.a11y.aria.State.SORT, "none", goog.a11y.aria.State.BUSY, false, goog.a11y.aria.State.DISABLED, false, goog.a11y.aria.State.HIDDEN, false, goog.a11y.aria.State.INVALID, "false");
  }
  return goog.a11y.aria.DefaultStateValueMap_;
};
goog.provide("goog.a11y.aria");
goog.require("goog.a11y.aria.Role");
goog.require("goog.a11y.aria.State");
goog.require("goog.a11y.aria.datatables");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.dom");
goog.require("goog.dom.TagName");
goog.require("goog.object");
goog.require("goog.string");
goog.a11y.aria.ARIA_PREFIX_ = "aria-";
goog.a11y.aria.ROLE_ATTRIBUTE_ = "role";
goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_ = goog.object.createSet([goog.dom.TagName.A, goog.dom.TagName.AREA, goog.dom.TagName.BUTTON, goog.dom.TagName.HEAD, goog.dom.TagName.INPUT, goog.dom.TagName.LINK, goog.dom.TagName.MENU, goog.dom.TagName.META, goog.dom.TagName.OPTGROUP, goog.dom.TagName.OPTION, goog.dom.TagName.PROGRESS, goog.dom.TagName.STYLE, goog.dom.TagName.SELECT, goog.dom.TagName.SOURCE, goog.dom.TagName.TEXTAREA, goog.dom.TagName.TITLE, goog.dom.TagName.TRACK]);
goog.a11y.aria.CONTAINER_ROLES_ = [goog.a11y.aria.Role.COMBOBOX, goog.a11y.aria.Role.GRID, goog.a11y.aria.Role.GROUP, goog.a11y.aria.Role.LISTBOX, goog.a11y.aria.Role.MENU, goog.a11y.aria.Role.MENUBAR, goog.a11y.aria.Role.RADIOGROUP, goog.a11y.aria.Role.ROW, goog.a11y.aria.Role.ROWGROUP, goog.a11y.aria.Role.TAB_LIST, goog.a11y.aria.Role.TEXTBOX, goog.a11y.aria.Role.TOOLBAR, goog.a11y.aria.Role.TREE, goog.a11y.aria.Role.TREEGRID];
goog.a11y.aria.setRole = function(element, roleName) {
  if (!roleName) {
    goog.a11y.aria.removeRole(element);
  } else {
    if (goog.asserts.ENABLE_ASSERTS) {
      goog.asserts.assert(goog.object.containsValue(goog.a11y.aria.Role, roleName), "No such ARIA role " + roleName);
    }
    element.setAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_, roleName);
  }
};
goog.a11y.aria.getRole = function(element) {
  var role = element.getAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_);
  return role || null;
};
goog.a11y.aria.removeRole = function(element) {
  element.removeAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_);
};
goog.a11y.aria.setState = function(element, stateName, value) {
  if (goog.isArray(value)) {
    value = value.join(" ");
  }
  var attrStateName = goog.a11y.aria.getAriaAttributeName_(stateName);
  if (value === "" || value == undefined) {
    var defaultValueMap = goog.a11y.aria.datatables.getDefaultValuesMap();
    if (stateName in defaultValueMap) {
      element.setAttribute(attrStateName, defaultValueMap[stateName]);
    } else {
      element.removeAttribute(attrStateName);
    }
  } else {
    element.setAttribute(attrStateName, value);
  }
};
goog.a11y.aria.toggleState = function(el, attr) {
  var val = goog.a11y.aria.getState(el, attr);
  if (!goog.string.isEmptyOrWhitespace(goog.string.makeSafe(val)) && !(val == "true" || val == "false")) {
    goog.a11y.aria.removeState(el, attr);
    return;
  }
  goog.a11y.aria.setState(el, attr, val == "true" ? "false" : "true");
};
goog.a11y.aria.removeState = function(element, stateName) {
  element.removeAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
};
goog.a11y.aria.getState = function(element, stateName) {
  var attr = element.getAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
  var isNullOrUndefined = attr == null || attr == undefined;
  return isNullOrUndefined ? "" : String(attr);
};
goog.a11y.aria.getActiveDescendant = function(element) {
  var id = goog.a11y.aria.getState(element, goog.a11y.aria.State.ACTIVEDESCENDANT);
  return goog.dom.getOwnerDocument(element).getElementById(id);
};
goog.a11y.aria.setActiveDescendant = function(element, activeElement) {
  var id = "";
  if (activeElement) {
    id = activeElement.id;
    goog.asserts.assert(id, "The active element should have an id.");
  }
  goog.a11y.aria.setState(element, goog.a11y.aria.State.ACTIVEDESCENDANT, id);
};
goog.a11y.aria.getLabel = function(element) {
  return goog.a11y.aria.getState(element, goog.a11y.aria.State.LABEL);
};
goog.a11y.aria.setLabel = function(element, label) {
  goog.a11y.aria.setState(element, goog.a11y.aria.State.LABEL, label);
};
goog.a11y.aria.assertRoleIsSetInternalUtil = function(element, allowedRoles) {
  if (goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_[element.tagName]) {
    return;
  }
  var elementRole = goog.a11y.aria.getRole(element);
  goog.asserts.assert(elementRole != null, "The element ARIA role cannot be null.");
  goog.asserts.assert(goog.array.contains(allowedRoles, elementRole), "Non existing or incorrect role set for element." + 'The role set is "' + elementRole + '". The role should be any of "' + allowedRoles + '". Check the ARIA specification for more details ' + "http://www.w3.org/TR/wai-aria/roles.");
};
goog.a11y.aria.getStateBoolean = function(element, stateName) {
  var attr = element.getAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
  goog.asserts.assert(goog.isBoolean(attr) || attr == null || attr == "true" || attr == "false");
  if (attr == null) {
    return attr;
  }
  return goog.isBoolean(attr) ? attr : attr == "true";
};
goog.a11y.aria.getStateNumber = function(element, stateName) {
  var attr = element.getAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
  goog.asserts.assert((attr == null || !isNaN(Number(attr))) && !goog.isBoolean(attr));
  return attr == null ? null : Number(attr);
};
goog.a11y.aria.getStateString = function(element, stateName) {
  var attr = element.getAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
  goog.asserts.assert((attr == null || goog.isString(attr)) && (attr == "" || isNaN(Number(attr))) && attr != "true" && attr != "false");
  return attr == null || attr == "" ? null : attr;
};
goog.a11y.aria.getStringArrayStateInternalUtil = function(element, stateName) {
  var attrValue = element.getAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
  return goog.a11y.aria.splitStringOnWhitespace_(attrValue);
};
goog.a11y.aria.hasState = function(element, stateName) {
  return element.hasAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
};
goog.a11y.aria.isContainerRole = function(element) {
  var role = goog.a11y.aria.getRole(element);
  return goog.array.contains(goog.a11y.aria.CONTAINER_ROLES_, role);
};
goog.a11y.aria.splitStringOnWhitespace_ = function(stringValue) {
  return stringValue ? stringValue.split(/\s+/) : [];
};
goog.a11y.aria.getAriaAttributeName_ = function(ariaName) {
  if (goog.asserts.ENABLE_ASSERTS) {
    goog.asserts.assert(ariaName, "ARIA attribute cannot be empty.");
    goog.asserts.assert(goog.object.containsValue(goog.a11y.aria.State, ariaName), "No such ARIA attribute " + ariaName);
  }
  return goog.a11y.aria.ARIA_PREFIX_ + ariaName;
};
goog.provide("goog.Thenable");
goog.forwardDeclare("goog.Promise");
goog.Thenable = function() {
};
goog.Thenable.prototype.then = function(opt_onFulfilled, opt_onRejected, opt_context) {
};
goog.Thenable.IMPLEMENTED_BY_PROP = "$goog_Thenable";
goog.Thenable.addImplementation = function(ctor) {
  ctor.prototype["then"] = ctor.prototype.then;
  if (COMPILED) {
    ctor.prototype[goog.Thenable.IMPLEMENTED_BY_PROP] = true;
  } else {
    ctor.prototype.$goog_Thenable = true;
  }
};
goog.Thenable.isImplementedBy = function(object) {
  if (!object) {
    return false;
  }
  try {
    if (COMPILED) {
      return !!object[goog.Thenable.IMPLEMENTED_BY_PROP];
    }
    return !!object.$goog_Thenable;
  } catch (e) {
    return false;
  }
};
goog.provide("goog.async.FreeList");
goog.async.FreeList = goog.defineClass(null, {constructor:function(create, reset, limit) {
  this.limit_ = limit;
  this.create_ = create;
  this.reset_ = reset;
  this.occupants_ = 0;
  this.head_ = null;
}, get:function() {
  var item;
  if (this.occupants_ > 0) {
    this.occupants_--;
    item = this.head_;
    this.head_ = item.next;
    item.next = null;
  } else {
    item = this.create_();
  }
  return item;
}, put:function(item) {
  this.reset_(item);
  if (this.occupants_ < this.limit_) {
    this.occupants_++;
    item.next = this.head_;
    this.head_ = item;
  }
}, occupants:function() {
  return this.occupants_;
}});
goog.provide("goog.async.WorkItem");
goog.provide("goog.async.WorkQueue");
goog.require("goog.asserts");
goog.require("goog.async.FreeList");
goog.async.WorkQueue = function() {
  this.workHead_ = null;
  this.workTail_ = null;
};
goog.define("goog.async.WorkQueue.DEFAULT_MAX_UNUSED", 100);
goog.async.WorkQueue.freelist_ = new goog.async.FreeList(function() {
  return new goog.async.WorkItem;
}, function(item) {
  item.reset();
}, goog.async.WorkQueue.DEFAULT_MAX_UNUSED);
goog.async.WorkQueue.prototype.add = function(fn, scope) {
  var item = this.getUnusedItem_();
  item.set(fn, scope);
  if (this.workTail_) {
    this.workTail_.next = item;
    this.workTail_ = item;
  } else {
    goog.asserts.assert(!this.workHead_);
    this.workHead_ = item;
    this.workTail_ = item;
  }
};
goog.async.WorkQueue.prototype.remove = function() {
  var item = null;
  if (this.workHead_) {
    item = this.workHead_;
    this.workHead_ = this.workHead_.next;
    if (!this.workHead_) {
      this.workTail_ = null;
    }
    item.next = null;
  }
  return item;
};
goog.async.WorkQueue.prototype.returnUnused = function(item) {
  goog.async.WorkQueue.freelist_.put(item);
};
goog.async.WorkQueue.prototype.getUnusedItem_ = function() {
  return goog.async.WorkQueue.freelist_.get();
};
goog.async.WorkItem = function() {
  this.fn = null;
  this.scope = null;
  this.next = null;
};
goog.async.WorkItem.prototype.set = function(fn, scope) {
  this.fn = fn;
  this.scope = scope;
  this.next = null;
};
goog.async.WorkItem.prototype.reset = function() {
  this.fn = null;
  this.scope = null;
  this.next = null;
};
goog.provide("goog.async.nextTick");
goog.provide("goog.async.throwException");
goog.require("goog.debug.entryPointRegistry");
goog.require("goog.dom.TagName");
goog.require("goog.functions");
goog.require("goog.labs.userAgent.browser");
goog.require("goog.labs.userAgent.engine");
goog.async.throwException = function(exception) {
  goog.global.setTimeout(function() {
    throw exception;
  }, 0);
};
goog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) {
  var cb = callback;
  if (opt_context) {
    cb = goog.bind(callback, opt_context);
  }
  cb = goog.async.nextTick.wrapCallback_(cb);
  if (goog.isFunction(goog.global.setImmediate) && (opt_useSetImmediate || goog.async.nextTick.useSetImmediate_())) {
    goog.global.setImmediate(cb);
    return;
  }
  if (!goog.async.nextTick.setImmediate_) {
    goog.async.nextTick.setImmediate_ = goog.async.nextTick.getSetImmediateEmulator_();
  }
  goog.async.nextTick.setImmediate_(cb);
};
goog.async.nextTick.useSetImmediate_ = function() {
  if (!goog.global.Window || !goog.global.Window.prototype) {
    return true;
  }
  if (goog.labs.userAgent.browser.isEdge() || goog.global.Window.prototype.setImmediate != goog.global.setImmediate) {
    return true;
  }
  return false;
};
goog.async.nextTick.setImmediate_;
goog.async.nextTick.getSetImmediateEmulator_ = function() {
  var Channel = goog.global["MessageChannel"];
  if (typeof Channel === "undefined" && typeof window !== "undefined" && window.postMessage && window.addEventListener && !goog.labs.userAgent.engine.isPresto()) {
    Channel = function() {
      var iframe = document.createElement(String(goog.dom.TagName.IFRAME));
      iframe.style.display = "none";
      iframe.src = "";
      document.documentElement.appendChild(iframe);
      var win = iframe.contentWindow;
      var doc = win.document;
      doc.open();
      doc.write("");
      doc.close();
      var message = "callImmediate" + Math.random();
      var origin = win.location.protocol == "file:" ? "*" : win.location.protocol + "//" + win.location.host;
      var onmessage = goog.bind(function(e) {
        if (origin != "*" && e.origin != origin || e.data != message) {
          return;
        }
        this["port1"].onmessage();
      }, this);
      win.addEventListener("message", onmessage, false);
      this["port1"] = {};
      this["port2"] = {postMessage:function() {
        win.postMessage(message, origin);
      }};
    };
  }
  if (typeof Channel !== "undefined" && !goog.labs.userAgent.browser.isIE()) {
    var channel = new Channel;
    var head = {};
    var tail = head;
    channel["port1"].onmessage = function() {
      if (goog.isDef(head.next)) {
        head = head.next;
        var cb = head.cb;
        head.cb = null;
        cb();
      }
    };
    return function(cb) {
      tail.next = {cb:cb};
      tail = tail.next;
      channel["port2"].postMessage(0);
    };
  }
  if (typeof document !== "undefined" && "onreadystatechange" in document.createElement(String(goog.dom.TagName.SCRIPT))) {
    return function(cb) {
      var script = document.createElement(String(goog.dom.TagName.SCRIPT));
      script.onreadystatechange = function() {
        script.onreadystatechange = null;
        script.parentNode.removeChild(script);
        script = null;
        cb();
        cb = null;
      };
      document.documentElement.appendChild(script);
    };
  }
  return function(cb) {
    goog.global.setTimeout(cb, 0);
  };
};
goog.async.nextTick.wrapCallback_ = goog.functions.identity;
goog.debug.entryPointRegistry.register(function(transformer) {
  goog.async.nextTick.wrapCallback_ = transformer;
});
goog.provide("goog.async.run");
goog.require("goog.async.WorkQueue");
goog.require("goog.async.nextTick");
goog.require("goog.async.throwException");
goog.async.run = function(callback, opt_context) {
  if (!goog.async.run.schedule_) {
    goog.async.run.initializeRunner_();
  }
  if (!goog.async.run.workQueueScheduled_) {
    goog.async.run.schedule_();
    goog.async.run.workQueueScheduled_ = true;
  }
  goog.async.run.workQueue_.add(callback, opt_context);
};
goog.async.run.initializeRunner_ = function() {
  if (String(goog.global.Promise).indexOf("[native code]") != -1) {
    var promise = goog.global.Promise.resolve(undefined);
    goog.async.run.schedule_ = function() {
      promise.then(goog.async.run.processWorkQueue);
    };
  } else {
    goog.async.run.schedule_ = function() {
      goog.async.nextTick(goog.async.run.processWorkQueue);
    };
  }
};
goog.async.run.forceNextTick = function(opt_realSetTimeout) {
  goog.async.run.schedule_ = function() {
    goog.async.nextTick(goog.async.run.processWorkQueue);
    if (opt_realSetTimeout) {
      opt_realSetTimeout(goog.async.run.processWorkQueue);
    }
  };
};
goog.async.run.schedule_;
goog.async.run.workQueueScheduled_ = false;
goog.async.run.workQueue_ = new goog.async.WorkQueue;
if (goog.DEBUG) {
  goog.async.run.resetQueue = function() {
    goog.async.run.workQueueScheduled_ = false;
    goog.async.run.workQueue_ = new goog.async.WorkQueue;
  };
}
goog.async.run.processWorkQueue = function() {
  var item = null;
  while (item = goog.async.run.workQueue_.remove()) {
    try {
      item.fn.call(item.scope);
    } catch (e) {
      goog.async.throwException(e);
    }
    goog.async.run.workQueue_.returnUnused(item);
  }
  goog.async.run.workQueueScheduled_ = false;
};
goog.provide("goog.promise.Resolver");
goog.promise.Resolver = function() {
};
goog.promise.Resolver.prototype.promise;
goog.promise.Resolver.prototype.resolve;
goog.promise.Resolver.prototype.reject;
goog.provide("goog.Promise");
goog.require("goog.Thenable");
goog.require("goog.asserts");
goog.require("goog.async.FreeList");
goog.require("goog.async.run");
goog.require("goog.async.throwException");
goog.require("goog.debug.Error");
goog.require("goog.promise.Resolver");
goog.Promise = function(resolver, opt_context) {
  this.state_ = goog.Promise.State_.PENDING;
  this.result_ = undefined;
  this.parent_ = null;
  this.callbackEntries_ = null;
  this.callbackEntriesTail_ = null;
  this.executing_ = false;
  if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {
    this.unhandledRejectionId_ = 0;
  } else {
    if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {
      this.hadUnhandledRejection_ = false;
    }
  }
  if (goog.Promise.LONG_STACK_TRACES) {
    this.stack_ = [];
    this.addStackTrace_(new Error("created"));
    this.currentStep_ = 0;
  }
  if (resolver != goog.nullFunction) {
    try {
      var self = this;
      resolver.call(opt_context, function(value) {
        self.resolve_(goog.Promise.State_.FULFILLED, value);
      }, function(reason) {
        if (goog.DEBUG && !(reason instanceof goog.Promise.CancellationError)) {
          try {
            if (reason instanceof Error) {
              throw reason;
            } else {
              throw new Error("Promise rejected.");
            }
          } catch (e) {
          }
        }
        self.resolve_(goog.Promise.State_.REJECTED, reason);
      });
    } catch (e) {
      this.resolve_(goog.Promise.State_.REJECTED, e);
    }
  }
};
goog.define("goog.Promise.LONG_STACK_TRACES", false);
goog.define("goog.Promise.UNHANDLED_REJECTION_DELAY", 0);
goog.Promise.State_ = {PENDING:0, BLOCKED:1, FULFILLED:2, REJECTED:3};
goog.Promise.CallbackEntry_ = function() {
  this.child = null;
  this.onFulfilled = null;
  this.onRejected = null;
  this.context = null;
  this.next = null;
  this.always = false;
};
goog.Promise.CallbackEntry_.prototype.reset = function() {
  this.child = null;
  this.onFulfilled = null;
  this.onRejected = null;
  this.context = null;
  this.always = false;
};
goog.define("goog.Promise.DEFAULT_MAX_UNUSED", 100);
goog.Promise.freelist_ = new goog.async.FreeList(function() {
  return new goog.Promise.CallbackEntry_;
}, function(item) {
  item.reset();
}, goog.Promise.DEFAULT_MAX_UNUSED);
goog.Promise.getCallbackEntry_ = function(onFulfilled, onRejected, context) {
  var entry = goog.Promise.freelist_.get();
  entry.onFulfilled = onFulfilled;
  entry.onRejected = onRejected;
  entry.context = context;
  return entry;
};
goog.Promise.returnEntry_ = function(entry) {
  goog.Promise.freelist_.put(entry);
};
goog.Promise.resolve = function(opt_value) {
  if (opt_value instanceof goog.Promise) {
    return opt_value;
  }
  var promise = new goog.Promise(goog.nullFunction);
  promise.resolve_(goog.Promise.State_.FULFILLED, opt_value);
  return promise;
};
goog.Promise.reject = function(opt_reason) {
  return new goog.Promise(function(resolve, reject) {
    reject(opt_reason);
  });
};
goog.Promise.resolveThen_ = function(value, onFulfilled, onRejected) {
  var isThenable = goog.Promise.maybeThen_(value, onFulfilled, onRejected, null);
  if (!isThenable) {
    goog.async.run(goog.partial(onFulfilled, value));
  }
};
goog.Promise.race = function(promises) {
  return new goog.Promise(function(resolve, reject) {
    if (!promises.length) {
      resolve(undefined);
    }
    for (var i = 0, promise; i < promises.length; i++) {
      promise = promises[i];
      goog.Promise.resolveThen_(promise, resolve, reject);
    }
  });
};
goog.Promise.all = function(promises) {
  return new goog.Promise(function(resolve, reject) {
    var toFulfill = promises.length;
    var values = [];
    if (!toFulfill) {
      resolve(values);
      return;
    }
    var onFulfill = function(index, value) {
      toFulfill--;
      values[index] = value;
      if (toFulfill == 0) {
        resolve(values);
      }
    };
    var onReject = function(reason) {
      reject(reason);
    };
    for (var i = 0, promise; i < promises.length; i++) {
      promise = promises[i];
      goog.Promise.resolveThen_(promise, goog.partial(onFulfill, i), onReject);
    }
  });
};
goog.Promise.allSettled = function(promises) {
  return new goog.Promise(function(resolve, reject) {
    var toSettle = promises.length;
    var results = [];
    if (!toSettle) {
      resolve(results);
      return;
    }
    var onSettled = function(index, fulfilled, result) {
      toSettle--;
      results[index] = fulfilled ? {fulfilled:true, value:result} : {fulfilled:false, reason:result};
      if (toSettle == 0) {
        resolve(results);
      }
    };
    for (var i = 0, promise; i < promises.length; i++) {
      promise = promises[i];
      goog.Promise.resolveThen_(promise, goog.partial(onSettled, i, true), goog.partial(onSettled, i, false));
    }
  });
};
goog.Promise.firstFulfilled = function(promises) {
  return new goog.Promise(function(resolve, reject) {
    var toReject = promises.length;
    var reasons = [];
    if (!toReject) {
      resolve(undefined);
      return;
    }
    var onFulfill = function(value) {
      resolve(value);
    };
    var onReject = function(index, reason) {
      toReject--;
      reasons[index] = reason;
      if (toReject == 0) {
        reject(reasons);
      }
    };
    for (var i = 0, promise; i < promises.length; i++) {
      promise = promises[i];
      goog.Promise.resolveThen_(promise, onFulfill, goog.partial(onReject, i));
    }
  });
};
goog.Promise.withResolver = function() {
  var resolve, reject;
  var promise = new goog.Promise(function(rs, rj) {
    resolve = rs;
    reject = rj;
  });
  return new goog.Promise.Resolver_(promise, resolve, reject);
};
goog.Promise.prototype.then = function(opt_onFulfilled, opt_onRejected, opt_context) {
  if (opt_onFulfilled != null) {
    goog.asserts.assertFunction(opt_onFulfilled, "opt_onFulfilled should be a function.");
  }
  if (opt_onRejected != null) {
    goog.asserts.assertFunction(opt_onRejected, "opt_onRejected should be a function. Did you pass opt_context " + "as the second argument instead of the third?");
  }
  if (goog.Promise.LONG_STACK_TRACES) {
    this.addStackTrace_(new Error("then"));
  }
  return this.addChildPromise_(goog.isFunction(opt_onFulfilled) ? opt_onFulfilled : null, goog.isFunction(opt_onRejected) ? opt_onRejected : null, opt_context);
};
goog.Thenable.addImplementation(goog.Promise);
goog.Promise.prototype.thenVoid = function(opt_onFulfilled, opt_onRejected, opt_context) {
  if (opt_onFulfilled != null) {
    goog.asserts.assertFunction(opt_onFulfilled, "opt_onFulfilled should be a function.");
  }
  if (opt_onRejected != null) {
    goog.asserts.assertFunction(opt_onRejected, "opt_onRejected should be a function. Did you pass opt_context " + "as the second argument instead of the third?");
  }
  if (goog.Promise.LONG_STACK_TRACES) {
    this.addStackTrace_(new Error("then"));
  }
  this.addCallbackEntry_(goog.Promise.getCallbackEntry_(opt_onFulfilled || goog.nullFunction, opt_onRejected || null, opt_context));
};
goog.Promise.prototype.thenAlways = function(onSettled, opt_context) {
  if (goog.Promise.LONG_STACK_TRACES) {
    this.addStackTrace_(new Error("thenAlways"));
  }
  var entry = goog.Promise.getCallbackEntry_(onSettled, onSettled, opt_context);
  entry.always = true;
  this.addCallbackEntry_(entry);
  return this;
};
goog.Promise.prototype.thenCatch = function(onRejected, opt_context) {
  if (goog.Promise.LONG_STACK_TRACES) {
    this.addStackTrace_(new Error("thenCatch"));
  }
  return this.addChildPromise_(null, onRejected, opt_context);
};
goog.Promise.prototype.cancel = function(opt_message) {
  if (this.state_ == goog.Promise.State_.PENDING) {
    goog.async.run(function() {
      var err = new goog.Promise.CancellationError(opt_message);
      this.cancelInternal_(err);
    }, this);
  }
};
goog.Promise.prototype.cancelInternal_ = function(err) {
  if (this.state_ == goog.Promise.State_.PENDING) {
    if (this.parent_) {
      this.parent_.cancelChild_(this, err);
      this.parent_ = null;
    } else {
      this.resolve_(goog.Promise.State_.REJECTED, err);
    }
  }
};
goog.Promise.prototype.cancelChild_ = function(childPromise, err) {
  if (!this.callbackEntries_) {
    return;
  }
  var childCount = 0;
  var childEntry = null;
  var beforeChildEntry = null;
  for (var entry = this.callbackEntries_; entry; entry = entry.next) {
    if (!entry.always) {
      childCount++;
      if (entry.child == childPromise) {
        childEntry = entry;
      }
      if (childEntry && childCount > 1) {
        break;
      }
    }
    if (!childEntry) {
      beforeChildEntry = entry;
    }
  }
  if (childEntry) {
    if (this.state_ == goog.Promise.State_.PENDING && childCount == 1) {
      this.cancelInternal_(err);
    } else {
      if (beforeChildEntry) {
        this.removeEntryAfter_(beforeChildEntry);
      } else {
        this.popEntry_();
      }
      this.executeCallback_(childEntry, goog.Promise.State_.REJECTED, err);
    }
  }
};
goog.Promise.prototype.addCallbackEntry_ = function(callbackEntry) {
  if (!this.hasEntry_() && (this.state_ == goog.Promise.State_.FULFILLED || this.state_ == goog.Promise.State_.REJECTED)) {
    this.scheduleCallbacks_();
  }
  this.queueEntry_(callbackEntry);
};
goog.Promise.prototype.addChildPromise_ = function(onFulfilled, onRejected, opt_context) {
  var callbackEntry = goog.Promise.getCallbackEntry_(null, null, null);
  callbackEntry.child = new goog.Promise(function(resolve, reject) {
    callbackEntry.onFulfilled = onFulfilled ? function(value) {
      try {
        var result = onFulfilled.call(opt_context, value);
        resolve(result);
      } catch (err$4) {
        reject(err$4);
      }
    } : resolve;
    callbackEntry.onRejected = onRejected ? function(reason) {
      try {
        var result = onRejected.call(opt_context, reason);
        if (!goog.isDef(result) && reason instanceof goog.Promise.CancellationError) {
          reject(reason);
        } else {
          resolve(result);
        }
      } catch (err$5) {
        reject(err$5);
      }
    } : reject;
  });
  callbackEntry.child.parent_ = this;
  this.addCallbackEntry_(callbackEntry);
  return callbackEntry.child;
};
goog.Promise.prototype.unblockAndFulfill_ = function(value) {
  goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED);
  this.state_ = goog.Promise.State_.PENDING;
  this.resolve_(goog.Promise.State_.FULFILLED, value);
};
goog.Promise.prototype.unblockAndReject_ = function(reason) {
  goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED);
  this.state_ = goog.Promise.State_.PENDING;
  this.resolve_(goog.Promise.State_.REJECTED, reason);
};
goog.Promise.prototype.resolve_ = function(state, x) {
  if (this.state_ != goog.Promise.State_.PENDING) {
    return;
  }
  if (this === x) {
    state = goog.Promise.State_.REJECTED;
    x = new TypeError("Promise cannot resolve to itself");
  }
  this.state_ = goog.Promise.State_.BLOCKED;
  var isThenable = goog.Promise.maybeThen_(x, this.unblockAndFulfill_, this.unblockAndReject_, this);
  if (isThenable) {
    return;
  }
  this.result_ = x;
  this.state_ = state;
  this.parent_ = null;
  this.scheduleCallbacks_();
  if (state == goog.Promise.State_.REJECTED && !(x instanceof goog.Promise.CancellationError)) {
    goog.Promise.addUnhandledRejection_(this, x);
  }
};
goog.Promise.maybeThen_ = function(value, onFulfilled, onRejected, context) {
  if (value instanceof goog.Promise) {
    value.thenVoid(onFulfilled, onRejected, context);
    return true;
  } else {
    if (goog.Thenable.isImplementedBy(value)) {
      value = value;
      value.then(onFulfilled, onRejected, context);
      return true;
    } else {
      if (goog.isObject(value)) {
        try {
          var then = value["then"];
          if (goog.isFunction(then)) {
            goog.Promise.tryThen_(value, then, onFulfilled, onRejected, context);
            return true;
          }
        } catch (e) {
          onRejected.call(context, e);
          return true;
        }
      }
    }
  }
  return false;
};
goog.Promise.tryThen_ = function(thenable, then, onFulfilled, onRejected, context) {
  var called = false;
  var resolve = function(value) {
    if (!called) {
      called = true;
      onFulfilled.call(context, value);
    }
  };
  var reject = function(reason) {
    if (!called) {
      called = true;
      onRejected.call(context, reason);
    }
  };
  try {
    then.call(thenable, resolve, reject);
  } catch (e) {
    reject(e);
  }
};
goog.Promise.prototype.scheduleCallbacks_ = function() {
  if (!this.executing_) {
    this.executing_ = true;
    goog.async.run(this.executeCallbacks_, this);
  }
};
goog.Promise.prototype.hasEntry_ = function() {
  return !!this.callbackEntries_;
};
goog.Promise.prototype.queueEntry_ = function(entry) {
  goog.asserts.assert(entry.onFulfilled != null);
  if (this.callbackEntriesTail_) {
    this.callbackEntriesTail_.next = entry;
    this.callbackEntriesTail_ = entry;
  } else {
    this.callbackEntries_ = entry;
    this.callbackEntriesTail_ = entry;
  }
};
goog.Promise.prototype.popEntry_ = function() {
  var entry = null;
  if (this.callbackEntries_) {
    entry = this.callbackEntries_;
    this.callbackEntries_ = entry.next;
    entry.next = null;
  }
  if (!this.callbackEntries_) {
    this.callbackEntriesTail_ = null;
  }
  if (entry != null) {
    goog.asserts.assert(entry.onFulfilled != null);
  }
  return entry;
};
goog.Promise.prototype.removeEntryAfter_ = function(previous) {
  goog.asserts.assert(this.callbackEntries_);
  goog.asserts.assert(previous != null);
  if (previous.next == this.callbackEntriesTail_) {
    this.callbackEntriesTail_ = previous;
  }
  previous.next = previous.next.next;
};
goog.Promise.prototype.executeCallbacks_ = function() {
  var entry = null;
  while (entry = this.popEntry_()) {
    if (goog.Promise.LONG_STACK_TRACES) {
      this.currentStep_++;
    }
    this.executeCallback_(entry, this.state_, this.result_);
  }
  this.executing_ = false;
};
goog.Promise.prototype.executeCallback_ = function(callbackEntry, state, result) {
  if (state == goog.Promise.State_.REJECTED && callbackEntry.onRejected && !callbackEntry.always) {
    this.removeUnhandledRejection_();
  }
  if (callbackEntry.child) {
    callbackEntry.child.parent_ = null;
    goog.Promise.invokeCallback_(callbackEntry, state, result);
  } else {
    try {
      callbackEntry.always ? callbackEntry.onFulfilled.call(callbackEntry.context) : goog.Promise.invokeCallback_(callbackEntry, state, result);
    } catch (err$6) {
      goog.Promise.handleRejection_.call(null, err$6);
    }
  }
  goog.Promise.returnEntry_(callbackEntry);
};
goog.Promise.invokeCallback_ = function(callbackEntry, state, result) {
  if (state == goog.Promise.State_.FULFILLED) {
    callbackEntry.onFulfilled.call(callbackEntry.context, result);
  } else {
    if (callbackEntry.onRejected) {
      callbackEntry.onRejected.call(callbackEntry.context, result);
    }
  }
};
goog.Promise.prototype.addStackTrace_ = function(err) {
  if (goog.Promise.LONG_STACK_TRACES && goog.isString(err.stack)) {
    var trace = err.stack.split("\n", 4)[3];
    var message = err.message;
    message += Array(11 - message.length).join(" ");
    this.stack_.push(message + trace);
  }
};
goog.Promise.prototype.appendLongStack_ = function(err) {
  if (goog.Promise.LONG_STACK_TRACES && err && goog.isString(err.stack) && this.stack_.length) {
    var longTrace = ["Promise trace:"];
    for (var promise = this; promise; promise = promise.parent_) {
      for (var i = this.currentStep_; i >= 0; i--) {
        longTrace.push(promise.stack_[i]);
      }
      longTrace.push("Value: " + "[" + (promise.state_ == goog.Promise.State_.REJECTED ? "REJECTED" : "FULFILLED") + "] " + "<" + String(promise.result_) + ">");
    }
    err.stack += "\n\n" + longTrace.join("\n");
  }
};
goog.Promise.prototype.removeUnhandledRejection_ = function() {
  if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {
    for (var p = this; p && p.unhandledRejectionId_; p = p.parent_) {
      goog.global.clearTimeout(p.unhandledRejectionId_);
      p.unhandledRejectionId_ = 0;
    }
  } else {
    if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {
      for (var p = this; p && p.hadUnhandledRejection_; p = p.parent_) {
        p.hadUnhandledRejection_ = false;
      }
    }
  }
};
goog.Promise.addUnhandledRejection_ = function(promise, reason) {
  if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {
    promise.unhandledRejectionId_ = goog.global.setTimeout(function() {
      promise.appendLongStack_(reason);
      goog.Promise.handleRejection_.call(null, reason);
    }, goog.Promise.UNHANDLED_REJECTION_DELAY);
  } else {
    if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {
      promise.hadUnhandledRejection_ = true;
      goog.async.run(function() {
        if (promise.hadUnhandledRejection_) {
          promise.appendLongStack_(reason);
          goog.Promise.handleRejection_.call(null, reason);
        }
      });
    }
  }
};
goog.Promise.handleRejection_ = goog.async.throwException;
goog.Promise.setUnhandledRejectionHandler = function(handler) {
  goog.Promise.handleRejection_ = handler;
};
goog.Promise.CancellationError = function(opt_message) {
  goog.Promise.CancellationError.base(this, "constructor", opt_message);
};
goog.inherits(goog.Promise.CancellationError, goog.debug.Error);
goog.Promise.CancellationError.prototype.name = "cancel";
goog.Promise.Resolver_ = function(promise, resolve, reject) {
  this.promise = promise;
  this.resolve = resolve;
  this.reject = reject;
};
goog.provide("goog.events.EventTarget");
goog.require("goog.Disposable");
goog.require("goog.asserts");
goog.require("goog.events");
goog.require("goog.events.Event");
goog.require("goog.events.Listenable");
goog.require("goog.events.ListenerMap");
goog.require("goog.object");
goog.events.EventTarget = function() {
  goog.Disposable.call(this);
  this.eventTargetListeners_ = new goog.events.ListenerMap(this);
  this.actualEventTarget_ = this;
  this.parentEventTarget_ = null;
};
goog.inherits(goog.events.EventTarget, goog.Disposable);
goog.events.Listenable.addImplementation(goog.events.EventTarget);
goog.events.EventTarget.MAX_ANCESTORS_ = 1000;
goog.events.EventTarget.prototype.getParentEventTarget = function() {
  return this.parentEventTarget_;
};
goog.events.EventTarget.prototype.setParentEventTarget = function(parent) {
  this.parentEventTarget_ = parent;
};
goog.events.EventTarget.prototype.addEventListener = function(type, handler, opt_capture, opt_handlerScope) {
  goog.events.listen(this, type, handler, opt_capture, opt_handlerScope);
};
goog.events.EventTarget.prototype.removeEventListener = function(type, handler, opt_capture, opt_handlerScope) {
  goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope);
};
goog.events.EventTarget.prototype.dispatchEvent = function(e) {
  this.assertInitialized_();
  var ancestorsTree, ancestor = this.getParentEventTarget();
  if (ancestor) {
    ancestorsTree = [];
    var ancestorCount = 1;
    for (; ancestor; ancestor = ancestor.getParentEventTarget()) {
      ancestorsTree.push(ancestor);
      goog.asserts.assert(++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_, "infinite loop");
    }
  }
  return goog.events.EventTarget.dispatchEventInternal_(this.actualEventTarget_, e, ancestorsTree);
};
goog.events.EventTarget.prototype.disposeInternal = function() {
  goog.events.EventTarget.superClass_.disposeInternal.call(this);
  this.removeAllListeners();
  this.parentEventTarget_ = null;
};
goog.events.EventTarget.prototype.listen = function(type, listener, opt_useCapture, opt_listenerScope) {
  this.assertInitialized_();
  return this.eventTargetListeners_.add(String(type), listener, false, opt_useCapture, opt_listenerScope);
};
goog.events.EventTarget.prototype.listenOnce = function(type, listener, opt_useCapture, opt_listenerScope) {
  return this.eventTargetListeners_.add(String(type), listener, true, opt_useCapture, opt_listenerScope);
};
goog.events.EventTarget.prototype.unlisten = function(type, listener, opt_useCapture, opt_listenerScope) {
  return this.eventTargetListeners_.remove(String(type), listener, opt_useCapture, opt_listenerScope);
};
goog.events.EventTarget.prototype.unlistenByKey = function(key) {
  return this.eventTargetListeners_.removeByKey(key);
};
goog.events.EventTarget.prototype.removeAllListeners = function(opt_type) {
  if (!this.eventTargetListeners_) {
    return 0;
  }
  return this.eventTargetListeners_.removeAll(opt_type);
};
goog.events.EventTarget.prototype.fireListeners = function(type, capture, eventObject) {
  var listenerArray = this.eventTargetListeners_.listeners[String(type)];
  if (!listenerArray) {
    return true;
  }
  listenerArray = listenerArray.concat();
  var rv = true;
  for (var i = 0; i < listenerArray.length; ++i) {
    var listener = listenerArray[i];
    if (listener && !listener.removed && listener.capture == capture) {
      var listenerFn = listener.listener;
      var listenerHandler = listener.handler || listener.src;
      if (listener.callOnce) {
        this.unlistenByKey(listener);
      }
      rv = listenerFn.call(listenerHandler, eventObject) !== false && rv;
    }
  }
  return rv && eventObject.returnValue_ != false;
};
goog.events.EventTarget.prototype.getListeners = function(type, capture) {
  return this.eventTargetListeners_.getListeners(String(type), capture);
};
goog.events.EventTarget.prototype.getListener = function(type, listener, capture, opt_listenerScope) {
  return this.eventTargetListeners_.getListener(String(type), listener, capture, opt_listenerScope);
};
goog.events.EventTarget.prototype.hasListener = function(opt_type, opt_capture) {
  var id = goog.isDef(opt_type) ? String(opt_type) : undefined;
  return this.eventTargetListeners_.hasListener(id, opt_capture);
};
goog.events.EventTarget.prototype.setTargetForTesting = function(target) {
  this.actualEventTarget_ = target;
};
goog.events.EventTarget.prototype.assertInitialized_ = function() {
  goog.asserts.assert(this.eventTargetListeners_, "Event target is not initialized. Did you call the superclass " + "(goog.events.EventTarget) constructor?");
};
goog.events.EventTarget.dispatchEventInternal_ = function(target, e, opt_ancestorsTree) {
  var type = e.type || e;
  if (goog.isString(e)) {
    e = new goog.events.Event(e, target);
  } else {
    if (!(e instanceof goog.events.Event)) {
      var oldEvent = e;
      e = new goog.events.Event(type, target);
      goog.object.extend(e, oldEvent);
    } else {
      e.target = e.target || target;
    }
  }
  var rv = true, currentTarget;
  if (opt_ancestorsTree) {
    for (var i = opt_ancestorsTree.length - 1; !e.propagationStopped_ && i >= 0; i--) {
      currentTarget = e.currentTarget = opt_ancestorsTree[i];
      rv = currentTarget.fireListeners(type, true, e) && rv;
    }
  }
  if (!e.propagationStopped_) {
    currentTarget = e.currentTarget = target;
    rv = currentTarget.fireListeners(type, true, e) && rv;
    if (!e.propagationStopped_) {
      rv = currentTarget.fireListeners(type, false, e) && rv;
    }
  }
  if (opt_ancestorsTree) {
    for (i = 0; !e.propagationStopped_ && i < opt_ancestorsTree.length; i++) {
      currentTarget = e.currentTarget = opt_ancestorsTree[i];
      rv = currentTarget.fireListeners(type, false, e) && rv;
    }
  }
  return rv;
};
goog.provide("goog.Timer");
goog.require("goog.Promise");
goog.require("goog.events.EventTarget");
goog.Timer = function(opt_interval, opt_timerObject) {
  goog.events.EventTarget.call(this);
  this.interval_ = opt_interval || 1;
  this.timerObject_ = opt_timerObject || goog.Timer.defaultTimerObject;
  this.boundTick_ = goog.bind(this.tick_, this);
  this.last_ = goog.now();
};
goog.inherits(goog.Timer, goog.events.EventTarget);
goog.Timer.MAX_TIMEOUT_ = 2147483647;
goog.Timer.INVALID_TIMEOUT_ID_ = -1;
goog.Timer.prototype.enabled = false;
goog.Timer.defaultTimerObject = goog.global;
goog.Timer.intervalScale = 0.8;
goog.Timer.prototype.timer_ = null;
goog.Timer.prototype.getInterval = function() {
  return this.interval_;
};
goog.Timer.prototype.setInterval = function(interval) {
  this.interval_ = interval;
  if (this.timer_ && this.enabled) {
    this.stop();
    this.start();
  } else {
    if (this.timer_) {
      this.stop();
    }
  }
};
goog.Timer.prototype.tick_ = function() {
  if (this.enabled) {
    var elapsed = goog.now() - this.last_;
    if (elapsed > 0 && elapsed < this.interval_ * goog.Timer.intervalScale) {
      this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_ - elapsed);
      return;
    }
    if (this.timer_) {
      this.timerObject_.clearTimeout(this.timer_);
      this.timer_ = null;
    }
    this.dispatchTick();
    if (this.enabled) {
      this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_);
      this.last_ = goog.now();
    }
  }
};
goog.Timer.prototype.dispatchTick = function() {
  this.dispatchEvent(goog.Timer.TICK);
};
goog.Timer.prototype.start = function() {
  this.enabled = true;
  if (!this.timer_) {
    this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_);
    this.last_ = goog.now();
  }
};
goog.Timer.prototype.stop = function() {
  this.enabled = false;
  if (this.timer_) {
    this.timerObject_.clearTimeout(this.timer_);
    this.timer_ = null;
  }
};
goog.Timer.prototype.disposeInternal = function() {
  goog.Timer.superClass_.disposeInternal.call(this);
  this.stop();
  delete this.timerObject_;
};
goog.Timer.TICK = "tick";
goog.Timer.callOnce = function(listener, opt_delay, opt_handler) {
  if (goog.isFunction(listener)) {
    if (opt_handler) {
      listener = goog.bind(listener, opt_handler);
    }
  } else {
    if (listener && typeof listener.handleEvent == "function") {
      listener = goog.bind(listener.handleEvent, listener);
    } else {
      throw Error("Invalid listener argument");
    }
  }
  if (Number(opt_delay) > goog.Timer.MAX_TIMEOUT_) {
    return goog.Timer.INVALID_TIMEOUT_ID_;
  } else {
    return goog.Timer.defaultTimerObject.setTimeout(listener, opt_delay || 0);
  }
};
goog.Timer.clear = function(timerId) {
  goog.Timer.defaultTimerObject.clearTimeout(timerId);
};
goog.Timer.promise = function(delay, opt_result) {
  var timerKey = null;
  return (new goog.Promise(function(resolve, reject) {
    timerKey = goog.Timer.callOnce(function() {
      resolve(opt_result);
    }, delay);
    if (timerKey == goog.Timer.INVALID_TIMEOUT_ID_) {
      reject(new Error("Failed to schedule timer."));
    }
  })).thenCatch(function(error) {
    goog.Timer.clear(timerKey);
    throw error;
  });
};
goog.provide("goog.Delay");
goog.provide("goog.async.Delay");
goog.require("goog.Disposable");
goog.require("goog.Timer");
goog.async.Delay = function(listener, opt_interval, opt_handler) {
  goog.async.Delay.base(this, "constructor");
  this.listener_ = listener;
  this.interval_ = opt_interval || 0;
  this.handler_ = opt_handler;
  this.callback_ = goog.bind(this.doAction_, this);
};
goog.inherits(goog.async.Delay, goog.Disposable);
goog.Delay = goog.async.Delay;
goog.async.Delay.prototype.id_ = 0;
goog.async.Delay.prototype.disposeInternal = function() {
  goog.async.Delay.base(this, "disposeInternal");
  this.stop();
  delete this.listener_;
  delete this.handler_;
};
goog.async.Delay.prototype.start = function(opt_interval) {
  this.stop();
  this.id_ = goog.Timer.callOnce(this.callback_, goog.isDef(opt_interval) ? opt_interval : this.interval_);
};
goog.async.Delay.prototype.startIfNotActive = function(opt_interval) {
  if (!this.isActive()) {
    this.start(opt_interval);
  }
};
goog.async.Delay.prototype.stop = function() {
  if (this.isActive()) {
    goog.Timer.clear(this.id_);
  }
  this.id_ = 0;
};
goog.async.Delay.prototype.fire = function() {
  this.stop();
  this.doAction_();
};
goog.async.Delay.prototype.fireIfActive = function() {
  if (this.isActive()) {
    this.fire();
  }
};
goog.async.Delay.prototype.isActive = function() {
  return this.id_ != 0;
};
goog.async.Delay.prototype.doAction_ = function() {
  this.id_ = 0;
  if (this.listener_) {
    this.listener_.call(this.handler_);
  }
};
goog.provide("goog.editor.defines");
goog.define("goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3", false);
goog.provide("goog.userAgent.product");
goog.require("goog.labs.userAgent.browser");
goog.require("goog.labs.userAgent.platform");
goog.require("goog.userAgent");
goog.define("goog.userAgent.product.ASSUME_FIREFOX", false);
goog.define("goog.userAgent.product.ASSUME_IPHONE", false);
goog.define("goog.userAgent.product.ASSUME_IPAD", false);
goog.define("goog.userAgent.product.ASSUME_ANDROID", false);
goog.define("goog.userAgent.product.ASSUME_CHROME", false);
goog.define("goog.userAgent.product.ASSUME_SAFARI", false);
goog.userAgent.product.PRODUCT_KNOWN_ = goog.userAgent.ASSUME_IE || goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_OPERA || goog.userAgent.product.ASSUME_FIREFOX || goog.userAgent.product.ASSUME_IPHONE || goog.userAgent.product.ASSUME_IPAD || goog.userAgent.product.ASSUME_ANDROID || goog.userAgent.product.ASSUME_CHROME || goog.userAgent.product.ASSUME_SAFARI;
goog.userAgent.product.OPERA = goog.userAgent.OPERA;
goog.userAgent.product.IE = goog.userAgent.IE;
goog.userAgent.product.EDGE = goog.userAgent.EDGE;
goog.userAgent.product.FIREFOX = goog.userAgent.product.PRODUCT_KNOWN_ ? goog.userAgent.product.ASSUME_FIREFOX : goog.labs.userAgent.browser.isFirefox();
goog.userAgent.product.isIphoneOrIpod_ = function() {
  return goog.labs.userAgent.platform.isIphone() || goog.labs.userAgent.platform.isIpod();
};
goog.userAgent.product.IPHONE = goog.userAgent.product.PRODUCT_KNOWN_ ? goog.userAgent.product.ASSUME_IPHONE : goog.userAgent.product.isIphoneOrIpod_();
goog.userAgent.product.IPAD = goog.userAgent.product.PRODUCT_KNOWN_ ? goog.userAgent.product.ASSUME_IPAD : goog.labs.userAgent.platform.isIpad();
goog.userAgent.product.ANDROID = goog.userAgent.product.PRODUCT_KNOWN_ ? goog.userAgent.product.ASSUME_ANDROID : goog.labs.userAgent.browser.isAndroidBrowser();
goog.userAgent.product.CHROME = goog.userAgent.product.PRODUCT_KNOWN_ ? goog.userAgent.product.ASSUME_CHROME : goog.labs.userAgent.browser.isChrome();
goog.userAgent.product.isSafariDesktop_ = function() {
  return goog.labs.userAgent.browser.isSafari() && !goog.labs.userAgent.platform.isIos();
};
goog.userAgent.product.SAFARI = goog.userAgent.product.PRODUCT_KNOWN_ ? goog.userAgent.product.ASSUME_SAFARI : goog.userAgent.product.isSafariDesktop_();
goog.provide("goog.userAgent.product.isVersion");
goog.require("goog.labs.userAgent.platform");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.require("goog.userAgent.product");
goog.userAgent.product.determineVersion_ = function() {
  if (goog.userAgent.product.FIREFOX) {
    return goog.userAgent.product.getFirstRegExpGroup_(/Firefox\/([0-9.]+)/);
  }
  if (goog.userAgent.product.IE || goog.userAgent.product.EDGE || goog.userAgent.product.OPERA) {
    return goog.userAgent.VERSION;
  }
  if (goog.userAgent.product.CHROME) {
    if (goog.labs.userAgent.platform.isIos()) {
      return goog.userAgent.product.getFirstRegExpGroup_(/CriOS\/([0-9.]+)/);
    }
    return goog.userAgent.product.getFirstRegExpGroup_(/Chrome\/([0-9.]+)/);
  }
  if (goog.userAgent.product.SAFARI && !goog.labs.userAgent.platform.isIos()) {
    return goog.userAgent.product.getFirstRegExpGroup_(/Version\/([0-9.]+)/);
  }
  if (goog.userAgent.product.IPHONE || goog.userAgent.product.IPAD) {
    var arr = goog.userAgent.product.execRegExp_(/Version\/(\S+).*Mobile\/(\S+)/);
    if (arr) {
      return arr[1] + "." + arr[2];
    }
  } else {
    if (goog.userAgent.product.ANDROID) {
      var version = goog.userAgent.product.getFirstRegExpGroup_(/Android\s+([0-9.]+)/);
      if (version) {
        return version;
      }
      return goog.userAgent.product.getFirstRegExpGroup_(/Version\/([0-9.]+)/);
    }
  }
  return "";
};
goog.userAgent.product.getFirstRegExpGroup_ = function(re) {
  var arr = goog.userAgent.product.execRegExp_(re);
  return arr ? arr[1] : "";
};
goog.userAgent.product.execRegExp_ = function(re) {
  return re.exec(goog.userAgent.getUserAgentString());
};
goog.userAgent.product.VERSION = goog.userAgent.product.determineVersion_();
goog.userAgent.product.isVersion = function(version) {
  return goog.string.compareVersions(goog.userAgent.product.VERSION, version) >= 0;
};
goog.provide("goog.editor.BrowserFeature");
goog.require("goog.editor.defines");
goog.require("goog.labs.userAgent.browser");
goog.require("goog.userAgent");
goog.require("goog.userAgent.product");
goog.require("goog.userAgent.product.isVersion");
goog.editor.BrowserFeature = {HAS_IE_RANGES:goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9), HAS_W3C_RANGES:goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA || goog.userAgent.EDGE || goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9), HAS_CONTENT_EDITABLE:goog.userAgent.IE || goog.userAgent.WEBKIT || goog.userAgent.OPERA || goog.userAgent.EDGE || goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3 && goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9"), 
USE_MUTATION_EVENTS:goog.userAgent.GECKO, HAS_DOM_SUBTREE_MODIFIED_EVENT:goog.userAgent.WEBKIT || goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3 && goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9"), HAS_DOCUMENT_INDEPENDENT_NODES:goog.userAgent.GECKO, PUTS_CURSOR_BEFORE_FIRST_BLOCK_ELEMENT_ON_FOCUS:goog.userAgent.GECKO, CLEARS_SELECTION_WHEN_FOCUS_LEAVES:goog.userAgent.IE || goog.userAgent.WEBKIT || goog.userAgent.OPERA, HAS_UNSELECTABLE_STYLE:goog.userAgent.GECKO || goog.userAgent.WEBKIT, 
FORMAT_BLOCK_WORKS_FOR_BLOCKQUOTES:goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA, CREATES_MULTIPLE_BLOCKQUOTES:goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("534.16") || goog.userAgent.OPERA, WRAPS_BLOCKQUOTE_IN_DIVS:goog.userAgent.OPERA, PREFERS_READY_STATE_CHANGE_EVENT:goog.userAgent.IE, TAB_FIRES_KEYPRESS:!goog.userAgent.IE, NEEDS_99_WIDTH_IN_STANDARDS_MODE:goog.userAgent.IE, USE_DOCUMENT_FOR_KEY_EVENTS:goog.userAgent.GECKO && !goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3, 
SHOWS_CUSTOM_ATTRS_IN_INNER_HTML:goog.userAgent.IE, COLLAPSES_EMPTY_NODES:goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA, CONVERT_TO_B_AND_I_TAGS:goog.userAgent.GECKO || goog.userAgent.OPERA, TABS_THROUGH_IMAGES:goog.userAgent.IE, UNESCAPES_URLS_WITHOUT_ASKING:goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("7.0"), HAS_STYLE_WITH_CSS:goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.8") || goog.userAgent.WEBKIT || goog.userAgent.OPERA, FOLLOWS_EDITABLE_LINKS:goog.userAgent.WEBKIT || 
goog.userAgent.IE && goog.userAgent.isVersionOrHigher("9"), HAS_ACTIVE_ELEMENT:goog.userAgent.IE || goog.userAgent.EDGE || goog.userAgent.OPERA || goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9"), HAS_SET_CAPTURE:goog.userAgent.IE, EATS_EMPTY_BACKGROUND_COLOR:goog.userAgent.GECKO || goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("527"), SUPPORTS_FOCUSIN:goog.userAgent.IE || goog.userAgent.OPERA, SELECTS_IMAGES_ON_CLICK:goog.userAgent.IE || goog.userAgent.OPERA, MOVES_STYLE_TO_HEAD:goog.userAgent.WEBKIT, 
COLLAPSES_SELECTION_ONMOUSEDOWN:false, CARET_INSIDE_SELECTION:goog.userAgent.OPERA, FOCUSES_EDITABLE_BODY_ON_HTML_CLICK:true, USES_KEYDOWN:goog.userAgent.IE || goog.userAgent.EDGE || goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher("525"), ADDS_NBSPS_IN_REMOVE_FORMAT:goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("531"), GETS_STUCK_IN_LINKS:goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("528"), NORMALIZE_CORRUPTS_EMPTY_TEXT_NODES:goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9") || 
goog.userAgent.IE || goog.userAgent.EDGE || goog.userAgent.OPERA || goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher("531"), NORMALIZE_CORRUPTS_ALL_TEXT_NODES:goog.userAgent.IE, NESTS_SUBSCRIPT_SUPERSCRIPT:goog.userAgent.IE || goog.userAgent.EDGE || goog.userAgent.GECKO || goog.userAgent.OPERA, CAN_SELECT_EMPTY_ELEMENT:!goog.userAgent.IE && !goog.userAgent.WEBKIT, FORGETS_FORMATTING_WHEN_LISTIFYING:goog.userAgent.GECKO || goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("526"), 
LEAVES_P_WHEN_REMOVING_LISTS:goog.userAgent.IE || goog.userAgent.OPERA, CAN_LISTIFY_BR:!goog.userAgent.IE && !goog.userAgent.OPERA, DOESNT_OVERRIDE_FONT_SIZE_IN_STYLE_ATTR:!goog.userAgent.WEBKIT && !goog.userAgent.EDGE, SUPPORTS_HTML5_FILE_DRAGGING:goog.userAgent.product.CHROME && goog.userAgent.product.isVersion("4") || goog.userAgent.product.SAFARI && goog.userAgent.isVersionOrHigher("533") || goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("2.0") || goog.userAgent.IE && goog.userAgent.isVersionOrHigher("10") || 
goog.userAgent.OPERA && goog.labs.userAgent.browser.isVersionOrHigher("15") || goog.userAgent.EDGE, SUPPORTS_OPERA_DEFAULTBLOCK_COMMAND:goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher("11.10"), SUPPORTS_FILE_PASTING:goog.userAgent.product.CHROME && goog.userAgent.product.isVersion("12")};
goog.provide("goog.editor.Plugin");
goog.require("goog.events.EventTarget");
goog.require("goog.functions");
goog.require("goog.log");
goog.require("goog.object");
goog.require("goog.reflect");
goog.require("goog.userAgent");
goog.editor.Plugin = function() {
  goog.events.EventTarget.call(this);
  this.enabled_ = this.activeOnUneditableFields();
  this.fieldObject = null;
  this.autoDispose_ = true;
  this.logger = goog.log.getLogger("goog.editor.Plugin");
};
goog.inherits(goog.editor.Plugin, goog.events.EventTarget);
goog.editor.Plugin.prototype.getFieldDomHelper = function() {
  return this.getFieldObject() && this.getFieldObject().getEditableDomHelper();
};
goog.editor.Plugin.prototype.getFieldObject = function() {
  return this.fieldObject;
};
goog.editor.Plugin.prototype.setFieldObject = function(fieldObject) {
  this.fieldObject = fieldObject;
};
goog.editor.Plugin.prototype.registerFieldObject = function(fieldObject) {
  this.setFieldObject(fieldObject);
};
goog.editor.Plugin.prototype.unregisterFieldObject = function(fieldObj) {
  if (this.getFieldObject()) {
    this.disable(this.getFieldObject());
    this.setFieldObject(null);
  }
};
goog.editor.Plugin.prototype.enable = function(fieldObject) {
  if (this.getFieldObject() == fieldObject) {
    this.enabled_ = true;
  } else {
    goog.log.error(this.logger, "Trying to enable an unregistered field with " + "this plugin.");
  }
};
goog.editor.Plugin.prototype.disable = function(fieldObject) {
  if (this.getFieldObject() == fieldObject) {
    this.enabled_ = false;
  } else {
    goog.log.error(this.logger, "Trying to disable an unregistered field " + "with this plugin.");
  }
};
goog.editor.Plugin.prototype.isEnabled = function(fieldObject) {
  return this.getFieldObject() == fieldObject ? this.enabled_ : false;
};
goog.editor.Plugin.prototype.setAutoDispose = function(autoDispose) {
  this.autoDispose_ = autoDispose;
};
goog.editor.Plugin.prototype.isAutoDispose = function() {
  return this.autoDispose_;
};
goog.editor.Plugin.prototype.activeOnUneditableFields = goog.functions.FALSE;
goog.editor.Plugin.prototype.isSilentCommand = goog.functions.FALSE;
goog.editor.Plugin.prototype.disposeInternal = function() {
  if (this.getFieldObject()) {
    this.unregisterFieldObject(this.getFieldObject());
  }
  goog.editor.Plugin.superClass_.disposeInternal.call(this);
};
goog.editor.Plugin.prototype.getTrogClassId;
goog.editor.Plugin.Op = {KEYDOWN:1, KEYPRESS:2, KEYUP:3, SELECTION:4, SHORTCUT:5, EXEC_COMMAND:6, QUERY_COMMAND:7, PREPARE_CONTENTS_HTML:8, CLEAN_CONTENTS_HTML:10, CLEAN_CONTENTS_DOM:11};
goog.editor.Plugin.OPCODE = goog.object.transpose(goog.reflect.object(goog.editor.Plugin, {handleKeyDown:goog.editor.Plugin.Op.KEYDOWN, handleKeyPress:goog.editor.Plugin.Op.KEYPRESS, handleKeyUp:goog.editor.Plugin.Op.KEYUP, handleSelectionChange:goog.editor.Plugin.Op.SELECTION, handleKeyboardShortcut:goog.editor.Plugin.Op.SHORTCUT, execCommand:goog.editor.Plugin.Op.EXEC_COMMAND, queryCommandValue:goog.editor.Plugin.Op.QUERY_COMMAND, prepareContentsHtml:goog.editor.Plugin.Op.PREPARE_CONTENTS_HTML, 
cleanContentsHtml:goog.editor.Plugin.Op.CLEAN_CONTENTS_HTML, cleanContentsDom:goog.editor.Plugin.Op.CLEAN_CONTENTS_DOM}));
goog.editor.Plugin.IRREPRESSIBLE_OPS = goog.object.createSet(goog.editor.Plugin.Op.PREPARE_CONTENTS_HTML, goog.editor.Plugin.Op.CLEAN_CONTENTS_HTML, goog.editor.Plugin.Op.CLEAN_CONTENTS_DOM);
goog.editor.Plugin.prototype.handleKeyDown;
goog.editor.Plugin.prototype.handleKeyPress;
goog.editor.Plugin.prototype.handleKeyUp;
goog.editor.Plugin.prototype.handleSelectionChange;
goog.editor.Plugin.prototype.handleKeyboardShortcut;
goog.editor.Plugin.prototype.execCommand = function(command, var_args) {
  var silent = this.isSilentCommand(command);
  if (!silent) {
    if (goog.userAgent.GECKO) {
      this.getFieldObject().stopChangeEvents(true, true);
    }
    this.getFieldObject().dispatchBeforeChange();
  }
  try {
    var result = this.execCommandInternal.apply(this, arguments);
  } finally {
    if (!silent) {
      this.getFieldObject().dispatchChange();
      this.getFieldObject().dispatchSelectionChangeEvent();
    }
  }
  return result;
};
goog.editor.Plugin.prototype.execCommandInternal;
goog.editor.Plugin.prototype.queryCommandValue;
goog.editor.Plugin.prototype.prepareContentsHtml;
goog.editor.Plugin.prototype.cleanContentsDom;
goog.editor.Plugin.prototype.cleanContentsHtml;
goog.editor.Plugin.prototype.isSupportedCommand = function(command) {
  return false;
};
goog.editor.Plugin.prototype.saveScrollPosition = function() {
  if (this.getFieldObject() && goog.userAgent.EDGE) {
    var win = this.getFieldObject().getEditableDomHelper().getWindow();
    return win.scrollTo.bind(win, win.scrollX, win.scrollY);
  }
  return function() {
  };
};
goog.provide("goog.editor.icontent");
goog.provide("goog.editor.icontent.FieldFormatInfo");
goog.provide("goog.editor.icontent.FieldStyleInfo");
goog.require("goog.dom");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.style");
goog.require("goog.userAgent");
goog.editor.icontent.FieldFormatInfo = function(fieldId, standards, blended, fixedHeight, opt_extraStyles) {
  this.fieldId_ = fieldId;
  this.standards_ = standards;
  this.blended_ = blended;
  this.fixedHeight_ = fixedHeight;
  this.extraStyles_ = opt_extraStyles || {};
};
goog.editor.icontent.FieldStyleInfo = function(wrapper, css) {
  this.wrapper_ = wrapper;
  this.css_ = css;
};
goog.editor.icontent.useStandardsModeIframes_ = false;
goog.editor.icontent.forceStandardsModeIframes = function() {
  goog.editor.icontent.useStandardsModeIframes_ = true;
};
goog.editor.icontent.getInitialIframeContent_ = function(info, bodyHtml, style) {
  var html = [];
  if (info.blended_ && info.standards_ || goog.editor.icontent.useStandardsModeIframes_) {
    html.push("<!DOCTYPE HTML>");
  }
  html.push('<html style="background:none transparent;min-width:0;');
  if (info.blended_) {
    html.push("height:", info.fixedHeight_ ? "100%" : "auto");
  }
  html.push('">');
  html.push("<head><style>");
  if (style && style.css_) {
    html.push(style.css_);
  }
  if (goog.userAgent.GECKO && info.standards_) {
    html.push(" img {-moz-force-broken-image-icon: 1;}");
  }
  html.push("</style></head>");
  html.push('<body g_editable="true" hidefocus="true" ');
  if (goog.editor.BrowserFeature.HAS_CONTENT_EDITABLE) {
    html.push("contentEditable ");
  }
  html.push('class="editable ');
  html.push('" id="', info.fieldId_, '" style="min-width:0;');
  if (goog.userAgent.GECKO && info.blended_) {
    html.push(";width:100%;border:0;margin:0;background:none transparent;", ";height:", info.standards_ ? "100%" : "auto");
    if (info.fixedHeight_) {
      html.push(";overflow:auto");
    } else {
      html.push(";overflow-y:hidden;overflow-x:auto");
    }
  }
  if (goog.userAgent.OPERA) {
    html.push(";outline:hidden");
  }
  for (var key in info.extraStyles_) {
    html.push(";" + key + ":" + info.extraStyles_[key]);
  }
  html.push('">', bodyHtml, "</body></html>");
  return html.join("");
};
goog.editor.icontent.writeNormalInitialBlendedIframe = function(info, bodyHtml, style, iframe) {
  if (info.blended_) {
    var field = style.wrapper_;
    var paddingBox = goog.style.getPaddingBox(field);
    if (paddingBox.top || paddingBox.left || paddingBox.right || paddingBox.bottom) {
      goog.style.setStyle(iframe, "margin", -paddingBox.top + "px " + -paddingBox.right + "px " + -paddingBox.bottom + "px " + -paddingBox.left + "px");
    }
  }
  goog.editor.icontent.writeNormalInitialIframe(info, bodyHtml, style, iframe);
};
goog.editor.icontent.writeNormalInitialIframe = function(info, bodyHtml, style, iframe) {
  var html = goog.editor.icontent.getInitialIframeContent_(info, bodyHtml, style);
  var doc = goog.dom.getFrameContentDocument(iframe);
  doc.open();
  doc.write(html);
  doc.close();
};
goog.editor.icontent.writeHttpsInitialIframe = function(info, doc, bodyHtml) {
  var body = doc.body;
  if (goog.editor.BrowserFeature.HAS_CONTENT_EDITABLE) {
    body.contentEditable = true;
  }
  body.className = "editable";
  body.setAttribute("g_editable", true);
  body.hideFocus = true;
  body.id = info.fieldId_;
  goog.style.setStyle(body, info.extraStyles_);
  body.innerHTML = bodyHtml;
};
goog.provide("goog.dom.iter.AncestorIterator");
goog.provide("goog.dom.iter.ChildIterator");
goog.provide("goog.dom.iter.SiblingIterator");
goog.require("goog.iter.Iterator");
goog.require("goog.iter.StopIteration");
goog.dom.iter.SiblingIterator = function(node, opt_includeNode, opt_reverse) {
  this.node_ = node;
  this.reverse_ = !!opt_reverse;
  if (node && !opt_includeNode) {
    this.next();
  }
};
goog.inherits(goog.dom.iter.SiblingIterator, goog.iter.Iterator);
goog.dom.iter.SiblingIterator.prototype.next = function() {
  var node = this.node_;
  if (!node) {
    throw goog.iter.StopIteration;
  }
  this.node_ = this.reverse_ ? node.previousSibling : node.nextSibling;
  return node;
};
goog.dom.iter.ChildIterator = function(element, opt_reverse, opt_startIndex) {
  if (!goog.isDef(opt_startIndex)) {
    opt_startIndex = opt_reverse && element.childNodes.length ? element.childNodes.length - 1 : 0;
  }
  goog.dom.iter.SiblingIterator.call(this, element.childNodes[opt_startIndex], true, opt_reverse);
};
goog.inherits(goog.dom.iter.ChildIterator, goog.dom.iter.SiblingIterator);
goog.dom.iter.AncestorIterator = function(node, opt_includeNode) {
  this.node_ = node;
  if (node && !opt_includeNode) {
    this.next();
  }
};
goog.inherits(goog.dom.iter.AncestorIterator, goog.iter.Iterator);
goog.dom.iter.AncestorIterator.prototype.next = function() {
  var node = this.node_;
  if (!node) {
    throw goog.iter.StopIteration;
  }
  this.node_ = node.parentNode;
  return node;
};
goog.provide("goog.editor.node");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagName");
goog.require("goog.dom.iter.ChildIterator");
goog.require("goog.dom.iter.SiblingIterator");
goog.require("goog.iter");
goog.require("goog.object");
goog.require("goog.string");
goog.require("goog.string.Unicode");
goog.require("goog.userAgent");
goog.editor.node.BLOCK_TAG_NAMES_ = goog.object.createSet(goog.dom.TagName.ADDRESS, goog.dom.TagName.ARTICLE, goog.dom.TagName.ASIDE, goog.dom.TagName.BLOCKQUOTE, goog.dom.TagName.BODY, goog.dom.TagName.CAPTION, goog.dom.TagName.CENTER, goog.dom.TagName.COL, goog.dom.TagName.COLGROUP, goog.dom.TagName.DETAILS, goog.dom.TagName.DIR, goog.dom.TagName.DIV, goog.dom.TagName.DL, goog.dom.TagName.DD, goog.dom.TagName.DT, goog.dom.TagName.FIELDSET, goog.dom.TagName.FIGCAPTION, goog.dom.TagName.FIGURE, goog.dom.TagName.FOOTER, 
goog.dom.TagName.FORM, goog.dom.TagName.H1, goog.dom.TagName.H2, goog.dom.TagName.H3, goog.dom.TagName.H4, goog.dom.TagName.H5, goog.dom.TagName.H6, goog.dom.TagName.HEADER, goog.dom.TagName.HGROUP, goog.dom.TagName.HR, goog.dom.TagName.ISINDEX, goog.dom.TagName.OL, goog.dom.TagName.LI, goog.dom.TagName.MAP, goog.dom.TagName.MENU, goog.dom.TagName.NAV, goog.dom.TagName.OPTGROUP, goog.dom.TagName.OPTION, goog.dom.TagName.P, goog.dom.TagName.PRE, goog.dom.TagName.SECTION, goog.dom.TagName.SUMMARY, 
goog.dom.TagName.TABLE, goog.dom.TagName.TBODY, goog.dom.TagName.TD, goog.dom.TagName.TFOOT, goog.dom.TagName.TH, goog.dom.TagName.THEAD, goog.dom.TagName.TR, goog.dom.TagName.UL);
goog.editor.node.NON_EMPTY_TAGS_ = goog.object.createSet(goog.dom.TagName.IMG, goog.dom.TagName.IFRAME, goog.dom.TagName.EMBED);
goog.editor.node.isStandardsMode = function(node) {
  return goog.dom.getDomHelper(node).isCss1CompatMode();
};
goog.editor.node.getRightMostLeaf = function(parent) {
  var temp;
  while (temp = goog.editor.node.getLastChild(parent)) {
    parent = temp;
  }
  return parent;
};
goog.editor.node.getLeftMostLeaf = function(parent) {
  var temp;
  while (temp = goog.editor.node.getFirstChild(parent)) {
    parent = temp;
  }
  return parent;
};
goog.editor.node.getFirstChild = function(parent) {
  return goog.editor.node.getChildHelper_(parent, false);
};
goog.editor.node.getLastChild = function(parent) {
  return goog.editor.node.getChildHelper_(parent, true);
};
goog.editor.node.getPreviousSibling = function(sibling) {
  return goog.editor.node.getFirstValue_(goog.iter.filter(new goog.dom.iter.SiblingIterator(sibling, false, true), goog.editor.node.isImportant));
};
goog.editor.node.getNextSibling = function(sibling) {
  return goog.editor.node.getFirstValue_(goog.iter.filter(new goog.dom.iter.SiblingIterator(sibling), goog.editor.node.isImportant));
};
goog.editor.node.getChildHelper_ = function(parent, isReversed) {
  return !parent || parent.nodeType != goog.dom.NodeType.ELEMENT ? null : goog.editor.node.getFirstValue_(goog.iter.filter(new goog.dom.iter.ChildIterator(parent, isReversed), goog.editor.node.isImportant));
};
goog.editor.node.getFirstValue_ = function(iterator) {
  try {
    return iterator.next();
  } catch (e) {
    return null;
  }
};
goog.editor.node.isImportant = function(node) {
  return node.nodeType == goog.dom.NodeType.ELEMENT || node.nodeType == goog.dom.NodeType.TEXT && !goog.editor.node.isAllNonNbspWhiteSpace(node);
};
goog.editor.node.isAllNonNbspWhiteSpace = function(textNode) {
  return goog.string.isBreakingWhitespace(textNode.nodeValue);
};
goog.editor.node.isEmpty = function(node, opt_prohibitSingleNbsp) {
  var nodeData = goog.dom.getRawTextContent(node);
  if (node.getElementsByTagName) {
    node = node;
    for (var tag in goog.editor.node.NON_EMPTY_TAGS_) {
      if (node.tagName == tag || node.getElementsByTagName(tag).length > 0) {
        return false;
      }
    }
  }
  return !opt_prohibitSingleNbsp && nodeData == goog.string.Unicode.NBSP || goog.string.isBreakingWhitespace(nodeData);
};
goog.editor.node.getLength = function(node) {
  return node.length || node.childNodes.length;
};
goog.editor.node.findInChildren = function(parent, hasProperty) {
  for (var i = 0, len = parent.childNodes.length; i < len; i++) {
    if (hasProperty(parent.childNodes[i])) {
      return i;
    }
  }
  return null;
};
goog.editor.node.findHighestMatchingAncestor = function(node, hasProperty) {
  var parent = node.parentNode;
  var ancestor = null;
  while (parent && hasProperty(parent)) {
    ancestor = parent;
    parent = parent.parentNode;
  }
  return ancestor;
};
goog.editor.node.isBlockTag = function(node) {
  return !!goog.editor.node.BLOCK_TAG_NAMES_[node.tagName];
};
goog.editor.node.skipEmptyTextNodes = function(node) {
  while (node && node.nodeType == goog.dom.NodeType.TEXT && !node.nodeValue) {
    node = node.nextSibling;
  }
  return node;
};
goog.editor.node.isEditableContainer = function(element) {
  return element.getAttribute && element.getAttribute("g_editable") == "true";
};
goog.editor.node.isEditable = function(node) {
  return !!goog.dom.getAncestor(node, goog.editor.node.isEditableContainer);
};
goog.editor.node.findTopMostEditableAncestor = function(node, criteria) {
  var targetNode = null;
  while (node && !goog.editor.node.isEditableContainer(node)) {
    if (criteria(node)) {
      targetNode = node;
    }
    node = node.parentNode;
  }
  return targetNode;
};
goog.editor.node.splitDomTreeAt = function(currentNode, opt_secondHalf, opt_root) {
  var parent;
  while (currentNode != opt_root && (parent = currentNode.parentNode)) {
    opt_secondHalf = goog.editor.node.getSecondHalfOfNode_(parent, currentNode, opt_secondHalf);
    currentNode = parent;
  }
  return opt_secondHalf;
};
goog.editor.node.getSecondHalfOfNode_ = function(node, startNode, firstChild) {
  var secondHalf = node.cloneNode(false);
  while (startNode.nextSibling) {
    goog.dom.appendChild(secondHalf, startNode.nextSibling);
  }
  if (firstChild) {
    secondHalf.insertBefore(firstChild, secondHalf.firstChild);
  }
  return secondHalf;
};
goog.editor.node.transferChildren = function(newNode, oldNode) {
  goog.dom.append(newNode, oldNode.childNodes);
};
goog.editor.node.replaceInnerHtml = function(node, html) {
  if (goog.userAgent.IE) {
    goog.dom.removeChildren(node);
  }
  node.innerHTML = html;
};
goog.provide("goog.events.EventHandler");
goog.require("goog.Disposable");
goog.require("goog.events");
goog.require("goog.object");
goog.forwardDeclare("goog.events.EventWrapper");
goog.events.EventHandler = function(opt_scope) {
  goog.Disposable.call(this);
  this.handler_ = opt_scope;
  this.keys_ = {};
};
goog.inherits(goog.events.EventHandler, goog.Disposable);
goog.events.EventHandler.typeArray_ = [];
goog.events.EventHandler.prototype.listen = function(src, type, opt_fn, opt_capture) {
  var self = this;
  return self.listen_(src, type, opt_fn, opt_capture);
};
goog.events.EventHandler.prototype.listenWithScope = function(src, type, fn, capture, scope) {
  var self = this;
  return self.listen_(src, type, fn, capture, scope);
};
goog.events.EventHandler.prototype.listen_ = function(src, type, opt_fn, opt_capture, opt_scope) {
  var self = this;
  if (!goog.isArray(type)) {
    if (type) {
      goog.events.EventHandler.typeArray_[0] = type.toString();
    }
    type = goog.events.EventHandler.typeArray_;
  }
  for (var i = 0; i < type.length; i++) {
    var listenerObj = goog.events.listen(src, type[i], opt_fn || self.handleEvent, opt_capture || false, opt_scope || self.handler_ || self);
    if (!listenerObj) {
      return self;
    }
    var key = listenerObj.key;
    self.keys_[key] = listenerObj;
  }
  return self;
};
goog.events.EventHandler.prototype.listenOnce = function(src, type, opt_fn, opt_capture) {
  var self = this;
  return self.listenOnce_(src, type, opt_fn, opt_capture);
};
goog.events.EventHandler.prototype.listenOnceWithScope = function(src, type, fn, capture, scope) {
  var self = this;
  return self.listenOnce_(src, type, fn, capture, scope);
};
goog.events.EventHandler.prototype.listenOnce_ = function(src, type, opt_fn, opt_capture, opt_scope) {
  var self = this;
  if (goog.isArray(type)) {
    for (var i = 0; i < type.length; i++) {
      self.listenOnce_(src, type[i], opt_fn, opt_capture, opt_scope);
    }
  } else {
    var listenerObj = goog.events.listenOnce(src, type, opt_fn || self.handleEvent, opt_capture, opt_scope || self.handler_ || self);
    if (!listenerObj) {
      return self;
    }
    var key = listenerObj.key;
    self.keys_[key] = listenerObj;
  }
  return self;
};
goog.events.EventHandler.prototype.listenWithWrapper = function(src, wrapper, listener, opt_capt) {
  var self = this;
  return self.listenWithWrapper_(src, wrapper, listener, opt_capt);
};
goog.events.EventHandler.prototype.listenWithWrapperAndScope = function(src, wrapper, listener, capture, scope) {
  var self = this;
  return self.listenWithWrapper_(src, wrapper, listener, capture, scope);
};
goog.events.EventHandler.prototype.listenWithWrapper_ = function(src, wrapper, listener, opt_capt, opt_scope) {
  var self = this;
  wrapper.listen(src, listener, opt_capt, opt_scope || self.handler_ || self, self);
  return self;
};
goog.events.EventHandler.prototype.getListenerCount = function() {
  var count = 0;
  for (var key in this.keys_) {
    if (Object.prototype.hasOwnProperty.call(this.keys_, key)) {
      count++;
    }
  }
  return count;
};
goog.events.EventHandler.prototype.unlisten = function(src, type, opt_fn, opt_capture, opt_scope) {
  var self = this;
  if (goog.isArray(type)) {
    for (var i = 0; i < type.length; i++) {
      self.unlisten(src, type[i], opt_fn, opt_capture, opt_scope);
    }
  } else {
    var listener = goog.events.getListener(src, type, opt_fn || self.handleEvent, opt_capture, opt_scope || self.handler_ || self);
    if (listener) {
      goog.events.unlistenByKey(listener);
      delete self.keys_[listener.key];
    }
  }
  return self;
};
goog.events.EventHandler.prototype.unlistenWithWrapper = function(src, wrapper, listener, opt_capt, opt_scope) {
  var self = this;
  wrapper.unlisten(src, listener, opt_capt, opt_scope || self.handler_ || self, self);
  return self;
};
goog.events.EventHandler.prototype.removeAll = function() {
  goog.object.forEach(this.keys_, function(listenerObj, key) {
    if (this.keys_.hasOwnProperty(key)) {
      goog.events.unlistenByKey(listenerObj);
    }
  }, this);
  this.keys_ = {};
};
goog.events.EventHandler.prototype.disposeInternal = function() {
  goog.events.EventHandler.superClass_.disposeInternal.call(this);
  this.removeAll();
};
goog.events.EventHandler.prototype.handleEvent = function(e) {
  throw Error("EventHandler.handleEvent not implemented");
};
goog.provide("goog.editor.style");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagName");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.events.EventHandler");
goog.require("goog.events.EventType");
goog.require("goog.object");
goog.require("goog.style");
goog.require("goog.userAgent");
goog.editor.style.getComputedOrCascadedStyle_ = function(node, stylePropertyName) {
  if (node.nodeType != goog.dom.NodeType.ELEMENT) {
    return null;
  }
  return goog.userAgent.IE ? goog.style.getCascadedStyle(node, stylePropertyName) : goog.style.getComputedStyle(node, stylePropertyName);
};
goog.editor.style.isDisplayBlock = function(node) {
  return goog.editor.style.getComputedOrCascadedStyle_(node, "display") == "block";
};
goog.editor.style.isContainer = function(element) {
  var nodeName = element && element.nodeName;
  return !!(element && (goog.editor.style.isDisplayBlock(element) || nodeName == goog.dom.TagName.TD || nodeName == goog.dom.TagName.TABLE || nodeName == goog.dom.TagName.LI));
};
goog.editor.style.getContainer = function(node) {
  return goog.dom.getAncestor(node, goog.editor.style.isContainer, true);
};
goog.editor.style.SELECTABLE_INPUT_TYPES_ = goog.object.createSet("text", "file", "url");
goog.editor.style.cancelMouseDownHelper_ = function(e) {
  var targetTagName = e.target.tagName;
  if (targetTagName != goog.dom.TagName.TEXTAREA && targetTagName != goog.dom.TagName.INPUT) {
    e.preventDefault();
  }
};
goog.editor.style.makeUnselectable = function(element, eventHandler) {
  if (goog.editor.BrowserFeature.HAS_UNSELECTABLE_STYLE) {
    eventHandler.listen(element, goog.events.EventType.MOUSEDOWN, goog.editor.style.cancelMouseDownHelper_, true);
  }
  goog.style.setUnselectable(element, true);
  var inputs = goog.dom.getElementsByTagName(goog.dom.TagName.INPUT, goog.asserts.assert(element));
  for (var i = 0, len = inputs.length; i < len; i++) {
    var input = inputs[i];
    if (input.type in goog.editor.style.SELECTABLE_INPUT_TYPES_) {
      goog.editor.style.makeSelectable(input);
    }
  }
  goog.array.forEach(goog.dom.getElementsByTagName(goog.dom.TagName.TEXTAREA, goog.asserts.assert(element)), goog.editor.style.makeSelectable);
};
goog.editor.style.makeSelectable = function(element) {
  goog.style.setUnselectable(element, false);
  if (goog.editor.BrowserFeature.HAS_UNSELECTABLE_STYLE) {
    var child = element;
    var current = element.parentNode;
    while (current && current.tagName != goog.dom.TagName.HTML) {
      if (goog.style.isUnselectable(current)) {
        goog.style.setUnselectable(current, false, true);
        for (var i = 0, len = current.childNodes.length; i < len; i++) {
          var node = current.childNodes[i];
          if (node != child && node.nodeType == goog.dom.NodeType.ELEMENT) {
            goog.style.setUnselectable(current.childNodes[i], true);
          }
        }
      }
      child = current;
      current = current.parentNode;
    }
  }
};
goog.provide("goog.editor.range");
goog.provide("goog.editor.range.Point");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.Range");
goog.require("goog.dom.RangeEndpoint");
goog.require("goog.dom.SavedCaretRange");
goog.require("goog.editor.node");
goog.require("goog.editor.style");
goog.require("goog.iter");
goog.require("goog.userAgent");
goog.editor.range.narrow = function(range, el) {
  var startContainer = range.getStartNode();
  var endContainer = range.getEndNode();
  if (startContainer && endContainer) {
    var isElement = function(node) {
      return node == el;
    };
    var hasStart = goog.dom.getAncestor(startContainer, isElement, true);
    var hasEnd = goog.dom.getAncestor(endContainer, isElement, true);
    if (hasStart && hasEnd) {
      return range.clone();
    } else {
      if (hasStart) {
        var leaf = goog.editor.node.getRightMostLeaf(el);
        return goog.dom.Range.createFromNodes(range.getStartNode(), range.getStartOffset(), leaf, goog.editor.node.getLength(leaf));
      } else {
        if (hasEnd) {
          return goog.dom.Range.createFromNodes(goog.editor.node.getLeftMostLeaf(el), 0, range.getEndNode(), range.getEndOffset());
        }
      }
    }
  }
  return null;
};
goog.editor.range.expand = function(range, opt_stopNode) {
  var expandedRange = goog.editor.range.expandEndPointToContainer_(range, goog.dom.RangeEndpoint.START, opt_stopNode);
  expandedRange = goog.editor.range.expandEndPointToContainer_(expandedRange, goog.dom.RangeEndpoint.END, opt_stopNode);
  var startNode = expandedRange.getStartNode();
  var endNode = expandedRange.getEndNode();
  var startOffset = expandedRange.getStartOffset();
  var endOffset = expandedRange.getEndOffset();
  if (startNode == endNode) {
    while (endNode != opt_stopNode && startOffset == 0 && endOffset == goog.editor.node.getLength(endNode)) {
      var parentNode = endNode.parentNode;
      startOffset = goog.array.indexOf(parentNode.childNodes, endNode);
      endOffset = startOffset + 1;
      endNode = parentNode;
    }
    startNode = endNode;
  }
  return goog.dom.Range.createFromNodes(startNode, startOffset, endNode, endOffset);
};
goog.editor.range.expandEndPointToContainer_ = function(range, endpoint, opt_stopNode) {
  var expandStart = endpoint == goog.dom.RangeEndpoint.START;
  var node = expandStart ? range.getStartNode() : range.getEndNode();
  var offset = expandStart ? range.getStartOffset() : range.getEndOffset();
  var container = range.getContainerElement();
  while (node != container && node != opt_stopNode) {
    if (expandStart && offset != 0 || !expandStart && offset != goog.editor.node.getLength(node)) {
      break;
    }
    var parentNode = node.parentNode;
    var index = goog.array.indexOf(parentNode.childNodes, node);
    offset = expandStart ? index : index + 1;
    node = parentNode;
  }
  return goog.dom.Range.createFromNodes(expandStart ? node : range.getStartNode(), expandStart ? offset : range.getStartOffset(), expandStart ? range.getEndNode() : node, expandStart ? range.getEndOffset() : offset);
};
goog.editor.range.selectNodeStart = function(node) {
  goog.dom.Range.createCaret(goog.editor.node.getLeftMostLeaf(node), 0).select();
};
goog.editor.range.placeCursorNextTo = function(node, toLeft) {
  var parent = node.parentNode;
  var offset = goog.array.indexOf(parent.childNodes, node) + (toLeft ? 0 : 1);
  var point = goog.editor.range.Point.createDeepestPoint(parent, offset, toLeft, true);
  var range = goog.dom.Range.createCaret(point.node, point.offset);
  range.select();
  return range;
};
goog.editor.range.selectionPreservingNormalize = function(node) {
  var doc = goog.dom.getOwnerDocument(node);
  var selection = goog.dom.Range.createFromWindow(goog.dom.getWindow(doc));
  var normalizedRange = goog.editor.range.rangePreservingNormalize(node, selection);
  if (normalizedRange) {
    normalizedRange.select();
  }
};
goog.editor.range.normalizeNodeIe_ = function(node) {
  var lastText = null;
  var child = node.firstChild;
  while (child) {
    var next = child.nextSibling;
    if (child.nodeType == goog.dom.NodeType.TEXT) {
      if (child.nodeValue == "") {
        node.removeChild(child);
      } else {
        if (lastText) {
          lastText.nodeValue += child.nodeValue;
          node.removeChild(child);
        } else {
          lastText = child;
        }
      }
    } else {
      goog.editor.range.normalizeNodeIe_(child);
      lastText = null;
    }
    child = next;
  }
};
goog.editor.range.normalizeNode = function(node) {
  if (goog.userAgent.IE) {
    goog.editor.range.normalizeNodeIe_(node);
  } else {
    node.normalize();
  }
};
goog.editor.range.rangePreservingNormalize = function(node, range) {
  if (range) {
    var rangeFactory = goog.editor.range.normalize(range);
    var container = goog.editor.style.getContainer(range.getContainerElement());
  }
  if (container) {
    goog.editor.range.normalizeNode(goog.dom.findCommonAncestor(container, node));
  } else {
    if (node) {
      goog.editor.range.normalizeNode(node);
    }
  }
  if (rangeFactory) {
    return rangeFactory();
  } else {
    return null;
  }
};
goog.editor.range.getDeepEndPoint = function(range, atStart) {
  return atStart ? goog.editor.range.Point.createDeepestPoint(range.getStartNode(), range.getStartOffset()) : goog.editor.range.Point.createDeepestPoint(range.getEndNode(), range.getEndOffset());
};
goog.editor.range.normalize = function(range) {
  var isReversed = range.isReversed();
  var anchorPoint = goog.editor.range.normalizePoint_(goog.editor.range.getDeepEndPoint(range, !isReversed));
  var anchorParent = anchorPoint.getParentPoint();
  var anchorPreviousSibling = anchorPoint.node.previousSibling;
  if (anchorPoint.node.nodeType == goog.dom.NodeType.TEXT) {
    anchorPoint.node = null;
  }
  var focusPoint = goog.editor.range.normalizePoint_(goog.editor.range.getDeepEndPoint(range, isReversed));
  var focusParent = focusPoint.getParentPoint();
  var focusPreviousSibling = focusPoint.node.previousSibling;
  if (focusPoint.node.nodeType == goog.dom.NodeType.TEXT) {
    focusPoint.node = null;
  }
  return function() {
    if (!anchorPoint.node && anchorPreviousSibling) {
      anchorPoint.node = anchorPreviousSibling.nextSibling;
      if (!anchorPoint.node) {
        anchorPoint = goog.editor.range.Point.getPointAtEndOfNode(anchorPreviousSibling);
      }
    }
    if (!focusPoint.node && focusPreviousSibling) {
      focusPoint.node = focusPreviousSibling.nextSibling;
      if (!focusPoint.node) {
        focusPoint = goog.editor.range.Point.getPointAtEndOfNode(focusPreviousSibling);
      }
    }
    return goog.dom.Range.createFromNodes(anchorPoint.node || anchorParent.node.firstChild || anchorParent.node, anchorPoint.offset, focusPoint.node || focusParent.node.firstChild || focusParent.node, focusPoint.offset);
  };
};
goog.editor.range.normalizePoint_ = function(point) {
  var previous;
  if (point.node.nodeType == goog.dom.NodeType.TEXT) {
    for (var current = point.node.previousSibling; current && current.nodeType == goog.dom.NodeType.TEXT; current = current.previousSibling) {
      point.offset += goog.editor.node.getLength(current);
    }
    previous = current;
  } else {
    previous = point.node.previousSibling;
  }
  var parent = point.node.parentNode;
  point.node = previous ? previous.nextSibling : parent.firstChild;
  return point;
};
goog.editor.range.isEditable = function(range) {
  var rangeContainer = range.getContainerElement();
  var rangeContainerIsOutsideRange = range.getStartNode() != rangeContainer.parentElement;
  return rangeContainerIsOutsideRange && goog.editor.node.isEditableContainer(rangeContainer) || goog.editor.node.isEditable(rangeContainer);
};
goog.editor.range.intersectsTag = function(range, tagName) {
  if (goog.dom.getAncestorByTagNameAndClass(range.getContainerElement(), tagName)) {
    return true;
  }
  return goog.iter.some(range, function(node) {
    return node.tagName == tagName;
  });
};
goog.editor.range.Point = function(node, offset) {
  this.node = node;
  this.offset = offset;
};
goog.editor.range.Point.prototype.getParentPoint = function() {
  var parent = this.node.parentNode;
  return new goog.editor.range.Point(parent, goog.array.indexOf(parent.childNodes, this.node));
};
goog.editor.range.Point.createDeepestPoint = function(node, offset, opt_trendLeft, opt_stopOnChildlessElement) {
  while (node.nodeType == goog.dom.NodeType.ELEMENT) {
    var child = node.childNodes[offset];
    if (!child && !node.lastChild) {
      break;
    } else {
      if (child) {
        var prevSibling = child.previousSibling;
        if (opt_trendLeft && prevSibling) {
          if (opt_stopOnChildlessElement && goog.editor.range.Point.isTerminalElement_(prevSibling)) {
            break;
          }
          node = prevSibling;
          offset = goog.editor.node.getLength(node);
        } else {
          if (opt_stopOnChildlessElement && goog.editor.range.Point.isTerminalElement_(child)) {
            break;
          }
          node = child;
          offset = 0;
        }
      } else {
        if (opt_stopOnChildlessElement && goog.editor.range.Point.isTerminalElement_(node.lastChild)) {
          break;
        }
        node = node.lastChild;
        offset = goog.editor.node.getLength(node);
      }
    }
  }
  return new goog.editor.range.Point(node, offset);
};
goog.editor.range.Point.isTerminalElement_ = function(node) {
  return node.nodeType == goog.dom.NodeType.ELEMENT && !goog.dom.canHaveChildren(node);
};
goog.editor.range.Point.getPointAtEndOfNode = function(node) {
  return new goog.editor.range.Point(node, goog.editor.node.getLength(node));
};
goog.editor.range.saveUsingNormalizedCarets = function(range) {
  return new goog.editor.range.NormalizedCaretRange_(range);
};
goog.editor.range.NormalizedCaretRange_ = function(range) {
  goog.dom.SavedCaretRange.call(this, range);
};
goog.inherits(goog.editor.range.NormalizedCaretRange_, goog.dom.SavedCaretRange);
goog.editor.range.NormalizedCaretRange_.prototype.removeCarets = function(opt_range) {
  var startCaret = this.getCaret(true);
  var endCaret = this.getCaret(false);
  var node = startCaret && endCaret ? goog.dom.findCommonAncestor(startCaret, endCaret) : startCaret || endCaret;
  goog.editor.range.NormalizedCaretRange_.superClass_.removeCarets.call(this);
  if (opt_range) {
    return goog.editor.range.rangePreservingNormalize(node, opt_range);
  } else {
    if (node) {
      goog.editor.range.selectionPreservingNormalize(node);
    }
  }
};
goog.provide("goog.events.KeyCodes");
goog.require("goog.userAgent");
goog.forwardDeclare("goog.events.BrowserEvent");
goog.events.KeyCodes = {WIN_KEY_FF_LINUX:0, MAC_ENTER:3, BACKSPACE:8, TAB:9, NUM_CENTER:12, ENTER:13, SHIFT:16, CTRL:17, ALT:18, PAUSE:19, CAPS_LOCK:20, ESC:27, SPACE:32, PAGE_UP:33, PAGE_DOWN:34, END:35, HOME:36, LEFT:37, UP:38, RIGHT:39, DOWN:40, PLUS_SIGN:43, PRINT_SCREEN:44, INSERT:45, DELETE:46, ZERO:48, ONE:49, TWO:50, THREE:51, FOUR:52, FIVE:53, SIX:54, SEVEN:55, EIGHT:56, NINE:57, FF_SEMICOLON:59, FF_EQUALS:61, FF_DASH:173, QUESTION_MARK:63, AT_SIGN:64, A:65, B:66, C:67, D:68, E:69, F:70, 
G:71, H:72, I:73, J:74, K:75, L:76, M:77, N:78, O:79, P:80, Q:81, R:82, S:83, T:84, U:85, V:86, W:87, X:88, Y:89, Z:90, META:91, WIN_KEY_RIGHT:92, CONTEXT_MENU:93, NUM_ZERO:96, NUM_ONE:97, NUM_TWO:98, NUM_THREE:99, NUM_FOUR:100, NUM_FIVE:101, NUM_SIX:102, NUM_SEVEN:103, NUM_EIGHT:104, NUM_NINE:105, NUM_MULTIPLY:106, NUM_PLUS:107, NUM_MINUS:109, NUM_PERIOD:110, NUM_DIVISION:111, F1:112, F2:113, F3:114, F4:115, F5:116, F6:117, F7:118, F8:119, F9:120, F10:121, F11:122, F12:123, NUMLOCK:144, SCROLL_LOCK:145, 
FIRST_MEDIA_KEY:166, LAST_MEDIA_KEY:183, SEMICOLON:186, DASH:189, EQUALS:187, COMMA:188, PERIOD:190, SLASH:191, APOSTROPHE:192, TILDE:192, SINGLE_QUOTE:222, OPEN_SQUARE_BRACKET:219, BACKSLASH:220, CLOSE_SQUARE_BRACKET:221, WIN_KEY:224, MAC_FF_META:224, MAC_WK_CMD_LEFT:91, MAC_WK_CMD_RIGHT:93, WIN_IME:229, VK_NONAME:252, PHANTOM:255};
goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) {
  if (e.altKey && !e.ctrlKey || e.metaKey || e.keyCode >= goog.events.KeyCodes.F1 && e.keyCode <= goog.events.KeyCodes.F12) {
    return false;
  }
  switch(e.keyCode) {
    case goog.events.KeyCodes.ALT:
    case goog.events.KeyCodes.CAPS_LOCK:
    case goog.events.KeyCodes.CONTEXT_MENU:
    case goog.events.KeyCodes.CTRL:
    case goog.events.KeyCodes.DOWN:
    case goog.events.KeyCodes.END:
    case goog.events.KeyCodes.ESC:
    case goog.events.KeyCodes.HOME:
    case goog.events.KeyCodes.INSERT:
    case goog.events.KeyCodes.LEFT:
    case goog.events.KeyCodes.MAC_FF_META:
    case goog.events.KeyCodes.META:
    case goog.events.KeyCodes.NUMLOCK:
    case goog.events.KeyCodes.NUM_CENTER:
    case goog.events.KeyCodes.PAGE_DOWN:
    case goog.events.KeyCodes.PAGE_UP:
    case goog.events.KeyCodes.PAUSE:
    case goog.events.KeyCodes.PHANTOM:
    case goog.events.KeyCodes.PRINT_SCREEN:
    case goog.events.KeyCodes.RIGHT:
    case goog.events.KeyCodes.SCROLL_LOCK:
    case goog.events.KeyCodes.SHIFT:
    case goog.events.KeyCodes.UP:
    case goog.events.KeyCodes.VK_NONAME:
    case goog.events.KeyCodes.WIN_KEY:
    case goog.events.KeyCodes.WIN_KEY_RIGHT:
      return false;
    case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
      return !goog.userAgent.GECKO;
    default:
      return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY || e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY;
  }
};
goog.events.KeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode, opt_shiftKey, opt_ctrlKey, opt_altKey, opt_metaKey) {
  if (!goog.userAgent.IE && !goog.userAgent.EDGE && !(goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher("525"))) {
    return true;
  }
  if (goog.userAgent.MAC && opt_altKey) {
    return goog.events.KeyCodes.isCharacterKey(keyCode);
  }
  if (opt_altKey && !opt_ctrlKey) {
    return false;
  }
  if (goog.isNumber(opt_heldKeyCode)) {
    opt_heldKeyCode = goog.events.KeyCodes.normalizeKeyCode(opt_heldKeyCode);
  }
  var heldKeyIsModifier = opt_heldKeyCode == goog.events.KeyCodes.CTRL || opt_heldKeyCode == goog.events.KeyCodes.ALT || goog.userAgent.MAC && opt_heldKeyCode == goog.events.KeyCodes.META;
  var modifiedShiftKey = opt_heldKeyCode == goog.events.KeyCodes.SHIFT && (opt_ctrlKey || opt_metaKey);
  if ((!opt_shiftKey || goog.userAgent.MAC) && heldKeyIsModifier || goog.userAgent.MAC && modifiedShiftKey) {
    return false;
  }
  if ((goog.userAgent.WEBKIT || goog.userAgent.EDGE) && opt_ctrlKey && opt_shiftKey) {
    switch(keyCode) {
      case goog.events.KeyCodes.BACKSLASH:
      case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
      case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
      case goog.events.KeyCodes.TILDE:
      case goog.events.KeyCodes.SEMICOLON:
      case goog.events.KeyCodes.DASH:
      case goog.events.KeyCodes.EQUALS:
      case goog.events.KeyCodes.COMMA:
      case goog.events.KeyCodes.PERIOD:
      case goog.events.KeyCodes.SLASH:
      case goog.events.KeyCodes.APOSTROPHE:
      case goog.events.KeyCodes.SINGLE_QUOTE:
        return false;
    }
  }
  if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) {
    return false;
  }
  switch(keyCode) {
    case goog.events.KeyCodes.ENTER:
      return true;
    case goog.events.KeyCodes.ESC:
      return !(goog.userAgent.WEBKIT || goog.userAgent.EDGE);
  }
  return goog.events.KeyCodes.isCharacterKey(keyCode);
};
goog.events.KeyCodes.isCharacterKey = function(keyCode) {
  if (keyCode >= goog.events.KeyCodes.ZERO && keyCode <= goog.events.KeyCodes.NINE) {
    return true;
  }
  if (keyCode >= goog.events.KeyCodes.NUM_ZERO && keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) {
    return true;
  }
  if (keyCode >= goog.events.KeyCodes.A && keyCode <= goog.events.KeyCodes.Z) {
    return true;
  }
  if ((goog.userAgent.WEBKIT || goog.userAgent.EDGE) && keyCode == 0) {
    return true;
  }
  switch(keyCode) {
    case goog.events.KeyCodes.SPACE:
    case goog.events.KeyCodes.PLUS_SIGN:
    case goog.events.KeyCodes.QUESTION_MARK:
    case goog.events.KeyCodes.AT_SIGN:
    case goog.events.KeyCodes.NUM_PLUS:
    case goog.events.KeyCodes.NUM_MINUS:
    case goog.events.KeyCodes.NUM_PERIOD:
    case goog.events.KeyCodes.NUM_DIVISION:
    case goog.events.KeyCodes.SEMICOLON:
    case goog.events.KeyCodes.FF_SEMICOLON:
    case goog.events.KeyCodes.DASH:
    case goog.events.KeyCodes.EQUALS:
    case goog.events.KeyCodes.FF_EQUALS:
    case goog.events.KeyCodes.COMMA:
    case goog.events.KeyCodes.PERIOD:
    case goog.events.KeyCodes.SLASH:
    case goog.events.KeyCodes.APOSTROPHE:
    case goog.events.KeyCodes.SINGLE_QUOTE:
    case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
    case goog.events.KeyCodes.BACKSLASH:
    case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
      return true;
    default:
      return false;
  }
};
goog.events.KeyCodes.normalizeKeyCode = function(keyCode) {
  if (goog.userAgent.GECKO) {
    return goog.events.KeyCodes.normalizeGeckoKeyCode(keyCode);
  } else {
    if (goog.userAgent.MAC && goog.userAgent.WEBKIT) {
      return goog.events.KeyCodes.normalizeMacWebKitKeyCode(keyCode);
    } else {
      return keyCode;
    }
  }
};
goog.events.KeyCodes.normalizeGeckoKeyCode = function(keyCode) {
  switch(keyCode) {
    case goog.events.KeyCodes.FF_EQUALS:
      return goog.events.KeyCodes.EQUALS;
    case goog.events.KeyCodes.FF_SEMICOLON:
      return goog.events.KeyCodes.SEMICOLON;
    case goog.events.KeyCodes.FF_DASH:
      return goog.events.KeyCodes.DASH;
    case goog.events.KeyCodes.MAC_FF_META:
      return goog.events.KeyCodes.META;
    case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
      return goog.events.KeyCodes.WIN_KEY;
    default:
      return keyCode;
  }
};
goog.events.KeyCodes.normalizeMacWebKitKeyCode = function(keyCode) {
  switch(keyCode) {
    case goog.events.KeyCodes.MAC_WK_CMD_RIGHT:
      return goog.events.KeyCodes.META;
    default:
      return keyCode;
  }
};
goog.provide("goog.editor.Field");
goog.provide("goog.editor.Field.EventType");
goog.require("goog.a11y.aria");
goog.require("goog.a11y.aria.Role");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.async.Delay");
goog.require("goog.dom");
goog.require("goog.dom.Range");
goog.require("goog.dom.TagName");
goog.require("goog.dom.classlist");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Command");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.icontent");
goog.require("goog.editor.icontent.FieldFormatInfo");
goog.require("goog.editor.icontent.FieldStyleInfo");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("goog.events");
goog.require("goog.events.EventHandler");
goog.require("goog.events.EventTarget");
goog.require("goog.events.EventType");
goog.require("goog.events.KeyCodes");
goog.require("goog.functions");
goog.require("goog.html.SafeHtml");
goog.require("goog.html.legacyconversions");
goog.require("goog.log");
goog.require("goog.log.Level");
goog.require("goog.string");
goog.require("goog.string.Unicode");
goog.require("goog.style");
goog.require("goog.userAgent");
goog.require("goog.userAgent.product");
goog.editor.Field = function(id, opt_doc) {
  goog.events.EventTarget.call(this);
  this.id = id;
  this.hashCode_ = id;
  this.editableDomHelper = null;
  this.plugins_ = {};
  this.indexedPlugins_ = {};
  for (var op in goog.editor.Plugin.OPCODE) {
    this.indexedPlugins_[op] = [];
  }
  this.cssStyles = "";
  this.stoppedEvents_ = {};
  this.stopEvent(goog.editor.Field.EventType.CHANGE);
  this.stopEvent(goog.editor.Field.EventType.DELAYEDCHANGE);
  this.isModified_ = false;
  this.isEverModified_ = false;
  this.delayedChangeTimer_ = new goog.async.Delay(this.dispatchDelayedChange_, goog.editor.Field.DELAYED_CHANGE_FREQUENCY, this);
  this.debouncedEvents_ = {};
  for (var key in goog.editor.Field.EventType) {
    this.debouncedEvents_[goog.editor.Field.EventType[key]] = 0;
  }
  if (goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
    this.changeTimerGecko_ = new goog.async.Delay(this.handleChange, goog.editor.Field.CHANGE_FREQUENCY, this);
  }
  this.eventRegister = new goog.events.EventHandler(this);
  this.wrappers_ = [];
  this.loadState_ = goog.editor.Field.LoadState_.UNEDITABLE;
  var doc = opt_doc || document;
  this.originalDomHelper = goog.dom.getDomHelper(doc);
  this.originalElement = this.originalDomHelper.getElement(this.id);
  this.followLinkInNewWindow_ = goog.editor.BrowserFeature.FOLLOWS_EDITABLE_LINKS;
  this.appWindow_ = this.originalDomHelper.getWindow();
};
goog.inherits(goog.editor.Field, goog.events.EventTarget);
goog.editor.Field.prototype.field = null;
goog.editor.Field.prototype.logger = goog.log.getLogger("goog.editor.Field");
goog.editor.Field.EventType = {COMMAND_VALUE_CHANGE:"cvc", LOAD:"load", UNLOAD:"unload", BEFORECHANGE:"beforechange", CHANGE:"change", DELAYEDCHANGE:"delayedchange", BEFOREFOCUS:"beforefocus", FOCUS:"focus", BLUR:"blur", BEFORETAB:"beforetab", IFRAME_RESIZED:"ifrsz", BEFORESELECTIONCHANGE:"beforeselectionchange", SELECTIONCHANGE:"selectionchange"};
goog.editor.Field.LoadState_ = {UNEDITABLE:0, LOADING:1, EDITABLE:2};
goog.editor.Field.DEBOUNCE_TIME_MS_ = 500;
goog.editor.Field.activeFieldId_ = null;
goog.editor.Field.prototype.inModalMode_ = false;
goog.editor.Field.prototype.appWindow_;
goog.editor.Field.prototype.selectionChangeTarget_;
goog.editor.Field.prototype.useWindowMouseUp_ = false;
goog.editor.Field.prototype.waitingForMouseUp_ = false;
goog.editor.Field.setActiveFieldId = function(fieldId) {
  goog.editor.Field.activeFieldId_ = fieldId;
};
goog.editor.Field.getActiveFieldId = function() {
  return goog.editor.Field.activeFieldId_;
};
goog.editor.Field.prototype.setUseWindowMouseUp = function(flag) {
  goog.asserts.assert(!flag || !this.usesIframe(), "procssing window mouse up should only be enabled when not using iframe");
  this.useWindowMouseUp_ = flag;
};
goog.editor.Field.prototype.inModalMode = function() {
  return this.inModalMode_;
};
goog.editor.Field.prototype.setModalMode = function(inModalMode) {
  this.inModalMode_ = inModalMode;
};
goog.editor.Field.prototype.getHashCode = function() {
  return this.hashCode_;
};
goog.editor.Field.prototype.getElement = function() {
  return this.field;
};
goog.editor.Field.prototype.getOriginalElement = function() {
  return this.originalElement;
};
goog.editor.Field.prototype.addListener = function(type, listener, opt_capture, opt_handler) {
  var elem = this.getElement();
  if (goog.editor.BrowserFeature.USE_DOCUMENT_FOR_KEY_EVENTS && elem && this.usesIframe()) {
    elem = elem.ownerDocument;
  }
  if (opt_handler) {
    this.eventRegister.listenWithScope(elem, type, listener, opt_capture, opt_handler);
  } else {
    this.eventRegister.listen(elem, type, listener, opt_capture);
  }
};
goog.editor.Field.prototype.getPluginByClassId = function(classId) {
  return this.plugins_[classId];
};
goog.editor.Field.prototype.registerPlugin = function(plugin) {
  var classId = plugin.getTrogClassId();
  if (this.plugins_[classId]) {
    goog.log.error(this.logger, "Cannot register the same class of plugin twice.");
  }
  this.plugins_[classId] = plugin;
  for (var op in goog.editor.Plugin.OPCODE) {
    var opcode = goog.editor.Plugin.OPCODE[op];
    if (plugin[opcode]) {
      this.indexedPlugins_[op].push(plugin);
    }
  }
  plugin.registerFieldObject(this);
  if (this.isLoaded()) {
    plugin.enable(this);
  }
};
goog.editor.Field.prototype.unregisterPlugin = function(plugin) {
  var classId = plugin.getTrogClassId();
  if (!this.plugins_[classId]) {
    goog.log.error(this.logger, "Cannot unregister a plugin that isn't registered.");
  }
  delete this.plugins_[classId];
  for (var op in goog.editor.Plugin.OPCODE) {
    var opcode = goog.editor.Plugin.OPCODE[op];
    if (plugin[opcode]) {
      goog.array.remove(this.indexedPlugins_[op], plugin);
    }
  }
  plugin.unregisterFieldObject(this);
};
goog.editor.Field.prototype.setInitialStyle = function(cssText) {
  this.cssText = cssText;
};
goog.editor.Field.prototype.resetOriginalElemProperties = function() {
  var field = this.getOriginalElement();
  field.removeAttribute("contentEditable");
  field.removeAttribute("g_editable");
  field.removeAttribute("role");
  if (!this.id) {
    field.removeAttribute("id");
  } else {
    field.id = this.id;
  }
  field.className = this.savedClassName_ || "";
  var cssText = this.cssText;
  if (!cssText) {
    field.removeAttribute("style");
  } else {
    goog.dom.setProperties(field, {"style":cssText});
  }
  if (goog.isString(this.originalFieldLineHeight_)) {
    goog.style.setStyle(field, "lineHeight", this.originalFieldLineHeight_);
    this.originalFieldLineHeight_ = null;
  }
};
goog.editor.Field.prototype.isModified = function(opt_useIsEverModified) {
  return opt_useIsEverModified ? this.isEverModified_ : this.isModified_;
};
goog.editor.Field.CHANGE_FREQUENCY = 15;
goog.editor.Field.DELAYED_CHANGE_FREQUENCY = 250;
goog.editor.Field.prototype.usesIframe = goog.functions.TRUE;
goog.editor.Field.prototype.isFixedHeight = goog.functions.TRUE;
goog.editor.Field.prototype.shouldRefocusOnInputMobileSafari = goog.functions.FALSE;
goog.editor.Field.KEYS_CAUSING_CHANGES_ = {46:true, 8:true};
if (!goog.userAgent.IE) {
  goog.editor.Field.KEYS_CAUSING_CHANGES_[9] = true;
}
goog.editor.Field.CTRL_KEYS_CAUSING_CHANGES_ = {86:true, 88:true};
if (goog.userAgent.WINDOWS && !goog.userAgent.GECKO) {
  goog.editor.Field.KEYS_CAUSING_CHANGES_[229] = true;
}
goog.editor.Field.isGeneratingKey_ = function(e, testAllKeys) {
  if (goog.editor.Field.isSpecialGeneratingKey_(e)) {
    return true;
  }
  return !!(testAllKeys && !(e.ctrlKey || e.metaKey) && (!goog.userAgent.GECKO || e.charCode));
};
goog.editor.Field.isSpecialGeneratingKey_ = function(e) {
  var testCtrlKeys = (e.ctrlKey || e.metaKey) && e.keyCode in goog.editor.Field.CTRL_KEYS_CAUSING_CHANGES_;
  var testRegularKeys = !(e.ctrlKey || e.metaKey) && e.keyCode in goog.editor.Field.KEYS_CAUSING_CHANGES_;
  return testCtrlKeys || testRegularKeys;
};
goog.editor.Field.prototype.setAppWindow = function(appWindow) {
  this.appWindow_ = appWindow;
};
goog.editor.Field.prototype.getAppWindow = function() {
  return this.appWindow_;
};
goog.editor.Field.prototype.setBaseZindex = function(zindex) {
  this.baseZindex_ = zindex;
};
goog.editor.Field.prototype.getBaseZindex = function() {
  return this.baseZindex_ || 0;
};
goog.editor.Field.prototype.setupFieldObject = function(field) {
  this.loadState_ = goog.editor.Field.LoadState_.EDITABLE;
  this.field = field;
  this.editableDomHelper = goog.dom.getDomHelper(field);
  this.isModified_ = false;
  this.isEverModified_ = false;
  field.setAttribute("g_editable", "true");
  goog.a11y.aria.setRole(field, goog.a11y.aria.Role.TEXTBOX);
};
goog.editor.Field.prototype.tearDownFieldObject_ = function() {
  this.loadState_ = goog.editor.Field.LoadState_.UNEDITABLE;
  for (var classId in this.plugins_) {
    var plugin = this.plugins_[classId];
    if (!plugin.activeOnUneditableFields()) {
      plugin.disable(this);
    }
  }
  this.field = null;
  this.editableDomHelper = null;
};
goog.editor.Field.prototype.setupChangeListeners_ = function() {
  if ((goog.userAgent.product.IPHONE || goog.userAgent.product.IPAD) && this.usesIframe() && this.shouldRefocusOnInputMobileSafari()) {
    var editWindow = this.getEditableDomHelper().getWindow();
    this.boundRefocusListenerMobileSafari_ = goog.bind(editWindow.focus, editWindow);
    editWindow.addEventListener(goog.events.EventType.KEYDOWN, this.boundRefocusListenerMobileSafari_, false);
    editWindow.addEventListener(goog.events.EventType.TOUCHEND, this.boundRefocusListenerMobileSafari_, false);
  }
  if (goog.userAgent.OPERA && this.usesIframe()) {
    this.boundFocusListenerOpera_ = goog.bind(this.dispatchFocusAndBeforeFocus_, this);
    this.boundBlurListenerOpera_ = goog.bind(this.dispatchBlur, this);
    var editWindow = this.getEditableDomHelper().getWindow();
    editWindow.addEventListener(goog.events.EventType.FOCUS, this.boundFocusListenerOpera_, false);
    editWindow.addEventListener(goog.events.EventType.BLUR, this.boundBlurListenerOpera_, false);
  } else {
    if (goog.editor.BrowserFeature.SUPPORTS_FOCUSIN) {
      this.addListener(goog.events.EventType.FOCUS, this.dispatchFocus_);
      this.addListener(goog.events.EventType.FOCUSIN, this.dispatchBeforeFocus_);
    } else {
      this.addListener(goog.events.EventType.FOCUS, this.dispatchFocusAndBeforeFocus_);
    }
    this.addListener(goog.events.EventType.BLUR, this.dispatchBlur, goog.editor.BrowserFeature.USE_MUTATION_EVENTS);
  }
  if (goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
    this.setupMutationEventHandlersGecko();
  } else {
    this.addListener(["beforecut", "beforepaste", "drop", "dragend"], this.dispatchBeforeChange);
    this.addListener(["cut", "paste"], goog.functions.lock(this.dispatchChange));
    this.addListener("drop", this.handleDrop_);
  }
  var dropEventName = goog.userAgent.WEBKIT ? "dragend" : "dragdrop";
  this.addListener(dropEventName, this.handleDrop_);
  this.addListener(goog.events.EventType.KEYDOWN, this.handleKeyDown_);
  this.addListener(goog.events.EventType.KEYPRESS, this.handleKeyPress_);
  this.addListener(goog.events.EventType.KEYUP, this.handleKeyUp_);
  this.selectionChangeTimer_ = new goog.async.Delay(this.handleSelectionChangeTimer_, goog.editor.Field.SELECTION_CHANGE_FREQUENCY_, this);
  if (this.followLinkInNewWindow_) {
    this.addListener(goog.events.EventType.CLICK, goog.editor.Field.cancelLinkClick_);
  }
  this.addListener(goog.events.EventType.MOUSEDOWN, this.handleMouseDown_);
  if (this.useWindowMouseUp_) {
    this.eventRegister.listen(this.editableDomHelper.getDocument(), goog.events.EventType.MOUSEUP, this.handleMouseUp_);
    this.addListener(goog.events.EventType.DRAGSTART, this.handleDragStart_);
  } else {
    this.addListener(goog.events.EventType.MOUSEUP, this.handleMouseUp_);
  }
};
goog.editor.Field.SELECTION_CHANGE_FREQUENCY_ = 250;
goog.editor.Field.prototype.clearListeners = function() {
  if (this.eventRegister) {
    this.eventRegister.removeAll();
  }
  if ((goog.userAgent.product.IPHONE || goog.userAgent.product.IPAD) && this.usesIframe() && this.shouldRefocusOnInputMobileSafari()) {
    try {
      var editWindow = this.getEditableDomHelper().getWindow();
      editWindow.removeEventListener(goog.events.EventType.KEYDOWN, this.boundRefocusListenerMobileSafari_, false);
      editWindow.removeEventListener(goog.events.EventType.TOUCHEND, this.boundRefocusListenerMobileSafari_, false);
    } catch (e) {
    }
    delete this.boundRefocusListenerMobileSafari_;
  }
  if (goog.userAgent.OPERA && this.usesIframe()) {
    try {
      var editWindow = this.getEditableDomHelper().getWindow();
      editWindow.removeEventListener(goog.events.EventType.FOCUS, this.boundFocusListenerOpera_, false);
      editWindow.removeEventListener(goog.events.EventType.BLUR, this.boundBlurListenerOpera_, false);
    } catch (e$7) {
    }
    delete this.boundFocusListenerOpera_;
    delete this.boundBlurListenerOpera_;
  }
  if (this.changeTimerGecko_) {
    this.changeTimerGecko_.stop();
  }
  this.delayedChangeTimer_.stop();
};
goog.editor.Field.prototype.disposeInternal = function() {
  if (this.isLoading() || this.isLoaded()) {
    goog.log.warning(this.logger, "Disposing a field that is in use.");
  }
  if (this.getOriginalElement()) {
    this.execCommand(goog.editor.Command.CLEAR_LOREM);
  }
  this.tearDownFieldObject_();
  this.clearListeners();
  this.clearFieldLoadListener_();
  this.originalDomHelper = null;
  if (this.eventRegister) {
    this.eventRegister.dispose();
    this.eventRegister = null;
  }
  this.removeAllWrappers();
  if (goog.editor.Field.getActiveFieldId() == this.id) {
    goog.editor.Field.setActiveFieldId(null);
  }
  for (var classId in this.plugins_) {
    var plugin = this.plugins_[classId];
    if (plugin.isAutoDispose()) {
      plugin.dispose();
    }
  }
  delete this.plugins_;
  goog.editor.Field.superClass_.disposeInternal.call(this);
};
goog.editor.Field.prototype.attachWrapper = function(wrapper) {
  this.wrappers_.push(wrapper);
};
goog.editor.Field.prototype.removeAllWrappers = function() {
  var wrapper;
  while (wrapper = this.wrappers_.pop()) {
    wrapper.dispose();
  }
};
goog.editor.Field.prototype.setFollowLinkInNewWindow = function(followLinkInNewWindow) {
  this.followLinkInNewWindow_ = followLinkInNewWindow;
};
goog.editor.Field.MUTATION_EVENTS_GECKO = ["DOMNodeInserted", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument", "DOMCharacterDataModified"];
goog.editor.Field.prototype.setupMutationEventHandlersGecko = function() {
  if (goog.editor.BrowserFeature.HAS_DOM_SUBTREE_MODIFIED_EVENT || !this.usesIframe()) {
    this.eventRegister.listen(this.getElement(), "DOMSubtreeModified", this.handleMutationEventGecko_);
  } else {
    var doc = this.getEditableDomHelper().getDocument();
    this.eventRegister.listen(doc, goog.editor.Field.MUTATION_EVENTS_GECKO, this.handleMutationEventGecko_, true);
    this.eventRegister.listen(doc, "DOMAttrModified", goog.bind(this.handleDomAttrChange, this, this.handleMutationEventGecko_), true);
  }
};
goog.editor.Field.prototype.handleBeforeChangeKeyEvent_ = function(e) {
  var block = e.keyCode == goog.events.KeyCodes.TAB && !this.dispatchBeforeTab_(e) || goog.userAgent.GECKO && e.metaKey && !goog.userAgent.isVersionOrHigher(29) && (e.keyCode == goog.events.KeyCodes.LEFT || e.keyCode == goog.events.KeyCodes.RIGHT);
  if (block) {
    e.preventDefault();
    return false;
  } else {
    this.gotGeneratingKey_ = e.charCode || goog.editor.Field.isGeneratingKey_(e, goog.userAgent.GECKO);
    if (this.gotGeneratingKey_) {
      this.dispatchBeforeChange();
    }
  }
  return true;
};
goog.editor.Field.SELECTION_CHANGE_KEYCODES = {8:1, 9:1, 13:1, 33:1, 34:1, 35:1, 36:1, 37:1, 38:1, 39:1, 40:1, 46:1};
goog.editor.Field.CTRL_KEYS_CAUSING_SELECTION_CHANGES_ = {65:true, 86:true, 88:true};
goog.editor.Field.POTENTIAL_SHORTCUT_KEYCODES_ = {8:1, 9:1, 13:1, 27:1, 33:1, 34:1, 37:1, 38:1, 39:1, 40:1};
goog.editor.Field.prototype.invokeShortCircuitingOp_ = function(op, var_args) {
  var plugins = this.indexedPlugins_[op];
  var argList = goog.array.slice(arguments, 1);
  for (var i = 0; i < plugins.length; ++i) {
    var plugin = plugins[i];
    if ((plugin.isEnabled(this) || goog.editor.Plugin.IRREPRESSIBLE_OPS[op]) && plugin[goog.editor.Plugin.OPCODE[op]].apply(plugin, argList)) {
      return true;
    }
  }
  return false;
};
goog.editor.Field.prototype.invokeOp_ = function(op, var_args) {
  var plugins = this.indexedPlugins_[op];
  var argList = goog.array.slice(arguments, 1);
  for (var i = 0; i < plugins.length; ++i) {
    var plugin = plugins[i];
    if (plugin.isEnabled(this) || goog.editor.Plugin.IRREPRESSIBLE_OPS[op]) {
      plugin[goog.editor.Plugin.OPCODE[op]].apply(plugin, argList);
    }
  }
};
goog.editor.Field.prototype.reduceOp_ = function(op, arg, var_args) {
  var plugins = this.indexedPlugins_[op];
  var argList = goog.array.slice(arguments, 1);
  for (var i = 0; i < plugins.length; ++i) {
    var plugin = plugins[i];
    if (plugin.isEnabled(this) || goog.editor.Plugin.IRREPRESSIBLE_OPS[op]) {
      argList[0] = plugin[goog.editor.Plugin.OPCODE[op]].apply(plugin, argList);
    }
  }
  return argList[0];
};
goog.editor.Field.prototype.injectContents = function(contents, field) {
  var styles = {};
  var newHtml = this.getInjectableContents(contents, styles);
  goog.style.setStyle(field, styles);
  goog.editor.node.replaceInnerHtml(field, newHtml);
};
goog.editor.Field.prototype.getInjectableContents = function(contents, styles) {
  return this.reduceOp_(goog.editor.Plugin.Op.PREPARE_CONTENTS_HTML, contents || "", styles);
};
goog.editor.Field.prototype.handleKeyDown_ = function(e) {
  if (goog.userAgent.MAC && e.keyCode == goog.events.KeyCodes.A) {
    this.maybeStartSelectionChangeTimer_(e);
  }
  if (!goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
    if (!this.handleBeforeChangeKeyEvent_(e)) {
      return;
    }
  }
  if (!this.invokeShortCircuitingOp_(goog.editor.Plugin.Op.KEYDOWN, e) && goog.editor.BrowserFeature.USES_KEYDOWN) {
    this.handleKeyboardShortcut_(e);
  }
};
goog.editor.Field.prototype.handleKeyPress_ = function(e) {
  if (goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
    if (!this.handleBeforeChangeKeyEvent_(e)) {
      return;
    }
  } else {
    this.gotGeneratingKey_ = true;
    this.dispatchBeforeChange();
  }
  if (!this.invokeShortCircuitingOp_(goog.editor.Plugin.Op.KEYPRESS, e) && !goog.editor.BrowserFeature.USES_KEYDOWN) {
    this.handleKeyboardShortcut_(e);
  }
};
goog.editor.Field.prototype.handleKeyUp_ = function(e) {
  if (!goog.editor.BrowserFeature.USE_MUTATION_EVENTS && (this.gotGeneratingKey_ || goog.editor.Field.isSpecialGeneratingKey_(e))) {
    this.handleChange();
  }
  this.invokeShortCircuitingOp_(goog.editor.Plugin.Op.KEYUP, e);
  this.maybeStartSelectionChangeTimer_(e);
};
goog.editor.Field.prototype.maybeStartSelectionChangeTimer_ = function(e) {
  if (this.isEventStopped(goog.editor.Field.EventType.SELECTIONCHANGE)) {
    return;
  }
  if (goog.editor.Field.SELECTION_CHANGE_KEYCODES[e.keyCode] || (e.ctrlKey || e.metaKey) && goog.editor.Field.CTRL_KEYS_CAUSING_SELECTION_CHANGES_[e.keyCode]) {
    this.dispatchEvent(goog.editor.Field.EventType.BEFORESELECTIONCHANGE);
    this.selectionChangeTimer_.start();
  }
};
goog.editor.Field.prototype.handleKeyboardShortcut_ = function(e) {
  if (e.altKey) {
    return;
  }
  var isModifierPressed = goog.userAgent.MAC ? e.metaKey : e.ctrlKey;
  if (isModifierPressed || goog.editor.Field.POTENTIAL_SHORTCUT_KEYCODES_[e.keyCode]) {
    var key = e.charCode || e.keyCode;
    if (key == 17) {
      return;
    }
    var stringKey = String.fromCharCode(key).toLowerCase();
    if (goog.userAgent.MAC && goog.userAgent.GECKO && stringKey == "`" && e.getBrowserEvent().key == " ") {
      stringKey = " ";
    }
    if (e.keyCode == goog.events.KeyCodes.BACKSLASH) {
      stringKey = "\\";
    }
    if (this.invokeShortCircuitingOp_(goog.editor.Plugin.Op.SHORTCUT, e, stringKey, isModifierPressed)) {
      e.preventDefault();
    }
  }
};
goog.editor.Field.prototype.execCommand = function(command, var_args) {
  var args = arguments;
  var result;
  var plugins = this.indexedPlugins_[goog.editor.Plugin.Op.EXEC_COMMAND];
  for (var i = 0; i < plugins.length; ++i) {
    var plugin = plugins[i];
    if (plugin.isEnabled(this) && plugin.isSupportedCommand(command)) {
      result = plugin.execCommand.apply(plugin, args);
      break;
    }
  }
  return result;
};
goog.editor.Field.prototype.queryCommandValue = function(commands) {
  var isEditable = this.isLoaded() && this.isSelectionEditable();
  if (goog.isString(commands)) {
    return this.queryCommandValueInternal_(commands, isEditable);
  } else {
    var state = {};
    for (var i = 0; i < commands.length; i++) {
      state[commands[i]] = this.queryCommandValueInternal_(commands[i], isEditable);
    }
    return state;
  }
};
goog.editor.Field.prototype.queryCommandValueInternal_ = function(command, isEditable) {
  var plugins = this.indexedPlugins_[goog.editor.Plugin.Op.QUERY_COMMAND];
  for (var i = 0; i < plugins.length; ++i) {
    var plugin = plugins[i];
    if (plugin.isEnabled(this) && plugin.isSupportedCommand(command) && (isEditable || plugin.activeOnUneditableFields())) {
      return plugin.queryCommandValue(command);
    }
  }
  return isEditable ? null : false;
};
goog.editor.Field.prototype.handleDomAttrChange = function(handler, browserEvent) {
  if (this.isEventStopped(goog.editor.Field.EventType.CHANGE)) {
    return;
  }
  var e = browserEvent.getBrowserEvent();
  try {
    if (e.originalTarget.prefix || e.originalTarget.nodeName == "scrollbar") {
      return;
    }
  } catch (ex1) {
    return;
  }
  if (e.prevValue == e.newValue) {
    return;
  }
  handler.call(this, e);
};
goog.editor.Field.prototype.handleMutationEventGecko_ = function(e) {
  if (this.isEventStopped(goog.editor.Field.EventType.CHANGE)) {
    return;
  }
  e = e.getBrowserEvent ? e.getBrowserEvent() : e;
  if (e.target.firebugIgnore) {
    return;
  }
  this.isModified_ = true;
  this.isEverModified_ = true;
  this.changeTimerGecko_.start();
};
goog.editor.Field.prototype.handleDrop_ = function(e) {
  if (goog.userAgent.IE) {
    this.execCommand(goog.editor.Command.CLEAR_LOREM, true);
  }
  if (goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
    this.dispatchFocusAndBeforeFocus_();
  }
  this.dispatchChange();
};
goog.editor.Field.prototype.getEditableIframe = function() {
  var dh;
  if (this.usesIframe() && (dh = this.getEditableDomHelper())) {
    var win = dh.getWindow();
    return win && win.frameElement;
  }
  return null;
};
goog.editor.Field.prototype.getEditableDomHelper = function() {
  return this.editableDomHelper;
};
goog.editor.Field.prototype.getRange = function() {
  var win = this.editableDomHelper && this.editableDomHelper.getWindow();
  return win && goog.dom.Range.createFromWindow(win);
};
goog.editor.Field.prototype.dispatchSelectionChangeEvent = function(opt_e, opt_target) {
  if (this.isEventStopped(goog.editor.Field.EventType.SELECTIONCHANGE)) {
    return;
  }
  var range = this.getRange();
  var rangeContainer = range && range.getContainerElement();
  this.isSelectionEditable_ = !!rangeContainer && goog.dom.contains(this.getElement(), rangeContainer);
  this.dispatchCommandValueChange();
  this.dispatchEvent({type:goog.editor.Field.EventType.SELECTIONCHANGE, originalType:opt_e && opt_e.type});
  this.invokeShortCircuitingOp_(goog.editor.Plugin.Op.SELECTION, opt_e, opt_target);
};
goog.editor.Field.prototype.handleSelectionChangeTimer_ = function() {
  var t = this.selectionChangeTarget_;
  this.selectionChangeTarget_ = null;
  this.dispatchSelectionChangeEvent(undefined, t);
};
goog.editor.Field.prototype.dispatchBeforeChange = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.BEFORECHANGE)) {
    return;
  }
  this.dispatchEvent(goog.editor.Field.EventType.BEFORECHANGE);
};
goog.editor.Field.prototype.dispatchBeforeTab_ = function(e) {
  return this.dispatchEvent({type:goog.editor.Field.EventType.BEFORETAB, shiftKey:e.shiftKey, altKey:e.altKey, ctrlKey:e.ctrlKey});
};
goog.editor.Field.prototype.stopChangeEvents = function(opt_stopChange, opt_stopDelayedChange) {
  if (opt_stopChange) {
    if (this.changeTimerGecko_) {
      this.changeTimerGecko_.fireIfActive();
    }
    this.stopEvent(goog.editor.Field.EventType.CHANGE);
  }
  if (opt_stopDelayedChange) {
    this.clearDelayedChange();
    this.stopEvent(goog.editor.Field.EventType.DELAYEDCHANGE);
  }
};
goog.editor.Field.prototype.startChangeEvents = function(opt_fireChange, opt_fireDelayedChange) {
  if (!opt_fireChange && this.changeTimerGecko_) {
    this.changeTimerGecko_.fireIfActive();
  }
  this.startEvent(goog.editor.Field.EventType.CHANGE);
  this.startEvent(goog.editor.Field.EventType.DELAYEDCHANGE);
  if (opt_fireChange) {
    this.handleChange();
  }
  if (opt_fireDelayedChange) {
    this.dispatchDelayedChange_();
  }
};
goog.editor.Field.prototype.stopEvent = function(eventType) {
  this.stoppedEvents_[eventType] = 1;
};
goog.editor.Field.prototype.startEvent = function(eventType) {
  this.stoppedEvents_[eventType] = 0;
};
goog.editor.Field.prototype.debounceEvent = function(eventType) {
  this.debouncedEvents_[eventType] = goog.now();
};
goog.editor.Field.prototype.isEventStopped = function(eventType) {
  return !!this.stoppedEvents_[eventType] || this.debouncedEvents_[eventType] && goog.now() - this.debouncedEvents_[eventType] <= goog.editor.Field.DEBOUNCE_TIME_MS_;
};
goog.editor.Field.prototype.manipulateDom = function(func, opt_preventDelayedChange, opt_handler) {
  this.stopChangeEvents(true, true);
  try {
    func.call(opt_handler);
  } finally {
    if (this.isLoaded()) {
      if (opt_preventDelayedChange) {
        this.startEvent(goog.editor.Field.EventType.CHANGE);
        this.handleChange();
        this.startEvent(goog.editor.Field.EventType.DELAYEDCHANGE);
      } else {
        this.dispatchChange();
      }
    }
  }
};
goog.editor.Field.prototype.dispatchCommandValueChange = function(opt_commands) {
  if (opt_commands) {
    this.dispatchEvent({type:goog.editor.Field.EventType.COMMAND_VALUE_CHANGE, commands:opt_commands});
  } else {
    this.dispatchEvent(goog.editor.Field.EventType.COMMAND_VALUE_CHANGE);
  }
};
goog.editor.Field.prototype.dispatchChange = function(opt_noDelay) {
  this.startChangeEvents(true, opt_noDelay);
};
goog.editor.Field.prototype.handleChange = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.CHANGE)) {
    return;
  }
  if (this.changeTimerGecko_) {
    this.changeTimerGecko_.stop();
  }
  this.isModified_ = true;
  this.isEverModified_ = true;
  if (this.isEventStopped(goog.editor.Field.EventType.DELAYEDCHANGE)) {
    return;
  }
  this.delayedChangeTimer_.start();
};
goog.editor.Field.prototype.dispatchDelayedChange_ = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.DELAYEDCHANGE)) {
    return;
  }
  this.delayedChangeTimer_.stop();
  this.isModified_ = false;
  this.dispatchEvent(goog.editor.Field.EventType.DELAYEDCHANGE);
};
goog.editor.Field.prototype.clearDelayedChange = function() {
  if (this.changeTimerGecko_) {
    this.changeTimerGecko_.fireIfActive();
  }
  this.delayedChangeTimer_.fireIfActive();
};
goog.editor.Field.prototype.dispatchFocusAndBeforeFocus_ = function() {
  this.dispatchBeforeFocus_();
  this.dispatchFocus_();
};
goog.editor.Field.prototype.dispatchBeforeFocus_ = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.BEFOREFOCUS)) {
    return;
  }
  this.execCommand(goog.editor.Command.CLEAR_LOREM, true);
  this.dispatchEvent(goog.editor.Field.EventType.BEFOREFOCUS);
};
goog.editor.Field.prototype.dispatchFocus_ = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.FOCUS)) {
    return;
  }
  goog.editor.Field.setActiveFieldId(this.id);
  this.isSelectionEditable_ = true;
  this.dispatchEvent(goog.editor.Field.EventType.FOCUS);
  if (goog.editor.BrowserFeature.PUTS_CURSOR_BEFORE_FIRST_BLOCK_ELEMENT_ON_FOCUS) {
    var field = this.getElement();
    var range = this.getRange();
    if (range) {
      var focusNode = range.getFocusNode();
      if (range.getFocusOffset() == 0 && (!focusNode || focusNode == field || focusNode.tagName == goog.dom.TagName.BODY)) {
        goog.editor.range.selectNodeStart(field);
      }
    }
  }
  if (!goog.editor.BrowserFeature.CLEARS_SELECTION_WHEN_FOCUS_LEAVES && this.usesIframe()) {
    var parent = this.getEditableDomHelper().getWindow().parent;
    parent.getSelection().removeAllRanges();
  }
};
goog.editor.Field.prototype.dispatchBlur = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.BLUR)) {
    return;
  }
  if (goog.editor.Field.getActiveFieldId() == this.id) {
    goog.editor.Field.setActiveFieldId(null);
  }
  this.isSelectionEditable_ = false;
  this.dispatchEvent(goog.editor.Field.EventType.BLUR);
};
goog.editor.Field.prototype.isSelectionEditable = function() {
  return this.isSelectionEditable_;
};
goog.editor.Field.cancelLinkClick_ = function(e) {
  if (goog.dom.getAncestorByTagNameAndClass(e.target, goog.dom.TagName.A)) {
    e.preventDefault();
  }
};
goog.editor.Field.prototype.handleMouseDown_ = function(e) {
  goog.editor.Field.setActiveFieldId(this.id);
  if (goog.userAgent.IE) {
    var targetElement = e.target;
    if (targetElement && targetElement.tagName == goog.dom.TagName.A && e.ctrlKey) {
      this.originalDomHelper.getWindow().open(targetElement.href);
    }
  }
  this.waitingForMouseUp_ = true;
};
goog.editor.Field.prototype.handleDragStart_ = function(e) {
  this.waitingForMouseUp_ = false;
};
goog.editor.Field.prototype.handleMouseUp_ = function(e) {
  if (this.useWindowMouseUp_ && !this.waitingForMouseUp_) {
    return;
  }
  this.waitingForMouseUp_ = false;
  this.dispatchEvent(goog.editor.Field.EventType.BEFORESELECTIONCHANGE);
  this.dispatchSelectionChangeEvent(e);
  if (goog.userAgent.IE) {
    this.selectionChangeTarget_ = e.target;
    this.selectionChangeTimer_.start();
  }
};
goog.editor.Field.prototype.getCleanContents = function() {
  if (this.queryCommandValue(goog.editor.Command.USING_LOREM)) {
    return goog.string.Unicode.NBSP;
  }
  if (!this.isLoaded()) {
    var elem = this.getOriginalElement();
    if (!elem) {
      goog.log.log(this.logger, goog.log.Level.SHOUT, "Couldn't get the field element to read the contents");
    }
    return elem.innerHTML;
  }
  var fieldCopy = this.getFieldCopy();
  this.invokeOp_(goog.editor.Plugin.Op.CLEAN_CONTENTS_DOM, fieldCopy);
  return this.reduceOp_(goog.editor.Plugin.Op.CLEAN_CONTENTS_HTML, fieldCopy.innerHTML);
};
goog.editor.Field.prototype.getFieldCopy = function() {
  var field = this.getElement();
  var fieldCopy = field.cloneNode(false);
  var html = field.innerHTML;
  if (goog.userAgent.IE && html.match(/^\s*<script/i)) {
    html = goog.string.Unicode.NBSP + html;
  }
  fieldCopy.innerHTML = html;
  return fieldCopy;
};
goog.editor.Field.prototype.setHtml = function(addParas, html, opt_dontFireDelayedChange, opt_applyLorem) {
  var safeHtml = html ? goog.html.legacyconversions.safeHtmlFromString(html) : null;
  this.setSafeHtml(addParas, safeHtml, opt_dontFireDelayedChange, opt_applyLorem);
};
goog.editor.Field.prototype.setSafeHtml = function(addParas, html, opt_dontFireDelayedChange, opt_applyLorem) {
  if (this.isLoading()) {
    goog.log.error(this.logger, "Can't set html while loading Trogedit");
    return;
  }
  if (opt_applyLorem) {
    this.execCommand(goog.editor.Command.CLEAR_LOREM);
  }
  if (html && addParas) {
    html = goog.html.SafeHtml.create("p", {}, html);
  }
  if (opt_dontFireDelayedChange) {
    this.stopChangeEvents(false, true);
  }
  this.setInnerHtml_(html);
  if (opt_applyLorem) {
    this.execCommand(goog.editor.Command.UPDATE_LOREM);
  }
  if (this.isLoaded()) {
    if (opt_dontFireDelayedChange) {
      if (goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
        this.changeTimerGecko_.fireIfActive();
      }
      this.startChangeEvents();
    } else {
      this.dispatchChange();
    }
  }
};
goog.editor.Field.prototype.setInnerHtml_ = function(html) {
  var field = this.getElement();
  if (field) {
    if (this.usesIframe() && goog.editor.BrowserFeature.MOVES_STYLE_TO_HEAD) {
      var heads = goog.dom.getElementsByTagName(goog.dom.TagName.HEAD, goog.asserts.assert(field.ownerDocument));
      for (var i = heads.length - 1; i >= 1; --i) {
        heads[i].parentNode.removeChild(heads[i]);
      }
    }
  } else {
    field = this.getOriginalElement();
  }
  if (field) {
    this.injectContents(html && goog.html.SafeHtml.unwrap(html), field);
  }
};
goog.editor.Field.prototype.turnOnDesignModeGecko = function() {
  var doc = this.getEditableDomHelper().getDocument();
  doc.designMode = "on";
  if (goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS) {
    doc.execCommand("styleWithCSS", false, false);
  }
};
goog.editor.Field.prototype.installStyles = function() {
  if (this.cssStyles && this.shouldLoadAsynchronously()) {
    goog.style.installSafeStyleSheet(goog.html.legacyconversions.safeStyleSheetFromString(this.cssStyles), this.getElement());
  }
};
goog.editor.Field.prototype.dispatchLoadEvent_ = function() {
  this.getElement();
  this.installStyles();
  this.startChangeEvents();
  goog.log.info(this.logger, "Dispatching load " + this.id);
  this.dispatchEvent(goog.editor.Field.EventType.LOAD);
};
goog.editor.Field.prototype.isUneditable = function() {
  return this.loadState_ == goog.editor.Field.LoadState_.UNEDITABLE;
};
goog.editor.Field.prototype.isLoaded = function() {
  return this.loadState_ == goog.editor.Field.LoadState_.EDITABLE;
};
goog.editor.Field.prototype.isLoading = function() {
  return this.loadState_ == goog.editor.Field.LoadState_.LOADING;
};
goog.editor.Field.prototype.focus = function() {
  if (!goog.editor.BrowserFeature.HAS_CONTENT_EDITABLE && this.usesIframe()) {
    this.getEditableDomHelper().getWindow().focus();
  } else {
    if (goog.userAgent.OPERA) {
      var scrollX = this.appWindow_.pageXOffset;
      var scrollY = this.appWindow_.pageYOffset;
    }
    this.getElement().focus();
    if (goog.userAgent.OPERA) {
      this.appWindow_.scrollTo(scrollX, scrollY);
    }
  }
};
goog.editor.Field.prototype.focusAndPlaceCursorAtStart = function() {
  if (goog.editor.BrowserFeature.HAS_IE_RANGES || !goog.userAgent.GECKO) {
    this.placeCursorAtStart();
  }
  this.focus();
};
goog.editor.Field.prototype.placeCursorAtStart = function() {
  this.placeCursorAtStartOrEnd_(true);
};
goog.editor.Field.prototype.placeCursorAtEnd = function() {
  this.placeCursorAtStartOrEnd_(false);
};
goog.editor.Field.prototype.placeCursorAtStartOrEnd_ = function(isStart) {
  var field = this.getElement();
  if (field) {
    var cursorPosition = isStart ? goog.editor.node.getLeftMostLeaf(field) : goog.editor.node.getRightMostLeaf(field);
    if (field == cursorPosition) {
      goog.dom.Range.createCaret(field, 0).select();
    } else {
      goog.editor.range.placeCursorNextTo(cursorPosition, isStart);
    }
    this.dispatchSelectionChangeEvent();
  }
};
goog.editor.Field.prototype.restoreSavedRange = function(opt_range) {
  if (opt_range) {
    opt_range.restore();
  }
  this.focus();
};
goog.editor.Field.prototype.makeEditable = function(opt_iframeSrc) {
  this.loadState_ = goog.editor.Field.LoadState_.LOADING;
  var field = this.getOriginalElement();
  this.nodeName = field.nodeName;
  this.savedClassName_ = field.className;
  this.setInitialStyle(field.style.cssText);
  goog.dom.classlist.add(field, "editable");
  this.makeEditableInternal(opt_iframeSrc);
};
goog.editor.Field.prototype.makeEditableInternal = function(opt_iframeSrc) {
  this.makeIframeField_(opt_iframeSrc);
};
goog.editor.Field.prototype.handleFieldLoad = function() {
  if (goog.userAgent.IE) {
    goog.dom.Range.clearSelection(this.editableDomHelper.getWindow());
  }
  if (goog.editor.Field.getActiveFieldId() != this.id) {
    this.execCommand(goog.editor.Command.UPDATE_LOREM);
  }
  this.setupChangeListeners_();
  this.dispatchLoadEvent_();
  for (var classId in this.plugins_) {
    this.plugins_[classId].enable(this);
  }
};
goog.editor.Field.prototype.makeUneditable = function(opt_skipRestore) {
  if (this.isUneditable()) {
    throw Error("makeUneditable: Field is already uneditable");
  }
  this.clearDelayedChange();
  this.selectionChangeTimer_.fireIfActive();
  this.execCommand(goog.editor.Command.CLEAR_LOREM);
  var html = null;
  if (!opt_skipRestore && this.getElement()) {
    html = this.getCleanContents();
  }
  this.clearFieldLoadListener_();
  var field = this.getOriginalElement();
  if (goog.editor.Field.getActiveFieldId() == field.id) {
    goog.editor.Field.setActiveFieldId(null);
  }
  this.clearListeners();
  if (goog.isString(html)) {
    goog.editor.node.replaceInnerHtml(field, html);
    this.resetOriginalElemProperties();
  }
  this.restoreDom();
  this.tearDownFieldObject_();
  if (goog.userAgent.WEBKIT) {
    field.blur();
  }
  this.execCommand(goog.editor.Command.UPDATE_LOREM);
  this.dispatchEvent(goog.editor.Field.EventType.UNLOAD);
};
goog.editor.Field.prototype.restoreDom = function() {
  var field = this.getOriginalElement();
  if (field) {
    var iframe = this.getEditableIframe();
    if (iframe) {
      goog.dom.replaceNode(field, iframe);
    }
  }
};
goog.editor.Field.prototype.shouldLoadAsynchronously = function() {
  if (!goog.isDef(this.isHttps_)) {
    this.isHttps_ = false;
    if (goog.userAgent.IE && this.usesIframe()) {
      var win = this.originalDomHelper.getWindow();
      while (win != win.parent) {
        try {
          win = win.parent;
        } catch (e) {
          break;
        }
      }
      var loc = win.location;
      this.isHttps_ = loc.protocol == "https:" && loc.search.indexOf("nocheckhttps") == -1;
    }
  }
  return this.isHttps_;
};
goog.editor.Field.prototype.makeIframeField_ = function(opt_iframeSrc) {
  var field = this.getOriginalElement();
  if (field) {
    var html = field.innerHTML;
    var styles = {};
    html = this.reduceOp_(goog.editor.Plugin.Op.PREPARE_CONTENTS_HTML, html, styles);
    var iframe = this.originalDomHelper.createDom(goog.dom.TagName.IFRAME, this.getIframeAttributes());
    if (this.shouldLoadAsynchronously()) {
      var onLoad = goog.bind(this.iframeFieldLoadHandler, this, iframe, html, styles);
      this.fieldLoadListenerKey_ = goog.events.listen(iframe, goog.events.EventType.LOAD, onLoad, true);
      if (opt_iframeSrc) {
        iframe.src = opt_iframeSrc;
      }
    }
    this.attachIframe(iframe);
    if (!this.shouldLoadAsynchronously()) {
      this.iframeFieldLoadHandler(iframe, html, styles);
    }
  }
};
goog.editor.Field.prototype.attachIframe = function(iframe) {
  var field = this.getOriginalElement();
  iframe.className = field.className;
  iframe.id = field.id;
  goog.dom.replaceNode(iframe, field);
};
goog.editor.Field.prototype.getFieldFormatInfo = function(extraStyles) {
  var originalElement = this.getOriginalElement();
  var isStandardsMode = goog.editor.node.isStandardsMode(originalElement);
  return new goog.editor.icontent.FieldFormatInfo(this.id, isStandardsMode, false, false, extraStyles);
};
goog.editor.Field.prototype.writeIframeContent = function(iframe, innerHtml, extraStyles) {
  var formatInfo = this.getFieldFormatInfo(extraStyles);
  if (this.shouldLoadAsynchronously()) {
    var doc = goog.dom.getFrameContentDocument(iframe);
    goog.editor.icontent.writeHttpsInitialIframe(formatInfo, doc, innerHtml);
  } else {
    var styleInfo = new goog.editor.icontent.FieldStyleInfo(this.getElement(), this.cssStyles);
    goog.editor.icontent.writeNormalInitialIframe(formatInfo, innerHtml, styleInfo, iframe);
  }
};
goog.editor.Field.prototype.iframeFieldLoadHandler = function(iframe, innerHtml, styles) {
  this.clearFieldLoadListener_();
  iframe.allowTransparency = "true";
  this.writeIframeContent(iframe, innerHtml, styles);
  var doc = goog.dom.getFrameContentDocument(iframe);
  var body = doc.body;
  this.setupFieldObject(body);
  if (!goog.editor.BrowserFeature.HAS_CONTENT_EDITABLE && this.usesIframe()) {
    this.turnOnDesignModeGecko();
  }
  this.handleFieldLoad();
};
goog.editor.Field.prototype.clearFieldLoadListener_ = function() {
  if (this.fieldLoadListenerKey_) {
    goog.events.unlistenByKey(this.fieldLoadListenerKey_);
    this.fieldLoadListenerKey_ = null;
  }
};
goog.editor.Field.prototype.getIframeAttributes = function() {
  var iframeStyle = "padding:0;" + this.getOriginalElement().style.cssText;
  if (!goog.string.endsWith(iframeStyle, ";")) {
    iframeStyle += ";";
  }
  iframeStyle += "background-color:white;";
  if (goog.userAgent.IE) {
    iframeStyle += "overflow:visible;";
  }
  return {"frameBorder":0, "style":iframeStyle};
};
goog.provide("goog.cssom");
goog.provide("goog.cssom.CssRuleType");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.TagName");
goog.cssom.CssRuleType = {STYLE:1, IMPORT:3, MEDIA:4, FONT_FACE:5, PAGE:6, NAMESPACE:7};
goog.cssom.getAllCssText = function(opt_styleSheet) {
  var styleSheet = opt_styleSheet || document.styleSheets;
  return goog.cssom.getAllCss_(styleSheet, true);
};
goog.cssom.getAllCssStyleRules = function(opt_styleSheet) {
  var styleSheet = opt_styleSheet || document.styleSheets;
  return goog.cssom.getAllCss_(styleSheet, false);
};
goog.cssom.getCssRulesFromStyleSheet = function(styleSheet) {
  var cssRuleList = null;
  try {
    cssRuleList = styleSheet.cssRules || styleSheet.rules;
  } catch (e) {
    if (e.code == 15) {
      e.styleSheet = styleSheet;
      throw e;
    }
  }
  return cssRuleList;
};
goog.cssom.getAllCssStyleSheets = function(opt_styleSheet, opt_includeDisabled) {
  var styleSheetsOutput = [];
  var styleSheet = opt_styleSheet || document.styleSheets;
  var includeDisabled = goog.isDef(opt_includeDisabled) ? opt_includeDisabled : false;
  if (styleSheet.imports && styleSheet.imports.length) {
    for (var i = 0, n = styleSheet.imports.length; i < n; i++) {
      goog.array.extend(styleSheetsOutput, goog.cssom.getAllCssStyleSheets(styleSheet.imports[i]));
    }
  } else {
    if (styleSheet.length) {
      for (var i = 0, n = styleSheet.length; i < n; i++) {
        goog.array.extend(styleSheetsOutput, goog.cssom.getAllCssStyleSheets(styleSheet[i]));
      }
    } else {
      var cssRuleList = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
      if (cssRuleList && cssRuleList.length) {
        for (var i = 0, n = cssRuleList.length, cssRule; i < n; i++) {
          cssRule = cssRuleList[i];
          if (cssRule.styleSheet) {
            goog.array.extend(styleSheetsOutput, goog.cssom.getAllCssStyleSheets(cssRule.styleSheet));
          }
        }
      }
    }
  }
  if ((styleSheet.type || styleSheet.rules || styleSheet.cssRules) && (!styleSheet.disabled || includeDisabled)) {
    styleSheetsOutput.push(styleSheet);
  }
  return styleSheetsOutput;
};
goog.cssom.getCssTextFromCssRule = function(cssRule) {
  var cssText = "";
  if (cssRule.cssText) {
    cssText = cssRule.cssText;
  } else {
    if (cssRule.style && cssRule.style.cssText && cssRule.selectorText) {
      var styleCssText = cssRule.style.cssText.replace(/\s*-closure-parent-stylesheet:\s*\[object\];?\s*/gi, "").replace(/\s*-closure-rule-index:\s*[\d]+;?\s*/gi, "");
      var thisCssText = cssRule.selectorText + " { " + styleCssText + " }";
      cssText = thisCssText;
    }
  }
  return cssText;
};
goog.cssom.getCssRuleIndexInParentStyleSheet = function(cssRule, opt_parentStyleSheet) {
  if (cssRule.style && cssRule.style["-closure-rule-index"]) {
    return cssRule.style["-closure-rule-index"];
  }
  var parentStyleSheet = opt_parentStyleSheet || goog.cssom.getParentStyleSheet(cssRule);
  if (!parentStyleSheet) {
    throw Error("Cannot find a parentStyleSheet.");
  }
  var cssRuleList = goog.cssom.getCssRulesFromStyleSheet(parentStyleSheet);
  if (cssRuleList && cssRuleList.length) {
    for (var i = 0, n = cssRuleList.length, thisCssRule; i < n; i++) {
      thisCssRule = cssRuleList[i];
      if (thisCssRule == cssRule) {
        return i;
      }
    }
  }
  return -1;
};
goog.cssom.getParentStyleSheet = function(cssRule) {
  return cssRule.parentStyleSheet || cssRule.style && cssRule.style["-closure-parent-stylesheet"];
};
goog.cssom.replaceCssRule = function(cssRule, cssText, opt_parentStyleSheet, opt_index) {
  var parentStyleSheet = opt_parentStyleSheet || goog.cssom.getParentStyleSheet(cssRule);
  if (parentStyleSheet) {
    var index = Number(opt_index) >= 0 ? Number(opt_index) : goog.cssom.getCssRuleIndexInParentStyleSheet(cssRule, parentStyleSheet);
    if (index >= 0) {
      goog.cssom.removeCssRule(parentStyleSheet, index);
      goog.cssom.addCssRule(parentStyleSheet, cssText, index);
    } else {
      throw Error("Cannot proceed without the index of the cssRule.");
    }
  } else {
    throw Error("Cannot proceed without the parentStyleSheet.");
  }
};
goog.cssom.addCssRule = function(cssStyleSheet, cssText, opt_index) {
  var index = opt_index;
  if (index == undefined || index < 0) {
    var rules = goog.cssom.getCssRulesFromStyleSheet(cssStyleSheet);
    index = rules.length;
  }
  if (cssStyleSheet.insertRule) {
    cssStyleSheet.insertRule(cssText, index);
  } else {
    var matches = /^([^\{]+)\{([^\{]+)\}/.exec(cssText);
    if (matches.length == 3) {
      var selector = matches[1];
      var style = matches[2];
      cssStyleSheet.addRule(selector, style, index);
    } else {
      throw Error("Your CSSRule appears to be ill-formatted.");
    }
  }
};
goog.cssom.removeCssRule = function(cssStyleSheet, index) {
  if (cssStyleSheet.deleteRule) {
    cssStyleSheet.deleteRule(index);
  } else {
    cssStyleSheet.removeRule(index);
  }
};
goog.cssom.addCssText = function(cssText, opt_domHelper) {
  var domHelper = opt_domHelper || goog.dom.getDomHelper();
  var document = domHelper.getDocument();
  var cssNode = domHelper.createElement(goog.dom.TagName.STYLE);
  cssNode.type = "text/css";
  var head = domHelper.getElementsByTagName(goog.dom.TagName.HEAD)[0];
  head.appendChild(cssNode);
  if (cssNode.styleSheet) {
    cssNode.styleSheet.cssText = cssText;
  } else {
    var cssTextNode = document.createTextNode(cssText);
    cssNode.appendChild(cssTextNode);
  }
  return cssNode;
};
goog.cssom.getFileNameFromStyleSheet = function(styleSheet) {
  var href = styleSheet.href;
  if (!href) {
    return null;
  }
  var matches = /([^\/\?]+)[^\/]*$/.exec(href);
  var filename = matches[1];
  return filename;
};
goog.cssom.getAllCss_ = function(styleSheet, isTextOutput) {
  var cssOut = [];
  var styleSheets = goog.cssom.getAllCssStyleSheets(styleSheet);
  for (var i = 0; styleSheet = styleSheets[i]; i++) {
    var cssRuleList = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
    if (cssRuleList && cssRuleList.length) {
      var ruleIndex = 0;
      for (var j = 0, n = cssRuleList.length, cssRule; j < n; j++) {
        cssRule = cssRuleList[j];
        if (isTextOutput && !cssRule.href) {
          var res = goog.cssom.getCssTextFromCssRule(cssRule);
          cssOut.push(res);
        } else {
          if (!cssRule.href) {
            if (cssRule.style) {
              if (!cssRule.parentStyleSheet) {
                cssRule.style["-closure-parent-stylesheet"] = styleSheet;
              }
              cssRule.style["-closure-rule-index"] = isTextOutput ? undefined : ruleIndex;
            }
            cssOut.push(cssRule);
          }
        }
        if (!isTextOutput) {
          ruleIndex++;
        }
      }
    }
  }
  return isTextOutput ? cssOut.join(" ") : cssOut;
};
goog.provide("goog.cssom.iframe.style");
goog.require("goog.asserts");
goog.require("goog.cssom");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagName");
goog.require("goog.dom.classlist");
goog.require("goog.string");
goog.require("goog.style");
goog.require("goog.userAgent");
goog.cssom.iframe.style.selectorPartAnchorRegex_ = /a(:(link|visited|active|hover))?/;
goog.cssom.iframe.style.SELECTOR_DELIMITER_ = ",";
goog.cssom.iframe.style.SELECTOR_PART_DELIMITER_ = " ";
goog.cssom.iframe.style.DECLARATION_START_DELIMITER_ = "{";
goog.cssom.iframe.style.DECLARATION_END_DELIMITER_ = "}\n";
goog.cssom.iframe.style.CssRuleSet_ = function() {
  this.declarationText = "";
  this.selectors = [];
};
goog.cssom.iframe.style.CssRuleSet_.prototype.initializeFromCssRule = function(cssRule) {
  var ruleStyle = cssRule.style;
  if (!ruleStyle) {
    return false;
  }
  var selector;
  var declarations = "";
  if (ruleStyle && (selector = cssRule.selectorText) && (declarations = ruleStyle.cssText)) {
    if (goog.userAgent.IE) {
      declarations += "/* */";
    }
  } else {
    if (cssRule.cssText) {
      var cssSelectorMatch = /([^\{]+)\{/;
      var endTagMatch = /\}[^\}]*$/g;
      selector = cssSelectorMatch.exec(cssRule.cssText)[1];
      declarations = cssRule.cssText.replace(cssSelectorMatch, "").replace(endTagMatch, "");
    }
  }
  if (selector) {
    this.setSelectorsFromString(selector);
    this.declarationText = declarations;
    return true;
  }
  return false;
};
goog.cssom.iframe.style.CssRuleSet_.prototype.setSelectorsFromString = function(selectorsString) {
  this.selectors = [];
  var selectors = selectorsString.split(/,\s*/gm);
  for (var i = 0; i < selectors.length; i++) {
    var selector = selectors[i];
    if (selector.length > 0) {
      this.selectors.push(new goog.cssom.iframe.style.CssSelector_(selector));
    }
  }
};
goog.cssom.iframe.style.CssRuleSet_.prototype.clone = function() {
  var newRuleSet = new goog.cssom.iframe.style.CssRuleSet_;
  newRuleSet.selectors = this.selectors.concat();
  newRuleSet.declarationText = this.declarationText;
  return newRuleSet;
};
goog.cssom.iframe.style.CssRuleSet_.prototype.setDeclarationTextFromObject = function(sourceObject, opt_important) {
  var stringParts = [];
  for (var prop in sourceObject) {
    var value = sourceObject[prop];
    if (value) {
      stringParts.push(prop, ":", value, opt_important ? " !important" : "", ";");
    }
  }
  this.declarationText = stringParts.join("");
};
goog.cssom.iframe.style.CssRuleSet_.prototype.writeToArray = function(array) {
  var selectorCount = this.selectors.length;
  var matchesAnchorTag = false;
  for (var i = 0; i < selectorCount; i++) {
    var selectorParts = this.selectors[i].parts;
    var partCount = selectorParts.length;
    for (var j = 0; j < partCount; j++) {
      array.push(selectorParts[j].inputString_, goog.cssom.iframe.style.SELECTOR_PART_DELIMITER_);
    }
    if (i < selectorCount - 1) {
      array.push(goog.cssom.iframe.style.SELECTOR_DELIMITER_);
    }
    if (goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher("1.9a")) {
      matchesAnchorTag = matchesAnchorTag || goog.cssom.iframe.style.selectorPartAnchorRegex_.test(selectorParts[partCount - 1].inputString_);
    }
  }
  var declarationText = this.declarationText;
  if (matchesAnchorTag) {
    declarationText = goog.cssom.iframe.style.makeColorRuleImportant_(declarationText);
  }
  array.push(goog.cssom.iframe.style.DECLARATION_START_DELIMITER_, declarationText, goog.cssom.iframe.style.DECLARATION_END_DELIMITER_);
};
goog.cssom.iframe.style.colorImportantReplaceRegex_ = /(^|;|{)\s*color:([^;]+);/g;
goog.cssom.iframe.style.makeColorRuleImportant_ = function(cssText) {
  return cssText.replace(goog.cssom.iframe.style.colorImportantReplaceRegex_, "$1 color: $2 ! important; ");
};
goog.cssom.iframe.style.CssSelector_ = function(opt_selectorString) {
  this.ancestryMatchCache_ = {};
  if (opt_selectorString) {
    this.setPartsFromString_(opt_selectorString);
  }
};
goog.cssom.iframe.style.CssSelector_.prototype.setPartsFromString_ = function(selectorString) {
  var parts = [];
  var selectorPartStrings = selectorString.split(/\s+/gm);
  for (var i = 0; i < selectorPartStrings.length; i++) {
    if (!selectorPartStrings[i]) {
      continue;
    }
    var part = new goog.cssom.iframe.style.CssSelectorPart_(selectorPartStrings[i]);
    parts.push(part);
  }
  this.parts = parts;
};
goog.cssom.iframe.style.CssSelector_.prototype.matchElementAncestry = function(elementAncestry) {
  var ancestryUid = elementAncestry.uid;
  if (this.ancestryMatchCache_[ancestryUid]) {
    return this.ancestryMatchCache_[ancestryUid];
  }
  var elementIndex = 0;
  var match = null;
  var selectorPart = null;
  var lastSelectorPart = null;
  var ancestorNodes = elementAncestry.nodes;
  var ancestorNodeCount = ancestorNodes.length;
  for (var i = 0; i <= this.parts.length; i++) {
    selectorPart = this.parts[i];
    while (elementIndex < ancestorNodeCount) {
      var currentElementInfo = ancestorNodes[elementIndex];
      if (selectorPart && selectorPart.testElement(currentElementInfo)) {
        match = {elementIndex:elementIndex, selectorPartIndex:i};
        elementIndex++;
        break;
      } else {
        if (lastSelectorPart && lastSelectorPart.testElement(currentElementInfo)) {
          match = {elementIndex:elementIndex, selectorPartIndex:i - 1};
        }
      }
      elementIndex++;
    }
    lastSelectorPart = selectorPart;
  }
  this.ancestryMatchCache_[ancestryUid] = match;
  return match;
};
goog.cssom.iframe.style.CssSelectorPart_ = function(selectorPartString) {
  var cacheEntry = goog.cssom.iframe.style.CssSelectorPart_.instances_[selectorPartString];
  if (cacheEntry) {
    return cacheEntry;
  }
  var identifiers;
  if (selectorPartString.match(/[#\.]/)) {
    identifiers = selectorPartString.split(/(?=[#\.])/);
  } else {
    identifiers = [selectorPartString];
  }
  var properties = {};
  for (var i = 0; i < identifiers.length; i++) {
    var identifier = identifiers[i];
    if (identifier.charAt(0) == ".") {
      properties.className = identifier.substring(1, identifier.length);
    } else {
      if (identifier.charAt(0) == "#") {
        properties.id = identifier.substring(1, identifier.length);
      } else {
        properties.tagName = identifier.toUpperCase();
      }
    }
  }
  this.inputString_ = selectorPartString;
  this.matchProperties_ = properties;
  this.testedElements_ = {};
  goog.cssom.iframe.style.CssSelectorPart_.instances_[selectorPartString] = this;
};
goog.cssom.iframe.style.CssSelectorPart_.instances_ = {};
goog.cssom.iframe.style.CssSelectorPart_.prototype.testElement = function(elementInfo) {
  var elementUid = elementInfo.uid;
  var cachedMatch = this.testedElements_[elementUid];
  if (typeof cachedMatch != "undefined") {
    return cachedMatch;
  }
  var matchProperties = this.matchProperties_;
  var testTag = matchProperties.tagName;
  var testClass = matchProperties.className;
  var testId = matchProperties.id;
  var matched = true;
  if (testTag && testTag != "*" && testTag != elementInfo.nodeName) {
    matched = false;
  } else {
    if (testId && testId != elementInfo.id) {
      matched = false;
    } else {
      if (testClass && !elementInfo.classNames[testClass]) {
        matched = false;
      }
    }
  }
  this.testedElements_[elementUid] = matched;
  return matched;
};
goog.cssom.iframe.style.NodeAncestry_ = function(el) {
  var node = el;
  var nodeUid = goog.getUid(node);
  var ancestry = goog.cssom.iframe.style.NodeAncestry_.instances_[nodeUid];
  if (ancestry) {
    return ancestry;
  }
  var nodes = [];
  do {
    var nodeInfo = {id:node.id, nodeName:node.nodeName};
    nodeInfo.uid = goog.getUid(nodeInfo);
    var className = node.className;
    var classNamesLookup = {};
    if (className) {
      var classNames = goog.dom.classlist.get(goog.asserts.assertElement(node));
      for (var i = 0; i < classNames.length; i++) {
        classNamesLookup[classNames[i]] = 1;
      }
    }
    nodeInfo.classNames = classNamesLookup;
    nodes.unshift(nodeInfo);
  } while (node = node.parentNode);
  this.nodes = nodes;
  this.uid = goog.getUid(this);
  goog.cssom.iframe.style.NodeAncestry_.instances_[nodeUid] = this;
};
goog.cssom.iframe.style.NodeAncestry_.instances_ = {};
goog.cssom.iframe.style.resetDomCache = function() {
  goog.cssom.iframe.style.NodeAncestry_.instances_ = {};
};
goog.cssom.iframe.style.getRuleSetsFromDocument_ = function(doc) {
  var ruleSets = [];
  var styleSheets = goog.cssom.getAllCssStyleSheets(doc.styleSheets);
  for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++) {
    var domRuleSets = goog.cssom.getCssRulesFromStyleSheet(styleSheet);
    if (domRuleSets && domRuleSets.length) {
      for (var j = 0, n = domRuleSets.length; j < n; j++) {
        var ruleSet = new goog.cssom.iframe.style.CssRuleSet_;
        if (ruleSet.initializeFromCssRule(domRuleSets[j])) {
          ruleSets.push(ruleSet);
        }
      }
    }
  }
  return ruleSets;
};
goog.cssom.iframe.style.ruleSetCache_ = {};
goog.cssom.iframe.style.ruleSetCache_.ruleSetCache_ = {};
goog.cssom.iframe.style.ruleSetCache_.loadRuleSetsForDocument = function(doc) {
  var docUid = goog.getUid(doc);
  goog.cssom.iframe.style.ruleSetCache_.ruleSetCache_[docUid] = goog.cssom.iframe.style.getRuleSetsFromDocument_(doc);
};
goog.cssom.iframe.style.ruleSetCache_.getRuleSetsForDocument = function(doc) {
  var docUid = goog.getUid(doc);
  var cache = goog.cssom.iframe.style.ruleSetCache_.ruleSetCache_;
  if (!cache[docUid]) {
    goog.cssom.iframe.style.ruleSetCache_.loadRuleSetsForDocument(doc);
  }
  var ruleSets = cache[docUid];
  var ruleSetsCopy = [];
  for (var i = 0; i < ruleSets.length; i++) {
    ruleSetsCopy.push(ruleSets[i].clone());
  }
  return ruleSetsCopy;
};
goog.cssom.iframe.style.inheritedProperties_ = ["color", "visibility", "quotes", "list-style-type", "list-style-image", "list-style-position", "list-style", "page-break-inside", "orphans", "widows", "font-family", "font-style", "font-variant", "font-weight", "text-indent", "text-align", "text-transform", "white-space", "caption-side", "border-collapse", "border-spacing", "empty-cells", "cursor"];
goog.cssom.iframe.style.textProperties_ = ["font-family", "font-size", "font-weight", "font-variant", "font-style", "color", "text-align", "text-decoration", "text-indent", "text-transform", "letter-spacing", "white-space", "word-spacing"];
goog.cssom.iframe.style.getElementContext = function(element, opt_forceRuleSetCacheUpdate, opt_copyBackgroundContext) {
  var sourceDocument = element.ownerDocument;
  if (opt_forceRuleSetCacheUpdate) {
    goog.cssom.iframe.style.ruleSetCache_.loadRuleSetsForDocument(sourceDocument);
  }
  var ruleSets = goog.cssom.iframe.style.ruleSetCache_.getRuleSetsForDocument(sourceDocument);
  var elementAncestry = new goog.cssom.iframe.style.NodeAncestry_(element);
  var bodySelectorPart = new goog.cssom.iframe.style.CssSelectorPart_("body");
  for (var i = 0; i < ruleSets.length; i++) {
    var ruleSet = ruleSets[i];
    var selectors = ruleSet.selectors;
    var ruleCount = selectors.length;
    for (var j = 0; j < ruleCount; j++) {
      var selector = selectors[j];
      var match = selector.matchElementAncestry(elementAncestry);
      if (match) {
        var ruleIndex = match.selectorPartIndex;
        var selectorParts = selector.parts;
        var lastSelectorPartIndex = selectorParts.length - 1;
        var selectorCopy;
        if (match.elementIndex == elementAncestry.nodes.length - 1 || ruleIndex < lastSelectorPartIndex) {
          var selectorPartsCopy = selectorParts.concat();
          selectorPartsCopy.splice(0, ruleIndex + 1, bodySelectorPart);
          selectorCopy = new goog.cssom.iframe.style.CssSelector_;
          selectorCopy.parts = selectorPartsCopy;
          selectors.push(selectorCopy);
        } else {
          if (ruleIndex > 0 && ruleIndex == lastSelectorPartIndex) {
            selectorCopy = new goog.cssom.iframe.style.CssSelector_;
            selectorCopy.parts = [bodySelectorPart, selectorParts[lastSelectorPartIndex]];
            selectors.push(selectorCopy);
          }
        }
      }
    }
  }
  var defaultPropertiesRuleSet = new goog.cssom.iframe.style.CssRuleSet_;
  var computedStyle = goog.cssom.iframe.style.getComputedStyleObject_(element);
  var htmlSelector = new goog.cssom.iframe.style.CssSelector_;
  htmlSelector.parts = [new goog.cssom.iframe.style.CssSelectorPart_("html")];
  defaultPropertiesRuleSet.selectors = [htmlSelector];
  var defaultProperties = {};
  for (var i = 0, prop; prop = goog.cssom.iframe.style.inheritedProperties_[i]; i++) {
    defaultProperties[prop] = computedStyle[goog.string.toCamelCase(prop)];
  }
  defaultPropertiesRuleSet.setDeclarationTextFromObject(defaultProperties);
  ruleSets.push(defaultPropertiesRuleSet);
  var bodyRuleSet = new goog.cssom.iframe.style.CssRuleSet_;
  var bodySelector = new goog.cssom.iframe.style.CssSelector_;
  bodySelector.parts = [new goog.cssom.iframe.style.CssSelectorPart_("body")];
  var bodyProperties = {position:"relative", top:"0", left:"0", right:"auto", display:"block", visibility:"visible"};
  for (i = 0; prop = goog.cssom.iframe.style.textProperties_[i]; i++) {
    bodyProperties[prop] = computedStyle[goog.string.toCamelCase(prop)];
  }
  if (opt_copyBackgroundContext && goog.cssom.iframe.style.isTransparentValue_(computedStyle["backgroundColor"])) {
    var bgProperties = goog.cssom.iframe.style.getBackgroundContext(element);
    bodyProperties["background-color"] = bgProperties["backgroundColor"];
    var elementBgImage = computedStyle["backgroundImage"];
    if (!elementBgImage || elementBgImage == "none") {
      bodyProperties["background-image"] = bgProperties["backgroundImage"];
      bodyProperties["background-repeat"] = bgProperties["backgroundRepeat"];
      bodyProperties["background-position"] = bgProperties["backgroundPosition"];
    }
  }
  bodyRuleSet.setDeclarationTextFromObject(bodyProperties, true);
  bodyRuleSet.selectors = [bodySelector];
  ruleSets.push(bodyRuleSet);
  var ruleSetStrings = [];
  ruleCount = ruleSets.length;
  for (i = 0; i < ruleCount; i++) {
    ruleSets[i].writeToArray(ruleSetStrings);
  }
  return ruleSetStrings.join("");
};
goog.cssom.iframe.style.isTransparentValue_ = function(colorValue) {
  return colorValue == "transparent" || colorValue == "rgba(0, 0, 0, 0)";
};
goog.cssom.iframe.style.getComputedStyleObject_ = function(element) {
  return element.currentStyle || goog.dom.getOwnerDocument(element).defaultView.getComputedStyle(element, "") || {};
};
goog.cssom.iframe.style.valueWithUnitsRegEx_ = /^(-?)([0-9]+)([a-z]*|%)/;
goog.cssom.iframe.style.getBackgroundXYValues_ = function(styleObject) {
  if (styleObject["backgroundPositionY"]) {
    return [styleObject["backgroundPositionX"], styleObject["backgroundPositionY"]];
  } else {
    return (styleObject["backgroundPosition"] || "0 0").split(" ");
  }
};
goog.cssom.iframe.style.getBackgroundContext = function(element) {
  var propertyValues = {"backgroundImage":"none"};
  var ancestor = element;
  var currentIframeWindow;
  while ((ancestor = ancestor.parentNode) && ancestor.nodeType == goog.dom.NodeType.ELEMENT) {
    var computedStyle = goog.cssom.iframe.style.getComputedStyleObject_(ancestor);
    var backgroundColorValue = computedStyle["backgroundColor"];
    if (!goog.cssom.iframe.style.isTransparentValue_(backgroundColorValue)) {
      propertyValues["backgroundColor"] = backgroundColorValue;
    }
    if (computedStyle["backgroundImage"] && computedStyle["backgroundImage"] != "none") {
      propertyValues["backgroundImage"] = computedStyle["backgroundImage"];
      propertyValues["backgroundRepeat"] = computedStyle["backgroundRepeat"];
      var relativePosition;
      if (currentIframeWindow) {
        relativePosition = goog.style.getFramedPageOffset(element, currentIframeWindow);
        var frameElement = currentIframeWindow.frameElement;
        var iframeRelativePosition = goog.style.getRelativePosition(frameElement, ancestor);
        var iframeBorders = goog.style.getBorderBox(frameElement);
        relativePosition.x += iframeRelativePosition.x + iframeBorders.left;
        relativePosition.y += iframeRelativePosition.y + iframeBorders.top;
      } else {
        relativePosition = goog.style.getRelativePosition(element, ancestor);
      }
      var backgroundXYValues = goog.cssom.iframe.style.getBackgroundXYValues_(computedStyle);
      for (var i = 0; i < 2; i++) {
        var positionValue = backgroundXYValues[i];
        var coordinate = i == 0 ? "X" : "Y";
        var positionProperty = "backgroundPosition" + coordinate;
        var positionValueParts = goog.cssom.iframe.style.valueWithUnitsRegEx_.exec(positionValue);
        if (positionValueParts) {
          var value = parseInt(positionValueParts[1] + positionValueParts[2], 10);
          var units = positionValueParts[3];
          if (value == 0 || units == "px") {
            value -= coordinate == "X" ? relativePosition.x : relativePosition.y;
          }
          positionValue = value + units;
        }
        propertyValues[positionProperty] = positionValue;
      }
      propertyValues["backgroundPosition"] = propertyValues["backgroundPositionX"] + " " + propertyValues["backgroundPositionY"];
    }
    if (propertyValues["backgroundColor"]) {
      break;
    }
    if (ancestor.tagName == goog.dom.TagName.HTML) {
      try {
        currentIframeWindow = goog.dom.getWindow(ancestor.parentNode);
        ancestor = currentIframeWindow.frameElement;
        if (!ancestor) {
          break;
        }
      } catch (e) {
        break;
      }
    }
  }
  return propertyValues;
};
goog.provide("goog.editor.SeamlessField");
goog.require("goog.cssom.iframe.style");
goog.require("goog.dom");
goog.require("goog.dom.Range");
goog.require("goog.dom.TagName");
goog.require("goog.dom.safe");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Field");
goog.require("goog.editor.icontent");
goog.require("goog.editor.icontent.FieldFormatInfo");
goog.require("goog.editor.icontent.FieldStyleInfo");
goog.require("goog.editor.node");
goog.require("goog.events");
goog.require("goog.events.EventType");
goog.require("goog.html.legacyconversions");
goog.require("goog.html.uncheckedconversions");
goog.require("goog.log");
goog.require("goog.string.Const");
goog.require("goog.style");
goog.editor.SeamlessField = function(id, opt_doc) {
  goog.editor.Field.call(this, id, opt_doc);
};
goog.inherits(goog.editor.SeamlessField, goog.editor.Field);
goog.editor.SeamlessField.prototype.logger = goog.log.getLogger("goog.editor.SeamlessField");
goog.editor.SeamlessField.prototype.listenForDragOverEventKey_;
goog.editor.SeamlessField.prototype.listenForIframeLoadEventKey_;
goog.editor.SeamlessField.prototype.setMinHeight = function(height) {
  if (height == this.minHeight_) {
    return;
  }
  this.minHeight_ = height;
  if (this.usesIframe()) {
    this.doFieldSizingGecko();
  }
};
goog.editor.SeamlessField.prototype.isFixedHeight_ = false;
goog.editor.SeamlessField.prototype.isFixedHeightOverridden_ = false;
goog.editor.SeamlessField.prototype.isFixedHeight = function() {
  return this.isFixedHeight_;
};
goog.editor.SeamlessField.prototype.overrideFixedHeight = function(newVal) {
  this.isFixedHeight_ = newVal;
  this.isFixedHeightOverridden_ = true;
};
goog.editor.SeamlessField.prototype.autoDetectFixedHeight_ = function() {
  if (!this.isFixedHeightOverridden_) {
    var originalElement = this.getOriginalElement();
    if (originalElement) {
      this.isFixedHeight_ = goog.style.getComputedOverflowY(originalElement) == "auto";
    }
  }
};
goog.editor.SeamlessField.prototype.handleOuterDocChange_ = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.CHANGE)) {
    return;
  }
  this.sizeIframeToWrapperGecko_();
};
goog.editor.SeamlessField.prototype.sizeIframeToBodyHeightGecko_ = function() {
  if (this.acquireSizeIframeLockGecko_()) {
    var resized = false;
    var ifr = this.getEditableIframe();
    if (ifr) {
      var fieldHeight = this.getIframeBodyHeightGecko_();
      if (this.minHeight_) {
        fieldHeight = Math.max(fieldHeight, this.minHeight_);
      }
      if (parseInt(goog.style.getStyle(ifr, "height"), 10) != fieldHeight) {
        ifr.style.height = fieldHeight + "px";
        resized = true;
      }
    }
    this.releaseSizeIframeLockGecko_();
    if (resized) {
      this.dispatchEvent(goog.editor.Field.EventType.IFRAME_RESIZED);
    }
  }
};
goog.editor.SeamlessField.prototype.getIframeBodyHeightGecko_ = function() {
  var ifr = this.getEditableIframe();
  var body = ifr.contentDocument.body;
  var htmlElement = body.parentNode;
  if (parseInt(goog.style.getStyle(ifr, "height"), 10) === 0) {
    goog.style.setStyle(ifr, "height", 1 + "px");
  }
  var fieldHeight;
  if (goog.editor.node.isStandardsMode(body)) {
    fieldHeight = htmlElement.offsetHeight;
  } else {
    fieldHeight = htmlElement.scrollHeight;
    if (htmlElement.clientHeight != htmlElement.offsetHeight) {
      fieldHeight += goog.editor.SeamlessField.getScrollbarWidth_();
    }
  }
  return fieldHeight;
};
goog.editor.SeamlessField.getScrollbarWidth_ = function() {
  return goog.editor.SeamlessField.scrollbarWidth_ || (goog.editor.SeamlessField.scrollbarWidth_ = goog.style.getScrollbarWidth());
};
goog.editor.SeamlessField.prototype.sizeIframeToWrapperGecko_ = function() {
  if (this.acquireSizeIframeLockGecko_()) {
    var ifr = this.getEditableIframe();
    var field = this.getElement();
    var resized = false;
    if (ifr && field) {
      var fieldPaddingBox;
      var widthDiv = ifr.parentNode;
      var width = widthDiv.offsetWidth;
      if (parseInt(goog.style.getStyle(ifr, "width"), 10) != width) {
        fieldPaddingBox = goog.style.getPaddingBox(field);
        ifr.style.width = width + "px";
        field.style.width = width - fieldPaddingBox.left - fieldPaddingBox.right + "px";
        resized = true;
      }
      var height = widthDiv.offsetHeight;
      if (this.isFixedHeight() && parseInt(goog.style.getStyle(ifr, "height"), 10) != height) {
        if (!fieldPaddingBox) {
          fieldPaddingBox = goog.style.getPaddingBox(field);
        }
        ifr.style.height = height + "px";
        field.style.height = height - fieldPaddingBox.top - fieldPaddingBox.bottom + "px";
        resized = true;
      }
    }
    this.releaseSizeIframeLockGecko_();
    if (resized) {
      this.dispatchEvent(goog.editor.Field.EventType.IFRAME_RESIZED);
    }
  }
};
goog.editor.SeamlessField.prototype.doFieldSizingGecko = function() {
  if (this.getElement()) {
    this.sizeIframeToWrapperGecko_();
    if (!this.isFixedHeight()) {
      this.sizeIframeToBodyHeightGecko_();
    }
  }
};
goog.editor.SeamlessField.prototype.acquireSizeIframeLockGecko_ = function() {
  if (this.sizeIframeLock_) {
    return false;
  }
  return this.sizeIframeLock_ = true;
};
goog.editor.SeamlessField.prototype.releaseSizeIframeLockGecko_ = function() {
  this.sizeIframeLock_ = false;
};
goog.editor.SeamlessField.prototype.iframeableCss_ = "";
goog.editor.SeamlessField.prototype.getIframeableCss = function(opt_forceRegeneration) {
  if (!this.iframeableCss_ || opt_forceRegeneration) {
    var originalElement = this.getOriginalElement();
    if (originalElement) {
      this.iframeableCss_ = goog.cssom.iframe.style.getElementContext(originalElement, opt_forceRegeneration);
    }
  }
  return this.iframeableCss_;
};
goog.editor.SeamlessField.prototype.setIframeableCss = function(iframeableCss) {
  this.iframeableCss_ = iframeableCss;
};
goog.editor.SeamlessField.haveInstalledCss_ = false;
goog.editor.SeamlessField.prototype.inheritBlendedCSS = function() {
  if (!this.usesIframe()) {
    return;
  }
  var field = this.getElement();
  var head = goog.dom.getDomHelper(field).getElementsByTagNameAndClass(goog.dom.TagName.HEAD)[0];
  if (head) {
    goog.dom.removeChildren(head);
  }
  var newCSS = this.getIframeableCss(true);
  goog.style.installSafeStyleSheet(goog.html.legacyconversions.safeStyleSheetFromString(newCSS), field);
};
goog.editor.SeamlessField.prototype.usesIframe = function() {
  return !goog.editor.BrowserFeature.HAS_CONTENT_EDITABLE;
};
goog.editor.SeamlessField.prototype.setupMutationEventHandlersGecko = function() {
  goog.editor.SeamlessField.superClass_.setupMutationEventHandlersGecko.call(this);
  if (this.usesIframe()) {
    var iframe = this.getEditableIframe();
    var outerDoc = iframe.ownerDocument;
    this.eventRegister.listen(outerDoc, goog.editor.Field.MUTATION_EVENTS_GECKO, this.handleOuterDocChange_, true);
    this.listenForIframeLoadEventKey_ = goog.events.listenOnce(this.getEditableDomHelper().getWindow(), goog.events.EventType.LOAD, this.sizeIframeToBodyHeightGecko_, true, this);
    this.eventRegister.listen(outerDoc, "DOMAttrModified", goog.bind(this.handleDomAttrChange, this, this.handleOuterDocChange_), true);
  }
};
goog.editor.SeamlessField.prototype.handleChange = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.CHANGE)) {
    return;
  }
  goog.editor.SeamlessField.superClass_.handleChange.call(this);
  if (this.usesIframe()) {
    this.sizeIframeToBodyHeightGecko_();
  }
};
goog.editor.SeamlessField.prototype.dispatchBlur = function() {
  if (this.isEventStopped(goog.editor.Field.EventType.BLUR)) {
    return;
  }
  goog.editor.SeamlessField.superClass_.dispatchBlur.call(this);
  if (!goog.editor.BrowserFeature.HAS_CONTENT_EDITABLE && !goog.editor.BrowserFeature.CLEARS_SELECTION_WHEN_FOCUS_LEAVES) {
    var win = this.getEditableDomHelper().getWindow();
    var dragging = false;
    goog.events.unlistenByKey(this.listenForDragOverEventKey_);
    this.listenForDragOverEventKey_ = goog.events.listenOnce(win.document.body, "dragover", function() {
      dragging = true;
    });
    goog.global.setTimeout(goog.bind(function() {
      if (!dragging) {
        if (this.editableDomHelper) {
          var rng = this.getRange();
          var iframeWindow = this.editableDomHelper.getWindow();
          goog.dom.Range.clearSelection(iframeWindow);
          if (rng) {
            rng.collapse(true);
            rng.select();
          }
        }
      }
    }, this), 0);
  }
};
goog.editor.SeamlessField.prototype.turnOnDesignModeGecko = function() {
  goog.editor.SeamlessField.superClass_.turnOnDesignModeGecko.call(this);
  var doc = this.getEditableDomHelper().getDocument();
  doc.execCommand("enableInlineTableEditing", false, "false");
  doc.execCommand("enableObjectResizing", false, "false");
};
goog.editor.SeamlessField.prototype.installStyles = function() {
  if (!this.usesIframe()) {
    if (!goog.editor.SeamlessField.haveInstalledCss_) {
      if (this.cssStyles) {
        goog.style.installSafeStyleSheet(goog.html.legacyconversions.safeStyleSheetFromString(this.cssStyles), this.getElement());
      }
      goog.editor.SeamlessField.haveInstalledCss_ = true;
    }
  }
};
goog.editor.SeamlessField.prototype.makeEditableInternal = function(opt_iframeSrc) {
  if (this.usesIframe()) {
    goog.editor.SeamlessField.superClass_.makeEditableInternal.call(this, opt_iframeSrc);
  } else {
    var field = this.getOriginalElement();
    if (field) {
      this.setupFieldObject(field);
      field.contentEditable = true;
      this.injectContents(field.innerHTML, field);
      this.handleFieldLoad();
    }
  }
};
goog.editor.SeamlessField.prototype.handleFieldLoad = function() {
  if (this.usesIframe()) {
    var self = this;
    goog.global.setTimeout(function() {
      self.doFieldSizingGecko();
    }, 0);
  }
  goog.editor.SeamlessField.superClass_.handleFieldLoad.call(this);
};
goog.editor.SeamlessField.prototype.getIframeAttributes = function() {
  return {"frameBorder":0, "style":"padding:0;"};
};
goog.editor.SeamlessField.prototype.attachIframe = function(iframe) {
  this.autoDetectFixedHeight_();
  var field = this.getOriginalElement();
  var dh = goog.dom.getDomHelper(field);
  var oldWidth = field.style.width;
  var oldHeight = field.style.height;
  goog.style.setStyle(field, "visibility", "hidden");
  var startDiv = dh.createDom(goog.dom.TagName.DIV, {"style":"height:0;clear:both", "innerHTML":"&nbsp;"});
  var endDiv = startDiv.cloneNode(true);
  field.insertBefore(startDiv, field.firstChild);
  goog.dom.appendChild(field, endDiv);
  var contentBox = goog.style.getContentBoxSize(field);
  var width = contentBox.width;
  var height = contentBox.height;
  var html = "";
  if (this.isFixedHeight()) {
    html = "&nbsp;";
    goog.style.setStyle(field, "position", "relative");
    goog.style.setStyle(field, "overflow", "visible");
    goog.style.setStyle(iframe, "position", "absolute");
    goog.style.setStyle(iframe, "top", "0");
    goog.style.setStyle(iframe, "left", "0");
  }
  goog.style.setSize(field, width, height);
  if (goog.editor.node.isStandardsMode(field)) {
    this.originalFieldLineHeight_ = field.style.lineHeight;
    goog.style.setStyle(field, "lineHeight", "0");
  }
  goog.editor.node.replaceInnerHtml(field, html);
  goog.style.setSize(iframe, width, height);
  goog.style.setSize(field, oldWidth, oldHeight);
  goog.style.setStyle(field, "visibility", "");
  goog.dom.appendChild(field, iframe);
  if (!this.shouldLoadAsynchronously()) {
    var doc = iframe.contentWindow.document;
    if (goog.editor.node.isStandardsMode(iframe.ownerDocument)) {
      doc.open();
      var emptyHtml = goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract(goog.string.Const.from("HTML from constant string"), "<!DOCTYPE HTML><html></html>");
      goog.dom.safe.documentWrite(doc, emptyHtml);
      doc.close();
    }
  }
};
goog.editor.SeamlessField.prototype.getFieldFormatInfo = function(extraStyles) {
  var originalElement = this.getOriginalElement();
  if (originalElement) {
    return new goog.editor.icontent.FieldFormatInfo(this.id, goog.editor.node.isStandardsMode(originalElement), true, this.isFixedHeight(), extraStyles);
  }
  throw Error("no field");
};
goog.editor.SeamlessField.prototype.writeIframeContent = function(iframe, innerHtml, extraStyles) {
  goog.style.setStyle(iframe, "visibility", "hidden");
  var formatInfo = this.getFieldFormatInfo(extraStyles);
  var styleInfo = new goog.editor.icontent.FieldStyleInfo(this.getOriginalElement(), this.cssStyles + this.getIframeableCss());
  goog.editor.icontent.writeNormalInitialBlendedIframe(formatInfo, innerHtml, styleInfo, iframe);
  this.doFieldSizingGecko();
  goog.style.setStyle(iframe, "visibility", "visible");
};
goog.editor.SeamlessField.prototype.restoreDom = function() {
  if (this.usesIframe()) {
    goog.dom.removeNode(this.getEditableIframe());
  }
};
goog.editor.SeamlessField.prototype.clearListeners = function() {
  goog.events.unlistenByKey(this.listenForDragOverEventKey_);
  goog.events.unlistenByKey(this.listenForIframeLoadEventKey_);
  goog.editor.SeamlessField.base(this, "clearListeners");
};
goog.provide("goog.uri.utils");
goog.provide("goog.uri.utils.ComponentIndex");
goog.provide("goog.uri.utils.QueryArray");
goog.provide("goog.uri.utils.QueryValue");
goog.provide("goog.uri.utils.StandardQueryParam");
goog.require("goog.array");
goog.require("goog.asserts");
goog.require("goog.string");
goog.uri.utils.CharCode_ = {AMPERSAND:38, EQUAL:61, HASH:35, QUESTION:63};
goog.uri.utils.buildFromEncodedParts = function(opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData, opt_fragment) {
  var out = "";
  if (opt_scheme) {
    out += opt_scheme + ":";
  }
  if (opt_domain) {
    out += "//";
    if (opt_userInfo) {
      out += opt_userInfo + "@";
    }
    out += opt_domain;
    if (opt_port) {
      out += ":" + opt_port;
    }
  }
  if (opt_path) {
    out += opt_path;
  }
  if (opt_queryData) {
    out += "?" + opt_queryData;
  }
  if (opt_fragment) {
    out += "#" + opt_fragment;
  }
  return out;
};
goog.uri.utils.splitRe_ = new RegExp("^" + "(?:" + "([^:/?#.]+)" + ":)?" + "(?://" + "(?:([^/?#]*)@)?" + "([^/#?]*?)" + "(?::([0-9]+))?" + "(?=[/#?]|$)" + ")?" + "([^?#]+)?" + "(?:\\?([^#]*))?" + "(?:#([\\s\\S]*))?" + "$");
goog.uri.utils.ComponentIndex = {SCHEME:1, USER_INFO:2, DOMAIN:3, PORT:4, PATH:5, QUERY_DATA:6, FRAGMENT:7};
goog.uri.utils.split = function(uri) {
  return uri.match(goog.uri.utils.splitRe_);
};
goog.uri.utils.decodeIfPossible_ = function(uri, opt_preserveReserved) {
  if (!uri) {
    return uri;
  }
  return opt_preserveReserved ? decodeURI(uri) : decodeURIComponent(uri);
};
goog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) {
  return goog.uri.utils.split(uri)[componentIndex] || null;
};
goog.uri.utils.getScheme = function(uri) {
  return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.SCHEME, uri);
};
goog.uri.utils.getEffectiveScheme = function(uri) {
  var scheme = goog.uri.utils.getScheme(uri);
  if (!scheme && goog.global.self && goog.global.self.location) {
    var protocol = goog.global.self.location.protocol;
    scheme = protocol.substr(0, protocol.length - 1);
  }
  return scheme ? scheme.toLowerCase() : "";
};
goog.uri.utils.getUserInfoEncoded = function(uri) {
  return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.USER_INFO, uri);
};
goog.uri.utils.getUserInfo = function(uri) {
  return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getUserInfoEncoded(uri));
};
goog.uri.utils.getDomainEncoded = function(uri) {
  return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.DOMAIN, uri);
};
goog.uri.utils.getDomain = function(uri) {
  return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getDomainEncoded(uri), true);
};
goog.uri.utils.getPort = function(uri) {
  return Number(goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.PORT, uri)) || null;
};
goog.uri.utils.getPathEncoded = function(uri) {
  return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.PATH, uri);
};
goog.uri.utils.getPath = function(uri) {
  return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getPathEncoded(uri), true);
};
goog.uri.utils.getQueryData = function(uri) {
  return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.QUERY_DATA, uri);
};
goog.uri.utils.getFragmentEncoded = function(uri) {
  var hashIndex = uri.indexOf("#");
  return hashIndex < 0 ? null : uri.substr(hashIndex + 1);
};
goog.uri.utils.setFragmentEncoded = function(uri, fragment) {
  return goog.uri.utils.removeFragment(uri) + (fragment ? "#" + fragment : "");
};
goog.uri.utils.getFragment = function(uri) {
  return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getFragmentEncoded(uri));
};
goog.uri.utils.getHost = function(uri) {
  var pieces = goog.uri.utils.split(uri);
  return goog.uri.utils.buildFromEncodedParts(pieces[goog.uri.utils.ComponentIndex.SCHEME], pieces[goog.uri.utils.ComponentIndex.USER_INFO], pieces[goog.uri.utils.ComponentIndex.DOMAIN], pieces[goog.uri.utils.ComponentIndex.PORT]);
};
goog.uri.utils.getOrigin = function(uri) {
  var pieces = goog.uri.utils.split(uri);
  return goog.uri.utils.buildFromEncodedParts(pieces[goog.uri.utils.ComponentIndex.SCHEME], null, pieces[goog.uri.utils.ComponentIndex.DOMAIN], pieces[goog.uri.utils.ComponentIndex.PORT]);
};
goog.uri.utils.getPathAndAfter = function(uri) {
  var pieces = goog.uri.utils.split(uri);
  return goog.uri.utils.buildFromEncodedParts(null, null, null, null, pieces[goog.uri.utils.ComponentIndex.PATH], pieces[goog.uri.utils.ComponentIndex.QUERY_DATA], pieces[goog.uri.utils.ComponentIndex.FRAGMENT]);
};
goog.uri.utils.removeFragment = function(uri) {
  var hashIndex = uri.indexOf("#");
  return hashIndex < 0 ? uri : uri.substr(0, hashIndex);
};
goog.uri.utils.haveSameDomain = function(uri1, uri2) {
  var pieces1 = goog.uri.utils.split(uri1);
  var pieces2 = goog.uri.utils.split(uri2);
  return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] == pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && pieces1[goog.uri.utils.ComponentIndex.SCHEME] == pieces2[goog.uri.utils.ComponentIndex.SCHEME] && pieces1[goog.uri.utils.ComponentIndex.PORT] == pieces2[goog.uri.utils.ComponentIndex.PORT];
};
goog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) {
  goog.asserts.assert(uri.indexOf("#") < 0 && uri.indexOf("?") < 0, "goog.uri.utils: Fragment or query identifiers are not supported: [%s]", uri);
};
goog.uri.utils.QueryValue;
goog.uri.utils.QueryArray;
goog.uri.utils.parseQueryData = function(encodedQuery, callback) {
  if (!encodedQuery) {
    return;
  }
  var pairs = encodedQuery.split("&");
  for (var i = 0; i < pairs.length; i++) {
    var indexOfEquals = pairs[i].indexOf("=");
    var name = null;
    var value = null;
    if (indexOfEquals >= 0) {
      name = pairs[i].substring(0, indexOfEquals);
      value = pairs[i].substring(indexOfEquals + 1);
    } else {
      name = pairs[i];
    }
    callback(name, value ? goog.string.urlDecode(value) : "");
  }
};
goog.uri.utils.splitQueryData_ = function(uri) {
  var hashIndex = uri.indexOf("#");
  if (hashIndex < 0) {
    hashIndex = uri.length;
  }
  var questionIndex = uri.indexOf("?");
  var queryData;
  if (questionIndex < 0 || questionIndex > hashIndex) {
    questionIndex = hashIndex;
    queryData = "";
  } else {
    queryData = uri.substring(questionIndex + 1, hashIndex);
  }
  return [uri.substr(0, questionIndex), queryData, uri.substr(hashIndex)];
};
goog.uri.utils.joinQueryData_ = function(parts) {
  return parts[0] + (parts[1] ? "?" + parts[1] : "") + parts[2];
};
goog.uri.utils.appendQueryData_ = function(queryData, newData) {
  if (!newData) {
    return queryData;
  }
  return queryData ? queryData + "&" + newData : newData;
};
goog.uri.utils.appendQueryDataToUri_ = function(uri, queryData) {
  if (!queryData) {
    return uri;
  }
  var parts = goog.uri.utils.splitQueryData_(uri);
  parts[1] = goog.uri.utils.appendQueryData_(parts[1], queryData);
  return goog.uri.utils.joinQueryData_(parts);
};
goog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) {
  goog.asserts.assertString(key);
  if (goog.isArray(value)) {
    goog.asserts.assertArray(value);
    for (var j = 0; j < value.length; j++) {
      goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs);
    }
  } else {
    if (value != null) {
      pairs.push(key + (value === "" ? "" : "=" + goog.string.urlEncode(value)));
    }
  }
};
goog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) {
  goog.asserts.assert(Math.max(keysAndValues.length - (opt_startIndex || 0), 0) % 2 == 0, "goog.uri.utils: Key/value lists must be even in length.");
  var params = [];
  for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) {
    var key = keysAndValues[i];
    goog.uri.utils.appendKeyValuePairs_(key, keysAndValues[i + 1], params);
  }
  return params.join("&");
};
goog.uri.utils.buildQueryDataFromMap = function(map) {
  var params = [];
  for (var key in map) {
    goog.uri.utils.appendKeyValuePairs_(key, map[key], params);
  }
  return params.join("&");
};
goog.uri.utils.appendParams = function(uri, var_args) {
  var queryData = arguments.length == 2 ? goog.uri.utils.buildQueryData(arguments[1], 0) : goog.uri.utils.buildQueryData(arguments, 1);
  return goog.uri.utils.appendQueryDataToUri_(uri, queryData);
};
goog.uri.utils.appendParamsFromMap = function(uri, map) {
  var queryData = goog.uri.utils.buildQueryDataFromMap(map);
  return goog.uri.utils.appendQueryDataToUri_(uri, queryData);
};
goog.uri.utils.appendParam = function(uri, key, opt_value) {
  var value = goog.isDefAndNotNull(opt_value) ? "=" + goog.string.urlEncode(opt_value) : "";
  return goog.uri.utils.appendQueryDataToUri_(uri, key + value);
};
goog.uri.utils.findParam_ = function(uri, startIndex, keyEncoded, hashOrEndIndex) {
  var index = startIndex;
  var keyLength = keyEncoded.length;
  while ((index = uri.indexOf(keyEncoded, index)) >= 0 && index < hashOrEndIndex) {
    var precedingChar = uri.charCodeAt(index - 1);
    if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND || precedingChar == goog.uri.utils.CharCode_.QUESTION) {
      var followingChar = uri.charCodeAt(index + keyLength);
      if (!followingChar || followingChar == goog.uri.utils.CharCode_.EQUAL || followingChar == goog.uri.utils.CharCode_.AMPERSAND || followingChar == goog.uri.utils.CharCode_.HASH) {
        return index;
      }
    }
    index += keyLength + 1;
  }
  return -1;
};
goog.uri.utils.hashOrEndRe_ = /#|$/;
goog.uri.utils.hasParam = function(uri, keyEncoded) {
  return goog.uri.utils.findParam_(uri, 0, keyEncoded, uri.search(goog.uri.utils.hashOrEndRe_)) >= 0;
};
goog.uri.utils.getParamValue = function(uri, keyEncoded) {
  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
  var foundIndex = goog.uri.utils.findParam_(uri, 0, keyEncoded, hashOrEndIndex);
  if (foundIndex < 0) {
    return null;
  } else {
    var endPosition = uri.indexOf("&", foundIndex);
    if (endPosition < 0 || endPosition > hashOrEndIndex) {
      endPosition = hashOrEndIndex;
    }
    foundIndex += keyEncoded.length + 1;
    return goog.string.urlDecode(uri.substr(foundIndex, endPosition - foundIndex));
  }
};
goog.uri.utils.getParamValues = function(uri, keyEncoded) {
  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
  var position = 0;
  var foundIndex;
  var result = [];
  while ((foundIndex = goog.uri.utils.findParam_(uri, position, keyEncoded, hashOrEndIndex)) >= 0) {
    position = uri.indexOf("&", foundIndex);
    if (position < 0 || position > hashOrEndIndex) {
      position = hashOrEndIndex;
    }
    foundIndex += keyEncoded.length + 1;
    result.push(goog.string.urlDecode(uri.substr(foundIndex, position - foundIndex)));
  }
  return result;
};
goog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/;
goog.uri.utils.removeParam = function(uri, keyEncoded) {
  var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);
  var position = 0;
  var foundIndex;
  var buffer = [];
  while ((foundIndex = goog.uri.utils.findParam_(uri, position, keyEncoded, hashOrEndIndex)) >= 0) {
    buffer.push(uri.substring(position, foundIndex));
    position = Math.min(uri.indexOf("&", foundIndex) + 1 || hashOrEndIndex, hashOrEndIndex);
  }
  buffer.push(uri.substr(position));
  return buffer.join("").replace(goog.uri.utils.trailingQueryPunctuationRe_, "$1");
};
goog.uri.utils.setParam = function(uri, keyEncoded, value) {
  return goog.uri.utils.appendParam(goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value);
};
goog.uri.utils.setParamsFromMap = function(uri, params) {
  var parts = goog.uri.utils.splitQueryData_(uri);
  var queryData = parts[1];
  var buffer = [];
  if (queryData) {
    goog.array.forEach(queryData.split("&"), function(pair) {
      var indexOfEquals = pair.indexOf("=");
      var name = indexOfEquals >= 0 ? pair.substr(0, indexOfEquals) : pair;
      if (!params.hasOwnProperty(name)) {
        buffer.push(pair);
      }
    });
  }
  parts[1] = goog.uri.utils.appendQueryData_(buffer.join("&"), goog.uri.utils.buildQueryDataFromMap(params));
  return goog.uri.utils.joinQueryData_(parts);
};
goog.uri.utils.appendPath = function(baseUri, path) {
  goog.uri.utils.assertNoFragmentsOrQueries_(baseUri);
  if (goog.string.endsWith(baseUri, "/")) {
    baseUri = baseUri.substr(0, baseUri.length - 1);
  }
  if (goog.string.startsWith(path, "/")) {
    path = path.substr(1);
  }
  return goog.string.buildString(baseUri, "/", path);
};
goog.uri.utils.setPath = function(uri, path) {
  if (!goog.string.startsWith(path, "/")) {
    path = "/" + path;
  }
  var parts = goog.uri.utils.split(uri);
  return goog.uri.utils.buildFromEncodedParts(parts[goog.uri.utils.ComponentIndex.SCHEME], parts[goog.uri.utils.ComponentIndex.USER_INFO], parts[goog.uri.utils.ComponentIndex.DOMAIN], parts[goog.uri.utils.ComponentIndex.PORT], path, parts[goog.uri.utils.ComponentIndex.QUERY_DATA], parts[goog.uri.utils.ComponentIndex.FRAGMENT]);
};
goog.uri.utils.StandardQueryParam = {RANDOM:"zx"};
goog.uri.utils.makeUnique = function(uri) {
  return goog.uri.utils.setParam(uri, goog.uri.utils.StandardQueryParam.RANDOM, goog.string.getRandomString());
};
goog.provide("goog.editor.Link");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.Range");
goog.require("goog.dom.TagName");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Command");
goog.require("goog.editor.Field");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("goog.string");
goog.require("goog.string.Unicode");
goog.require("goog.uri.utils");
goog.require("goog.uri.utils.ComponentIndex");
goog.editor.Link = function(anchor, isNew) {
  this.anchor_ = anchor;
  this.isNew_ = isNew;
  this.extraAnchors_ = [];
};
goog.editor.Link.prototype.getAnchor = function() {
  return this.anchor_;
};
goog.editor.Link.prototype.getExtraAnchors = function() {
  return this.extraAnchors_;
};
goog.editor.Link.prototype.getCurrentText = function() {
  if (!this.currentText_) {
    var anchor = this.getAnchor();
    var leaf = goog.editor.node.getLeftMostLeaf(anchor);
    if (leaf.tagName && leaf.tagName == goog.dom.TagName.IMG) {
      this.currentText_ = leaf.getAttribute("alt");
    } else {
      this.currentText_ = goog.dom.getRawTextContent(this.getAnchor());
    }
  }
  return this.currentText_;
};
goog.editor.Link.prototype.isNew = function() {
  return this.isNew_;
};
goog.editor.Link.prototype.initializeUrl = function(url) {
  this.getAnchor().href = url;
};
goog.editor.Link.prototype.removeLink = function() {
  goog.dom.flattenElement(this.anchor_);
  this.anchor_ = null;
  while (this.extraAnchors_.length) {
    goog.dom.flattenElement(this.extraAnchors_.pop());
  }
};
goog.editor.Link.prototype.setTextAndUrl = function(newText, newUrl) {
  var anchor = this.getAnchor();
  anchor.href = newUrl;
  var currentText = this.getCurrentText();
  if (newText != currentText) {
    var leaf = goog.editor.node.getLeftMostLeaf(anchor);
    if (leaf.tagName && leaf.tagName == goog.dom.TagName.IMG) {
      leaf.setAttribute("alt", newText ? newText : "");
    } else {
      if (leaf.nodeType == goog.dom.NodeType.TEXT) {
        leaf = leaf.parentNode;
      }
      if (goog.dom.getRawTextContent(leaf) != currentText) {
        leaf = anchor;
      }
      goog.dom.removeChildren(leaf);
      var domHelper = goog.dom.getDomHelper(leaf);
      goog.dom.appendChild(leaf, domHelper.createTextNode(newText));
    }
    this.currentText_ = null;
  }
  this.isNew_ = false;
};
goog.editor.Link.prototype.placeCursorRightOf = function() {
  var anchor = this.getAnchor();
  if (goog.editor.BrowserFeature.GETS_STUCK_IN_LINKS) {
    var spaceNode;
    var nextSibling = anchor.nextSibling;
    if (nextSibling && nextSibling.nodeType == goog.dom.NodeType.TEXT && (goog.string.startsWith(nextSibling.data, goog.string.Unicode.NBSP) || goog.string.startsWith(nextSibling.data, " "))) {
      spaceNode = nextSibling;
    } else {
      var dh = goog.dom.getDomHelper(anchor);
      spaceNode = dh.createTextNode(goog.string.Unicode.NBSP);
      goog.dom.insertSiblingAfter(spaceNode, anchor);
    }
    var range = goog.dom.Range.createCaret(spaceNode, 1);
    range.select();
  } else {
    goog.editor.range.placeCursorNextTo(anchor, false);
  }
};
goog.editor.Link.prototype.updateLinkDisplay_ = function(field, url) {
  this.initializeUrl(url);
  this.placeCursorRightOf();
  field.execCommand(goog.editor.Command.UPDATE_LINK_BUBBLE);
};
goog.editor.Link.prototype.getValidLinkFromText = function() {
  var text = goog.string.trim(this.getCurrentText());
  if (goog.editor.Link.isLikelyUrl(text)) {
    if (text.search(/:/) < 0) {
      return "http://" + goog.string.trimLeft(text);
    }
    return text;
  } else {
    if (goog.editor.Link.isLikelyEmailAddress(text)) {
      return "mailto:" + text;
    }
  }
  return null;
};
goog.editor.Link.prototype.finishLinkCreation = function(field) {
  var linkFromText = this.getValidLinkFromText();
  if (linkFromText) {
    this.updateLinkDisplay_(field, linkFromText);
  } else {
    field.execCommand(goog.editor.Command.MODAL_LINK_EDITOR, this);
  }
};
goog.editor.Link.createNewLink = function(anchor, url, opt_target, opt_extraAnchors) {
  var link = new goog.editor.Link(anchor, true);
  link.initializeUrl(url);
  if (opt_target) {
    anchor.target = opt_target;
  }
  if (opt_extraAnchors) {
    link.extraAnchors_ = opt_extraAnchors;
  }
  return link;
};
goog.editor.Link.createNewLinkFromText = function(anchor, opt_target) {
  var link = new goog.editor.Link(anchor, true);
  var text = link.getValidLinkFromText();
  link.initializeUrl(text ? text : "");
  if (opt_target) {
    anchor.target = opt_target;
  }
  return link;
};
goog.editor.Link.isLikelyUrl = function(str) {
  if (/\s/.test(str)) {
    return false;
  }
  if (goog.editor.Link.isLikelyEmailAddress(str)) {
    return false;
  }
  var addedScheme = false;
  if (!/^[^:\/?#.]+:/.test(str)) {
    str = "http://" + str;
    addedScheme = true;
  }
  var parts = goog.uri.utils.split(str);
  var scheme = parts[goog.uri.utils.ComponentIndex.SCHEME];
  if (goog.array.indexOf(["mailto", "aim"], scheme) != -1) {
    return true;
  }
  var domain = parts[goog.uri.utils.ComponentIndex.DOMAIN];
  if (!domain || addedScheme && domain.indexOf(".") == -1 || /[^\w\d\-\u0100-\uffff.%]/.test(domain)) {
    return false;
  }
  var path = parts[goog.uri.utils.ComponentIndex.PATH];
  return !path || path.indexOf("/") == 0;
};
goog.editor.Link.LIKELY_EMAIL_ADDRESS_ = new RegExp("^" + "[\\w-]+(\\.[\\w-]+)*" + "\\@" + "([\\w-]+\\.)+" + "(\\d+|\\w\\w+)$", "i");
goog.editor.Link.isLikelyEmailAddress = function(str) {
  return goog.editor.Link.LIKELY_EMAIL_ADDRESS_.test(str);
};
goog.editor.Link.isMailto = function(url) {
  return !!url && goog.string.startsWith(url, "mailto:");
};
goog.provide("goog.ui.editor.messages");
goog.require("goog.html.uncheckedconversions");
goog.require("goog.string.Const");
goog.ui.editor.messages.MSG_LINK_CAPTION = goog.getMsg("Link");
goog.ui.editor.messages.MSG_EDIT_LINK = goog.getMsg("Edit Link");
goog.ui.editor.messages.MSG_TEXT_TO_DISPLAY = goog.getMsg("Text to display:");
goog.ui.editor.messages.MSG_LINK_TO = goog.getMsg("Link to:");
goog.ui.editor.messages.MSG_ON_THE_WEB = goog.getMsg("Web address");
goog.ui.editor.messages.MSG_ON_THE_WEB_TIP = goog.getMsg("Link to a page or file somewhere else on the web");
goog.ui.editor.messages.MSG_TEST_THIS_LINK = goog.getMsg("Test this link");
goog.ui.editor.messages.MSG_TR_LINK_EXPLANATION = goog.getMsg("{$startBold}Not sure what to put in the box?{$endBold} " + "First, find the page on the web that you want to " + "link to. (A {$searchEngineLink}search engine{$endLink} " + "might be useful.) Then, copy the web address from " + "the box in your browser's address bar, and paste it into " + "the box above.", {"startBold":"<b>", "endBold":"</b>", "searchEngineLink":"<a href='http://www.google.com/' target='_new'>", "endLink":"</a>"});
goog.ui.editor.messages.getTrLinkExplanationSafeHtml = function() {
  return goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract(goog.string.Const.from("Parameterless translation"), goog.ui.editor.messages.MSG_TR_LINK_EXPLANATION);
};
goog.ui.editor.messages.MSG_WHAT_URL = goog.getMsg("To what URL should this link go?");
goog.ui.editor.messages.MSG_EMAIL_ADDRESS = goog.getMsg("Email address");
goog.ui.editor.messages.MSG_EMAIL_ADDRESS_TIP = goog.getMsg("Link to an email address");
goog.ui.editor.messages.MSG_INVALID_EMAIL = goog.getMsg("Invalid email address");
goog.ui.editor.messages.MSG_WHAT_EMAIL = goog.getMsg("To what email address should this link?");
goog.ui.editor.messages.MSG_EMAIL_EXPLANATION = goog.getMsg("{$preb}Be careful.{$postb} " + "Remember that any time you include an email address on a web page, " + "nasty spammers can find it too.", {"preb":"<b>", "postb":"</b>"});
goog.ui.editor.messages.getEmailExplanationSafeHtml = function() {
  return goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract(goog.string.Const.from("Parameterless translation"), goog.ui.editor.messages.MSG_EMAIL_EXPLANATION);
};
goog.ui.editor.messages.MSG_OPEN_IN_NEW_WINDOW = goog.getMsg("Open this link in a new window");
goog.ui.editor.messages.MSG_IMAGE_CAPTION = goog.getMsg("Image");
goog.provide("goog.editor.plugins.BasicTextFormatter");
goog.provide("goog.editor.plugins.BasicTextFormatter.COMMAND");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.Range");
goog.require("goog.dom.TagName");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Command");
goog.require("goog.editor.Link");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("goog.editor.style");
goog.require("goog.iter");
goog.require("goog.iter.StopIteration");
goog.require("goog.log");
goog.require("goog.object");
goog.require("goog.string");
goog.require("goog.string.Unicode");
goog.require("goog.style");
goog.require("goog.ui.editor.messages");
goog.require("goog.userAgent");
goog.editor.plugins.BasicTextFormatter = function() {
  goog.editor.Plugin.call(this);
};
goog.inherits(goog.editor.plugins.BasicTextFormatter, goog.editor.Plugin);
goog.editor.plugins.BasicTextFormatter.prototype.getTrogClassId = function() {
  return "BTF";
};
goog.editor.plugins.BasicTextFormatter.prototype.logger = goog.log.getLogger("goog.editor.plugins.BasicTextFormatter");
goog.editor.plugins.BasicTextFormatter.COMMAND = {LINK:"+link", CREATE_LINK:"+createLink", FORMAT_BLOCK:"+formatBlock", INDENT:"+indent", OUTDENT:"+outdent", STRIKE_THROUGH:"+strikeThrough", HORIZONTAL_RULE:"+insertHorizontalRule", SUBSCRIPT:"+subscript", SUPERSCRIPT:"+superscript", UNDERLINE:"+underline", BOLD:"+bold", ITALIC:"+italic", FONT_SIZE:"+fontSize", FONT_FACE:"+fontName", FONT_COLOR:"+foreColor", BACKGROUND_COLOR:"+backColor", ORDERED_LIST:"+insertOrderedList", UNORDERED_LIST:"+insertUnorderedList", 
JUSTIFY_CENTER:"+justifyCenter", JUSTIFY_FULL:"+justifyFull", JUSTIFY_RIGHT:"+justifyRight", JUSTIFY_LEFT:"+justifyLeft"};
goog.editor.plugins.BasicTextFormatter.SUPPORTED_COMMANDS_ = goog.object.transpose(goog.editor.plugins.BasicTextFormatter.COMMAND);
goog.editor.plugins.BasicTextFormatter.prototype.isSupportedCommand = function(command) {
  return command in goog.editor.plugins.BasicTextFormatter.SUPPORTED_COMMANDS_;
};
goog.editor.plugins.BasicTextFormatter.SILENT_COMMANDS_ = [goog.editor.plugins.BasicTextFormatter.COMMAND.CREATE_LINK];
goog.editor.plugins.BasicTextFormatter.prototype.isSilentCommand = function(command) {
  return goog.array.contains(goog.editor.plugins.BasicTextFormatter.SILENT_COMMANDS_, command);
};
goog.editor.plugins.BasicTextFormatter.prototype.getRange_ = function() {
  return this.getFieldObject().getRange();
};
goog.editor.plugins.BasicTextFormatter.prototype.getDocument_ = function() {
  return this.getFieldDomHelper().getDocument();
};
goog.editor.plugins.BasicTextFormatter.prototype.execCommandInternal = function(command, var_args) {
  var preserveDir, styleWithCss, needsFormatBlockDiv, hasDummySelection;
  var result;
  var opt_arg = arguments[1];
  switch(command) {
    case goog.editor.plugins.BasicTextFormatter.COMMAND.BACKGROUND_COLOR:
      if (!goog.isNull(opt_arg)) {
        if (goog.editor.BrowserFeature.EATS_EMPTY_BACKGROUND_COLOR) {
          this.applyBgColorManually_(opt_arg);
        } else {
          if (goog.userAgent.OPERA) {
            this.execCommandHelper_("hiliteColor", opt_arg);
          } else {
            this.execCommandHelper_(command, opt_arg);
          }
        }
      }
      break;
    case goog.editor.plugins.BasicTextFormatter.COMMAND.CREATE_LINK:
      result = this.createLink_(arguments[1], arguments[2], arguments[3]);
      break;
    case goog.editor.plugins.BasicTextFormatter.COMMAND.LINK:
      result = this.toggleLink_(opt_arg);
      break;
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_CENTER:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_FULL:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_RIGHT:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_LEFT:
      this.justify_(command);
      break;
    default:
      if (goog.userAgent.IE && command == goog.editor.plugins.BasicTextFormatter.COMMAND.FORMAT_BLOCK && opt_arg) {
        opt_arg = "<" + opt_arg + ">";
      }
      if (command == goog.editor.plugins.BasicTextFormatter.COMMAND.FONT_COLOR && goog.isNull(opt_arg)) {
        break;
      }
      switch(command) {
        case goog.editor.plugins.BasicTextFormatter.COMMAND.INDENT:
        case goog.editor.plugins.BasicTextFormatter.COMMAND.OUTDENT:
          if (goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS) {
            if (goog.userAgent.GECKO) {
              styleWithCss = true;
            }
            if (goog.userAgent.OPERA) {
              if (command == goog.editor.plugins.BasicTextFormatter.COMMAND.OUTDENT) {
                styleWithCss = !this.getDocument_().queryCommandEnabled("outdent");
              } else {
                styleWithCss = true;
              }
            }
          }
        case goog.editor.plugins.BasicTextFormatter.COMMAND.ORDERED_LIST:
        case goog.editor.plugins.BasicTextFormatter.COMMAND.UNORDERED_LIST:
          if (goog.editor.BrowserFeature.LEAVES_P_WHEN_REMOVING_LISTS && this.queryCommandStateInternal_(this.getDocument_(), command)) {
            needsFormatBlockDiv = this.getFieldObject().queryCommandValue(goog.editor.Command.DEFAULT_TAG) != goog.dom.TagName.P;
          } else {
            if (!goog.editor.BrowserFeature.CAN_LISTIFY_BR) {
              this.convertBreaksToDivs_();
            }
          }
          if (goog.userAgent.GECKO && goog.editor.BrowserFeature.FORGETS_FORMATTING_WHEN_LISTIFYING && !this.queryCommandValue(command)) {
            hasDummySelection |= this.beforeInsertListGecko_();
          }
        case goog.editor.plugins.BasicTextFormatter.COMMAND.FORMAT_BLOCK:
          preserveDir = !!this.getFieldObject().getPluginByClassId("Bidi");
          break;
        case goog.editor.plugins.BasicTextFormatter.COMMAND.SUBSCRIPT:
        case goog.editor.plugins.BasicTextFormatter.COMMAND.SUPERSCRIPT:
          if (goog.editor.BrowserFeature.NESTS_SUBSCRIPT_SUPERSCRIPT) {
            this.applySubscriptSuperscriptWorkarounds_(command);
          }
          break;
        case goog.editor.plugins.BasicTextFormatter.COMMAND.UNDERLINE:
        case goog.editor.plugins.BasicTextFormatter.COMMAND.BOLD:
        case goog.editor.plugins.BasicTextFormatter.COMMAND.ITALIC:
          styleWithCss = goog.userAgent.GECKO && goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS && this.queryCommandValue(command);
          break;
        case goog.editor.plugins.BasicTextFormatter.COMMAND.FONT_COLOR:
        case goog.editor.plugins.BasicTextFormatter.COMMAND.FONT_FACE:
          styleWithCss = goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS && goog.userAgent.GECKO;
      }this.execCommandHelper_(command, opt_arg, preserveDir, !!styleWithCss);
      if (hasDummySelection) {
        this.getDocument_().execCommand("Delete", false, true);
      }
      if (needsFormatBlockDiv) {
        this.getDocument_().execCommand("FormatBlock", false, "<div>");
      }
  }
  if (goog.userAgent.GECKO && !this.getFieldObject().inModalMode()) {
    this.focusField_();
  }
  return result;
};
goog.editor.plugins.BasicTextFormatter.prototype.focusField_ = function() {
  this.getFieldDomHelper().getWindow().focus();
};
goog.editor.plugins.BasicTextFormatter.prototype.queryCommandValue = function(command) {
  var styleWithCss;
  switch(command) {
    case goog.editor.plugins.BasicTextFormatter.COMMAND.LINK:
      return this.isNodeInState_(goog.dom.TagName.A);
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_CENTER:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_FULL:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_RIGHT:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.JUSTIFY_LEFT:
      return this.isJustification_(command);
    case goog.editor.plugins.BasicTextFormatter.COMMAND.FORMAT_BLOCK:
      return goog.editor.plugins.BasicTextFormatter.getSelectionBlockState_(this.getFieldObject().getRange());
    case goog.editor.plugins.BasicTextFormatter.COMMAND.INDENT:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.OUTDENT:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.HORIZONTAL_RULE:
      return false;
    case goog.editor.plugins.BasicTextFormatter.COMMAND.FONT_SIZE:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.FONT_FACE:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.FONT_COLOR:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.BACKGROUND_COLOR:
      return this.queryCommandValueInternal_(this.getDocument_(), command, goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS && goog.userAgent.GECKO);
    case goog.editor.plugins.BasicTextFormatter.COMMAND.UNDERLINE:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.BOLD:
    case goog.editor.plugins.BasicTextFormatter.COMMAND.ITALIC:
      styleWithCss = goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS && goog.userAgent.GECKO;
    default:
      return this.queryCommandStateInternal_(this.getDocument_(), command, styleWithCss);
  }
};
goog.editor.plugins.BasicTextFormatter.prototype.prepareContentsHtml = function(html) {
  if (goog.editor.BrowserFeature.COLLAPSES_EMPTY_NODES && html.match(/^\s*<script/i)) {
    html = "&nbsp;" + html;
  }
  if (goog.editor.BrowserFeature.CONVERT_TO_B_AND_I_TAGS) {
    html = html.replace(/<(\/?)strong([^\w])/gi, "<$1b$2");
    html = html.replace(/<(\/?)em([^\w])/gi, "<$1i$2");
  }
  return html;
};
goog.editor.plugins.BasicTextFormatter.prototype.cleanContentsDom = function(fieldCopy) {
  var images = goog.dom.getElementsByTagName(goog.dom.TagName.IMG, fieldCopy);
  for (var i = 0, image; image = images[i]; i++) {
    if (goog.editor.BrowserFeature.SHOWS_CUSTOM_ATTRS_IN_INNER_HTML) {
      image.removeAttribute("tabIndex");
      image.removeAttribute("tabIndexSet");
      goog.removeUid(image);
      image.oldTabIndex;
      if (image.oldTabIndex) {
        image.tabIndex = image.oldTabIndex;
      }
    }
  }
};
goog.editor.plugins.BasicTextFormatter.prototype.cleanContentsHtml = function(html) {
  if (goog.editor.BrowserFeature.MOVES_STYLE_TO_HEAD) {
    var heads = this.getFieldObject().getEditableDomHelper().getElementsByTagNameAndClass(goog.dom.TagName.HEAD);
    var stylesHtmlArr = [];
    var numHeads = heads.length;
    for (var i = 1; i < numHeads; ++i) {
      var styles = goog.dom.getElementsByTagName(goog.dom.TagName.STYLE, heads[i]);
      var numStyles = styles.length;
      for (var j = 0; j < numStyles; ++j) {
        stylesHtmlArr.push(styles[j].outerHTML);
      }
    }
    return stylesHtmlArr.join("") + html;
  }
  return html;
};
goog.editor.plugins.BasicTextFormatter.prototype.handleKeyboardShortcut = function(e, key, isModifierPressed) {
  if (!isModifierPressed) {
    return false;
  }
  var command;
  switch(key) {
    case "b":
      command = goog.editor.plugins.BasicTextFormatter.COMMAND.BOLD;
      break;
    case "i":
      command = goog.editor.plugins.BasicTextFormatter.COMMAND.ITALIC;
      break;
    case "u":
      command = goog.editor.plugins.BasicTextFormatter.COMMAND.UNDERLINE;
      break;
    case "s":
      return true;
  }
  if (command) {
    this.getFieldObject().execCommand(command);
    return true;
  }
  return false;
};
goog.editor.plugins.BasicTextFormatter.BR_REGEXP_ = goog.userAgent.IE ? /<br([^\/>]*)\/?>/gi : /<br([^\/>]*)\/?>(?!<\/(div|p)>)/gi;
goog.editor.plugins.BasicTextFormatter.prototype.convertBreaksToDivs_ = function() {
  if (!goog.userAgent.IE && !goog.userAgent.OPERA) {
    return false;
  }
  var range = this.getRange_();
  var parent = range.getContainerElement();
  var doc = this.getDocument_();
  var dom = this.getFieldDomHelper();
  goog.editor.plugins.BasicTextFormatter.BR_REGEXP_.lastIndex = 0;
  if (goog.editor.plugins.BasicTextFormatter.BR_REGEXP_.test(parent.innerHTML)) {
    var savedRange = range.saveUsingCarets();
    if (parent.tagName == goog.dom.TagName.P) {
      goog.editor.plugins.BasicTextFormatter.convertParagraphToDiv_(parent, true);
    } else {
      var attribute = "trtempbr";
      var value = "temp_br";
      var newHtml = parent.innerHTML.replace(goog.editor.plugins.BasicTextFormatter.BR_REGEXP_, "<p$1 " + attribute + '="' + value + '">');
      goog.editor.node.replaceInnerHtml(parent, newHtml);
      var paragraphs = goog.array.toArray(goog.dom.getElementsByTagName(goog.dom.TagName.P, parent));
      goog.iter.forEach(paragraphs, function(paragraph) {
        if (paragraph.getAttribute(attribute) == value) {
          paragraph.removeAttribute(attribute);
          if (goog.string.isBreakingWhitespace(goog.dom.getTextContent(paragraph))) {
            var child = goog.userAgent.IE ? doc.createTextNode(goog.string.Unicode.NBSP) : dom.createElement(goog.dom.TagName.BR);
            paragraph.appendChild(child);
          }
          goog.editor.plugins.BasicTextFormatter.convertParagraphToDiv_(paragraph);
        }
      });
    }
    savedRange.restore();
    return true;
  }
  return false;
};
goog.editor.plugins.BasicTextFormatter.convertParagraphToDiv_ = function(paragraph, opt_convertBrs) {
  if (!goog.userAgent.IE && !goog.userAgent.OPERA) {
    return;
  }
  var outerHTML = paragraph.outerHTML.replace(/<(\/?)p/gi, "<$1div");
  if (opt_convertBrs) {
    outerHTML = outerHTML.replace(goog.editor.plugins.BasicTextFormatter.BR_REGEXP_, "</div><div$1>");
  }
  if (goog.userAgent.OPERA && !/<\/div>$/i.test(outerHTML)) {
    outerHTML += "</div>";
  }
  paragraph.outerHTML = outerHTML;
};
goog.editor.plugins.BasicTextFormatter.convertToRealExecCommand_ = function(command) {
  return command.indexOf("+") == 0 ? command.substring(1) : command;
};
goog.editor.plugins.BasicTextFormatter.prototype.justify_ = function(command) {
  this.execCommandHelper_(command, null, false, true);
  if (goog.userAgent.GECKO) {
    this.execCommandHelper_(command, null, false, true);
  }
  if (!(goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS && goog.userAgent.GECKO)) {
    goog.iter.forEach(this.getFieldObject().getRange(), goog.editor.plugins.BasicTextFormatter.convertContainerToTextAlign_);
  }
};
goog.editor.plugins.BasicTextFormatter.convertContainerToTextAlign_ = function(node) {
  var container = goog.editor.style.getContainer(node);
  if (container.align) {
    container.style.textAlign = container.align;
    container.removeAttribute("align");
  }
};
goog.editor.plugins.BasicTextFormatter.prototype.execCommandHelper_ = function(command, opt_value, opt_preserveDir, opt_styleWithCss) {
  var dir = null;
  if (opt_preserveDir) {
    dir = this.getFieldObject().queryCommandValue(goog.editor.Command.DIR_RTL) ? "rtl" : this.getFieldObject().queryCommandValue(goog.editor.Command.DIR_LTR) ? "ltr" : null;
  }
  command = goog.editor.plugins.BasicTextFormatter.convertToRealExecCommand_(command);
  var endDiv, nbsp;
  if (goog.userAgent.IE) {
    var ret = this.applyExecCommandIEFixes_(command);
    endDiv = ret[0];
    nbsp = ret[1];
  }
  if (goog.userAgent.WEBKIT) {
    endDiv = this.applyExecCommandSafariFixes_(command);
  }
  if (goog.userAgent.GECKO) {
    this.applyExecCommandGeckoFixes_(command);
  }
  if (goog.editor.BrowserFeature.DOESNT_OVERRIDE_FONT_SIZE_IN_STYLE_ATTR && command.toLowerCase() == "fontsize") {
    this.removeFontSizeFromStyleAttrs_();
  }
  var doc = this.getDocument_();
  if (opt_styleWithCss && goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS) {
    doc.execCommand("styleWithCSS", false, true);
    if (goog.userAgent.OPERA) {
      this.invalidateInlineCss_();
    }
  }
  doc.execCommand(command, false, opt_value);
  if (opt_styleWithCss && goog.editor.BrowserFeature.HAS_STYLE_WITH_CSS) {
    doc.execCommand("styleWithCSS", false, false);
  }
  if (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("526") && command.toLowerCase() == "formatblock" && opt_value && /^[<]?h\d[>]?$/i.test(opt_value)) {
    this.cleanUpSafariHeadings_();
  }
  if (/insert(un)?orderedlist/i.test(command)) {
    if (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher(534)) {
      this.fixSafariLists_();
    }
    if (goog.userAgent.IE) {
      this.fixIELists_();
      if (nbsp) {
        goog.dom.removeNode(nbsp);
      }
    }
  }
  if (endDiv) {
    goog.dom.removeNode(endDiv);
  }
  if (dir) {
    this.getFieldObject().execCommand(dir);
  }
};
goog.editor.plugins.BasicTextFormatter.prototype.applyBgColorManually_ = function(bgColor) {
  var needsSpaceInTextNode = goog.userAgent.GECKO;
  var range = this.getFieldObject().getRange();
  var textNode;
  var parentTag;
  if (range && range.isCollapsed()) {
    textNode = this.getFieldDomHelper().createTextNode(needsSpaceInTextNode ? " " : "");
    var containerNode = range.getStartNode();
    parentTag = containerNode.nodeType == goog.dom.NodeType.ELEMENT ? containerNode : containerNode.parentNode;
    if (parentTag.innerHTML == "") {
      parentTag.style.textIndent = "-10000px";
      parentTag.appendChild(textNode);
    } else {
      parentTag = this.getFieldDomHelper().createDom(goog.dom.TagName.SPAN, {"style":"text-indent:-10000px"}, textNode);
      range.replaceContentsWithNode(parentTag);
    }
    goog.dom.Range.createFromNodeContents(textNode).select();
  }
  this.execCommandHelper_("hiliteColor", bgColor, false, true);
  if (textNode) {
    if (needsSpaceInTextNode) {
      textNode.data = "";
    }
    parentTag.style.textIndent = "";
  }
};
goog.editor.plugins.BasicTextFormatter.prototype.toggleLink_ = function(opt_target) {
  if (!this.getFieldObject().isSelectionEditable()) {
    this.focusField_();
  }
  var range = this.getRange_();
  var parent = range && range.getContainerElement();
  var link = goog.dom.getAncestorByTagNameAndClass(parent, goog.dom.TagName.A);
  if (link && goog.editor.node.isEditable(link)) {
    goog.dom.flattenElement(link);
  } else {
    var editableLink = this.createLink_(range, "/", opt_target);
    if (editableLink) {
      if (!this.getFieldObject().execCommand(goog.editor.Command.MODAL_LINK_EDITOR, editableLink)) {
        var url = this.getFieldObject().getAppWindow().prompt(goog.ui.editor.messages.MSG_LINK_TO, "http://");
        if (url) {
          editableLink.setTextAndUrl(editableLink.getCurrentText() || url, url);
          editableLink.placeCursorRightOf();
        } else {
          var savedRange = goog.editor.range.saveUsingNormalizedCarets(goog.dom.Range.createFromNodeContents(editableLink.getAnchor()));
          editableLink.removeLink();
          savedRange.restore().select();
          return null;
        }
      }
      return editableLink;
    }
  }
  return null;
};
goog.editor.plugins.BasicTextFormatter.prototype.createLink_ = function(range, url, opt_target) {
  var anchor = null;
  var anchors = [];
  var parent = range && range.getContainerElement();
  if (parent && parent.tagName == goog.dom.TagName.IMG) {
    return null;
  }
  if (!range) {
    return null;
  }
  if (range.isCollapsed()) {
    var textRange = range.getTextRange(0).getBrowserRangeObject();
    if (goog.editor.BrowserFeature.HAS_W3C_RANGES) {
      anchor = this.getFieldDomHelper().createElement(goog.dom.TagName.A);
      textRange.insertNode(anchor);
    } else {
      if (goog.editor.BrowserFeature.HAS_IE_RANGES) {
        textRange.pasteHTML("<a id='newLink'></a>");
        anchor = this.getFieldDomHelper().getElement("newLink");
        anchor.removeAttribute("id");
      }
    }
  } else {
    var uniqueId = goog.string.createUniqueString();
    this.execCommandHelper_("CreateLink", uniqueId);
    var setHrefAndLink = function(element, index, arr) {
      if (goog.string.endsWith(element.href, uniqueId)) {
        anchors.push(element);
      }
    };
    goog.array.forEach(goog.dom.getElementsByTagName(goog.dom.TagName.A, this.getFieldObject().getElement()), setHrefAndLink);
    if (anchors.length) {
      anchor = anchors.pop();
    }
    var isLikelyUrl = function(a, i, anchors) {
      return goog.editor.Link.isLikelyUrl(goog.dom.getRawTextContent(a));
    };
    if (anchors.length && goog.array.every(anchors, isLikelyUrl)) {
      for (var i = 0, a; a = anchors[i]; i++) {
        goog.editor.Link.createNewLinkFromText(a, opt_target);
      }
      anchors = null;
    }
  }
  return goog.editor.Link.createNewLink(anchor, url, opt_target, anchors);
};
goog.editor.plugins.BasicTextFormatter.brokenExecCommandsIE_ = {"indent":1, "outdent":1, "insertOrderedList":1, "insertUnorderedList":1, "justifyCenter":1, "justifyFull":1, "justifyRight":1, "justifyLeft":1, "ltr":1, "rtl":1};
goog.editor.plugins.BasicTextFormatter.blockquoteHatingCommandsIE_ = {"insertOrderedList":1, "insertUnorderedList":1};
goog.editor.plugins.BasicTextFormatter.prototype.applySubscriptSuperscriptWorkarounds_ = function(command) {
  if (!this.queryCommandValue(command)) {
    var oppositeCommand = command == goog.editor.plugins.BasicTextFormatter.COMMAND.SUBSCRIPT ? goog.editor.plugins.BasicTextFormatter.COMMAND.SUPERSCRIPT : goog.editor.plugins.BasicTextFormatter.COMMAND.SUBSCRIPT;
    var oppositeExecCommand = goog.editor.plugins.BasicTextFormatter.convertToRealExecCommand_(oppositeCommand);
    if (!this.queryCommandValue(oppositeCommand)) {
      this.getDocument_().execCommand(oppositeExecCommand, false, null);
    }
    this.getDocument_().execCommand(oppositeExecCommand, false, null);
  }
};
goog.editor.plugins.BasicTextFormatter.prototype.removeFontSizeFromStyleAttrs_ = function() {
  var range = goog.editor.range.expand(this.getFieldObject().getRange(), this.getFieldObject().getElement());
  goog.iter.forEach(goog.iter.filter(range, function(tag, dummy, iter) {
    return iter.isStartTag() && range.containsNode(tag);
  }), function(node) {
    goog.style.setStyle(node, "font-size", "");
    if (goog.userAgent.GECKO && node.style.length == 0 && node.getAttribute("style") != null) {
      node.removeAttribute("style");
    }
  });
};
goog.editor.plugins.BasicTextFormatter.prototype.applyExecCommandIEFixes_ = function(command) {
  var toRemove = [];
  var endDiv = null;
  var range = this.getRange_();
  var dh = this.getFieldDomHelper();
  if (command in goog.editor.plugins.BasicTextFormatter.blockquoteHatingCommandsIE_) {
    var parent = range && range.getContainerElement();
    if (parent) {
      var blockquotes = goog.dom.getElementsByTagNameAndClass(goog.dom.TagName.BLOCKQUOTE, null, parent);
      var bq;
      for (var i = 0; i < blockquotes.length; i++) {
        if (range.containsNode(blockquotes[i])) {
          bq = blockquotes[i];
          break;
        }
      }
      var bqThatNeedsDummyDiv = bq || goog.dom.getAncestorByTagNameAndClass(parent, goog.dom.TagName.BLOCKQUOTE);
      if (bqThatNeedsDummyDiv) {
        endDiv = dh.createDom(goog.dom.TagName.DIV, {style:"height:0"});
        goog.dom.appendChild(bqThatNeedsDummyDiv, endDiv);
        toRemove.push(endDiv);
        if (bq) {
          range = goog.dom.Range.createFromNodes(bq, 0, endDiv, 0);
        } else {
          if (range.containsNode(endDiv)) {
            range = goog.dom.Range.createFromNodes(range.getStartNode(), range.getStartOffset(), endDiv, 0);
          }
        }
        range.select();
      }
    }
  }
  var fieldObject = this.getFieldObject();
  if (!fieldObject.usesIframe() && !endDiv) {
    if (command in goog.editor.plugins.BasicTextFormatter.brokenExecCommandsIE_) {
      var field = fieldObject.getElement();
      if (range && range.isCollapsed() && !goog.dom.getFirstElementChild(field)) {
        var selection = range.getTextRange(0).getBrowserRangeObject();
        var testRange = selection.duplicate();
        testRange.moveToElementText(field);
        testRange.collapse(false);
        if (testRange.isEqual(selection)) {
          var nbsp = dh.createTextNode(goog.string.Unicode.NBSP);
          field.appendChild(nbsp);
          selection.move("character", 1);
          selection.move("character", -1);
          selection.select();
          toRemove.push(nbsp);
        }
      }
      endDiv = dh.createDom(goog.dom.TagName.DIV, {style:"height:0"});
      goog.dom.appendChild(field, endDiv);
      toRemove.push(endDiv);
    }
  }
  return toRemove;
};
goog.editor.plugins.BasicTextFormatter.prototype.cleanUpSafariHeadings_ = function() {
  goog.iter.forEach(this.getRange_(), function(node) {
    if (node.className == "Apple-style-span") {
      node.style.fontSize = "";
      node.style.fontWeight = "";
    }
  });
};
goog.editor.plugins.BasicTextFormatter.prototype.fixSafariLists_ = function() {
  var previousList = false;
  goog.iter.forEach(this.getRange_(), function(node) {
    var tagName = node.tagName;
    if (tagName == goog.dom.TagName.UL || tagName == goog.dom.TagName.OL) {
      if (!previousList) {
        previousList = true;
        return;
      }
      var previousElementSibling = goog.dom.getPreviousElementSibling(node);
      if (!previousElementSibling) {
        return;
      }
      var range = node.ownerDocument.createRange();
      range.setStartAfter(previousElementSibling);
      range.setEndBefore(node);
      if (!goog.string.isEmptyOrWhitespace(range.toString())) {
        return;
      }
      if (previousElementSibling.nodeName == node.nodeName) {
        while (previousElementSibling.lastChild) {
          node.insertBefore(previousElementSibling.lastChild, node.firstChild);
        }
        previousElementSibling.parentNode.removeChild(previousElementSibling);
      }
    }
  });
};
goog.editor.plugins.BasicTextFormatter.orderedListTypes_ = {1:1, "a":1, "A":1, "i":1, "I":1};
goog.editor.plugins.BasicTextFormatter.unorderedListTypes_ = {"disc":1, "circle":1, "square":1};
goog.editor.plugins.BasicTextFormatter.prototype.fixIELists_ = function() {
  var range = this.getRange_();
  var container = range && range.getContainer();
  while (container && container.tagName != goog.dom.TagName.UL && container.tagName != goog.dom.TagName.OL) {
    container = container.parentNode;
  }
  if (container) {
    container = container.parentNode;
  }
  if (!container) {
    return;
  }
  var lists = goog.array.toArray(goog.dom.getElementsByTagName(goog.dom.TagName.UL, container));
  goog.array.extend(lists, goog.array.toArray(goog.dom.getElementsByTagName(goog.dom.TagName.OL, container)));
  goog.array.forEach(lists, function(node) {
    var type = node.type;
    if (type) {
      var saneTypes = node.tagName == goog.dom.TagName.UL ? goog.editor.plugins.BasicTextFormatter.unorderedListTypes_ : goog.editor.plugins.BasicTextFormatter.orderedListTypes_;
      if (!saneTypes[type]) {
        node.type = "";
      }
    }
  });
};
goog.editor.plugins.BasicTextFormatter.brokenExecCommandsSafari_ = {"justifyCenter":1, "justifyFull":1, "justifyRight":1, "justifyLeft":1, "formatBlock":1};
goog.editor.plugins.BasicTextFormatter.hangingExecCommandWebkit_ = {"insertOrderedList":1, "insertUnorderedList":1};
goog.editor.plugins.BasicTextFormatter.prototype.applyExecCommandSafariFixes_ = function(command) {
  var div;
  if (goog.editor.plugins.BasicTextFormatter.brokenExecCommandsSafari_[command]) {
    div = this.getFieldDomHelper().createDom(goog.dom.TagName.DIV, {"style":"height: 0"}, "x");
    goog.dom.appendChild(this.getFieldObject().getElement(), div);
  }
  if (!goog.userAgent.isVersionOrHigher(534) && goog.editor.plugins.BasicTextFormatter.hangingExecCommandWebkit_[command]) {
    var field = this.getFieldObject().getElement();
    div = this.getFieldDomHelper().createDom(goog.dom.TagName.DIV, {"style":"height: 0"}, "x");
    field.insertBefore(div, field.firstChild);
  }
  return div;
};
goog.editor.plugins.BasicTextFormatter.prototype.applyExecCommandGeckoFixes_ = function(command) {
  if (goog.userAgent.isVersionOrHigher("1.9") && command.toLowerCase() == "formatblock") {
    var range = this.getRange_();
    var startNode = range.getStartNode();
    if (range.isCollapsed() && startNode && startNode.tagName == goog.dom.TagName.BODY) {
      var startOffset = range.getStartOffset();
      var childNode = startNode.childNodes[startOffset];
      if (childNode && childNode.tagName == goog.dom.TagName.BR) {
        var browserRange = range.getBrowserRangeObject();
        browserRange.setStart(childNode, 0);
        browserRange.setEnd(childNode, 0);
      }
    }
  }
};
goog.editor.plugins.BasicTextFormatter.prototype.invalidateInlineCss_ = function() {
  var ancestors = [];
  var ancestor = this.getFieldObject().getRange().getContainerElement();
  do {
    ancestors.push(ancestor);
  } while (ancestor = ancestor.parentNode);
  var nodesInSelection = goog.iter.chain(goog.iter.toIterator(this.getFieldObject().getRange()), goog.iter.toIterator(ancestors));
  var containersInSelection = goog.iter.filter(nodesInSelection, goog.editor.style.isContainer);
  goog.iter.forEach(containersInSelection, function(element) {
    var oldOutline = element.style.outline;
    element.style.outline = "0px solid red";
    element.style.outline = oldOutline;
  });
};
goog.editor.plugins.BasicTextFormatter.prototype.beforeInsertListGecko_ = function() {
  var tag = this.getFieldObject().queryCommandValue(goog.editor.Command.DEFAULT_TAG);
  if (tag == goog.dom.TagName.P || tag == goog.dom.TagName.DIV) {
    return false;
  }
  var range = this.getRange_();
  if (range.isCollapsed() && range.getContainer().nodeType != goog.dom.NodeType.TEXT) {
    var tempTextNode = this.getFieldDomHelper().createTextNode(goog.string.Unicode.NBSP);
    range.insertNode(tempTextNode, false);
    goog.dom.Range.createFromNodeContents(tempTextNode).select();
    return true;
  }
  return false;
};
goog.editor.plugins.BasicTextFormatter.getSelectionBlockState_ = function(range) {
  var tagName = null;
  goog.iter.forEach(range, function(node, ignore, it) {
    if (!it.isEndTag()) {
      var container = goog.editor.style.getContainer(node);
      var thisTagName = container.tagName;
      tagName = tagName || thisTagName;
      if (tagName != thisTagName) {
        tagName = null;
        throw goog.iter.StopIteration;
      }
      it.skipTag();
    }
  });
  return tagName;
};
goog.editor.plugins.BasicTextFormatter.SUPPORTED_JUSTIFICATIONS_ = {"center":1, "justify":1, "right":1, "left":1};
goog.editor.plugins.BasicTextFormatter.prototype.isJustification_ = function(command) {
  var alignment = command.replace("+justify", "").toLowerCase();
  if (alignment == "full") {
    alignment = "justify";
  }
  var bidiPlugin = this.getFieldObject().getPluginByClassId("Bidi");
  if (bidiPlugin) {
    bidiPlugin.getSelectionAlignment;
    return alignment == bidiPlugin.getSelectionAlignment();
  } else {
    var range = this.getRange_();
    if (!range) {
      return false;
    }
    var parent = range.getContainerElement();
    var nodes = goog.array.filter(parent.childNodes, function(node) {
      return goog.editor.node.isImportant(node) && range.containsNode(node, true);
    });
    nodes = nodes.length ? nodes : [parent];
    for (var i = 0; i < nodes.length; i++) {
      var current = nodes[i];
      var container = goog.editor.style.getContainer(current);
      if (alignment != goog.editor.plugins.BasicTextFormatter.getNodeJustification_(container)) {
        return false;
      }
    }
    return true;
  }
};
goog.editor.plugins.BasicTextFormatter.getNodeJustification_ = function(element) {
  var value = goog.style.getComputedTextAlign(element);
  value = value.replace(/^-(moz|webkit)-/, "");
  if (!goog.editor.plugins.BasicTextFormatter.SUPPORTED_JUSTIFICATIONS_[value]) {
    value = element.align || "left";
  }
  return value;
};
goog.editor.plugins.BasicTextFormatter.prototype.isNodeInState_ = function(nodeName) {
  var range = this.getRange_();
  var node = range && range.getContainerElement();
  var ancestor = goog.dom.getAncestorByTagNameAndClass(node, nodeName);
  return !!ancestor && goog.editor.node.isEditable(ancestor);
};
goog.editor.plugins.BasicTextFormatter.prototype.queryCommandStateInternal_ = function(queryObject, command, opt_styleWithCss) {
  return this.queryCommandHelper_(true, queryObject, command, opt_styleWithCss);
};
goog.editor.plugins.BasicTextFormatter.prototype.queryCommandValueInternal_ = function(queryObject, command, opt_styleWithCss) {
  return this.queryCommandHelper_(false, queryObject, command, opt_styleWithCss);
};
goog.editor.plugins.BasicTextFormatter.prototype.queryCommandHelper_ = function(isGetQueryCommandState, queryObject, command, opt_styleWithCss) {
  command = goog.editor.plugins.BasicTextFormatter.convertToRealExecCommand_(command);
  if (opt_styleWithCss) {
    var doc = this.getDocument_();
    doc.execCommand("styleWithCSS", false, true);
  }
  var ret = isGetQueryCommandState ? queryObject.queryCommandState(command) : queryObject.queryCommandValue(command);
  if (opt_styleWithCss) {
    doc.execCommand("styleWithCSS", false, false);
  }
  return ret;
};
goog.provide("goog.dom.NodeOffset");
goog.require("goog.Disposable");
goog.require("goog.dom.TagName");
goog.dom.NodeOffset = function(node, baseNode) {
  goog.Disposable.call(this);
  this.offsetStack_ = [];
  this.nameStack_ = [];
  while (node && node.nodeName != goog.dom.TagName.BODY && node != baseNode) {
    var siblingOffset = 0;
    var sib = node.previousSibling;
    while (sib) {
      sib = sib.previousSibling;
      ++siblingOffset;
    }
    this.offsetStack_.unshift(siblingOffset);
    this.nameStack_.unshift(node.nodeName);
    node = node.parentNode;
  }
};
goog.inherits(goog.dom.NodeOffset, goog.Disposable);
goog.dom.NodeOffset.prototype.toString = function() {
  var strs = [];
  var name;
  for (var i = 0; name = this.nameStack_[i]; i++) {
    strs.push(this.offsetStack_[i] + "," + name);
  }
  return strs.join("\n");
};
goog.dom.NodeOffset.prototype.findTargetNode = function(baseNode) {
  var name;
  var curNode = baseNode;
  for (var i = 0; name = this.nameStack_[i]; ++i) {
    curNode = curNode.childNodes[this.offsetStack_[i]];
    if (!curNode || curNode.nodeName != name) {
      return null;
    }
  }
  return curNode;
};
goog.dom.NodeOffset.prototype.disposeInternal = function() {
  delete this.offsetStack_;
  delete this.nameStack_;
};
goog.provide("goog.editor.plugins.Blockquote");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagName");
goog.require("goog.dom.classlist");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Command");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.node");
goog.require("goog.functions");
goog.require("goog.log");
goog.editor.plugins.Blockquote = function(requiresClassNameToSplit, opt_className) {
  goog.editor.Plugin.call(this);
  this.requiresClassNameToSplit_ = requiresClassNameToSplit;
  this.className_ = opt_className || goog.getCssName("tr_bq");
};
goog.inherits(goog.editor.plugins.Blockquote, goog.editor.Plugin);
goog.editor.plugins.Blockquote.SPLIT_COMMAND = "+splitBlockquote";
goog.editor.plugins.Blockquote.CLASS_ID = "Blockquote";
goog.editor.plugins.Blockquote.prototype.logger = goog.log.getLogger("goog.editor.plugins.Blockquote");
goog.editor.plugins.Blockquote.prototype.getTrogClassId = function() {
  return goog.editor.plugins.Blockquote.CLASS_ID;
};
goog.editor.plugins.Blockquote.prototype.isSilentCommand = goog.functions.TRUE;
goog.editor.plugins.Blockquote.prototype.isSplittableBlockquote = function(node) {
  if (node.tagName != goog.dom.TagName.BLOCKQUOTE) {
    return false;
  }
  if (!this.requiresClassNameToSplit_) {
    return true;
  }
  return goog.dom.classlist.contains(node, this.className_);
};
goog.editor.plugins.Blockquote.prototype.isSetupBlockquote = function(node) {
  return node.tagName == goog.dom.TagName.BLOCKQUOTE && goog.dom.classlist.contains(node, this.className_);
};
goog.editor.plugins.Blockquote.prototype.isUnsetupBlockquote = function(node) {
  return node.tagName == goog.dom.TagName.BLOCKQUOTE && !this.isSetupBlockquote(node);
};
goog.editor.plugins.Blockquote.prototype.getBlockquoteClassName = function() {
  return this.className_;
};
goog.editor.plugins.Blockquote.findAndRemoveSingleChildAncestor_ = function(node, root) {
  var predicateFunc = function(parentNode) {
    return parentNode != root && parentNode.childNodes.length == 1;
  };
  var ancestor = goog.editor.node.findHighestMatchingAncestor(node, predicateFunc);
  if (!ancestor) {
    ancestor = node;
  }
  goog.dom.removeNode(ancestor);
};
goog.editor.plugins.Blockquote.removeAllWhiteSpaceNodes_ = function(nodes) {
  for (var i = 0; i < nodes.length; ++i) {
    if (goog.editor.node.isEmpty(nodes[i], true)) {
      goog.dom.removeNode(nodes[i]);
    }
  }
};
goog.editor.plugins.Blockquote.prototype.isSupportedCommand = function(command) {
  return command == goog.editor.plugins.Blockquote.SPLIT_COMMAND;
};
goog.editor.plugins.Blockquote.prototype.execCommandInternal = function(command, var_args) {
  var pos = arguments[1];
  if (command == goog.editor.plugins.Blockquote.SPLIT_COMMAND && pos && (this.className_ || !this.requiresClassNameToSplit_)) {
    return goog.editor.BrowserFeature.HAS_W3C_RANGES ? this.splitQuotedBlockW3C_(pos) : this.splitQuotedBlockIE_(pos);
  }
};
goog.editor.plugins.Blockquote.prototype.splitQuotedBlockW3C_ = function(anchorPos) {
  var cursorNode = anchorPos.node;
  var quoteNode = goog.editor.node.findTopMostEditableAncestor(cursorNode.parentNode, goog.bind(this.isSplittableBlockquote, this));
  var secondHalf, textNodeToRemove;
  var insertTextNode = false;
  if (quoteNode) {
    if (cursorNode.nodeType == goog.dom.NodeType.TEXT) {
      if (anchorPos.offset == cursorNode.length) {
        var siblingNode = cursorNode.nextSibling;
        if (siblingNode && siblingNode.tagName == goog.dom.TagName.BR) {
          cursorNode = siblingNode;
          secondHalf = siblingNode.nextSibling;
        } else {
          textNodeToRemove = cursorNode.splitText(anchorPos.offset);
          secondHalf = textNodeToRemove;
        }
      } else {
        secondHalf = cursorNode.splitText(anchorPos.offset);
      }
    } else {
      if (cursorNode.tagName == goog.dom.TagName.BR) {
        secondHalf = cursorNode.nextSibling;
      } else {
        insertTextNode = true;
      }
    }
  } else {
    if (this.isSetupBlockquote(cursorNode)) {
      quoteNode = cursorNode;
      insertTextNode = true;
    }
  }
  if (insertTextNode) {
    cursorNode = this.insertEmptyTextNodeBeforeRange_();
    secondHalf = this.insertEmptyTextNodeBeforeRange_();
  }
  if (!quoteNode) {
    return false;
  }
  secondHalf = goog.editor.node.splitDomTreeAt(cursorNode, secondHalf, quoteNode);
  goog.dom.insertSiblingAfter(secondHalf, quoteNode);
  var dh = this.getFieldDomHelper();
  var tagToInsert = this.getFieldObject().queryCommandValue(goog.editor.Command.DEFAULT_TAG) || goog.dom.TagName.DIV;
  var container = dh.createElement(tagToInsert);
  container.innerHTML = "&nbsp;";
  quoteNode.parentNode.insertBefore(container, secondHalf);
  dh.getWindow().getSelection().collapse(container, 0);
  if (textNodeToRemove) {
    goog.editor.plugins.Blockquote.findAndRemoveSingleChildAncestor_(textNodeToRemove, secondHalf);
  }
  goog.editor.plugins.Blockquote.removeAllWhiteSpaceNodes_([quoteNode, secondHalf]);
  return true;
};
goog.editor.plugins.Blockquote.prototype.insertEmptyTextNodeBeforeRange_ = function() {
  var range = this.getFieldObject().getRange();
  var node = this.getFieldDomHelper().createTextNode("");
  range.insertNode(node, true);
  return node;
};
goog.editor.plugins.Blockquote.prototype.splitQuotedBlockIE_ = function(splitNode) {
  var dh = this.getFieldDomHelper();
  var quoteNode = goog.editor.node.findTopMostEditableAncestor(splitNode.parentNode, goog.bind(this.isSplittableBlockquote, this));
  if (!quoteNode) {
    return false;
  }
  var clone = splitNode.cloneNode(false);
  if (splitNode.nextSibling && splitNode.nextSibling.tagName == goog.dom.TagName.BR) {
    splitNode = splitNode.nextSibling;
  }
  var secondHalf = goog.editor.node.splitDomTreeAt(splitNode, clone, quoteNode);
  goog.dom.insertSiblingAfter(secondHalf, quoteNode);
  var tagToInsert = this.getFieldObject().queryCommandValue(goog.editor.Command.DEFAULT_TAG) || goog.dom.TagName.DIV;
  var div = dh.createElement(tagToInsert);
  quoteNode.parentNode.insertBefore(div, secondHalf);
  div.innerHTML = "&nbsp;";
  var range = dh.getDocument().selection.createRange();
  range.moveToElementText(splitNode);
  range.move("character", 2);
  range.select();
  goog.dom.removeChildren(div);
  range.pasteHTML("");
  goog.editor.plugins.Blockquote.findAndRemoveSingleChildAncestor_(clone, secondHalf);
  goog.editor.plugins.Blockquote.removeAllWhiteSpaceNodes_([quoteNode, secondHalf]);
  return true;
};
goog.provide("goog.editor.plugins.EnterHandler");
goog.require("goog.dom");
goog.require("goog.dom.NodeOffset");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.Range");
goog.require("goog.dom.TagName");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.node");
goog.require("goog.editor.plugins.Blockquote");
goog.require("goog.editor.range");
goog.require("goog.editor.style");
goog.require("goog.events.KeyCodes");
goog.require("goog.functions");
goog.require("goog.object");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.editor.plugins.EnterHandler = function() {
  goog.editor.Plugin.call(this);
};
goog.inherits(goog.editor.plugins.EnterHandler, goog.editor.Plugin);
goog.editor.plugins.EnterHandler.prototype.tag = goog.dom.TagName.DIV;
goog.editor.plugins.EnterHandler.prototype.getTrogClassId = function() {
  return "EnterHandler";
};
goog.editor.plugins.EnterHandler.prototype.enable = function(fieldObject) {
  goog.editor.plugins.EnterHandler.base(this, "enable", fieldObject);
  if (goog.editor.BrowserFeature.SUPPORTS_OPERA_DEFAULTBLOCK_COMMAND && (this.tag == goog.dom.TagName.P || this.tag == goog.dom.TagName.DIV)) {
    var doc = this.getFieldDomHelper().getDocument();
    doc.execCommand("opera-defaultBlock", false, this.tag);
  }
};
goog.editor.plugins.EnterHandler.prototype.prepareContentsHtml = function(html) {
  if (!html || goog.string.isBreakingWhitespace(html)) {
    return goog.editor.BrowserFeature.COLLAPSES_EMPTY_NODES ? this.getNonCollapsingBlankHtml() : "";
  }
  return html;
};
goog.editor.plugins.EnterHandler.prototype.getNonCollapsingBlankHtml = goog.functions.constant("<br>");
goog.editor.plugins.EnterHandler.prototype.handleBackspaceInternal = function(e, range) {
  var field = this.getFieldObject().getElement();
  var container = range && range.getStartNode();
  if (field.firstChild == container && goog.editor.node.isEmpty(container)) {
    e.preventDefault();
    e.stopPropagation();
  }
};
goog.editor.plugins.EnterHandler.prototype.processParagraphTagsInternal = function(e, split) {
  if (goog.userAgent.IE || goog.userAgent.OPERA) {
    this.ensureBlockIeOpera(goog.dom.TagName.DIV);
  } else {
    if (!split && goog.userAgent.WEBKIT) {
      var range = this.getFieldObject().getRange();
      if (!range || !goog.editor.plugins.EnterHandler.isDirectlyInBlockquote(range.getContainerElement())) {
        return;
      }
      var dh = this.getFieldDomHelper();
      var br = dh.createElement(goog.dom.TagName.BR);
      range.insertNode(br, true);
      if (goog.editor.node.isBlockTag(br.parentNode) && !goog.editor.node.skipEmptyTextNodes(br.nextSibling)) {
        goog.dom.insertSiblingBefore(dh.createElement(goog.dom.TagName.BR), br);
      }
      goog.editor.range.placeCursorNextTo(br, false);
      e.preventDefault();
    }
  }
};
goog.editor.plugins.EnterHandler.isDirectlyInBlockquote = function(n) {
  for (var current = n; current; current = current.parentNode) {
    if (goog.editor.node.isBlockTag(current)) {
      return current.tagName == goog.dom.TagName.BLOCKQUOTE;
    }
  }
  return false;
};
goog.editor.plugins.EnterHandler.prototype.handleDeleteGecko = function(e) {
  this.deleteBrGecko(e);
};
goog.editor.plugins.EnterHandler.prototype.deleteBrGecko = function(e) {
  var range = this.getFieldObject().getRange();
  if (range.isCollapsed()) {
    var container = range.getEndNode();
    if (container.nodeType == goog.dom.NodeType.ELEMENT) {
      var nextNode = container.childNodes[range.getEndOffset()];
      if (nextNode && nextNode.tagName == goog.dom.TagName.BR) {
        var previousSibling = goog.editor.node.getPreviousSibling(nextNode);
        var nextSibling = nextNode.nextSibling;
        container.removeChild(nextNode);
        e.preventDefault();
        if (nextSibling && goog.editor.node.isBlockTag(nextSibling)) {
          if (previousSibling && !(previousSibling.tagName == goog.dom.TagName.BR || goog.editor.node.isBlockTag(previousSibling))) {
            goog.dom.Range.createCaret(previousSibling, goog.editor.node.getLength(previousSibling)).select();
          } else {
            var leftMostLeaf = goog.editor.node.getLeftMostLeaf(nextSibling);
            goog.dom.Range.createCaret(leftMostLeaf, 0).select();
          }
        }
      }
    }
  }
};
goog.editor.plugins.EnterHandler.prototype.handleKeyPress = function(e) {
  if (goog.userAgent.GECKO && this.getFieldObject().inModalMode()) {
    return false;
  }
  if (e.keyCode == goog.events.KeyCodes.BACKSPACE) {
    this.handleBackspaceInternal(e, this.getFieldObject().getRange());
  } else {
    if (e.keyCode == goog.events.KeyCodes.ENTER) {
      if (goog.userAgent.GECKO) {
        if (!e.shiftKey) {
          this.handleEnterGecko_(e);
        }
      } else {
        this.getFieldObject().dispatchBeforeChange();
        var cursorPosition = this.deleteCursorSelection_();
        var split = !!this.getFieldObject().execCommand(goog.editor.plugins.Blockquote.SPLIT_COMMAND, cursorPosition);
        if (split) {
          e.preventDefault();
          e.stopPropagation();
        }
        this.releasePositionObject_(cursorPosition);
        if (goog.userAgent.WEBKIT) {
          this.handleEnterWebkitInternal(e);
        }
        this.processParagraphTagsInternal(e, split);
        this.getFieldObject().dispatchChange();
      }
    } else {
      if (goog.userAgent.GECKO && e.keyCode == goog.events.KeyCodes.DELETE) {
        this.handleDeleteGecko(e);
      }
    }
  }
  return false;
};
goog.editor.plugins.EnterHandler.prototype.handleKeyUp = function(e) {
  if (goog.userAgent.GECKO && this.getFieldObject().inModalMode()) {
    return false;
  }
  this.handleKeyUpInternal(e);
  return false;
};
goog.editor.plugins.EnterHandler.prototype.handleKeyUpInternal = function(e) {
  if ((goog.userAgent.IE || goog.userAgent.OPERA) && e.keyCode == goog.events.KeyCodes.ENTER) {
    this.ensureBlockIeOpera(goog.dom.TagName.DIV, true);
  }
};
goog.editor.plugins.EnterHandler.prototype.handleEnterGecko_ = function(e) {
  var range = this.getFieldObject().getRange();
  var wasCollapsed = !range || range.isCollapsed();
  var cursorPosition = this.deleteCursorSelection_();
  var handled = this.getFieldObject().execCommand(goog.editor.plugins.Blockquote.SPLIT_COMMAND, cursorPosition);
  if (handled) {
    e.preventDefault();
    e.stopPropagation();
  }
  this.releasePositionObject_(cursorPosition);
  if (!handled) {
    this.handleEnterAtCursorGeckoInternal(e, wasCollapsed, range);
  }
};
goog.editor.plugins.EnterHandler.prototype.handleEnterWebkitInternal = goog.nullFunction;
goog.editor.plugins.EnterHandler.prototype.handleEnterAtCursorGeckoInternal = goog.nullFunction;
goog.editor.plugins.EnterHandler.DO_NOT_ENSURE_BLOCK_NODES_ = goog.object.createSet(goog.dom.TagName.LI, goog.dom.TagName.DIV, goog.dom.TagName.H1, goog.dom.TagName.H2, goog.dom.TagName.H3, goog.dom.TagName.H4, goog.dom.TagName.H5, goog.dom.TagName.H6);
goog.editor.plugins.EnterHandler.isBrElem = function(node) {
  return goog.editor.node.isEmpty(node) && goog.dom.getElementsByTagName(goog.dom.TagName.BR, node).length == 1;
};
goog.editor.plugins.EnterHandler.prototype.ensureBlockIeOpera = function(tag, opt_keyUp) {
  var range = this.getFieldObject().getRange();
  var container = range.getContainer();
  var field = this.getFieldObject().getElement();
  var paragraph;
  while (container && container != field) {
    var nodeName = container.nodeName;
    if (nodeName == tag || goog.editor.plugins.EnterHandler.DO_NOT_ENSURE_BLOCK_NODES_[nodeName] && !(opt_keyUp && goog.editor.plugins.EnterHandler.isBrElem(container))) {
      if (goog.userAgent.OPERA && paragraph) {
        if (nodeName == tag && paragraph == container.lastChild && goog.editor.node.isEmpty(paragraph)) {
          goog.dom.insertSiblingAfter(paragraph, container);
          goog.dom.Range.createFromNodeContents(paragraph).select();
        }
        break;
      }
      return;
    }
    if (goog.userAgent.OPERA && opt_keyUp && nodeName == goog.dom.TagName.P && nodeName != tag) {
      paragraph = container;
    }
    container = container.parentNode;
  }
  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher(9)) {
    var needsHelp = false;
    range = range.getBrowserRangeObject();
    var range2 = range.duplicate();
    range2.moveEnd("character", 1);
    if (range2.text.length) {
      var parent2 = range2.parentElement();
      var range3 = range2.duplicate();
      range3.collapse(false);
      var parent3 = range3.parentElement();
      if (needsHelp = parent2 != parent3 && parent3 != range.parentElement()) {
        range.move("character", -1);
        range.select();
      }
    }
  }
  this.getFieldObject().getEditableDomHelper().getDocument().execCommand("FormatBlock", false, "<" + tag + ">");
  if (needsHelp) {
    range.move("character", 1);
    range.select();
  }
};
goog.editor.plugins.EnterHandler.prototype.deleteCursorSelection_ = function() {
  return goog.editor.BrowserFeature.HAS_W3C_RANGES ? this.deleteCursorSelectionW3C_() : this.deleteCursorSelectionIE_();
};
goog.editor.plugins.EnterHandler.prototype.releasePositionObject_ = function(position) {
  if (!goog.editor.BrowserFeature.HAS_W3C_RANGES) {
    position.removeNode(true);
  }
};
goog.editor.plugins.EnterHandler.prototype.deleteCursorSelectionIE_ = function() {
  var doc = this.getFieldDomHelper().getDocument();
  var range = doc.selection.createRange();
  var id = goog.string.createUniqueString();
  range.pasteHTML('<span id="' + id + '"></span>');
  var splitNode = doc.getElementById(id);
  splitNode.id = "";
  return splitNode;
};
goog.editor.plugins.EnterHandler.prototype.deleteCursorSelectionW3C_ = function() {
  var range = this.getFieldObject().getRange();
  if (range && !range.isCollapsed()) {
    var shouldDelete = true;
    if (goog.userAgent.OPERA) {
      var startNode = range.getStartNode();
      var startOffset = range.getStartOffset();
      if (startNode == range.getEndNode() && startNode.lastChild && startNode.lastChild.tagName == goog.dom.TagName.BR && startOffset == startNode.childNodes.length - 1) {
        shouldDelete = false;
      }
    }
    if (shouldDelete) {
      goog.editor.plugins.EnterHandler.deleteW3cRange_(range);
    }
  }
  return goog.editor.range.getDeepEndPoint(range, true);
};
goog.editor.plugins.EnterHandler.deleteW3cRange_ = function(range) {
  if (range && !range.isCollapsed()) {
    var reselect = true;
    var baseNode = range.getContainerElement();
    var nodeOffset = new goog.dom.NodeOffset(range.getStartNode(), baseNode);
    var rangeOffset = range.getStartOffset();
    var isInOneContainer = goog.editor.plugins.EnterHandler.isInOneContainerW3c_(range);
    var isPartialEnd = !isInOneContainer && goog.editor.plugins.EnterHandler.isPartialEndW3c_(range);
    range.removeContents();
    var node = nodeOffset.findTargetNode(baseNode);
    if (node) {
      range = goog.dom.Range.createCaret(node, rangeOffset);
    } else {
      range = goog.dom.Range.createCaret(baseNode, baseNode.childNodes.length);
      reselect = false;
    }
    range.select();
    if (isInOneContainer) {
      var container = goog.editor.style.getContainer(range.getStartNode());
      if (goog.editor.node.isEmpty(container, true)) {
        var html = "&nbsp;";
        if (goog.userAgent.OPERA && container.tagName == goog.dom.TagName.LI) {
          html = "<br>";
        }
        goog.editor.node.replaceInnerHtml(container, html);
        goog.editor.range.selectNodeStart(container.firstChild);
        reselect = false;
      }
    }
    if (isPartialEnd) {
      var rangeStart = goog.editor.style.getContainer(range.getStartNode());
      var redundantContainer = goog.editor.node.getNextSibling(rangeStart);
      if (rangeStart && redundantContainer) {
        goog.dom.append(rangeStart, redundantContainer.childNodes);
        goog.dom.removeNode(redundantContainer);
      }
    }
    if (reselect) {
      range = goog.dom.Range.createCaret(nodeOffset.findTargetNode(baseNode), rangeOffset);
      range.select();
    }
  }
  return range;
};
goog.editor.plugins.EnterHandler.isInOneContainerW3c_ = function(range) {
  var startContainer = range.getStartNode();
  if (goog.editor.style.isContainer(startContainer)) {
    startContainer = startContainer.childNodes[range.getStartOffset()] || startContainer;
  }
  startContainer = goog.editor.style.getContainer(startContainer);
  var endContainer = range.getEndNode();
  if (goog.editor.style.isContainer(endContainer)) {
    endContainer = endContainer.childNodes[range.getEndOffset()] || endContainer;
  }
  endContainer = goog.editor.style.getContainer(endContainer);
  return startContainer == endContainer;
};
goog.editor.plugins.EnterHandler.isPartialEndW3c_ = function(range) {
  var endContainer = range.getEndNode();
  var endOffset = range.getEndOffset();
  var node = endContainer;
  if (goog.editor.style.isContainer(node)) {
    var child = node.childNodes[endOffset];
    if (!child || child.nodeType == goog.dom.NodeType.ELEMENT && goog.editor.style.isContainer(child)) {
      return false;
    }
  }
  var container = goog.editor.style.getContainer(node);
  while (container != node) {
    if (goog.editor.node.getNextSibling(node)) {
      return true;
    }
    node = node.parentNode;
  }
  return endOffset != goog.editor.node.getLength(endContainer);
};
goog.provide("goog.editor.plugins.RemoveFormatting");
goog.require("goog.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.Range");
goog.require("goog.dom.TagName");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.editor.plugins.RemoveFormatting = function() {
  goog.editor.Plugin.call(this);
  this.optRemoveFormattingFunc_ = null;
  this.keyboardShortcutKey_ = " ";
};
goog.inherits(goog.editor.plugins.RemoveFormatting, goog.editor.Plugin);
goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND = "+removeFormat";
goog.editor.plugins.RemoveFormatting.BLOCK_RE_ = /^(DIV|TR|LI|BLOCKQUOTE|H\d|PRE|XMP)/;
goog.editor.plugins.RemoveFormatting.appendNewline_ = function(sb) {
  sb.push("<br>");
};
goog.editor.plugins.RemoveFormatting.createRangeDelimitedByRanges_ = function(startRange, endRange) {
  return goog.dom.Range.createFromNodes(startRange.getStartNode(), startRange.getStartOffset(), endRange.getEndNode(), endRange.getEndOffset());
};
goog.editor.plugins.RemoveFormatting.prototype.getTrogClassId = function() {
  return "RemoveFormatting";
};
goog.editor.plugins.RemoveFormatting.prototype.isSupportedCommand = function(command) {
  return command == goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND;
};
goog.editor.plugins.RemoveFormatting.prototype.execCommandInternal = function(command, var_args) {
  if (command == goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND) {
    this.removeFormatting_();
  }
};
goog.editor.plugins.RemoveFormatting.prototype.handleKeyboardShortcut = function(e, key, isModifierPressed) {
  if (!isModifierPressed) {
    return false;
  }
  if (e.metaKey && e.ctrlKey) {
    return false;
  }
  if (e.shiftKey) {
    return false;
  }
  if (key == this.keyboardShortcutKey_) {
    this.getFieldObject().execCommand(goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND);
    return true;
  }
  return false;
};
goog.editor.plugins.RemoveFormatting.prototype.setKeyboardShortcutKey = function(key) {
  this.keyboardShortcutKey_ = key;
};
goog.editor.plugins.RemoveFormatting.prototype.removeFormatting_ = function() {
  var range = this.getFieldObject().getRange();
  if (range.isCollapsed()) {
    return;
  }
  var convFunc = this.optRemoveFormattingFunc_ || goog.bind(this.removeFormattingWorker_, this);
  this.convertSelectedHtmlText_(convFunc);
  var doc = this.getFieldDomHelper().getDocument();
  doc.execCommand("RemoveFormat", false, undefined);
  if (goog.editor.BrowserFeature.ADDS_NBSPS_IN_REMOVE_FORMAT) {
    this.convertSelectedHtmlText_(function(text) {
      var nbspRegExp = goog.userAgent.isVersionOrHigher("528") ? /&nbsp;/g : /\u00A0/g;
      return text.replace(nbspRegExp, " ");
    });
  }
};
goog.editor.plugins.RemoveFormatting.prototype.getTableAncestor_ = function(nodeToCheck) {
  var fieldElement = this.getFieldObject().getElement();
  while (nodeToCheck && nodeToCheck != fieldElement) {
    if (nodeToCheck.tagName == goog.dom.TagName.TABLE) {
      return nodeToCheck;
    }
    nodeToCheck = nodeToCheck.parentNode;
  }
  return null;
};
goog.editor.plugins.RemoveFormatting.prototype.pasteHtml_ = function(html) {
  var range = this.getFieldObject().getRange();
  var dh = this.getFieldDomHelper();
  var startSpanId = goog.string.createUniqueString();
  var endSpanId = goog.string.createUniqueString();
  html = '<span id="' + startSpanId + '"></span>' + html + '<span id="' + endSpanId + '"></span>';
  var dummyNodeId = goog.string.createUniqueString();
  var dummySpanText = '<span id="' + dummyNodeId + '"></span>';
  if (goog.editor.BrowserFeature.HAS_IE_RANGES) {
    var textRange = range.getTextRange(0).getBrowserRangeObject();
    textRange.pasteHTML(dummySpanText);
    var parent;
    while ((parent = textRange.parentElement()) && goog.editor.node.isEmpty(parent) && !goog.editor.node.isEditableContainer(parent)) {
      var tag = parent.nodeName;
      if (tag == goog.dom.TagName.TD || tag == goog.dom.TagName.TR || tag == goog.dom.TagName.TH) {
        break;
      }
      goog.dom.removeNode(parent);
    }
    textRange.pasteHTML(html);
    var dummySpan = dh.getElement(dummyNodeId);
    if (dummySpan) {
      goog.dom.removeNode(dummySpan);
    }
  } else {
    if (goog.editor.BrowserFeature.HAS_W3C_RANGES) {
      dh.getDocument().execCommand("insertImage", false, dummyNodeId);
      var dummyImageNodePattern = new RegExp("<[^<]*" + dummyNodeId + "[^>]*>");
      var parent = this.getFieldObject().getRange().getContainerElement();
      if (parent.nodeType == goog.dom.NodeType.TEXT) {
        parent = parent.parentNode;
      }
      while (!dummyImageNodePattern.test(parent.innerHTML)) {
        parent = parent.parentNode;
      }
      if (goog.userAgent.GECKO) {
        goog.editor.node.replaceInnerHtml(parent, parent.innerHTML.replace(dummyImageNodePattern, html.replace(/\$/g, "$$$$")));
      } else {
        goog.editor.node.replaceInnerHtml(parent, parent.innerHTML.replace(dummyImageNodePattern, dummySpanText));
        var dummySpan = dh.getElement(dummyNodeId);
        parent = dummySpan;
        while ((parent = dummySpan.parentNode) && goog.editor.node.isEmpty(parent) && !goog.editor.node.isEditableContainer(parent)) {
          var tag = parent.nodeName;
          if (tag == goog.dom.TagName.TD || tag == goog.dom.TagName.TR || tag == goog.dom.TagName.TH) {
            break;
          }
          goog.dom.insertSiblingAfter(dummySpan, parent);
          goog.dom.removeNode(parent);
        }
        goog.editor.node.replaceInnerHtml(parent, parent.innerHTML.replace(new RegExp(dummySpanText, "i"), html.replace(/\$/g, "$$$$")));
      }
    }
  }
  var startSpan = dh.getElement(startSpanId);
  var endSpan = dh.getElement(endSpanId);
  goog.dom.Range.createFromNodes(startSpan, 0, endSpan, endSpan.childNodes.length).select();
  goog.dom.removeNode(startSpan);
  goog.dom.removeNode(endSpan);
};
goog.editor.plugins.RemoveFormatting.prototype.getHtmlText_ = function(range) {
  var div = this.getFieldDomHelper().createDom(goog.dom.TagName.DIV);
  var textRange = range.getBrowserRangeObject();
  if (goog.editor.BrowserFeature.HAS_W3C_RANGES) {
    div.appendChild(textRange.cloneContents());
  } else {
    if (goog.editor.BrowserFeature.HAS_IE_RANGES) {
      var rngText = range.getText();
      rngText = rngText.replace(/\r\n/g, "\r");
      var rngTextLength = rngText.length;
      var left = rngTextLength - goog.string.trimLeft(rngText).length;
      var right = rngTextLength - goog.string.trimRight(rngText).length;
      textRange.moveStart("character", left);
      textRange.moveEnd("character", -right);
      var htmlText = textRange.htmlText;
      if (textRange.queryCommandValue("formatBlock") == "Formatted") {
        htmlText = goog.string.newLineToBr(textRange.htmlText);
      }
      div.innerHTML = htmlText;
    }
  }
  return div.innerHTML;
};
goog.editor.plugins.RemoveFormatting.prototype.adjustRangeForTables_ = function(range, startInTable, endInTable) {
  var savedCaretRange = goog.editor.range.saveUsingNormalizedCarets(range);
  var startNode = range.getStartNode();
  var startOffset = range.getStartOffset();
  var endNode = range.getEndNode();
  var endOffset = range.getEndOffset();
  var dh = this.getFieldDomHelper();
  if (startInTable) {
    var textNode = dh.createTextNode("");
    goog.dom.insertSiblingAfter(textNode, startInTable);
    startNode = textNode;
    startOffset = 0;
  }
  if (endInTable) {
    var textNode = dh.createTextNode("");
    goog.dom.insertSiblingBefore(textNode, endInTable);
    endNode = textNode;
    endOffset = 0;
  }
  goog.dom.Range.createFromNodes(startNode, startOffset, endNode, endOffset).select();
  return savedCaretRange;
};
goog.editor.plugins.RemoveFormatting.prototype.putCaretInCave_ = function(caretRange, isStart) {
  var cavedCaret = goog.dom.removeNode(caretRange.getCaret(isStart));
  if (isStart) {
    this.startCaretInCave_ = cavedCaret;
  } else {
    this.endCaretInCave_ = cavedCaret;
  }
};
goog.editor.plugins.RemoveFormatting.prototype.restoreCaretsFromCave_ = function() {
  var field = this.getFieldObject().getElement();
  if (this.startCaretInCave_) {
    field.insertBefore(this.startCaretInCave_, field.firstChild);
    this.startCaretInCave_ = null;
  }
  if (this.endCaretInCave_) {
    field.appendChild(this.endCaretInCave_);
    this.endCaretInCave_ = null;
  }
};
goog.editor.plugins.RemoveFormatting.prototype.convertSelectedHtmlText_ = function(convertFunc) {
  var range = this.getFieldObject().getRange();
  if (range.getTextRangeCount() > 1) {
    return;
  }
  if (goog.userAgent.GECKO || goog.userAgent.EDGE) {
    var expandedRange = goog.editor.range.expand(range, this.getFieldObject().getElement());
    var startInTable = this.getTableAncestor_(expandedRange.getStartNode());
    var endInTable = this.getTableAncestor_(expandedRange.getEndNode());
    if (startInTable || endInTable) {
      if (startInTable == endInTable) {
        return;
      }
      var savedCaretRange = this.adjustRangeForTables_(range, startInTable, endInTable);
      if (!startInTable) {
        this.putCaretInCave_(savedCaretRange, true);
      }
      if (!endInTable) {
        this.putCaretInCave_(savedCaretRange, false);
      }
      range = this.getFieldObject().getRange();
      expandedRange = goog.editor.range.expand(range, this.getFieldObject().getElement());
    }
    expandedRange.select();
    range = expandedRange;
  }
  var text = this.getHtmlText_(range);
  this.pasteHtml_(convertFunc(text));
  if ((goog.userAgent.GECKO || goog.userAgent.EDGE) && savedCaretRange) {
    range = this.getFieldObject().getRange();
    this.restoreCaretsFromCave_();
    var realSavedCaretRange = savedCaretRange.toAbstractRange();
    var startRange = startInTable ? realSavedCaretRange : range;
    var endRange = endInTable ? realSavedCaretRange : range;
    var restoredRange = goog.editor.plugins.RemoveFormatting.createRangeDelimitedByRanges_(startRange, endRange);
    restoredRange.select();
    savedCaretRange.dispose();
  }
};
goog.editor.plugins.RemoveFormatting.prototype.removeFormattingWorker_ = function(html) {
  var el = goog.dom.createElement(goog.dom.TagName.DIV);
  el.innerHTML = html;
  var sb = [];
  var stack = [el.childNodes, 0];
  var preTagStack = [];
  var preTagLevel = 0;
  var tableStack = [];
  var tableLevel = 0;
  for (var sp = 0; sp >= 0; sp -= 2) {
    var changedLevel = false;
    while (tableLevel > 0 && sp <= tableStack[tableLevel - 1]) {
      tableLevel--;
      changedLevel = true;
    }
    if (changedLevel) {
      goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
    }
    changedLevel = false;
    while (preTagLevel > 0 && sp <= preTagStack[preTagLevel - 1]) {
      preTagLevel--;
      changedLevel = true;
    }
    if (changedLevel) {
      goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
    }
    var nodeList = stack[sp];
    var numNodesProcessed = stack[sp + 1];
    while (numNodesProcessed < nodeList.length) {
      var node = nodeList[numNodesProcessed++];
      var nodeName = node.nodeName;
      var formatted = this.getValueForNode(node);
      if (goog.isDefAndNotNull(formatted)) {
        sb.push(formatted);
        continue;
      }
      switch(nodeName) {
        case "#text":
          var nodeValue = preTagLevel > 0 ? node.nodeValue : goog.string.stripNewlines(node.nodeValue);
          nodeValue = goog.string.htmlEscape(nodeValue);
          sb.push(nodeValue);
          continue;
        case String(goog.dom.TagName.P):
          goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
          goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
          break;
        case String(goog.dom.TagName.BR):
          goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
          continue;
        case String(goog.dom.TagName.TABLE):
          goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
          tableStack[tableLevel++] = sp;
          break;
        case String(goog.dom.TagName.PRE):
        case "XMP":
          preTagStack[preTagLevel++] = sp;
          break;
        case String(goog.dom.TagName.STYLE):
        case String(goog.dom.TagName.SCRIPT):
        case String(goog.dom.TagName.SELECT):
          continue;
        case String(goog.dom.TagName.A):
          if (node.href && node.href != "") {
            sb.push("<a href='");
            sb.push(node.href);
            sb.push("'>");
            sb.push(this.removeFormattingWorker_(node.innerHTML));
            sb.push("</a>");
            continue;
          } else {
            break;
          }
        case String(goog.dom.TagName.IMG):
          sb.push("<img src='");
          sb.push(node.src);
          sb.push("'");
          if (node.border == "0") {
            sb.push(" border='0'");
          }
          sb.push(">");
          continue;
        case String(goog.dom.TagName.TD):
          if (node.previousSibling) {
            sb.push(" ");
          }
          break;
        case String(goog.dom.TagName.TR):
          if (node.previousSibling) {
            goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
          }
          break;
        case String(goog.dom.TagName.DIV):
          var parent = node.parentNode;
          if (parent.firstChild == node && goog.editor.plugins.RemoveFormatting.BLOCK_RE_.test(parent.tagName)) {
            break;
          }
        default:
          if (goog.editor.plugins.RemoveFormatting.BLOCK_RE_.test(nodeName)) {
            goog.editor.plugins.RemoveFormatting.appendNewline_(sb);
          }
      }
      var children = node.childNodes;
      if (children.length > 0) {
        stack[sp++] = nodeList;
        stack[sp++] = numNodesProcessed;
        nodeList = children;
        numNodesProcessed = 0;
      }
    }
  }
  return goog.string.normalizeSpaces(sb.join(""));
};
goog.editor.plugins.RemoveFormatting.prototype.getValueForNode = function(node) {
  return null;
};
goog.editor.plugins.RemoveFormatting.prototype.setRemoveFormattingFunc = function(removeFormattingFunc) {
  this.optRemoveFormattingFunc_ = removeFormattingFunc;
};
goog.provide("goog.editor.plugins.AbstractTabHandler");
goog.require("goog.editor.Plugin");
goog.require("goog.events.KeyCodes");
goog.require("goog.userAgent");
goog.editor.plugins.AbstractTabHandler = function() {
  goog.editor.Plugin.call(this);
};
goog.inherits(goog.editor.plugins.AbstractTabHandler, goog.editor.Plugin);
goog.editor.plugins.AbstractTabHandler.prototype.getTrogClassId = goog.abstractMethod;
goog.editor.plugins.AbstractTabHandler.prototype.handleKeyboardShortcut = function(e, key, isModifierPressed) {
  if (goog.userAgent.GECKO && this.getFieldObject().inModalMode()) {
    return false;
  }
  if (e.keyCode == goog.events.KeyCodes.TAB && !e.metaKey && !e.ctrlKey) {
    return this.handleTabKey(e);
  }
  return false;
};
goog.editor.plugins.AbstractTabHandler.prototype.handleTabKey = goog.abstractMethod;
goog.provide("goog.editor.plugins.SpacesTabHandler");
goog.require("goog.dom.TagName");
goog.require("goog.editor.plugins.AbstractTabHandler");
goog.require("goog.editor.range");
goog.editor.plugins.SpacesTabHandler = function() {
  goog.editor.plugins.AbstractTabHandler.call(this);
};
goog.inherits(goog.editor.plugins.SpacesTabHandler, goog.editor.plugins.AbstractTabHandler);
goog.editor.plugins.SpacesTabHandler.prototype.getTrogClassId = function() {
  return "SpacesTabHandler";
};
goog.editor.plugins.SpacesTabHandler.prototype.handleTabKey = function(e) {
  var dh = this.getFieldDomHelper();
  var range = this.getFieldObject().getRange();
  if (!goog.editor.range.intersectsTag(range, goog.dom.TagName.LI)) {
    if (!e.shiftKey) {
      this.getFieldObject().stopChangeEvents(true, true);
      if (!range.isCollapsed()) {
        dh.getDocument().execCommand("delete", false, null);
        range = this.getFieldObject().getRange();
      }
      var elem = dh.createDom(goog.dom.TagName.SPAN, null, "\u00a0\u00a0 \u00a0");
      elem = range.insertNode(elem, false);
      this.getFieldObject().dispatchChange();
      goog.editor.range.placeCursorNextTo(elem, false);
      this.getFieldObject().dispatchSelectionChangeEvent();
    }
    e.preventDefault();
    return true;
  }
  return false;
};
goog.provide("goog.editor.Table");
goog.provide("goog.editor.TableCell");
goog.provide("goog.editor.TableRow");
goog.require("goog.asserts");
goog.require("goog.dom");
goog.require("goog.dom.DomHelper");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagName");
goog.require("goog.log");
goog.require("goog.string.Unicode");
goog.require("goog.style");
goog.editor.Table = function(node) {
  this.element = goog.dom.getAncestorByTagNameAndClass(node, goog.dom.TagName.TABLE);
  if (!this.element) {
    goog.log.error(this.logger_, "Can't create Table based on a node " + "that isn't a table, or descended from a table.");
  }
  this.dom_ = goog.dom.getDomHelper(this.element);
  this.refresh();
};
goog.editor.Table.prototype.logger_ = goog.log.getLogger("goog.editor.Table");
goog.editor.Table.prototype.refresh = function() {
  var rows = this.rows = [];
  var tbody = goog.dom.getElementsByTagName(goog.dom.TagName.TBODY, goog.asserts.assert(this.element))[0];
  if (!tbody) {
    return;
  }
  var trs = [];
  for (var child = tbody.firstChild; child; child = child.nextSibling) {
    if (child.nodeName == goog.dom.TagName.TR) {
      trs.push(child);
    }
  }
  for (var rowNum = 0, tr; tr = trs[rowNum]; rowNum++) {
    var existingRow = rows[rowNum];
    var tds = goog.editor.Table.getChildCellElements(tr);
    var columnNum = 0;
    for (var cellNum = 0, td; td = tds[cellNum]; cellNum++) {
      while (existingRow && existingRow.columns[columnNum]) {
        columnNum++;
      }
      var cell = new goog.editor.TableCell(td, rowNum, columnNum);
      for (var i = 0; i < cell.rowSpan; i++) {
        var cellRowNum = rowNum + i;
        var cellRow = rows[cellRowNum];
        if (!cellRow) {
          rows.push(cellRow = new goog.editor.TableRow(trs[cellRowNum], cellRowNum));
        }
        var minimumColumnLength = columnNum + cell.colSpan;
        if (cellRow.columns.length < minimumColumnLength) {
          cellRow.columns.length = minimumColumnLength;
        }
        for (var j = 0; j < cell.colSpan; j++) {
          var cellColumnNum = columnNum + j;
          cellRow.columns[cellColumnNum] = cell;
        }
      }
      columnNum += cell.colSpan;
    }
  }
};
goog.editor.Table.getChildCellElements = function(tr) {
  var cells = [];
  for (var i = 0, cell; cell = tr.childNodes[i]; i++) {
    if (cell.nodeName == goog.dom.TagName.TD || cell.nodeName == goog.dom.TagName.TH) {
      cells.push(cell);
    }
  }
  return cells;
};
goog.editor.Table.prototype.insertRow = function(opt_rowIndex) {
  var rowIndex = goog.isDefAndNotNull(opt_rowIndex) ? opt_rowIndex : this.rows.length;
  var refRow;
  var insertAfter;
  if (rowIndex == 0) {
    refRow = this.rows[0];
    insertAfter = false;
  } else {
    refRow = this.rows[rowIndex - 1];
    insertAfter = true;
  }
  var newTr = this.dom_.createElement(goog.dom.TagName.TR);
  for (var i = 0, cell; cell = refRow.columns[i]; i += 1) {
    if (insertAfter && cell.endRow > rowIndex || !insertAfter && cell.startRow < rowIndex) {
      cell.setRowSpan(cell.rowSpan + 1);
      if (cell.colSpan > 1) {
        i += cell.colSpan - 1;
      }
    } else {
      newTr.appendChild(this.createEmptyTd());
    }
    if (insertAfter) {
      goog.dom.insertSiblingAfter(newTr, refRow.element);
    } else {
      goog.dom.insertSiblingBefore(newTr, refRow.element);
    }
  }
  this.refresh();
  return newTr;
};
goog.editor.Table.prototype.insertColumn = function(opt_colIndex) {
  var colIndex = goog.isDefAndNotNull(opt_colIndex) ? opt_colIndex : this.rows[0] && this.rows[0].columns.length || 0;
  var newTds = [];
  for (var rowNum = 0, row; row = this.rows[rowNum]; rowNum++) {
    var existingCell = row.columns[colIndex];
    if (existingCell && existingCell.endCol >= colIndex && existingCell.startCol < colIndex) {
      existingCell.setColSpan(existingCell.colSpan + 1);
      rowNum += existingCell.rowSpan - 1;
    } else {
      var newTd = this.createEmptyTd();
      newTd.style.width = goog.editor.Table.OPTIMUM_EMPTY_CELL_WIDTH + "px";
      this.insertCellElement(newTd, rowNum, colIndex);
      newTds.push(newTd);
    }
  }
  this.refresh();
  return newTds;
};
goog.editor.Table.prototype.removeRow = function(rowIndex) {
  var row = this.rows[rowIndex];
  if (!row) {
    goog.log.warning(this.logger_, "Can't remove row at position " + rowIndex + ": no such row.");
  }
  for (var i = 0, cell; cell = row.columns[i]; i += cell.colSpan) {
    if (cell.rowSpan > 1) {
      cell.setRowSpan(cell.rowSpan - 1);
      if (cell.startRow == rowIndex) {
        this.insertCellElement(cell.element, rowIndex + 1, cell.startCol);
      }
    }
  }
  row.element.parentNode.removeChild(row.element);
  this.refresh();
};
goog.editor.Table.prototype.removeColumn = function(colIndex) {
  for (var i = 0, row; row = this.rows[i]; i++) {
    var cell = row.columns[colIndex];
    if (!cell) {
      goog.log.error(this.logger_, "Can't remove cell at position " + i + ", " + colIndex + ": no such cell.");
    }
    if (cell.colSpan > 1) {
      cell.setColSpan(cell.colSpan - 1);
    } else {
      cell.element.parentNode.removeChild(cell.element);
    }
    i += cell.rowSpan - 1;
  }
  this.refresh();
};
goog.editor.Table.prototype.mergeCells = function(startRowIndex, startColIndex, endRowIndex, endColIndex) {
  var cells = [];
  var cell;
  if (startRowIndex == endRowIndex && startColIndex == endColIndex) {
    goog.log.warning(this.logger_, "Can't merge single cell");
    return false;
  }
  for (var i = startRowIndex; i <= endRowIndex; i++) {
    for (var j = startColIndex; j <= endColIndex; j++) {
      cell = this.rows[i].columns[j];
      if (cell.startRow < startRowIndex || cell.endRow > endRowIndex || cell.startCol < startColIndex || cell.endCol > endColIndex) {
        goog.log.warning(this.logger_, "Can't merge cells: the cell in row " + i + ", column " + j + "extends outside the supplied rectangle.");
        return false;
      }
      cells.push(cell);
    }
  }
  var targetCell = cells[0];
  var targetTd = targetCell.element;
  var doc = this.dom_.getDocument();
  for (var i = 1; cell = cells[i]; i++) {
    var td = cell.element;
    if (!td.parentNode || td == targetTd) {
      continue;
    }
    if (targetTd.lastChild && targetTd.lastChild.nodeType == goog.dom.NodeType.TEXT) {
      targetTd.appendChild(doc.createTextNode(" "));
    }
    var childNode;
    while (childNode = td.firstChild) {
      targetTd.appendChild(childNode);
    }
    td.parentNode.removeChild(td);
  }
  targetCell.setColSpan(endColIndex - startColIndex + 1);
  targetCell.setRowSpan(endRowIndex - startRowIndex + 1);
  if (endColIndex > startColIndex) {
    targetTd.removeAttribute("width");
    targetTd.style.width = null;
  }
  this.refresh();
  return true;
};
goog.editor.Table.prototype.splitCell = function(rowIndex, colIndex) {
  var row = this.rows[rowIndex];
  var cell = row.columns[colIndex];
  var newTds = [];
  for (var i = 0; i < cell.rowSpan; i++) {
    for (var j = 0; j < cell.colSpan; j++) {
      if (i > 0 || j > 0) {
        var newTd = this.createEmptyTd();
        this.insertCellElement(newTd, rowIndex + i, colIndex + j);
        newTds.push(newTd);
      }
    }
  }
  cell.setColSpan(1);
  cell.setRowSpan(1);
  this.refresh();
  return newTds;
};
goog.editor.Table.prototype.insertCellElement = function(td, rowIndex, colIndex) {
  var row = this.rows[rowIndex];
  var nextSiblingElement = null;
  for (var i = colIndex, cell; cell = row.columns[i]; i += cell.colSpan) {
    if (cell.startRow == rowIndex) {
      nextSiblingElement = cell.element;
      break;
    }
  }
  row.element.insertBefore(td, nextSiblingElement);
};
goog.editor.Table.prototype.createEmptyTd = function() {
  return this.dom_.createDom(goog.dom.TagName.TD, {}, goog.string.Unicode.NBSP);
};
goog.editor.TableRow = function(trElement, rowIndex) {
  this.index = rowIndex;
  this.element = trElement;
  this.columns = [];
};
goog.editor.TableCell = function(td, startRow, startCol) {
  this.element = td;
  this.colSpan = parseInt(td.colSpan, 10) || 1;
  this.rowSpan = parseInt(td.rowSpan, 10) || 1;
  this.startRow = startRow;
  this.startCol = startCol;
  this.updateCoordinates_();
};
goog.editor.TableCell.prototype.updateCoordinates_ = function() {
  this.endCol = this.startCol + this.colSpan - 1;
  this.endRow = this.startRow + this.rowSpan - 1;
};
goog.editor.TableCell.prototype.setColSpan = function(colSpan) {
  if (colSpan != this.colSpan) {
    if (colSpan > 1) {
      this.element.colSpan = colSpan;
    } else {
      this.element.colSpan = 1, this.element.removeAttribute("colSpan");
    }
    this.colSpan = colSpan;
    this.updateCoordinates_();
  }
};
goog.editor.TableCell.prototype.setRowSpan = function(rowSpan) {
  if (rowSpan != this.rowSpan) {
    if (rowSpan > 1) {
      this.element.rowSpan = rowSpan.toString();
    } else {
      this.element.rowSpan = "1";
      this.element.removeAttribute("rowSpan");
    }
    this.rowSpan = rowSpan;
    this.updateCoordinates_();
  }
};
goog.editor.Table.OPTIMUM_EMPTY_CELL_WIDTH = 60;
goog.editor.Table.OPTIMUM_MAX_NEW_TABLE_WIDTH = 600;
goog.editor.Table.DEFAULT_BORDER_COLOR = "#888";
goog.editor.Table.createDomTable = function(doc, columns, rows, opt_tableStyle) {
  var style = {borderWidth:"1", borderColor:goog.editor.Table.DEFAULT_BORDER_COLOR};
  for (var prop in opt_tableStyle) {
    style[prop] = opt_tableStyle[prop];
  }
  var dom = new goog.dom.DomHelper(doc);
  var tableElement = dom.createTable(rows, columns, true);
  var minimumCellWidth = 10;
  var cellWidth = Math.max(minimumCellWidth, Math.min(goog.editor.Table.OPTIMUM_EMPTY_CELL_WIDTH, goog.editor.Table.OPTIMUM_MAX_NEW_TABLE_WIDTH / columns));
  var tds = goog.dom.getElementsByTagName(goog.dom.TagName.TD, tableElement);
  for (var i = 0, td; td = tds[i]; i++) {
    td.style.width = cellWidth + "px";
  }
  goog.style.setStyle(tableElement, {"borderCollapse":"collapse", "borderColor":style.borderColor, "borderWidth":style.borderWidth + "px"});
  tableElement.border = style.borderWidth;
  tableElement.setAttribute("bordercolor", style.borderColor);
  tableElement.setAttribute("cellspacing", "0");
  return tableElement;
};
goog.provide("goog.editor.plugins.TableEditor");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.dom.Range");
goog.require("goog.dom.TagName");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.Table");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("goog.object");
goog.require("goog.userAgent");
goog.editor.plugins.TableEditor = function() {
  goog.editor.plugins.TableEditor.base(this, "constructor");
  this.isTableEditableFunctions_ = [];
  this.isUserEditableTableBound_ = goog.bind(this.isUserEditableTable_, this);
};
goog.inherits(goog.editor.plugins.TableEditor, goog.editor.Plugin);
goog.editor.plugins.TableEditor.prototype.getTrogClassId = function() {
  return String(goog.getUid(this.constructor));
};
goog.editor.plugins.TableEditor.COMMAND = {TABLE:"+table", INSERT_ROW_AFTER:"+insertRowAfter", INSERT_ROW_BEFORE:"+insertRowBefore", INSERT_COLUMN_AFTER:"+insertColumnAfter", INSERT_COLUMN_BEFORE:"+insertColumnBefore", REMOVE_ROWS:"+removeRows", REMOVE_COLUMNS:"+removeColumns", SPLIT_CELL:"+splitCell", MERGE_CELLS:"+mergeCells", REMOVE_TABLE:"+removeTable"};
goog.editor.plugins.TableEditor.SUPPORTED_COMMANDS_ = goog.object.transpose(goog.editor.plugins.TableEditor.COMMAND);
goog.editor.plugins.TableEditor.prototype.isSupportedCommand = function(command) {
  return command in goog.editor.plugins.TableEditor.SUPPORTED_COMMANDS_;
};
goog.editor.plugins.TableEditor.prototype.enable = function(fieldObject) {
  goog.editor.plugins.TableEditor.base(this, "enable", fieldObject);
  if (goog.userAgent.GECKO) {
    var doc = this.getFieldDomHelper().getDocument();
    doc.execCommand("enableObjectResizing", false, "true");
  }
};
goog.editor.plugins.TableEditor.prototype.getCurrentTable_ = function() {
  var selectedElement = this.getFieldObject().getRange().getContainer();
  return this.getAncestorTable_(selectedElement);
};
goog.editor.plugins.TableEditor.prototype.getAncestorTable_ = function(node) {
  var ancestor = goog.dom.getAncestor(node, this.isUserEditableTableBound_, true);
  if (goog.editor.node.isEditable(ancestor)) {
    return ancestor;
  } else {
    return null;
  }
};
goog.editor.plugins.TableEditor.prototype.queryCommandValue = function(command) {
  if (command == goog.editor.plugins.TableEditor.COMMAND.TABLE) {
    return !!this.getCurrentTable_();
  }
};
goog.editor.plugins.TableEditor.prototype.execCommandInternal = function(command, opt_arg) {
  var result = null;
  var cursorCell = null;
  var range = this.getFieldObject().getRange();
  if (command == goog.editor.plugins.TableEditor.COMMAND.TABLE) {
    if (!goog.editor.range.isEditable(range)) {
      return null;
    }
    var tableProps = opt_arg || {width:4, height:2};
    var doc = this.getFieldDomHelper().getDocument();
    var table = goog.editor.Table.createDomTable(doc, tableProps.width, tableProps.height);
    range.replaceContentsWithNode(table);
    if (!goog.userAgent.IE) {
      cursorCell = goog.dom.getElementsByTagName(goog.dom.TagName.TD, table)[0];
    }
  } else {
    var cellSelection = new goog.editor.plugins.TableEditor.CellSelection_(range, goog.bind(this.getAncestorTable_, this));
    var table = cellSelection.getTable();
    if (!table) {
      return null;
    }
    switch(command) {
      case goog.editor.plugins.TableEditor.COMMAND.INSERT_ROW_BEFORE:
        table.insertRow(cellSelection.getFirstRowIndex());
        break;
      case goog.editor.plugins.TableEditor.COMMAND.INSERT_ROW_AFTER:
        table.insertRow(cellSelection.getLastRowIndex() + 1);
        break;
      case goog.editor.plugins.TableEditor.COMMAND.INSERT_COLUMN_BEFORE:
        table.insertColumn(cellSelection.getFirstColumnIndex());
        break;
      case goog.editor.plugins.TableEditor.COMMAND.INSERT_COLUMN_AFTER:
        table.insertColumn(cellSelection.getLastColumnIndex() + 1);
        break;
      case goog.editor.plugins.TableEditor.COMMAND.REMOVE_ROWS:
        var startRow = cellSelection.getFirstRowIndex();
        var endRow = cellSelection.getLastRowIndex();
        if (startRow == 0 && endRow == table.rows.length - 1) {
          return this.execCommandInternal(goog.editor.plugins.TableEditor.COMMAND.REMOVE_TABLE);
        }
        var startColumn = cellSelection.getFirstColumnIndex();
        var rowCount = endRow - startRow + 1;
        for (var i = 0; i < rowCount; i++) {
          table.removeRow(startRow);
        }
        if (table.rows.length > 0) {
          var closestRow = Math.min(startRow, table.rows.length - 1);
          cursorCell = table.rows[closestRow].columns[startColumn].element;
        }
        break;
      case goog.editor.plugins.TableEditor.COMMAND.REMOVE_COLUMNS:
        var startCol = cellSelection.getFirstColumnIndex();
        var endCol = cellSelection.getLastColumnIndex();
        if (startCol == 0 && endCol == table.rows[0].columns.length - 1) {
          return this.execCommandInternal(goog.editor.plugins.TableEditor.COMMAND.REMOVE_TABLE);
        }
        var startRow = cellSelection.getFirstRowIndex();
        var removeCount = endCol - startCol + 1;
        for (var i = 0; i < removeCount; i++) {
          table.removeColumn(startCol);
        }
        var currentRow = table.rows[startRow];
        if (currentRow) {
          var closestCol = Math.min(startCol, currentRow.columns.length - 1);
          cursorCell = currentRow.columns[closestCol].element;
        }
        break;
      case goog.editor.plugins.TableEditor.COMMAND.MERGE_CELLS:
        if (cellSelection.isRectangle()) {
          table.mergeCells(cellSelection.getFirstRowIndex(), cellSelection.getFirstColumnIndex(), cellSelection.getLastRowIndex(), cellSelection.getLastColumnIndex());
        }
        break;
      case goog.editor.plugins.TableEditor.COMMAND.SPLIT_CELL:
        if (cellSelection.containsSingleCell()) {
          table.splitCell(cellSelection.getFirstRowIndex(), cellSelection.getFirstColumnIndex());
        }
        break;
      case goog.editor.plugins.TableEditor.COMMAND.REMOVE_TABLE:
        table.element.parentNode.removeChild(table.element);
        break;
      default:
    }
  }
  if (cursorCell) {
    range = goog.dom.Range.createFromNodeContents(cursorCell);
    range.collapse(false);
    range.select();
  }
  return result;
};
goog.editor.plugins.TableEditor.prototype.isUserEditableTable_ = function(element) {
  if (element.tagName != goog.dom.TagName.TABLE) {
    return false;
  }
  return goog.array.every(this.isTableEditableFunctions_, function(func) {
    return func(element);
  });
};
goog.editor.plugins.TableEditor.prototype.addIsTableEditableFunction = function(func) {
  goog.array.insert(this.isTableEditableFunctions_, func);
};
goog.editor.plugins.TableEditor.CellSelection_ = function(range, getParentTableFunction) {
  this.cells_ = [];
  var selectionContainer = range.getContainerElement();
  var elementInSelection = function(node) {
    return selectionContainer == node || selectionContainer.parentNode == node || range.containsNode(node, false);
  };
  var parentTableElement = selectionContainer && getParentTableFunction(selectionContainer);
  if (!parentTableElement) {
    return;
  }
  var parentTable = new goog.editor.Table(parentTableElement);
  if (!parentTable.rows.length || !parentTable.rows[0].columns.length) {
    return;
  }
  for (var i = 0, row; row = parentTable.rows[i]; i++) {
    for (var j = 0, cell; cell = row.columns[j]; j++) {
      if (elementInSelection(cell.element)) {
        if (!this.cells_.length) {
          this.firstRowIndex_ = cell.startRow;
          this.lastRowIndex_ = cell.endRow;
          this.firstColIndex_ = cell.startCol;
          this.lastColIndex_ = cell.endCol;
        } else {
          this.firstRowIndex_ = Math.min(this.firstRowIndex_, cell.startRow);
          this.lastRowIndex_ = Math.max(this.lastRowIndex_, cell.endRow);
          this.firstColIndex_ = Math.min(this.firstColIndex_, cell.startCol);
          this.lastColIndex_ = Math.max(this.lastColIndex_, cell.endCol);
        }
        this.cells_.push(cell);
      }
    }
  }
  this.parentTable_ = parentTable;
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.getTable = function() {
  return this.parentTable_;
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.getFirstRowIndex = function() {
  return this.firstRowIndex_;
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.getLastRowIndex = function() {
  return this.lastRowIndex_;
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.getFirstColumnIndex = function() {
  return this.firstColIndex_;
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.getLastColumnIndex = function() {
  return this.lastColIndex_;
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.getCells = function() {
  return this.cells_;
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.isRectangle = function() {
  if (!this.cells_.length) {
    return false;
  }
  var firstCell = this.cells_[0];
  var lastCell = this.cells_[this.cells_.length - 1];
  return !(this.firstRowIndex_ < firstCell.startRow || this.lastRowIndex_ > lastCell.endRow || this.firstColIndex_ < firstCell.startCol || this.lastColIndex_ > lastCell.endCol);
};
goog.editor.plugins.TableEditor.CellSelection_.prototype.containsSingleCell = function() {
  var cellCount = this.cells_.length;
  return cellCount > 0 && this.cells_[0] == this.cells_[cellCount - 1];
};
goog.provide("goog.debug.RelativeTimeProvider");
goog.debug.RelativeTimeProvider = function() {
  this.relativeTimeStart_ = goog.now();
};
goog.debug.RelativeTimeProvider.defaultInstance_ = new goog.debug.RelativeTimeProvider;
goog.debug.RelativeTimeProvider.prototype.set = function(timeStamp) {
  this.relativeTimeStart_ = timeStamp;
};
goog.debug.RelativeTimeProvider.prototype.reset = function() {
  this.set(goog.now());
};
goog.debug.RelativeTimeProvider.prototype.get = function() {
  return this.relativeTimeStart_;
};
goog.debug.RelativeTimeProvider.getDefaultInstance = function() {
  return goog.debug.RelativeTimeProvider.defaultInstance_;
};
goog.provide("goog.debug.Formatter");
goog.provide("goog.debug.HtmlFormatter");
goog.provide("goog.debug.TextFormatter");
goog.require("goog.debug");
goog.require("goog.debug.Logger");
goog.require("goog.debug.RelativeTimeProvider");
goog.require("goog.html.SafeHtml");
goog.require("goog.html.SafeUrl");
goog.require("goog.html.uncheckedconversions");
goog.require("goog.string.Const");
goog.debug.Formatter = function(opt_prefix) {
  this.prefix_ = opt_prefix || "";
  this.startTimeProvider_ = goog.debug.RelativeTimeProvider.getDefaultInstance();
};
goog.debug.Formatter.prototype.appendNewline = true;
goog.debug.Formatter.prototype.showAbsoluteTime = true;
goog.debug.Formatter.prototype.showRelativeTime = true;
goog.debug.Formatter.prototype.showLoggerName = true;
goog.debug.Formatter.prototype.showExceptionText = false;
goog.debug.Formatter.prototype.showSeverityLevel = false;
goog.debug.Formatter.prototype.formatRecord = goog.abstractMethod;
goog.debug.Formatter.prototype.formatRecordAsHtml = goog.abstractMethod;
goog.debug.Formatter.prototype.setStartTimeProvider = function(provider) {
  this.startTimeProvider_ = provider;
};
goog.debug.Formatter.prototype.getStartTimeProvider = function() {
  return this.startTimeProvider_;
};
goog.debug.Formatter.prototype.resetRelativeTimeStart = function() {
  this.startTimeProvider_.reset();
};
goog.debug.Formatter.getDateTimeStamp_ = function(logRecord) {
  var time = new Date(logRecord.getMillis());
  return goog.debug.Formatter.getTwoDigitString_(time.getFullYear() - 2000) + goog.debug.Formatter.getTwoDigitString_(time.getMonth() + 1) + goog.debug.Formatter.getTwoDigitString_(time.getDate()) + " " + goog.debug.Formatter.getTwoDigitString_(time.getHours()) + ":" + goog.debug.Formatter.getTwoDigitString_(time.getMinutes()) + ":" + goog.debug.Formatter.getTwoDigitString_(time.getSeconds()) + "." + goog.debug.Formatter.getTwoDigitString_(Math.floor(time.getMilliseconds() / 10));
};
goog.debug.Formatter.getTwoDigitString_ = function(n) {
  if (n < 10) {
    return "0" + n;
  }
  return String(n);
};
goog.debug.Formatter.getRelativeTime_ = function(logRecord, relativeTimeStart) {
  var ms = logRecord.getMillis() - relativeTimeStart;
  var sec = ms / 1000;
  var str = sec.toFixed(3);
  var spacesToPrepend = 0;
  if (sec < 1) {
    spacesToPrepend = 2;
  } else {
    while (sec < 100) {
      spacesToPrepend++;
      sec *= 10;
    }
  }
  while (spacesToPrepend-- > 0) {
    str = " " + str;
  }
  return str;
};
goog.debug.HtmlFormatter = function(opt_prefix) {
  goog.debug.Formatter.call(this, opt_prefix);
};
goog.inherits(goog.debug.HtmlFormatter, goog.debug.Formatter);
goog.debug.HtmlFormatter.exposeException = function(err, fn) {
  var html = goog.debug.HtmlFormatter.exposeExceptionAsHtml(err, fn);
  return goog.html.SafeHtml.unwrap(html);
};
goog.debug.HtmlFormatter.exposeExceptionAsHtml = function(err, fn) {
  try {
    var e = goog.debug.normalizeErrorObject(err);
    var viewSourceUrl = goog.debug.HtmlFormatter.createViewSourceUrl_(e.fileName);
    var error = goog.html.SafeHtml.concat(goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces("Message: " + e.message + "\nUrl: "), goog.html.SafeHtml.create("a", {href:viewSourceUrl, target:"_new"}, e.fileName), goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces("\nLine: " + e.lineNumber + "\n\nBrowser stack:\n" + e.stack + "-> " + "[end]\n\nJS stack traversal:\n" + goog.debug.getStacktrace(fn) + "-> "));
    return error;
  } catch (e2) {
    return goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces("Exception trying to expose exception! You win, we lose. " + e2);
  }
};
goog.debug.HtmlFormatter.createViewSourceUrl_ = function(fileName) {
  if (!goog.isDefAndNotNull(fileName)) {
    fileName = "";
  }
  if (!/^https?:\/\//i.test(fileName)) {
    return goog.html.SafeUrl.fromConstant(goog.string.Const.from("sanitizedviewsrc"));
  }
  var sanitizedFileName = goog.html.SafeUrl.sanitize(fileName);
  return goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract(goog.string.Const.from("view-source scheme plus HTTP/HTTPS URL"), "view-source:" + goog.html.SafeUrl.unwrap(sanitizedFileName));
};
goog.debug.HtmlFormatter.prototype.showExceptionText = true;
goog.debug.HtmlFormatter.prototype.formatRecord = function(logRecord) {
  if (!logRecord) {
    return "";
  }
  return this.formatRecordAsHtml(logRecord).getTypedStringValue();
};
goog.debug.HtmlFormatter.prototype.formatRecordAsHtml = function(logRecord) {
  if (!logRecord) {
    return goog.html.SafeHtml.EMPTY;
  }
  var className;
  switch(logRecord.getLevel().value) {
    case goog.debug.Logger.Level.SHOUT.value:
      className = "dbg-sh";
      break;
    case goog.debug.Logger.Level.SEVERE.value:
      className = "dbg-sev";
      break;
    case goog.debug.Logger.Level.WARNING.value:
      className = "dbg-w";
      break;
    case goog.debug.Logger.Level.INFO.value:
      className = "dbg-i";
      break;
    case goog.debug.Logger.Level.FINE.value:
    default:
      className = "dbg-f";
      break;
  }
  var sb = [];
  sb.push(this.prefix_, " ");
  if (this.showAbsoluteTime) {
    sb.push("[", goog.debug.Formatter.getDateTimeStamp_(logRecord), "] ");
  }
  if (this.showRelativeTime) {
    sb.push("[", goog.debug.Formatter.getRelativeTime_(logRecord, this.startTimeProvider_.get()), "s] ");
  }
  if (this.showLoggerName) {
    sb.push("[", logRecord.getLoggerName(), "] ");
  }
  if (this.showSeverityLevel) {
    sb.push("[", logRecord.getLevel().name, "] ");
  }
  var fullPrefixHtml = goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces(sb.join(""));
  var exceptionHtml = goog.html.SafeHtml.EMPTY;
  if (this.showExceptionText && logRecord.getException()) {
    exceptionHtml = goog.html.SafeHtml.concat(goog.html.SafeHtml.BR, goog.debug.HtmlFormatter.exposeExceptionAsHtml(logRecord.getException()));
  }
  var logRecordHtml = goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces(logRecord.getMessage());
  var recordAndExceptionHtml = goog.html.SafeHtml.create("span", {"class":className}, goog.html.SafeHtml.concat(logRecordHtml, exceptionHtml));
  var html;
  if (this.appendNewline) {
    html = goog.html.SafeHtml.concat(fullPrefixHtml, recordAndExceptionHtml, goog.html.SafeHtml.BR);
  } else {
    html = goog.html.SafeHtml.concat(fullPrefixHtml, recordAndExceptionHtml);
  }
  return html;
};
goog.debug.TextFormatter = function(opt_prefix) {
  goog.debug.Formatter.call(this, opt_prefix);
};
goog.inherits(goog.debug.TextFormatter, goog.debug.Formatter);
goog.debug.TextFormatter.prototype.formatRecord = function(logRecord) {
  var sb = [];
  sb.push(this.prefix_, " ");
  if (this.showAbsoluteTime) {
    sb.push("[", goog.debug.Formatter.getDateTimeStamp_(logRecord), "] ");
  }
  if (this.showRelativeTime) {
    sb.push("[", goog.debug.Formatter.getRelativeTime_(logRecord, this.startTimeProvider_.get()), "s] ");
  }
  if (this.showLoggerName) {
    sb.push("[", logRecord.getLoggerName(), "] ");
  }
  if (this.showSeverityLevel) {
    sb.push("[", logRecord.getLevel().name, "] ");
  }
  sb.push(logRecord.getMessage());
  if (this.showExceptionText) {
    var exception = logRecord.getException();
    if (exception) {
      var exceptionText = exception instanceof Error ? exception.message : exception.toString();
      sb.push("\n", exceptionText);
    }
  }
  if (this.appendNewline) {
    sb.push("\n");
  }
  return sb.join("");
};
goog.debug.TextFormatter.prototype.formatRecordAsHtml = function(logRecord) {
  return goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces(goog.debug.TextFormatter.prototype.formatRecord(logRecord));
};
goog.provide("goog.debug.Console");
goog.require("goog.debug.LogManager");
goog.require("goog.debug.Logger");
goog.require("goog.debug.TextFormatter");
goog.debug.Console = function() {
  this.publishHandler_ = goog.bind(this.addLogRecord, this);
  this.formatter_ = new goog.debug.TextFormatter;
  this.formatter_.showAbsoluteTime = false;
  this.formatter_.showExceptionText = false;
  this.formatter_.appendNewline = false;
  this.isCapturing_ = false;
  this.logBuffer_ = "";
  this.filteredLoggers_ = {};
};
goog.debug.Console.prototype.getFormatter = function() {
  return this.formatter_;
};
goog.debug.Console.prototype.setCapturing = function(capturing) {
  if (capturing == this.isCapturing_) {
    return;
  }
  var rootLogger = goog.debug.LogManager.getRoot();
  if (capturing) {
    rootLogger.addHandler(this.publishHandler_);
  } else {
    rootLogger.removeHandler(this.publishHandler_);
    this.logBuffer = "";
  }
  this.isCapturing_ = capturing;
};
goog.debug.Console.prototype.addLogRecord = function(logRecord) {
  if (this.filteredLoggers_[logRecord.getLoggerName()]) {
    return;
  }
  var record = this.formatter_.formatRecord(logRecord);
  var console = goog.debug.Console.console_;
  if (console) {
    switch(logRecord.getLevel()) {
      case goog.debug.Logger.Level.SHOUT:
        goog.debug.Console.logToConsole_(console, "info", record);
        break;
      case goog.debug.Logger.Level.SEVERE:
        goog.debug.Console.logToConsole_(console, "error", record);
        break;
      case goog.debug.Logger.Level.WARNING:
        goog.debug.Console.logToConsole_(console, "warn", record);
        break;
      default:
        goog.debug.Console.logToConsole_(console, "debug", record);
        break;
    }
  } else {
    this.logBuffer_ += record;
  }
};
goog.debug.Console.prototype.addFilter = function(loggerName) {
  this.filteredLoggers_[loggerName] = true;
};
goog.debug.Console.prototype.removeFilter = function(loggerName) {
  delete this.filteredLoggers_[loggerName];
};
goog.debug.Console.instance = null;
goog.debug.Console.console_ = goog.global["console"];
goog.debug.Console.setConsole = function(console) {
  goog.debug.Console.console_ = console;
};
goog.debug.Console.autoInstall = function() {
  if (!goog.debug.Console.instance) {
    goog.debug.Console.instance = new goog.debug.Console;
  }
  if (goog.global.location && goog.global.location.href.indexOf("Debug=true") != -1) {
    goog.debug.Console.instance.setCapturing(true);
  }
};
goog.debug.Console.show = function() {
  alert(goog.debug.Console.instance.logBuffer_);
};
goog.debug.Console.logToConsole_ = function(console, fnName, record) {
  if (console[fnName]) {
    console[fnName](record);
  } else {
    console.log(record);
  }
};
goog.provide("uno.ConsoleLogger");
goog.require("goog.debug.Console");
(function() {
  var ConsoleLogger = uno.ConsoleLogger = function(opt) {
    goog.debug.Console.call(this);
    this.cache = [];
    this.cachingEnabled = true;
    this.maxEntries = null;
    this.configure(opt);
  };
  goog.inherits(uno.ConsoleLogger, goog.debug.Console);
  ConsoleLogger.prototype.configure = function(opt) {
    opt = opt || {};
    if (typeof opt.cachingEnabled !== "undefined") {
      this.cachingEnabled = !!opt.cachingEnabled;
    }
    this.maxEntries = opt.maxEntries;
    if (!this.cachingEnabled) {
      this.clear();
    }
    if (this.maxEntries != null && this.cache.length > this.maxEntries) {
      this.cache = this.cache.slice(this.cache.length - this.maxEntries);
    }
  };
  ConsoleLogger.prototype.addLogRecord = function(logRecord) {
    if (this.filteredLoggers_[logRecord.getLoggerName()]) {
      return;
    }
    logRecord.formattedText = this.formatter_.formatRecord(logRecord);
    var level = logRecord.getLevel();
    var formattedText = logRecord.formattedText;
    this.print(level, formattedText);
    if (this.cachingEnabled) {
      if (this.maxEntries != null && this.maxEntries <= this.cache.length) {
        this.cache.shift();
      }
      this.cache.push({level:level, formattedText:formattedText});
    }
  };
  ConsoleLogger.prototype.print = function(level, formattedText) {
    var console = goog.debug.Console.console_;
    if (console) {
      switch(level) {
        case goog.debug.Logger.Level.SHOUT:
          goog.debug.Console.logToConsole_(console, "info", formattedText);
          break;
        case goog.debug.Logger.Level.SEVERE:
          goog.debug.Console.logToConsole_(console, "error", formattedText);
          break;
        case goog.debug.Logger.Level.WARNING:
          goog.debug.Console.logToConsole_(console, "warn", formattedText);
          break;
        default:
          goog.debug.Console.logToConsole_(console, "debug", formattedText);
          break;
      }
    }
  };
  ConsoleLogger.prototype.dump = function() {
    var me = this;
    this.cache.forEach(function(record) {
      me.print(record.level, record.formattedText);
    });
  };
  ConsoleLogger.prototype.clear = function() {
    this.cache = [];
  };
})();
goog.provide("uno.defs");
(function() {
  uno.defs = {unicode:{ZERO_WIDTH_SPACE:"\u200b", NBSP:"\u00a0"}, dragtypes:{NATIVE:"native", IMAGE:"image", ATTACHMENT:"attachment", TABLE:"table", LIST:"list"}, containers:{EDITOR_BODY_SELECTOR:"en-note"}, structuretypes:{NOTE:"NOTE", CODE:"CODE", CRYPTO:"CRYPTO", EMOTICON:"EMOTICON", HR:"HR", LIST:"LIST", RESOURCE:"RESOURCE", TABLE:"TABLE", TEXT:"TEXT", TODO:"TODO", CMD_CRYPTO:"CMD_CRYPTO", CMD_INDENT:"CMD_INDENT", CMD_HR:"CMD_HR", CMD_LIST:"CMD_LIST", CMD_TODO:"CMD_TODO", CMD_CODE:"CMD_CODE", 
  TYPE_LIST:"TYPE_LIST"}, classes:{RESOURCE_CLASS:"en-media", MODULE_CLASS:"en-module"}, tags:{BLOCK:"div", BOLD:"b", ITALIC:"i", STRIKETHROUGH:"s", UNDERLINE:"u", TT:"tt"}, objects:{OBJECT_PLACEHOLDER_CLASS:"en-object-placeholder"}, crypto:{CRYPT_CLASS:"en-crypt", CRYPT_HIDDEN_CLASS:"en-crypt-placeholder", CRYPT_VISIBLE_CLASS:"en-crypt-revealed"}, format:{CLIPBOARD:"clipboard", ENML:"enml", CLIENT_HTML:"client_html"}, image:{TRANSPARENT_IMAGE_DATA_URL:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"}, 
  regex:{CODEBLOCK:"```", BULLETED_LIST:"^\u200b*\\s*\\*", HYPHEN_LIST:"^\u200b*\\s*\\-", HORIZONTAL_RULE:"^\u200b*\\s*[\\*\\-\\=]{3}[\\s\\*\\-\\=]*", INVALID_HTML_CHARS:"[\x00\u0001-\b\u000e-\u001f\u007f-\u009f\ufdd0-\ufdef\x0B\ufffe\uffff]|[\u0001-\u0010][\ufffe-\uffff]", NUMBERED_LIST:"^\u200b*\\s*[0-9]+\\.", SIMPLE_EMAIL:"[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}", TABLE:"^\u200b*\\s*(\\[\\s*\\]){2,}([xX][0-9]+)?", TODO:"\u200b*\\[[\\sxX]?\\]", WORD_CHARACTER:"[A-Za-z\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2183\u2184\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005\u3006\u3031-\u3035\u303b\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6e5\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]+", 
  SIMPLE_URL:"(" + "(?:" + "(?:[a-z]+://|www\\.)[a-z](?:[\\-\\.]*[a-z0-9])*" + "|" + "[a-z](?:[\\-\\.]*[a-z0-9])*\\.(?:com|net|edu|org)" + ")" + "(?:\\:\\d+)?" + ")" + "([\\/\\?#a-z0-9\\-_\\.~!\\$&%\\(\\)\\*\\+=:@]*[\\/\\?#a-z0-9&=]+)?", WEB_URL:"" + "(?:(?:https?|ftp)://)" + "(?:\\S+(?::\\S*)?@)?" + "(" + "(?:" + ("(?!(?:10|127)(?:\\.\\d{1,3}){3})" + "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + 
  "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))") + "|" + ("(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" + "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" + "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))") + ")" + ")" + "(?::\\d{2,5})?" + "(?:/\\S*)?", EMAIL:"\\S+@\\S+\\.\\S+"}, nbsp:{CHARACTER_SEQUENCE:"\u00a0"}, highlight:{COLOR:"rgb(255, 250, 165)", LEGACY_IOS:"rgb(255, 204, 102)", LEGACY_CLEARLY:"rgb(246, 238, 150)", regex:/rgb\(255, 204, 102\)|rgb\(255, 250, 165\)|rgb\(246, 238, 150\)/, 
  LEGACY_STYLE:"-evernote-highlighted", STYLE:"-evernote-highlight"}, table:{FIXED_WIDTH:792, CELL_LINE_HEIGHT:20, CELL_MIN_WIDTH:48, CELL_WIDTH:130, CELL_PADDING:8, CELL_HTML:"<div><br></div>", BORDER_COLOR:"rgb(204, 204, 204)"}, codeblock:{style:'box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial;'}, 
  bitfields:{NODE_SHOW_ALL:-1, NODE_SHOW_TEXT:4, NODE_FILTER_ACCEPT:1, NODE_FILTER_REJECT:2, NODE_ATTRIBUTE_NODE:2, NODE_TEXT_NODE:3, NODE_CDATA_SECTION_NODE:4, NODE_ENTITY_REFERENCE_NODE:5, NODE_ENTITY_NODE:6, NODE_PROCESSING_INSTRUCTION_NODE:7, NODE_COMMENT_NODE:8, NODE_DOCUMENT_NODE:9, NODE_DOCUMENT_TYPE_NODE:10, NODE_DOCUMENT_FRAGMENT_NODE:11, NODE_NOTATION_NODE:12, NODE_DOCUMENT_POSITION_PRECEDING:2, NODE_DOCUMENT_POSITION_FOLLOWING:4, NODE_DOCUMENT_POSITION_CONTAINS:8, NODE_DOCUMENT_POSITION_CONTAINED_BY:16}, 
  tab:{CHARACTER_SEQUENCE:"\u00a0\u00a0\u00a0\u00a0"}, blockElements:{p:true, h1:true, h2:true, h3:true, h4:true, h5:true, h6:true, pre:true, hr:true, br:true, li:true, div:true, table:true, tr:true, head:true, body:true}, edam:{TITLE_LEN_MAX:255}, paragraph:{indent:40}};
})();
goog.provide("uno.env");
goog.require("goog.userAgent");
(function() {
  var ua = goog.userAgent;
  var env = uno.env;
  env.getClient = function() {
    if (ua.MAC) {
      return "mac";
    } else {
      if (ua.WINDOWS) {
        return "win";
      } else {
        if (ua.ANDROID) {
          return "android";
        } else {
          if (ua.IOS) {
            return "ios";
          } else {
            return "web";
          }
        }
      }
    }
  };
})();
goog.provide("uno.EditorMultiRange");
goog.require("goog.debug.Logger");
goog.require("goog.dom.MultiRange");
(function() {
  var log = goog.debug.Logger.getLogger("uno.EditorMultiRange");
  var EditorMultiRange = uno.EditorMultiRange = function(editor) {
    this.invoking_ = false;
    this.invokedRangeIndex_ = -1;
    this.editor_ = editor;
  };
  goog.inherits(uno.EditorMultiRange, goog.dom.MultiRange);
  EditorMultiRange.Mode = {NONE:0, FIRST:1, ALL:2};
  EditorMultiRange.prototype.addTextRange = function(textRange) {
    if (this.findTextRangeIndex_(textRange) === -1) {
      this.browserRanges_.push(textRange.getBrowserRangeObject());
      this.clearCachedValues_();
    }
  };
  EditorMultiRange.prototype.removeTextRange = function(textRange) {
    var index = this.findTextRangeIndex_(textRange);
    if (index > -1) {
      this.browserRanges_.splice(index, 1);
      this.clearCachedValues_();
    }
  };
  EditorMultiRange.prototype.toggleTextRange = function(textRange, flag) {
    var index = this.findTextRangeIndex_(textRange);
    if (index === -1 && (flag || flag === undefined)) {
      this.browserRanges_.push(textRange.getBrowserRangeObject());
      this.clearCachedValues_();
    } else {
      if (index > -1 && !flag) {
        this.browserRanges_.splice(index, 1);
        this.clearCachedValues_();
      }
    }
  };
  EditorMultiRange.prototype.containsTextRange = function(textRange) {
    return this.findTextRangeIndex_(textRange) > -1;
  };
  EditorMultiRange.prototype.findTextRangeIndex_ = function(textRange) {
    if (!textRange) {
      return -1;
    }
    var wrapper = textRange.getBrowserRangeWrapper_();
    var start = goog.dom.RangeEndpoint.START;
    var end = goog.dom.RangeEndpoint.END;
    try {
      for (var i = 0, l = this.browserRanges_.length; i < l; i++) {
        var range = this.browserRanges_[i];
        if (wrapper.compareBrowserRangeEndpoints(range, end, end) >= 0 && wrapper.compareBrowserRangeEndpoints(range, start, start) <= 0) {
          return i;
        }
      }
    } catch (err$8) {
      this.clear();
      log.warning(err$8.stack || err$8);
    }
    return -1;
  };
  EditorMultiRange.prototype.isEmpty = function() {
    return !this.getTextRangeCount();
  };
  EditorMultiRange.prototype.isInvoking = function() {
    return this.invoking_;
  };
  EditorMultiRange.prototype.isLastInvokedRange = function() {
    return this.invokedRangeIndex_ >= this.browserRanges_.length - 1;
  };
  EditorMultiRange.prototype.isFirstInvokedRange = function() {
    return this.invokedRangeIndex_ === 0;
  };
  EditorMultiRange.prototype.clear = function() {
    this.browserRanges_ = [];
    this.clearCachedValues_();
  };
  EditorMultiRange.prototype.invoke = function(mode, fn, context) {
    var retVal = null;
    try {
      if (mode !== EditorMultiRange.Mode.NONE && !this.isEmpty()) {
        var originalRange = this.editor_.getRange();
        var iterFn = mode === EditorMultiRange.Mode.ALL ? goog.array.forEach : goog.array.some;
        this.invoking_ = true;
        iterFn(this.getTextRanges(), function(range, index) {
          this.currentInvokeRangeIndex_ = index;
          range.select();
          var result = fn.call(context || this.editor_);
          if (!retVal && result) {
            retVal = result;
          }
          return result;
        }, this);
        if (originalRange) {
          originalRange.select();
        }
        this.currentInvokeRangeIndex_ = -1;
        setTimeout(function() {
          this.invoking_ = false;
        }.bind(this));
        return !!retVal;
      }
      return !!fn.call(context || this.editor_);
    } catch (err$9) {
      log.severe(err$9.stack || err$9);
      return false;
    }
  };
})();
goog.provide("uno.util.zoomscale");
goog.require("uno.defs");
(function() {
  var util = uno.util;
  var note = null;
  util.zoomscale.getZoom = function() {
    if (!note) {
      note = document.querySelector(uno.defs.containers.EDITOR_BODY_SELECTOR);
    }
    var zoom = parseFloat(note.style.zoom);
    return isNaN(zoom) ? 1.0 : zoom;
  };
  util.zoomscale.normalizeRect = function(rect) {
    var zoom = uno.util.zoomscale.getZoom();
    if (rect && zoom && zoom !== 1.0) {
      var b = {};
      if (rect.left) {
        b.left = rect.left * zoom;
      }
      if (rect.right) {
        b.right = rect.right * zoom;
      }
      if (rect.top) {
        b.top = rect.top * zoom;
      }
      if (rect.bottom) {
        b.bottom = rect.bottom * zoom;
      }
      if (rect.width) {
        b.width = rect.width * zoom;
      }
      if (rect.height) {
        b.height = rect.height * zoom;
      }
      return b;
    }
    return rect;
  };
})();
goog.provide("uno.util.todo.generic");
(function() {
  var util = uno.util;
  var generic = util.todo.generic;
  generic.tryToInsertTodo = function(editor) {
    editor.execCommand("insertparagraph");
    editor.execCommand("inserttodo");
    return true;
  };
  generic.findTodosInClientHtml = function() {
    return [];
  };
})();
goog.provide("uno.util.todo.mac");
goog.require("goog.dom");
goog.require("goog.dom.classes");
goog.require("uno.util.todo.generic");
(function() {
  var mac = uno.util.todo.mac;
  var util = uno.util;
  mac.tryToInsertTodo = function(editor) {
    return util.todo.generic.tryToInsertTodo(editor);
  };
  mac.findTodosInClientHtml = function(frag) {
    return frag.querySelectorAll("img.en-todo");
  };
  mac.convertClientElementToTodo = function(el) {
    var checked = goog.dom.classes.has(el, "en-todo-checked");
    var entodo = util.todo.create(checked);
    goog.dom.replaceNode(entodo, el);
  };
  mac.convertTodoToClientElement = function(todo) {
    var img = goog.dom.createDom("img", {class:"en-todo"});
    if (util.todo.isChecked(todo)) {
      goog.dom.classes.add(img, "en-todo-checked");
    }
    goog.dom.replaceNode(img, todo);
  };
})();
goog.provide("uno.util.todo.ios");
(function() {
  var ios = uno.util.todo.ios;
  var util = uno.util;
  ios.tryToInsertTodo = function(editor) {
    return false;
  };
  ios.findTodosInClientHtml = function() {
    return [];
  };
  ios.convertTodoToClientElement = function() {
  };
  ios.convertClientElementToTodo = function(el) {
    var todo = util.todo.create(!!el.checked);
    goog.dom.replaceNode(todo, el);
  };
})();
goog.provide("uno.util.todo.win");
goog.require("goog.dom");
goog.require("uno.util.todo.generic");
(function() {
  var util = uno.util;
  var win = uno.util.todo.win;
  win.tryToInsertTodo = function(editor) {
    return util.todo.generic.tryToInsertTodo(editor);
  };
  win.findTodosInClientHtml = function(frag) {
    return frag.querySelectorAll("img[src^=en-resource\\:\\/\\/database\\/check]");
  };
  win.convertClientElementToTodo = function(el) {
    var src = el.getAttribute("src");
    var matches = /database\/check(\d+):(\d+)/.exec(src);
    var X = parseInt(matches[1], 10);
    var checked = X === 1 || X === 3;
    var entodo = util.todo.create(checked);
    goog.dom.replaceNode(entodo, el);
  };
  win.convertTodoToClientElement = function(todo) {
    var src = "en-resource://database/check";
    src += util.todo.isChecked(todo) ? "1" : "0";
    src += ":0";
    var img = goog.dom.createDom("img", {src:src});
    goog.dom.replaceNode(img, todo);
  };
})();
goog.provide("uno.util.todo");
goog.require("goog.debug.Logger");
goog.require("goog.dom.classes");
goog.require("uno.util.todo.generic");
goog.require("uno.util.todo.mac");
goog.require("uno.util.todo.ios");
goog.require("uno.util.todo.win");
goog.require("uno.defs");
(function() {
  var util = uno.util;
  var client = uno.util.todo.generic;
  util.todo.setClient = function(clientName) {
    client = uno.util.todo[clientName] || client;
  };
  util.todo.all = function(root) {
    return root.querySelectorAll(".en-todo");
  };
  util.todo.allEnmlTodos = function(root) {
    return root.querySelectorAll("en-todo");
  };
  util.todo.isTodo = function(el) {
    return el && goog.dom.classes.has(el, "en-todo");
  };
  util.todo.create = function(checked) {
    var todo = new Image;
    todo.src = uno.defs.image.TRANSPARENT_IMAGE_DATA_URL;
    goog.dom.classes.add(todo, "en-todo");
    if (checked) {
      util.todo.toggle(todo);
    }
    return todo;
  };
  util.todo.tryToInsertTodo = function(editor) {
    return client.tryToInsertTodo(editor);
  };
  util.todo.isChecked = function(todo) {
    return todo.getAttribute("checked") === "true";
  };
  util.todo.setChecked = function(todo, checked) {
    todo.setAttribute("checked", checked);
  };
  util.todo.toggle = function(todo) {
    todo.setAttribute("checked", !util.todo.isChecked(todo));
  };
  util.todo.remove = function(todo) {
    if (!todo || !todo.parentNode) {
      return;
    }
    var textNode = goog.editor.node.getNextSibling(todo);
    if (textNode && textNode.nodeType === Node.TEXT_NODE) {
      var text = textNode.textContent;
      var updated = goog.string.trimLeft(text);
      if (updated !== text) {
        if (updated.length === 0) {
          goog.dom.removeNode(textNode);
        } else {
          textNode.textContent = updated;
        }
      }
    }
    goog.dom.removeNode(todo);
  };
  util.todo.findTodosInClientHtml = function(root) {
    return client.findTodosInClientHtml(root);
  };
  util.todo.convertClientElementToTodo = function(el) {
    client.convertClientElementToTodo(el);
  };
  util.todo.convertTodoToClientElement = function(todo) {
    client.convertTodoToClientElement(todo);
  };
  util.todo.convertTodoInClipboard = function(todo) {
    return util.todo.create(todo.textContent === "[x]");
  };
  util.todo.convertTodoToClipboardElement = function(fragment) {
    var todo = goog.dom.createDom("span", "en-todo");
    var value = document.createTextNode("[]");
    if (util.todo.isChecked(fragment)) {
      value = document.createTextNode("[x]");
    }
    todo.appendChild(value);
    return todo;
  };
  util.todo.decorate = function(entodo) {
    var checked = util.todo.isChecked(entodo);
    goog.dom.replaceNode(util.todo.create(checked), entodo);
  };
  util.todo.undecorate = function(todo) {
    var entodo = goog.dom.createDom("en-todo");
    entodo.setAttribute("checked", util.todo.isChecked(todo));
    goog.dom.replaceNode(entodo, todo);
  };
  util.todo.addTodoToParagraph = function(node) {
    var todo = util.todo.create();
    node.insertBefore(todo, node.firstChild);
    return node;
  };
})();
goog.provide("uno.util.dom");
goog.require("uno.defs");
goog.require("uno.util.zoomscale");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.string");
goog.require("goog.editor.node");
goog.require("goog.html.SafeHtml");
goog.require("uno.util.todo");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.dom");
  var dom = uno.util.dom;
  var util = uno.util;
  dom.inlineObjects = ["en-media", "en-todo", "en-crypt", "en-cursor", "img", "embed", "object", "input", "param", "hr", "br", "en-adornments", "en-comment"];
  dom.blockObjects = ["object", "hr", "en-table", "en-codeblock", "en-imagelayout"];
  dom.uiObjects = ["ui-table", "ui-list"];
  dom.tableObjects = ["colgroup", "col", "tr", "td"];
  dom.inlineTagNames = ["en-media", "en-cursor", "span", "font", "a", "br", "img", "object", "embed"];
  dom.blockTagNames = ["en-note", "address", "article", "aside", "body", "blockquote", "caption", "center", "col", "colgroup", "dd", "details", "dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "listing", "menu", "nav", "ol", "p", "plaintext", "pre", "section", "summary", "table", "en-table", "tbody", "td", "tfoot", "th", "thead", "tr", "ul", "xmp"];
  dom.isInlineObject = function(node) {
    if (!node || !dom.isElementNode(node)) {
      return false;
    }
    return dom.inlineObjects.indexOf(node.tagName.toLowerCase()) > -1;
  };
  dom.isBlockObject = function(node) {
    if (!node || !dom.isElementNode(node)) {
      return false;
    }
    return dom.blockObjects.indexOf(node.tagName.toLowerCase()) > -1 || dom.isRevealedCrypt(node) || dom.isCodeBlock(node);
  };
  dom.isTextNode = function(node) {
    return !!(node && node.nodeType === Node.TEXT_NODE);
  };
  dom.isElementNode = function(node) {
    return !!(node && node.nodeType === Node.ELEMENT_NODE);
  };
  dom.isBlockNode = function(node) {
    if (!node) {
      return false;
    }
    return !!(dom.blockTagNames.indexOf(dom.getTagName(node)) > -1 || node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE);
  };
  dom.isInlineNode = function(node) {
    return !!(node && !dom.isBlockNode(node));
  };
  dom.isUneditable = function(node) {
    return dom.isElementNode(node) && node.getAttribute("contenteditable") === "false";
  };
  dom.isUIObject = function(node) {
    if (!node || dom.isTextNode(node)) {
      return false;
    }
    return dom.uiObjects.indexOf(node.tagName.toLowerCase()) > -1;
  };
  dom.getLastParagraphItem = function(node) {
    if (!node) {
      return null;
    }
    if (!node.childNodes || !node.childNodes.length) {
      return node;
    }
    var leafNode = null;
    goog.array.forEachRight(node.childNodes, function(element) {
      if (leafNode || dom.isEmpty(element)) {
        return;
      }
      if (!element.childNodes || !element.childNodes.length || dom.isInlineObject(element)) {
        leafNode = element;
      } else {
        leafNode = dom.getLastParagraphItem(element);
      }
    });
    return leafNode;
  };
  dom.getFirstParagraphItem = function(node) {
    if (!node) {
      return null;
    }
    if (!node.childNodes || !node.childNodes.length) {
      return node;
    }
    var leafNode = null;
    goog.array.forEach(node.childNodes, function(element) {
      if (leafNode || dom.isEmpty(element)) {
        return;
      }
      if (!element.childNodes || !element.childNodes.length || dom.isInlineObject(element)) {
        leafNode = element;
      } else {
        leafNode = dom.getFirstParagraphItem(element);
      }
    });
    return leafNode;
  };
  dom.isFragment = function(node) {
    return !!(node.nodeType === Node.DOCUMENT_FRAGMENT_NODE);
  };
  dom.isNoteSection = function(node) {
    if (!node) {
      return false;
    }
    return !!(dom.isEnnote(node) || dom.isTd(node) || dom.isCodeBlock(node) || dom.isLi(node) || dom.isRevealedCrypt(node) || dom.isBlockquote(node) || dom.isFragment(node));
  };
  dom.getNodeLeaves = function(root, forcedLeaves, skipTextNodes) {
    var deepestNodes = [];
    forcedLeaves = forcedLeaves || [];
    var getNodeLeaves = function(node, forcedLeaves) {
      var isForcedLeaf = node.tagName && forcedLeaves.indexOf(node.tagName.toLowerCase()) > -1;
      if (!node.childNodes || !node.childNodes.length || isForcedLeaf) {
        if (skipTextNodes && !dom.isTextNode(node) || !skipTextNodes) {
          deepestNodes.push(node);
        }
      }
      goog.iter.forEach(node.childNodes, function(child) {
        if (!isForcedLeaf) {
          getNodeLeaves(child, forcedLeaves);
        }
      });
    };
    if (root && root.childNodes) {
      goog.iter.forEach(root.childNodes, function(node) {
        getNodeLeaves(node, forcedLeaves);
      });
    }
    return deepestNodes;
  };
  dom.getTagName = function(node) {
    return node && node.tagName && node.tagName.toLowerCase() || "";
  };
  dom.endContent = function(node) {
    if (!node) {
      return null;
    }
    if (dom.isTextNode(node) || dom.isInlineObject(node)) {
      return node;
    }
    var leafNode = null;
    goog.array.forEachRight(node.childNodes || [], function(element) {
      if (leafNode || dom.isUIObject(element)) {
        return;
      }
      if (dom.isTextNode(element) || dom.isInlineObject(element)) {
        leafNode = element;
      } else {
        leafNode = dom.endContent(element);
      }
    });
    return leafNode;
  };
  dom.startContent = function(node) {
    if (!node) {
      return null;
    }
    if (dom.isTextNode(node) || dom.isInlineObject(node)) {
      return node;
    }
    var leafNode = null;
    goog.array.forEach(node.childNodes || [], function(element) {
      if (leafNode || dom.isUIObject(element)) {
        return;
      }
      if (dom.isTextNode(element) || dom.isInlineObject(element)) {
        leafNode = element;
      } else {
        leafNode = dom.startContent(element);
      }
    });
    return leafNode;
  };
  dom.isBlockOrInlineBlockNode = function(node) {
    if (!node || !node.style) {
      return false;
    }
    if (node.style.display === "block" || node.style.display === "inline-block") {
      return true;
    }
    if (node.style.display === "" || node.style.display === "inherit" || node.style.display === "default") {
      return dom.isBlockNode(node);
    }
    return false;
  };
  dom.changeTagName = function(node, newTagName) {
    if (!node || !newTagName) {
      return false;
    }
    var attributes = {};
    goog.array.forEach(node.attributes, function(item) {
      attributes[item.name] = item.value;
    });
    var newNode = goog.dom.createDom(newTagName, attributes, node.childNodes);
    goog.dom.replaceNode(newNode, node);
    return newNode;
  };
  dom.clone = function(node) {
    var clone = goog.dom.createDom("div", null);
    if (dom.isTextNode(node)) {
      clone.innerText = node.textContent;
    } else {
      clone.innerHTML = node.outerHTML;
    }
    return clone.firstChild;
  };
  dom.nodeFromHtml = function(html, tagName, attributes, childNodes) {
    var node = goog.dom.createDom(tagName || "div", attributes, childNodes);
    node.innerHTML = html;
    return node;
  };
  dom.isEmpty = function(node) {
    if (!node) {
      return true;
    }
    if (node.nodeType === Node.TEXT_NODE) {
      return !node.data.length;
    }
    if (node.firstChild) {
      if (node.querySelectorAll("br").length > 1) {
        return false;
      }
      if (node.querySelectorAll("li, blockquote, table").length > 0) {
        return false;
      }
      if (!dom.isEnnote(node) && dom.isBlockNode(node) && node.getAttribute && node.getAttribute("style")) {
        return false;
      }
      return Array.prototype.every.call(node.childNodes, function(childNode) {
        return dom.isEmpty(childNode);
      });
    }
    if (dom.isBlockOrInlineBlockNode(node) && util.styles.hasLayoutStyle(node)) {
      return false;
    }
    var tagName = dom.getTagName(node);
    var components = ["img", "embed", "object", "input", "param", "hr", "en-media", "en-table", "en-todo", "en-crypt"];
    var isObject = components.indexOf(tagName) > -1;
    return !isObject;
  };
  dom.isEmptyContent = function(node) {
    if (!node) {
      return true;
    }
    if (node.nodeType === Node.TEXT_NODE) {
      return !node.data.length;
    }
    if (node.firstChild) {
      if (node.querySelectorAll("br, li").length > 1) {
        return false;
      }
      return Array.prototype.every.call(node.childNodes, function(childNode) {
        return dom.isEmptyContent(childNode);
      });
    }
    var tagName = node.tagName.toLowerCase();
    var components = ["img", "embed", "object", "input", "param", "hr", "en-media", "en-table", "en-todo", "en-crypt"];
    var isObject = components.indexOf(tagName) > -1;
    return !isObject;
  };
  dom.parent = function(node, selector, rootNode) {
    if (!rootNode) {
      rootNode = document.body;
    }
    if (node === rootNode) {
      return null;
    }
    if (dom.matches(node, selector)) {
      return node;
    }
    var parentNode = node && node.parentNode;
    if (parentNode) {
      return dom.parent(parentNode, selector, rootNode);
    }
    return null;
  };
  var createIsTagNames = function() {
    dom.blockTagNames.concat(dom.inlineTagNames).forEach(function(tagName) {
      var fnName = "is" + goog.string.capitalize(tagName.replace("-", ""));
      dom[fnName] = function(node) {
        return node && node.tagName && node.tagName.toLowerCase() === tagName ? node : null;
      };
    });
  };
  createIsTagNames();
  dom.isHeader = function(node) {
    return node && node.tagName && ["h1", "h2", "h3", "h4", "h5", "h6"].indexOf(node.tagName.toLowerCase()) > -1 ? node : null;
  };
  dom.isCodeBlock = function(node) {
    if (!node || !dom.isElementNode(node)) {
      return false;
    }
    return node.classList.contains("en-code") || node.getAttribute("data-en-codeblock") !== null || (node.getAttribute("style") || "").indexOf("-en-codeblock:") > -1;
  };
  dom.isRevealedCrypt = function(node) {
    if (!node) {
      return false;
    }
    return !!goog.dom.classlist.contains(node, "en-crypt-revealed");
  };
  dom.getFirstAncestor = function(node, tagNames, includeNode) {
    return goog.dom.getAncestor(node, function(ancestor) {
      return ancestor && ancestor.tagName && tagNames.indexOf(ancestor.tagName.toLowerCase()) > -1;
    }, includeNode);
  };
  dom.getOrigin = function(child) {
    var origin = goog.dom.getAncestor(child, function(node) {
      return dom.isTd(node) || dom.isCodeBlock(node) || dom.isRevealedCrypt(node) || dom.isEnnote(node);
    }, true);
    return origin;
  };
  dom.ancestors = function(node) {
    var ancestors = [];
    while (node && node.parentNode) {
      ancestors.unshift(node.parentNode);
      node = node.parentNode;
    }
    return ancestors;
  };
  dom.getNextSiblings = function(node) {
    if (!node) {
      return [];
    }
    var nodes = [];
    var sib = node;
    while (sib.nextSibling) {
      nodes.push(sib.nextSibling);
      sib = sib.nextSibling;
    }
    return nodes;
  };
  dom.getPreviousSiblings = function(node) {
    if (!node) {
      return [];
    }
    var nodes = [];
    var sib = node;
    while (sib.previousSibling) {
      nodes.unshift(sib.previousSibling);
      sib = sib.previousSibling;
    }
    return nodes;
  };
  dom.contiguousInlineSiblings = function(node) {
    var nodes = [node];
    var sib = node.previousSibling;
    while (sib && !dom.isBlockNode(sib)) {
      nodes.unshift(sib);
      sib = sib.previousSibling;
    }
    sib = node.nextSibling;
    while (sib && !dom.isBlockNode(sib)) {
      nodes.push(sib);
      sib = sib.nextSibling;
    }
    return nodes;
  };
  var rxEscapeObj = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g;
  var rxEscape = function(value) {
    if (value instanceof RegExp) {
      return value.source;
    }
    return value.replace(rxEscapeObj, "\\$&");
  };
  var regexForAppDataNameCache = {};
  var regexForAppDataName = function(name) {
    var rx = regexForAppDataNameCache[name];
    if (!rx) {
      rx = new RegExp("(^|;)\\s*(" + rxEscape(name) + ")\\s*\\:\\s*(.*?)($|;)+", "gi");
      regexForAppDataName[name] = rx;
    } else {
      rx.lastIndex = 0;
    }
    return rx;
  };
  dom.fragFromString = function(html) {
    var frag = document.createDocumentFragment();
    var temp = document.createElement("div");
    temp.innerHTML = html;
    while (temp.firstChild) {
      if (temp.firstChild.nodeType === Node.TEXT_NODE && temp.firstChild.textContent.trim().length === 0) {
        goog.dom.removeNode(temp.firstChild);
        continue;
      }
      frag.appendChild(temp.firstChild);
    }
    return frag;
  };
  dom.stringFromFrag = function(frag) {
    return Array.prototype.reduce.call(frag.childNodes, function(html, node) {
      return html + (node.outerHTML || node.textContent);
    }, "");
  };
  dom.compareTagName = function(el, names, caseSensitive) {
    if (typeof names === "string") {
      names = [names];
    }
    if (el && el.tagName) {
      var tagName = caseSensitive ? el.tagName : el.tagName.toLowerCase();
      return names.some(function(name) {
        return caseSensitive ? tagName === name : tagName === name.toLowerCase();
      });
    }
    return false;
  };
  dom.getNodeLength = function(node) {
    if (!node) {
      return 0;
    }
    switch(node.nodeType) {
      case Node.PROCESSING_INSTRUCTION_NODE:
      case Node.DOCUMENT_TYPE_NODE:
        return 0;
      case Node.TEXT_NODE:
      case Node.COMMENT_NODE:
        return node.length;
      default:
        return node.childNodes.length;
    }
  };
  dom.nextNode = function(node) {
    if (node.hasChildNodes()) {
      return node.firstChild;
    }
    return dom.nextNodeDescendants(node);
  };
  dom.previousNode = function(node) {
    if (node.previousSibling) {
      node = node.previousSibling;
      while (node.hasChildNodes()) {
        node = node.lastChild;
      }
      return node;
    }
    if (dom.isElementNode(node.parentNode)) {
      return node.parentNode;
    }
    return null;
  };
  dom.nextNodeDescendants = function(node, root) {
    while (node && !node.nextSibling) {
      if (root === node) {
        break;
      }
      node = node.parentNode;
    }
    if (!node || root && root === node) {
      return null;
    }
    return node.nextSibling;
  };
  dom.isEditable = function(node) {
    return !!(node && dom.isInsideEditableContainer(node) && (dom.isElementNode(node) || dom.isElementNode(node.parentNode)));
  };
  dom.isComputedBlock = function(node) {
    var display = goog.style.getComputedStyle(node, "display");
    return !!(display === "block");
  };
  dom.hasEditableDescendants = function(node) {
    for (var i = 0; i < node.childNodes.length; i++) {
      if (dom.isEditable(node.childNodes[i]) || dom.hasEditableDescendants(node.childNodes[i])) {
        return true;
      }
    }
    return false;
  };
  dom.moveChildren = function(srcNode, destNode) {
    while (srcNode.firstChild) {
      destNode.appendChild(srcNode.firstChild);
    }
    return destNode;
  };
  dom.replaceContainer = function(node, replacementElement) {
    node.parentNode.insertBefore(replacementElement, node);
    dom.moveChildren(node, replacementElement);
    goog.dom.removeNode(node);
    return replacementElement;
  };
  dom.isVisible = function(node) {
    if (!node) {
      return false;
    }
    if (dom.isBlockNode(node) || dom.isImageLikeElement(node) || node.nodeType === Node.TEXT_NODE && !dom.isCollapsedWhitespaceNode(node) || node.tagName.toUpperCase() === "BR" && !dom.isExtraneousLineBreak(node)) {
      return true;
    }
    for (var i = 0; i < node.childNodes.length; i++) {
      if (dom.isVisible(node.childNodes[i])) {
        return true;
      }
    }
    return false;
  };
  dom.isImageLikeElement = function(node) {
    return !!(dom.compareTagName(node, ["img", "embed", "object", "input", "param", "hr"]) || goog.dom.classes.has(node, "en-media") || goog.dom.classes.has(node, "en-module") || goog.dom.classes.has(node, "en-richlink"));
  };
  dom.isCollapsedWhitespaceNode = function(node) {
    if (!dom.isWhitespaceNode(node)) {
      return false;
    }
    if (node.data === "") {
      return true;
    }
    var ancestor = node.parentNode;
    if (!ancestor) {
      return true;
    }
    while (!dom.isBlockNode(ancestor) && ancestor.parentNode) {
      ancestor = ancestor.parentNode;
    }
    var reference = node;
    while (reference != ancestor) {
      reference = dom.previousNode(reference);
      if (dom.isBlockNode(reference) || dom.isBr(reference)) {
        return true;
      }
      if (reference.nodeType == Node.TEXT_NODE && !dom.isWhitespaceNode(reference) || dom.isImageLikeElement(reference)) {
        break;
      }
    }
    reference = node;
    var stop = dom.nextNodeDescendants(ancestor);
    while (reference != stop) {
      reference = dom.nextNode(reference);
      if (dom.isBlockNode(reference) || dom.isBr(reference)) {
        return true;
      }
      if (reference && reference.nodeType == Node.TEXT_NODE && !dom.isWhitespaceNode(reference) || dom.isImageLikeElement(reference)) {
        break;
      }
    }
    return false;
  };
  dom.isWhitespaceNode = function(node) {
    dom.rxWhitespace.lastIndex = 0;
    return !!(node && node.nodeType === Node.TEXT_NODE && (node.data === "" || dom.rxWhitespace.test(node.data)));
  };
  dom.rxWhitespace = /^[\t\n\r ]+$/;
  dom.getEffectiveCssValue = function(node, propName) {
    if (!dom.isElementNode(node) && (!node.parentNode || !dom.isElementNode(node.parentNode))) {
      return null;
    }
    if (!dom.isElementNode(node)) {
      return dom.getEffectiveCssValue(node.parentNode, propName);
    }
    if (!dom.isRenderedDOMNode(node)) {
      log.warn("We are not on rendered DOM for fontSize retieval", node);
      return dom.styleInheritedForNode(node, propName, "");
    }
    if (node.style && node.style[propName] !== null && node.style[propName] !== "") {
      return node.style[propName];
    }
    var ret = goog.style.getComputedStyle(node, propName);
    return ret;
  };
  dom.styleInheritedForNode = function(node, styleName, defaultValue, root) {
    root = root || document.body;
    defaultValue = defaultValue || "";
    var styleValue;
    if (node == null) {
      return defaultValue;
    }
    if (!dom.isChild(node, root)) {
      do {
        if (dom.isElementNode(node) && node.hasAttribute("style")) {
          styleValue = node.style[styleName];
          if (styleValue != null) {
            break;
          }
        }
      } while ((node = node.parentNode) && root === node);
    }
    return styleValue || defaultValue;
  };
  dom.isUnwrappedTextMarkup = function(html) {
    var tags = (html.match(/<[a-z-]+/gi) || []).map(function(tag) {
      return tag.slice(1).toLowerCase();
    });
    return tags.every(function(tag) {
      return dom.inlineObjects.indexOf(tag) > -1;
    });
  };
  dom.isRenderedDOMNode = function(node) {
    return !!(node && (node.isEqualNode(document.documentElement) || document.documentElement.contains(node)));
  };
  dom.isBefore = function(node1, node2) {
    return node1 != null && node2 != null && !!(node1.compareDocumentPosition(node2) & Node.DOCUMENT_POSITION_FOLLOWING);
  };
  dom.isInsideEditableContainer = function(node) {
    return true;
  };
  dom.isExtraneousLineBreak = function(br) {
    return false;
  };
  dom.firstChild = function(node) {
    if (goog.dom.isElement(node) && node.firstChild) {
      return dom.firstChild(node.firstChild);
    } else {
      return node;
    }
  };
  dom.isBeginningOfLineChild = function(node, root) {
    var beginNode = dom.firstChild(node);
    if (beginNode.parentNode !== root) {
      while (beginNode.parentNode !== root) {
        beginNode = beginNode.parentNode;
      }
      return dom.firstChild(beginNode) === dom.firstChild(node);
    } else {
      return dom.index(beginNode) === 0;
    }
  };
  dom.isPrecededByInlineContent = function(node) {
    var div = goog.dom.getAncestorByTagNameAndClass(node, goog.dom.TagName.DIV);
    if (!div || !div.childNodes) {
      return false;
    }
    function hasInlineContentBeforeNode(elt) {
      var result = false;
      goog.array.some(elt.childNodes, function(child) {
        if (child === node) {
          return true;
        }
        if (child.contains(node) && !hasInlineContentBeforeNode(child)) {
          return true;
        }
        if (!dom.isBlockNode(child)) {
          if (child.nodeType === Node.TEXT_NODE && (child.textContent.length === 0 || child.textContent === uno.defs.unicode.ZERO_WIDTH_SPACE)) {
            return false;
          }
          result = true;
        }
        return false;
      });
      return result;
    }
    return hasInlineContentBeforeNode(div);
  };
  dom.index = function(node) {
    var ret = 0;
    while (node = node.previousSibling) {
      ret++;
    }
    return ret;
  };
  dom.matches = function(node, selector) {
    if (!node || !dom.isElementNode(node)) {
      return false;
    }
    if (goog.isString(selector)) {
      if (node.matches != null) {
        return node.matches(selector);
      } else {
        var matches = document.querySelectorAll(selector);
        var i;
        for (i = 0; i < matches.length; i += 1) {
          if (matches.item(i) === node) {
            return true;
          }
        }
      }
    } else {
      if (goog.isFunction(selector)) {
        return selector(node);
      }
    }
    return false;
  };
  dom.attributes = function(node) {
    var attrs = {};
    if (node) {
      var nodeAttrs = node.attributes;
      if (nodeAttrs) {
        for (var i = nodeAttrs.length; i--;) {
          attrs[nodeAttrs[i].name.toLowerCase()] = nodeAttrs[i].value;
        }
      }
    }
    return attrs;
  };
  dom.moveNode = function(node, newParent, newIndex, activeRange) {
    if (newParent && newIndex === -1) {
      newIndex = newParent.childNodes.length;
    }
    var oldParent = node.parentNode;
    var oldIndex = dom.index(node);
    var preserve = activeRange != null;
    if (preserve) {
      var boundaryPoints = [[activeRange.getStartNode(), activeRange.getStartOffset()], [activeRange.getEndNode(), activeRange.getEndOffset()]];
      boundaryPoints.forEach(function(boundaryPoint) {
        if (boundaryPoint[0] === newParent && boundaryPoint[1] > newIndex) {
          boundaryPoint[1]++;
        }
        if (boundaryPoint[0] === oldParent && (boundaryPoint[1] === oldIndex || boundaryPoint[1] === oldIndex + 1)) {
          if (newParent) {
            boundaryPoint[0] = newParent;
            boundaryPoint[1] += newIndex - oldIndex;
          } else {
            if (boundaryPoint[1] > oldIndex && boundaryPoint[1] > 0) {
              boundaryPoint[1] -= 1;
            }
          }
        }
        if (boundaryPoint[0] === oldParent && boundaryPoint[1] > oldIndex + 1) {
          boundaryPoint[1]--;
        }
        if (!newParent && dom.isChild(boundaryPoint[0], node)) {
          boundaryPoint[0] = node.parentNode;
          boundaryPoint[1] = dom.index(node);
        }
      });
    }
    if (!newParent) {
      goog.dom.removeNode(node);
      return;
    }
    if (newParent.childNodes.length === newIndex || newIndex === -1) {
      newParent.appendChild(node);
    } else {
      newParent.insertBefore(node, newParent.childNodes[+newIndex]);
    }
    goog.dom.Range.clearSelection();
    if (preserve) {
      goog.dom.browserrange.createRangeFromNodes(boundaryPoints[0][0], boundaryPoints[0][1], boundaryPoints[1][0], boundaryPoints[1][1]).select();
    }
  };
  dom.detachNode = function(node) {
    if (node) {
      node = goog.isArray(node) ? node : [node];
      node.forEach(function(el) {
        el.parentNode.removeChild(el);
      });
      return node;
    }
  };
  dom.getNextEquivalentPoint = function(node, offset) {
    if (dom.getNodeLength(node) === 0) {
      return null;
    }
    if (offset === dom.getNodeLength(node) && node.parentNode && dom.isInlineNode(node)) {
      return [node.parentNode, 1 + dom.index(node)];
    }
    if (0 <= offset && offset < node.childNodes.length && dom.getNodeLength(node.childNodes[offset]) !== 0 && dom.isInlineNode(node.childNodes[offset])) {
      return [node.childNodes[offset], 0];
    }
    return null;
  };
  dom.getLastEquivalentPoint = function(node, offset) {
    var next;
    while (next = dom.getNextEquivalentPoint(node, offset)) {
      node = next[0];
      offset = next[1];
    }
    return [node, offset];
  };
  dom.isChild = function(node, other) {
    if (!other || !node) {
      return false;
    }
    return !!(node.compareDocumentPosition(other) & Node.DOCUMENT_POSITION_CONTAINS);
  };
  dom.isParent = function(node, other) {
    if (!other || !node) {
      return false;
    }
    return !!(node.compareDocumentPosition(other) & 16);
  };
  dom.getStyleString = function(node) {
    if (!node || !node.getAttribute) {
      return "";
    }
    return node.getAttribute("style");
  };
  var TreeWalker = dom.TreeWalker = function(startNode, rootNode) {
    var node = startNode;
    function findSibling(node, startName, siblingName, shallow) {
      var sibling, parent;
      if (node) {
        if (!shallow && node[startName]) {
          return node[startName];
        }
        if (node != rootNode) {
          sibling = node[siblingName];
          if (sibling) {
            return sibling;
          }
          for (parent = node.parentNode; parent && parent != rootNode; parent = parent.parentNode) {
            sibling = parent[siblingName];
            if (sibling) {
              return sibling;
            }
          }
        }
      }
    }
    this.current = function() {
      return node;
    };
    this.next = function(shallow) {
      node = findSibling(node, "firstChild", "nextSibling", shallow);
      return node;
    };
    this.prev = function(shallow) {
      node = findSibling(node, "lastChild", "previousSibling", shallow);
      return node;
    };
  };
  dom.isBlockFormattingContext = function(node) {
    if (dom.isElementNode(node)) {
      var style = window.getComputedStyle(node);
      if (style.float !== "none") {
        return true;
      }
      if (style.position !== "static" && style.position !== "relative") {
        return true;
      }
      if (["flex", "inline-block", "inline-flex", "table-caption", "table-cell"].indexOf(style.display) != -1) {
        return true;
      }
      if (style.overlfow !== "visible") {
        return true;
      }
    }
    return false;
  };
  var voidElementNames = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"];
  dom.allowsChildren = function(node) {
    if (dom.isElementNode(node)) {
      if (voidElementNames.indexOf(node.tagName.toLowerCase()) != -1) {
        return true;
      }
    }
    return false;
  };
  dom.hasTextNextToIt = function(node) {
    var neighboringTextRegex = /[^\s]+/i;
    var leftNode = node.previousSibling;
    while (leftNode) {
      if (leftNode.nodeName && uno.defs.blockElements[leftNode.nodeName.toLowerCase()]) {
        break;
      }
      if (neighboringTextRegex.test(leftNode.textContent)) {
        return true;
      }
      leftNode = leftNode.previousSibling;
    }
    var rightNode = node.nextSibling;
    while (rightNode) {
      if (rightNode.nodeName && uno.defs.blockElements[rightNode.nodeName.toLowerCase()]) {
        break;
      }
      if (neighboringTextRegex.test(rightNode.textContent)) {
        return true;
      }
      rightNode = rightNode.nextSibling;
    }
    var parent = node.parentNode;
    if (parent && (!parent.nodeName || !uno.defs.blockElements[parent.nodeName.toLowerCase()])) {
      return dom.hasTextNextToIt(parent);
    }
    return false;
  };
  dom.hasTodoNextToIt = function(node) {
    var leftNode = node.previousSibling;
    while (leftNode) {
      if (util.todo.isTodo(leftNode)) {
        return true;
      }
      leftNode = leftNode.previousSibling;
    }
    var rightNode = node.nextSibling;
    while (rightNode) {
      if (util.todo.isTodo(rightNode)) {
        return true;
      }
      rightNode = rightNode.nextSibling;
    }
    return false;
  };
  dom.getViewportRect = function() {
    var rect = {top:util.dom.scrollTop(document.body), left:util.dom.scrollLeft(document.body), width:window.innerWidth, height:window.innerHeight, bottom:0, right:0};
    rect.bottom = rect.top + rect.height;
    rect.right = rect.left + rect.width;
    return rect;
  };
  dom.makeClientRect = function(rect, opt, client) {
    var offsetLeft;
    var offsetTop;
    if (rect == null) {
      return null;
    }
    goog.object.extend(opt, {absolute:false, zoomScale:1.0, ignoreOffset:false}, opt);
    if (client === "ios") {
      if (document.body.getClientRects()[0].top < 0 === false) {
        offsetLeft = 0;
        offsetTop = 0;
      }
    }
    if (!opt.absolute && offsetLeft == null) {
      offsetLeft = util.dom.scrollLeft(document.body);
      offsetTop = util.dom.scrollTop(document.body);
    } else {
      offsetLeft = 0;
      offsetTop = 0;
    }
    if (client === "android" && opt.ignoreOffset !== true) {
      var offsetElement = document.getElementById("offset");
      if (offsetElement != null) {
        offsetTop -= parseInt(offsetElement.style.height, 10);
      }
    }
    var clientRect;
    if (client === "web") {
      clientRect = {left:Math.round(rect.left * opt.zoomScale) + offsetLeft, right:Math.round(rect.right * opt.zoomScale) + offsetLeft, top:Math.round(rect.top * opt.zoomScale) + offsetTop, bottom:Math.round(rect.bottom * opt.zoomScale) + offsetTop, width:Math.round(rect.width * opt.zoomScale), height:Math.round(rect.height * opt.zoomScale)};
    } else {
      clientRect = {left:rect.left * opt.zoomScale + offsetLeft, right:rect.right * opt.zoomScale + offsetLeft, top:rect.top * opt.zoomScale + offsetTop, bottom:rect.bottom * opt.zoomScale + offsetTop, width:rect.width * opt.zoomScale, height:rect.height * opt.zoomScale};
    }
    return clientRect;
  };
  dom.getDataAttribute = function(node, key) {
    return node && node.getAttribute ? node.getAttribute(["data", goog.string.toSelectorCase(key)].join("-")) : null;
  };
  dom.setDataAttribute = function(node, key, value) {
    if (node) {
      node.setAttribute(["data", goog.string.toSelectorCase(key)].join("-"), value);
      return value;
    }
  };
  dom.removeDataAttribute = function(node, key) {
    if (node && node.dataset) {
      key = ["data", goog.string.toSelectorCase(key)].join("-");
      var value = node.getAttribute(key);
      node.removeAttribute(key);
      return value;
    }
    return null;
  };
  dom.removeDataAttributes = function(node) {
    Object.keys(node.dataset).forEach(function(key) {
      node.removeAttribute(["data", goog.string.toSelectorCase(key)].join("-"));
    });
  };
  dom.copyAttributes = function(srcNode, targetNode, regexAttrName) {
    goog.array.forEachRight(srcNode.attributes, function(attr) {
      if (!regexAttrName || regexAttrName.test(attr.name)) {
        targetNode.setAttribute(attr.name, attr.value);
      }
    });
  };
  dom.stripContainerElementFromMarkup = function(markup) {
    var start = markup.indexOf(">");
    var end = markup.lastIndexOf("<");
    if (start < 0 || end < 0) {
      return markup;
    }
    return markup.substring(start + 1, end);
  };
  dom.toHTML = function(obj) {
    var node;
    if (goog.isString(obj)) {
      node = document.createElement("div");
      node.textContent = obj;
    } else {
      if (obj instanceof Node) {
        node = obj.ownerDocument.createElement("div");
        node.appendChild(obj.cloneNode(true));
      } else {
        log.severe("Illegal argument type for en.toHTML");
      }
    }
    return dom.stripContainerElementFromMarkup(node.outerHTML);
  };
  dom.workOnTemporaryDOMNode = function(node, fn) {
    var domNode = goog.dom.createDom("div", {style:"position: absolute; width: 1px; height: 1px; " + "top: -9999px; left: -9999px;"});
    domNode.appendChild(node);
    document.body.appendChild(domNode);
    fn(node);
    var n = goog.dom.removeNode(node);
    goog.dom.removeNode(domNode);
    return n;
  };
  dom.isOnScreen = function(node, onScreenAmount) {
    if (!goog.dom.isElement(node)) {
      return false;
    }
    start("node.getBoundingClientRect");
    var box = node.getBoundingClientRect();
    stop("node.getBoundingClientRect");
    start("dom.isBoundingBoxOnScreen");
    var isBoundingBoxOnScreen = dom.isBoundingBoxOnScreen(box.top, box.bottom, onScreenAmount);
    stop("dom.isBoundingBoxOnScreen");
    return isBoundingBoxOnScreen;
  };
  dom.getBoundingBox = function(node, optAbsolute) {
    if (node == null) {
      return null;
    }
    if (optAbsolute == null) {
      optAbsolute = false;
    }
    if (node.nodeType == null) {
      return null;
    }
    if (!dom.isRenderedDOMNode(node)) {
      return null;
    }
    if (!goog.isFunction(node.getClientRects)) {
      return null;
    }
    var boxes = node.getClientRects();
    if (boxes.length === 0) {
      var range = node.ownerDocument.createRange();
      range.selectNode(node);
      boxes = range.getClientRects();
    }
    if (boxes.length >= 1) {
      return dom.makeClientRect(boxes[0], {absolute:optAbsolute, zoomScale:uno.util.zoomscale.getZoom()});
    }
    return null;
  };
  dom.isBoundingBoxOnScreen = function(boxTop, boxBottom, onScreenAmount) {
    var scrollTop = window.scrollY;
    var scrollBottom = scrollTop + window.innerHeight;
    onScreenAmount = onScreenAmount || 55;
    var elementTop = boxTop + scrollTop;
    var elementBottom = boxBottom + scrollTop;
    var commonTop = Math.max(scrollTop, elementTop);
    var commonBottom = Math.min(scrollBottom, elementBottom);
    var overlapPercent = Math.max(0, Math.round((commonBottom - commonTop) / (elementBottom - elementTop) * 100));
    return overlapPercent >= onScreenAmount;
  };
  dom.isVisibleInView = function(node, partial) {
    if (!dom.isElementNode(node) || !node.parentNode) {
      return false;
    }
    if (partial !== false) {
      partial = true;
    }
    var bounds = node.getBoundingClientRect();
    var parent = node.parentNode;
    var viewRect = {top:0, left:0, bottom:window.innerHeight, right:window.innerWidth, height:window.innerHeight, width:window.innerWidth};
    var isIntersect = function(rect) {
      return partial ? !(bounds.bottom <= rect.top || bounds.top >= rect.bottom || bounds.left >= rect.right || bounds.right <= rect.left) : !(rect.height === 0 || rect.width === 0 || bounds.bottom > rect.bottom && bounds.top > rect.top || bounds.top < rect.top && bounds.bottom < rect.bottom || bounds.left > rect.left && bounds.right > rect.right || bounds.left < rect.left && bounds.right < rect.right);
    };
    if (!isIntersect(viewRect)) {
      return false;
    }
    while (parent && parent !== document.documentElement) {
      var style = window.getComputedStyle(parent);
      if (style.display === "none" || style.visibility === "hidden") {
        return false;
      }
      if (style.position !== "static" && [style.overflow, style.overflowY, style.overflowX].indexOf("hidden") > -1) {
        var pbounds = parent.getBoundingClientRect();
        var rect = {top:Math.max(viewRect.top, pbounds.top), left:Math.max(viewRect.left, pbounds.left), bottom:Math.min(viewRect.bottom, pbounds.bottom), right:Math.min(viewRect.right, pbounds.right), width:pbounds.width, height:pbounds.height};
        if (!isIntersect(rect)) {
          return false;
        }
      }
      parent = parent.parentNode;
    }
    return !!parent;
  };
  dom.scrollTo = function(pixelsFromTop, animationDuration, relativeToElement) {
    relativeToElement = relativeToElement || document.body;
    animationDuration = animationDuration || 0;
    pixelsFromTop = pixelsFromTop || 0;
    if (animationDuration === 0) {
      relativeToElement.scrollTop = pixelsFromTop;
      return;
    }
    var start = relativeToElement.scrollTop;
    var change = pixelsFromTop - start;
    var currentTime = 0;
    var increment = 20;
    var easeInOutQuad = function(curTime, startValue, changeInValue, duration) {
      curTime /= duration / 2;
      if (curTime < 1) {
        return changeInValue / 2 * curTime * curTime + startValue;
      }
      curTime--;
      return -changeInValue / 2 * (curTime * (curTime - 2) - 1) + startValue;
    };
    var animateScroll = function() {
      currentTime += increment;
      relativeToElement.scrollTop = easeInOutQuad(currentTime, start, change, animationDuration);
      if (currentTime < animationDuration) {
        window.setTimeout(animateScroll, increment);
      }
    };
    animateScroll();
  };
  dom.scrollTop = function(node, value) {
    if (node === document.body) {
      node = document.scrollingElement || document.body;
    }
    if (goog.isNumber(value)) {
      node.scrollTop = value;
    } else {
      return node.scrollTop;
    }
  };
  dom.scrollLeft = function(node, value) {
    if (node === document.body) {
      node = document.scrollingElement || document.body;
    }
    if (goog.isNumber(value)) {
      node.scrollLeft = value;
    } else {
      return node.scrollLeft;
    }
  };
  var voidRx = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i;
  dom.isVoid = function(el) {
    return voidRx.test(el.tagName);
  };
  dom.isFollowedByContent = function(node) {
    while (node != null) {
      if (node.nextSibling) {
        return true;
      }
      node = node.parentElement;
      if (dom.isBlockNode(node)) {
        return false;
      }
    }
    return false;
  };
  dom.flattenElement = function(element) {
    var child, parent = element.parentNode;
    if (parent) {
      if (element.removeNode) {
        return element.removeNode(false);
      } else {
        while (child = element.firstChild) {
          parent.insertBefore(child, element);
        }
        return goog.dom.removeNode(element);
      }
    }
  };
  dom.textFromHtml = function(html) {
    var el = document.createElement("span");
    el.innerHTML = html;
    return el.textContent;
  };
})();
goog.provide("uno.EditorSelection");
goog.require("goog.dom");
goog.require("goog.debug.Logger");
goog.require("uno.util.dom");
uno.EditorSelection = function(Editor) {
  var util = uno.util;
  var dom = util.dom;
  Editor.prototype.select = function(startNode, startOffset, endNode, endOffset) {
    if (!startNode) {
      return false;
    }
    if (endNode) {
      goog.dom.Range.createFromNodes(startNode, startOffset, endNode, endOffset).select();
    } else {
      goog.dom.Range.createCaret(startNode, startOffset || 0).select();
    }
    return true;
  };
  Editor.prototype.selectContent = function(node, atStart) {
    if (!node) {
      return;
    }
    var content = atStart ? dom.startContent(node) : dom.endContent(node);
    if (util.dom.isTextNode(content)) {
      this.select(content, atStart ? 0 : content.length);
    } else {
      if (dom.isInlineObject(content)) {
        if (dom.isBr(content)) {
          this.select(content.parentNode, dom.index(content));
        } else {
          this.select(content.parentNode, dom.index(content) + (atStart ? 0 : 1));
        }
      }
    }
  };
  Editor.prototype.selectStart = function(node) {
    return this.selectContent(node, true);
  };
  Editor.prototype.selectEnd = function(node) {
    return this.selectContent(node);
  };
};
goog.provide("uno.BasePlugin");
goog.require("goog.debug.Logger");
goog.require("goog.editor.Plugin");
goog.require("uno.EditorMultiRange");
(function() {
  var Plugin = goog.editor.Plugin;
  var BasePlugin = uno.BasePlugin = function(trogClassId) {
    Plugin.call(this);
    this.trogClassId = trogClassId;
    this.client = null;
    this.multiRangeMode = uno.EditorMultiRange.Mode.FIRST;
  };
  goog.inherits(BasePlugin, Plugin);
  BasePlugin.prototype.getTrogClassId = function() {
    return this.trogClassId;
  };
  BasePlugin.prototype.registerFieldObject = function(fieldObject) {
    Plugin.prototype.registerFieldObject.call(this, fieldObject);
    var me = this;
    var id = this.getTrogClassId();
    var namespace = goog.getObjectByName(id.toLowerCase());
    if (namespace) {
      this.client = namespace[fieldObject.config.client] || namespace.generic || {};
      Object.keys(this.client).forEach(function(key) {
        if (typeof me.client[key] === "function") {
          me.client[key] = me.client[key].bind(me);
        }
      });
    }
    this.editor = this.getFieldObject();
    this.setParentEventTarget(this.editor);
  };
  BasePlugin.prototype.unregisterFieldObject = function(fieldObject) {
    Plugin.prototype.unregisterFieldObject.call(this, fieldObject);
    this.editor = null;
  };
})();
goog.provide("uno.util.objects");
goog.require("goog.object");
(function() {
  var objects = uno.util.objects;
  objects.mergeOptions = function(options, defaultOptions) {
    var parsedOptions = goog.object.clone(options || {});
    goog.object.extend(defaultOptions, parsedOptions);
    return defaultOptions;
  };
  objects.valueOrDefault = function(val, defaultVal) {
    if (typeof val === "undefined") {
      return defaultVal;
    }
    return val;
  };
})();
goog.provide("uno.util.tools");
goog.require("goog.dom");
(function() {
  var util = uno.util;
  util.tools.getContainer = function() {
    var container = document.querySelector("en-tools");
    if (!container) {
      container = document.createElement("en-tools");
      document.body.appendChild(container);
    }
    return container;
  };
  util.tools.query = function(selector) {
    var container = util.tools.getContainer();
    return container.querySelector(selector);
  };
  util.tools.append = function(node) {
    var container = util.tools.getContainer();
    container.appendChild(node);
    return node;
  };
  util.tools.preloadImages = function() {
    if (!util.tools.query("en-preload")) {
      util.tools.append(goog.dom.createDom("en-preload", {class:"en-preload"}));
    }
  };
})();
goog.provide("uno.commands.Accentuate");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.objects");
goog.require("uno.util.tools");
(function() {
  var util = uno.util;
  var log = goog.debug.Logger.getLogger("uno.commands.Accentuate");
  var Accentuate = uno.commands.Accentuate = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Accentuate, uno.BasePlugin);
  Accentuate.CONTAINER_CLASSNAME = "accentuate-container";
  Accentuate.BOX_CLASSNAME = "en-find-result";
  Accentuate.BOX_ACTIVE_CLASSNAME = "en-find-result-active";
  Accentuate.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Accentuate.prototype.isSupportedCommand = function(command) {
    return command === "accentuate";
  };
  Accentuate.prototype.execCommand = function(command, rawOptions) {
    var options = util.objects.mergeOptions(rawOptions, {boxes:[], selectedBoxIndex:-1, scrollToSelectedBox:true, clearFirst:false, clearOnClickSelector:"en-note"});
    var accentuateContainer = document.querySelector("." + Accentuate.CONTAINER_CLASSNAME);
    if (options.clearFirst && accentuateContainer) {
      accentuateContainer.innerHTML = "";
    }
    if (!accentuateContainer) {
      var toolsContainer = util.tools.getContainer();
      accentuateContainer = goog.dom.createDom("div", {class:Accentuate.CONTAINER_CLASSNAME});
      toolsContainer.appendChild(accentuateContainer);
    }
    var boxes = options.boxes;
    var currentIndex = accentuateContainer.querySelectorAll("." + Accentuate.BOX_CLASSNAME).length;
    for (var i = 0; i < boxes.length; i++) {
      var match = boxes[i];
      for (var j = 0; j < match.length; j++) {
        var item = match[j];
        var box = goog.dom.createDom("div", {id:Accentuate.BOX_CLASSNAME + currentIndex, class:Accentuate.BOX_CLASSNAME, style:createStyle({position:"absolute", top:item.top + "px", left:item.left + "px", width:item.width + "px", height:item.height + "px"})});
        currentIndex++;
        accentuateContainer.appendChild(box);
      }
    }
    var newActiveBox = accentuateContainer.querySelector("#" + Accentuate.BOX_CLASSNAME + options.selectedBoxIndex);
    if (newActiveBox) {
      var oldActiveBox = accentuateContainer.querySelector("." + Accentuate.BOX_ACTIVE_CLASSNAME);
      if (oldActiveBox) {
        goog.dom.classlist.remove(oldActiveBox, Accentuate.BOX_ACTIVE_CLASSNAME);
      }
      goog.dom.classlist.add(newActiveBox, Accentuate.BOX_ACTIVE_CLASSNAME);
      if (options.scrollToSelectedBox) {
        newActiveBox.scrollIntoView();
      }
    }
    return true;
  };
  function createStyle(style) {
    var finalStyle = "";
    for (var key in style) {
      if (style.hasOwnProperty(key)) {
        finalStyle += key + ":" + style[key] + ";";
      }
    }
    return finalStyle;
  }
})();
goog.provide("uno.commands.Active");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Active");
  var Active = uno.commands.Active = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Active, uno.BasePlugin);
  Active.prototype.isSupportedCommand = function(command) {
    return command === "active";
  };
  Active.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Active.prototype.execCommand = function(command, makeActive) {
    if (makeActive === "true") {
      makeActive = true;
    } else {
      if (makeActive === "false") {
        makeActive = false;
      }
    }
    if (makeActive) {
      this.editor.readOnly = false;
      if (this.editor.config.stayInEditMode) {
        this.editor.enterEditMode(false);
      }
    } else {
      this.editor.readOnly = true;
      this.editor.leaveEditMode();
    }
    return true;
  };
  Active.prototype.queryCommandValue = function() {
    return !this.editor.readOnly;
  };
})();
goog.provide("goog.crypt");
goog.require("goog.array");
goog.require("goog.asserts");
goog.crypt.stringToByteArray = function(str) {
  var output = [], p = 0;
  for (var i = 0; i < str.length; i++) {
    var c = str.charCodeAt(i);
    while (c > 255) {
      output[p++] = c & 255;
      c >>= 8;
    }
    output[p++] = c;
  }
  return output;
};
goog.crypt.byteArrayToString = function(bytes) {
  var CHUNK_SIZE = 8192;
  if (bytes.length <= CHUNK_SIZE) {
    return String.fromCharCode.apply(null, bytes);
  }
  var str = "";
  for (var i = 0; i < bytes.length; i += CHUNK_SIZE) {
    var chunk = goog.array.slice(bytes, i, i + CHUNK_SIZE);
    str += String.fromCharCode.apply(null, chunk);
  }
  return str;
};
goog.crypt.byteArrayToHex = function(array) {
  return goog.array.map(array, function(numByte) {
    var hexByte = numByte.toString(16);
    return hexByte.length > 1 ? hexByte : "0" + hexByte;
  }).join("");
};
goog.crypt.hexToByteArray = function(hexString) {
  goog.asserts.assert(hexString.length % 2 == 0, "Key string length must be multiple of 2");
  var arr = [];
  for (var i = 0; i < hexString.length; i += 2) {
    arr.push(parseInt(hexString.substring(i, i + 2), 16));
  }
  return arr;
};
goog.crypt.stringToUtf8ByteArray = function(str) {
  var out = [], p = 0;
  for (var i = 0; i < str.length; i++) {
    var c = str.charCodeAt(i);
    if (c < 128) {
      out[p++] = c;
    } else {
      if (c < 2048) {
        out[p++] = c >> 6 | 192;
        out[p++] = c & 63 | 128;
      } else {
        if ((c & 64512) == 55296 && i + 1 < str.length && (str.charCodeAt(i + 1) & 64512) == 56320) {
          c = 65536 + ((c & 1023) << 10) + (str.charCodeAt(++i) & 1023);
          out[p++] = c >> 18 | 240;
          out[p++] = c >> 12 & 63 | 128;
          out[p++] = c >> 6 & 63 | 128;
          out[p++] = c & 63 | 128;
        } else {
          out[p++] = c >> 12 | 224;
          out[p++] = c >> 6 & 63 | 128;
          out[p++] = c & 63 | 128;
        }
      }
    }
  }
  return out;
};
goog.crypt.utf8ByteArrayToString = function(bytes) {
  var out = [], pos = 0, c = 0;
  while (pos < bytes.length) {
    var c1 = bytes[pos++];
    if (c1 < 128) {
      out[c++] = String.fromCharCode(c1);
    } else {
      if (c1 > 191 && c1 < 224) {
        var c2 = bytes[pos++];
        out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
      } else {
        if (c1 > 239 && c1 < 365) {
          var c2 = bytes[pos++];
          var c3 = bytes[pos++];
          var c4 = bytes[pos++];
          var u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - 65536;
          out[c++] = String.fromCharCode(55296 + (u >> 10));
          out[c++] = String.fromCharCode(56320 + (u & 1023));
        } else {
          var c2 = bytes[pos++];
          var c3 = bytes[pos++];
          out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
        }
      }
    }
  }
  return out.join("");
};
goog.crypt.xorByteArray = function(bytes1, bytes2) {
  goog.asserts.assert(bytes1.length == bytes2.length, "XOR array lengths must match");
  var result = [];
  for (var i = 0; i < bytes1.length; i++) {
    result.push(bytes1[i] ^ bytes2[i]);
  }
  return result;
};
goog.provide("goog.crypt.Hash");
goog.crypt.Hash = function() {
  this.blockSize = -1;
};
goog.crypt.Hash.prototype.reset = goog.abstractMethod;
goog.crypt.Hash.prototype.update = goog.abstractMethod;
goog.crypt.Hash.prototype.digest = goog.abstractMethod;
goog.provide("goog.crypt.Md5");
goog.require("goog.crypt.Hash");
goog.crypt.Md5 = function() {
  goog.crypt.Md5.base(this, "constructor");
  this.blockSize = 512 / 8;
  this.chain_ = new Array(4);
  this.block_ = new Array(this.blockSize);
  this.blockLength_ = 0;
  this.totalLength_ = 0;
  this.reset();
};
goog.inherits(goog.crypt.Md5, goog.crypt.Hash);
goog.crypt.Md5.prototype.reset = function() {
  this.chain_[0] = 1732584193;
  this.chain_[1] = 4023233417;
  this.chain_[2] = 2562383102;
  this.chain_[3] = 271733878;
  this.blockLength_ = 0;
  this.totalLength_ = 0;
};
goog.crypt.Md5.prototype.compress_ = function(buf, opt_offset) {
  if (!opt_offset) {
    opt_offset = 0;
  }
  var X = new Array(16);
  if (goog.isString(buf)) {
    for (var i = 0; i < 16; ++i) {
      X[i] = buf.charCodeAt(opt_offset++) | buf.charCodeAt(opt_offset++) << 8 | buf.charCodeAt(opt_offset++) << 16 | buf.charCodeAt(opt_offset++) << 24;
    }
  } else {
    for (var i = 0; i < 16; ++i) {
      X[i] = buf[opt_offset++] | buf[opt_offset++] << 8 | buf[opt_offset++] << 16 | buf[opt_offset++] << 24;
    }
  }
  var A = this.chain_[0];
  var B = this.chain_[1];
  var C = this.chain_[2];
  var D = this.chain_[3];
  var sum = 0;
  sum = A + (D ^ B & (C ^ D)) + X[0] + 3614090360 & 4294967295;
  A = B + (sum << 7 & 4294967295 | sum >>> 25);
  sum = D + (C ^ A & (B ^ C)) + X[1] + 3905402710 & 4294967295;
  D = A + (sum << 12 & 4294967295 | sum >>> 20);
  sum = C + (B ^ D & (A ^ B)) + X[2] + 606105819 & 4294967295;
  C = D + (sum << 17 & 4294967295 | sum >>> 15);
  sum = B + (A ^ C & (D ^ A)) + X[3] + 3250441966 & 4294967295;
  B = C + (sum << 22 & 4294967295 | sum >>> 10);
  sum = A + (D ^ B & (C ^ D)) + X[4] + 4118548399 & 4294967295;
  A = B + (sum << 7 & 4294967295 | sum >>> 25);
  sum = D + (C ^ A & (B ^ C)) + X[5] + 1200080426 & 4294967295;
  D = A + (sum << 12 & 4294967295 | sum >>> 20);
  sum = C + (B ^ D & (A ^ B)) + X[6] + 2821735955 & 4294967295;
  C = D + (sum << 17 & 4294967295 | sum >>> 15);
  sum = B + (A ^ C & (D ^ A)) + X[7] + 4249261313 & 4294967295;
  B = C + (sum << 22 & 4294967295 | sum >>> 10);
  sum = A + (D ^ B & (C ^ D)) + X[8] + 1770035416 & 4294967295;
  A = B + (sum << 7 & 4294967295 | sum >>> 25);
  sum = D + (C ^ A & (B ^ C)) + X[9] + 2336552879 & 4294967295;
  D = A + (sum << 12 & 4294967295 | sum >>> 20);
  sum = C + (B ^ D & (A ^ B)) + X[10] + 4294925233 & 4294967295;
  C = D + (sum << 17 & 4294967295 | sum >>> 15);
  sum = B + (A ^ C & (D ^ A)) + X[11] + 2304563134 & 4294967295;
  B = C + (sum << 22 & 4294967295 | sum >>> 10);
  sum = A + (D ^ B & (C ^ D)) + X[12] + 1804603682 & 4294967295;
  A = B + (sum << 7 & 4294967295 | sum >>> 25);
  sum = D + (C ^ A & (B ^ C)) + X[13] + 4254626195 & 4294967295;
  D = A + (sum << 12 & 4294967295 | sum >>> 20);
  sum = C + (B ^ D & (A ^ B)) + X[14] + 2792965006 & 4294967295;
  C = D + (sum << 17 & 4294967295 | sum >>> 15);
  sum = B + (A ^ C & (D ^ A)) + X[15] + 1236535329 & 4294967295;
  B = C + (sum << 22 & 4294967295 | sum >>> 10);
  sum = A + (C ^ D & (B ^ C)) + X[1] + 4129170786 & 4294967295;
  A = B + (sum << 5 & 4294967295 | sum >>> 27);
  sum = D + (B ^ C & (A ^ B)) + X[6] + 3225465664 & 4294967295;
  D = A + (sum << 9 & 4294967295 | sum >>> 23);
  sum = C + (A ^ B & (D ^ A)) + X[11] + 643717713 & 4294967295;
  C = D + (sum << 14 & 4294967295 | sum >>> 18);
  sum = B + (D ^ A & (C ^ D)) + X[0] + 3921069994 & 4294967295;
  B = C + (sum << 20 & 4294967295 | sum >>> 12);
  sum = A + (C ^ D & (B ^ C)) + X[5] + 3593408605 & 4294967295;
  A = B + (sum << 5 & 4294967295 | sum >>> 27);
  sum = D + (B ^ C & (A ^ B)) + X[10] + 38016083 & 4294967295;
  D = A + (sum << 9 & 4294967295 | sum >>> 23);
  sum = C + (A ^ B & (D ^ A)) + X[15] + 3634488961 & 4294967295;
  C = D + (sum << 14 & 4294967295 | sum >>> 18);
  sum = B + (D ^ A & (C ^ D)) + X[4] + 3889429448 & 4294967295;
  B = C + (sum << 20 & 4294967295 | sum >>> 12);
  sum = A + (C ^ D & (B ^ C)) + X[9] + 568446438 & 4294967295;
  A = B + (sum << 5 & 4294967295 | sum >>> 27);
  sum = D + (B ^ C & (A ^ B)) + X[14] + 3275163606 & 4294967295;
  D = A + (sum << 9 & 4294967295 | sum >>> 23);
  sum = C + (A ^ B & (D ^ A)) + X[3] + 4107603335 & 4294967295;
  C = D + (sum << 14 & 4294967295 | sum >>> 18);
  sum = B + (D ^ A & (C ^ D)) + X[8] + 1163531501 & 4294967295;
  B = C + (sum << 20 & 4294967295 | sum >>> 12);
  sum = A + (C ^ D & (B ^ C)) + X[13] + 2850285829 & 4294967295;
  A = B + (sum << 5 & 4294967295 | sum >>> 27);
  sum = D + (B ^ C & (A ^ B)) + X[2] + 4243563512 & 4294967295;
  D = A + (sum << 9 & 4294967295 | sum >>> 23);
  sum = C + (A ^ B & (D ^ A)) + X[7] + 1735328473 & 4294967295;
  C = D + (sum << 14 & 4294967295 | sum >>> 18);
  sum = B + (D ^ A & (C ^ D)) + X[12] + 2368359562 & 4294967295;
  B = C + (sum << 20 & 4294967295 | sum >>> 12);
  sum = A + (B ^ C ^ D) + X[5] + 4294588738 & 4294967295;
  A = B + (sum << 4 & 4294967295 | sum >>> 28);
  sum = D + (A ^ B ^ C) + X[8] + 2272392833 & 4294967295;
  D = A + (sum << 11 & 4294967295 | sum >>> 21);
  sum = C + (D ^ A ^ B) + X[11] + 1839030562 & 4294967295;
  C = D + (sum << 16 & 4294967295 | sum >>> 16);
  sum = B + (C ^ D ^ A) + X[14] + 4259657740 & 4294967295;
  B = C + (sum << 23 & 4294967295 | sum >>> 9);
  sum = A + (B ^ C ^ D) + X[1] + 2763975236 & 4294967295;
  A = B + (sum << 4 & 4294967295 | sum >>> 28);
  sum = D + (A ^ B ^ C) + X[4] + 1272893353 & 4294967295;
  D = A + (sum << 11 & 4294967295 | sum >>> 21);
  sum = C + (D ^ A ^ B) + X[7] + 4139469664 & 4294967295;
  C = D + (sum << 16 & 4294967295 | sum >>> 16);
  sum = B + (C ^ D ^ A) + X[10] + 3200236656 & 4294967295;
  B = C + (sum << 23 & 4294967295 | sum >>> 9);
  sum = A + (B ^ C ^ D) + X[13] + 681279174 & 4294967295;
  A = B + (sum << 4 & 4294967295 | sum >>> 28);
  sum = D + (A ^ B ^ C) + X[0] + 3936430074 & 4294967295;
  D = A + (sum << 11 & 4294967295 | sum >>> 21);
  sum = C + (D ^ A ^ B) + X[3] + 3572445317 & 4294967295;
  C = D + (sum << 16 & 4294967295 | sum >>> 16);
  sum = B + (C ^ D ^ A) + X[6] + 76029189 & 4294967295;
  B = C + (sum << 23 & 4294967295 | sum >>> 9);
  sum = A + (B ^ C ^ D) + X[9] + 3654602809 & 4294967295;
  A = B + (sum << 4 & 4294967295 | sum >>> 28);
  sum = D + (A ^ B ^ C) + X[12] + 3873151461 & 4294967295;
  D = A + (sum << 11 & 4294967295 | sum >>> 21);
  sum = C + (D ^ A ^ B) + X[15] + 530742520 & 4294967295;
  C = D + (sum << 16 & 4294967295 | sum >>> 16);
  sum = B + (C ^ D ^ A) + X[2] + 3299628645 & 4294967295;
  B = C + (sum << 23 & 4294967295 | sum >>> 9);
  sum = A + (C ^ (B | ~D)) + X[0] + 4096336452 & 4294967295;
  A = B + (sum << 6 & 4294967295 | sum >>> 26);
  sum = D + (B ^ (A | ~C)) + X[7] + 1126891415 & 4294967295;
  D = A + (sum << 10 & 4294967295 | sum >>> 22);
  sum = C + (A ^ (D | ~B)) + X[14] + 2878612391 & 4294967295;
  C = D + (sum << 15 & 4294967295 | sum >>> 17);
  sum = B + (D ^ (C | ~A)) + X[5] + 4237533241 & 4294967295;
  B = C + (sum << 21 & 4294967295 | sum >>> 11);
  sum = A + (C ^ (B | ~D)) + X[12] + 1700485571 & 4294967295;
  A = B + (sum << 6 & 4294967295 | sum >>> 26);
  sum = D + (B ^ (A | ~C)) + X[3] + 2399980690 & 4294967295;
  D = A + (sum << 10 & 4294967295 | sum >>> 22);
  sum = C + (A ^ (D | ~B)) + X[10] + 4293915773 & 4294967295;
  C = D + (sum << 15 & 4294967295 | sum >>> 17);
  sum = B + (D ^ (C | ~A)) + X[1] + 2240044497 & 4294967295;
  B = C + (sum << 21 & 4294967295 | sum >>> 11);
  sum = A + (C ^ (B | ~D)) + X[8] + 1873313359 & 4294967295;
  A = B + (sum << 6 & 4294967295 | sum >>> 26);
  sum = D + (B ^ (A | ~C)) + X[15] + 4264355552 & 4294967295;
  D = A + (sum << 10 & 4294967295 | sum >>> 22);
  sum = C + (A ^ (D | ~B)) + X[6] + 2734768916 & 4294967295;
  C = D + (sum << 15 & 4294967295 | sum >>> 17);
  sum = B + (D ^ (C | ~A)) + X[13] + 1309151649 & 4294967295;
  B = C + (sum << 21 & 4294967295 | sum >>> 11);
  sum = A + (C ^ (B | ~D)) + X[4] + 4149444226 & 4294967295;
  A = B + (sum << 6 & 4294967295 | sum >>> 26);
  sum = D + (B ^ (A | ~C)) + X[11] + 3174756917 & 4294967295;
  D = A + (sum << 10 & 4294967295 | sum >>> 22);
  sum = C + (A ^ (D | ~B)) + X[2] + 718787259 & 4294967295;
  C = D + (sum << 15 & 4294967295 | sum >>> 17);
  sum = B + (D ^ (C | ~A)) + X[9] + 3951481745 & 4294967295;
  B = C + (sum << 21 & 4294967295 | sum >>> 11);
  this.chain_[0] = this.chain_[0] + A & 4294967295;
  this.chain_[1] = this.chain_[1] + B & 4294967295;
  this.chain_[2] = this.chain_[2] + C & 4294967295;
  this.chain_[3] = this.chain_[3] + D & 4294967295;
};
goog.crypt.Md5.prototype.update = function(bytes, opt_length) {
  if (!goog.isDef(opt_length)) {
    opt_length = bytes.length;
  }
  var lengthMinusBlock = opt_length - this.blockSize;
  var block = this.block_;
  var blockLength = this.blockLength_;
  var i = 0;
  while (i < opt_length) {
    if (blockLength == 0) {
      while (i <= lengthMinusBlock) {
        this.compress_(bytes, i);
        i += this.blockSize;
      }
    }
    if (goog.isString(bytes)) {
      while (i < opt_length) {
        block[blockLength++] = bytes.charCodeAt(i++);
        if (blockLength == this.blockSize) {
          this.compress_(block);
          blockLength = 0;
          break;
        }
      }
    } else {
      while (i < opt_length) {
        block[blockLength++] = bytes[i++];
        if (blockLength == this.blockSize) {
          this.compress_(block);
          blockLength = 0;
          break;
        }
      }
    }
  }
  this.blockLength_ = blockLength;
  this.totalLength_ += opt_length;
};
goog.crypt.Md5.prototype.digest = function() {
  var pad = new Array((this.blockLength_ < 56 ? this.blockSize : this.blockSize * 2) - this.blockLength_);
  pad[0] = 128;
  for (var i = 1; i < pad.length - 8; ++i) {
    pad[i] = 0;
  }
  var totalBits = this.totalLength_ * 8;
  for (var i = pad.length - 8; i < pad.length; ++i) {
    pad[i] = totalBits & 255;
    totalBits /= 256;
  }
  this.update(pad);
  var digest = new Array(16);
  var n = 0;
  for (var i = 0; i < 4; ++i) {
    for (var j = 0; j < 32; j += 8) {
      digest[n++] = this.chain_[i] >>> j & 255;
    }
  }
  return digest;
};
goog.provide("uno.util.copy.plain");
(function() {
  var util = uno.util;
  util.copy.plain.copy = function(root) {
    var resources = root.querySelectorAll("en-media");
    goog.array.forEach(resources, function(node) {
      goog.dom.removeNode(node);
    });
    var a = root.querySelectorAll("a");
    goog.array.forEach(a, function(node) {
      goog.dom.replaceNode(document.createTextNode(node.textContent), node);
    });
    var todos = util.todo.all(root);
    goog.array.forEach(todos, function(node) {
      var todo = document.createTextNode(util.todo.isChecked(node) ? "[x] " : "[ ] ");
      goog.dom.replaceNode(todo, node);
    });
    plainifyLists(root, 0);
    var entools = document.querySelector("en-tools");
    entools.appendChild(root);
    var n, walk = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
    while (n = walk.nextNode()) {
      n.data = n.data.replace(/ /g, "\u00a0");
    }
    var plainText = root.innerText;
    goog.dom.removeNode(root);
    plainText = plainText.replace(/<br>/g, "\n").replace(/-----PLACEHOLDER_TAB-----/g, "    ").replace(/\u00A0/g, " ").replace(/\n$/, "");
    return plainText;
  };
  function plainifyLists(node) {
    var parents = [];
    if (util.dom.isUl(node) || util.dom.isOl(node)) {
      parents.push(node);
    } else {
      if (util.dom.isElementNode(node)) {
        parents = node.querySelectorAll("ul, ol");
      }
    }
    goog.array.forEach(parents, function(parent) {
      if (util.dom.isElementNode(parent)) {
        var isOL = util.dom.isOl(parent);
        var count = parseInt(parent.getAttribute("start"), 10) || 1;
        var tabsCount = getTabCounts(parent);
        goog.array.forEach(parent.childNodes, function(li) {
          if (util.dom.isLi(li) && li.firstChild) {
            var prefix = goog.dom.createTextNode(insertTabs(tabsCount) + (isOL ? count + ". " : "* "));
            goog.dom.insertSiblingBefore(prefix, li.firstChild);
            count++;
          }
        });
      }
    });
  }
  function getTabCounts(node) {
    var tabsCount = 0;
    goog.dom.getAncestor(node, function(element) {
      if (util.dom.isUl(element) || util.dom.isOl(element)) {
        tabsCount++;
      }
      return !!util.dom.isEnnote(element);
    });
    return tabsCount;
  }
  function insertTabs(count) {
    var placeholder = "";
    for (var i = 0; i < count; i++) {
      placeholder += "-----PLACEHOLDER_TAB-----";
    }
    return placeholder;
  }
})();
goog.provide("goog.color.names");
goog.color.names = {"aliceblue":"#f0f8ff", "antiquewhite":"#faebd7", "aqua":"#00ffff", "aquamarine":"#7fffd4", "azure":"#f0ffff", "beige":"#f5f5dc", "bisque":"#ffe4c4", "black":"#000000", "blanchedalmond":"#ffebcd", "blue":"#0000ff", "blueviolet":"#8a2be2", "brown":"#a52a2a", "burlywood":"#deb887", "cadetblue":"#5f9ea0", "chartreuse":"#7fff00", "chocolate":"#d2691e", "coral":"#ff7f50", "cornflowerblue":"#6495ed", "cornsilk":"#fff8dc", "crimson":"#dc143c", "cyan":"#00ffff", "darkblue":"#00008b", "darkcyan":"#008b8b", 
"darkgoldenrod":"#b8860b", "darkgray":"#a9a9a9", "darkgreen":"#006400", "darkgrey":"#a9a9a9", "darkkhaki":"#bdb76b", "darkmagenta":"#8b008b", "darkolivegreen":"#556b2f", "darkorange":"#ff8c00", "darkorchid":"#9932cc", "darkred":"#8b0000", "darksalmon":"#e9967a", "darkseagreen":"#8fbc8f", "darkslateblue":"#483d8b", "darkslategray":"#2f4f4f", "darkslategrey":"#2f4f4f", "darkturquoise":"#00ced1", "darkviolet":"#9400d3", "deeppink":"#ff1493", "deepskyblue":"#00bfff", "dimgray":"#696969", "dimgrey":"#696969", 
"dodgerblue":"#1e90ff", "firebrick":"#b22222", "floralwhite":"#fffaf0", "forestgreen":"#228b22", "fuchsia":"#ff00ff", "gainsboro":"#dcdcdc", "ghostwhite":"#f8f8ff", "gold":"#ffd700", "goldenrod":"#daa520", "gray":"#808080", "green":"#008000", "greenyellow":"#adff2f", "grey":"#808080", "honeydew":"#f0fff0", "hotpink":"#ff69b4", "indianred":"#cd5c5c", "indigo":"#4b0082", "ivory":"#fffff0", "khaki":"#f0e68c", "lavender":"#e6e6fa", "lavenderblush":"#fff0f5", "lawngreen":"#7cfc00", "lemonchiffon":"#fffacd", 
"lightblue":"#add8e6", "lightcoral":"#f08080", "lightcyan":"#e0ffff", "lightgoldenrodyellow":"#fafad2", "lightgray":"#d3d3d3", "lightgreen":"#90ee90", "lightgrey":"#d3d3d3", "lightpink":"#ffb6c1", "lightsalmon":"#ffa07a", "lightseagreen":"#20b2aa", "lightskyblue":"#87cefa", "lightslategray":"#778899", "lightslategrey":"#778899", "lightsteelblue":"#b0c4de", "lightyellow":"#ffffe0", "lime":"#00ff00", "limegreen":"#32cd32", "linen":"#faf0e6", "magenta":"#ff00ff", "maroon":"#800000", "mediumaquamarine":"#66cdaa", 
"mediumblue":"#0000cd", "mediumorchid":"#ba55d3", "mediumpurple":"#9370db", "mediumseagreen":"#3cb371", "mediumslateblue":"#7b68ee", "mediumspringgreen":"#00fa9a", "mediumturquoise":"#48d1cc", "mediumvioletred":"#c71585", "midnightblue":"#191970", "mintcream":"#f5fffa", "mistyrose":"#ffe4e1", "moccasin":"#ffe4b5", "navajowhite":"#ffdead", "navy":"#000080", "oldlace":"#fdf5e6", "olive":"#808000", "olivedrab":"#6b8e23", "orange":"#ffa500", "orangered":"#ff4500", "orchid":"#da70d6", "palegoldenrod":"#eee8aa", 
"palegreen":"#98fb98", "paleturquoise":"#afeeee", "palevioletred":"#db7093", "papayawhip":"#ffefd5", "peachpuff":"#ffdab9", "peru":"#cd853f", "pink":"#ffc0cb", "plum":"#dda0dd", "powderblue":"#b0e0e6", "purple":"#800080", "red":"#ff0000", "rosybrown":"#bc8f8f", "royalblue":"#4169e1", "saddlebrown":"#8b4513", "salmon":"#fa8072", "sandybrown":"#f4a460", "seagreen":"#2e8b57", "seashell":"#fff5ee", "sienna":"#a0522d", "silver":"#c0c0c0", "skyblue":"#87ceeb", "slateblue":"#6a5acd", "slategray":"#708090", 
"slategrey":"#708090", "snow":"#fffafa", "springgreen":"#00ff7f", "steelblue":"#4682b4", "tan":"#d2b48c", "teal":"#008080", "thistle":"#d8bfd8", "tomato":"#ff6347", "turquoise":"#40e0d0", "violet":"#ee82ee", "wheat":"#f5deb3", "white":"#ffffff", "whitesmoke":"#f5f5f5", "yellow":"#ffff00", "yellowgreen":"#9acd32"};
goog.provide("goog.color");
goog.provide("goog.color.Hsl");
goog.provide("goog.color.Hsv");
goog.provide("goog.color.Rgb");
goog.require("goog.color.names");
goog.require("goog.math");
goog.color.Rgb;
goog.color.Hsv;
goog.color.Hsl;
goog.color.parse = function(str) {
  var result = {};
  str = String(str);
  var maybeHex = goog.color.prependHashIfNecessaryHelper(str);
  if (goog.color.isValidHexColor_(maybeHex)) {
    result.hex = goog.color.normalizeHex(maybeHex);
    result.type = "hex";
    return result;
  } else {
    var rgb = goog.color.isValidRgbColor_(str);
    if (rgb.length) {
      result.hex = goog.color.rgbArrayToHex(rgb);
      result.type = "rgb";
      return result;
    } else {
      if (goog.color.names) {
        var hex = goog.color.names[str.toLowerCase()];
        if (hex) {
          result.hex = hex;
          result.type = "named";
          return result;
        }
      }
    }
  }
  throw Error(str + " is not a valid color string");
};
goog.color.isValidColor = function(str) {
  var maybeHex = goog.color.prependHashIfNecessaryHelper(str);
  return !!(goog.color.isValidHexColor_(maybeHex) || goog.color.isValidRgbColor_(str).length || goog.color.names && goog.color.names[str.toLowerCase()]);
};
goog.color.parseRgb = function(str) {
  var rgb = goog.color.isValidRgbColor_(str);
  if (!rgb.length) {
    throw Error(str + " is not a valid RGB color");
  }
  return rgb;
};
goog.color.hexToRgbStyle = function(hexColor) {
  return goog.color.rgbStyle_(goog.color.hexToRgb(hexColor));
};
goog.color.hexTripletRe_ = /#(.)(.)(.)/;
goog.color.normalizeHex = function(hexColor) {
  if (!goog.color.isValidHexColor_(hexColor)) {
    throw Error("'" + hexColor + "' is not a valid hex color");
  }
  if (hexColor.length == 4) {
    hexColor = hexColor.replace(goog.color.hexTripletRe_, "#$1$1$2$2$3$3");
  }
  return hexColor.toLowerCase();
};
goog.color.hexToRgb = function(hexColor) {
  hexColor = goog.color.normalizeHex(hexColor);
  var r = parseInt(hexColor.substr(1, 2), 16);
  var g = parseInt(hexColor.substr(3, 2), 16);
  var b = parseInt(hexColor.substr(5, 2), 16);
  return [r, g, b];
};
goog.color.rgbToHex = function(r, g, b) {
  r = Number(r);
  g = Number(g);
  b = Number(b);
  if (r != (r & 255) || g != (g & 255) || b != (b & 255)) {
    throw Error('"(' + r + "," + g + "," + b + '") is not a valid RGB color');
  }
  var hexR = goog.color.prependZeroIfNecessaryHelper(r.toString(16));
  var hexG = goog.color.prependZeroIfNecessaryHelper(g.toString(16));
  var hexB = goog.color.prependZeroIfNecessaryHelper(b.toString(16));
  return "#" + hexR + hexG + hexB;
};
goog.color.rgbArrayToHex = function(rgb) {
  return goog.color.rgbToHex(rgb[0], rgb[1], rgb[2]);
};
goog.color.rgbToHsl = function(r, g, b) {
  var normR = r / 255;
  var normG = g / 255;
  var normB = b / 255;
  var max = Math.max(normR, normG, normB);
  var min = Math.min(normR, normG, normB);
  var h = 0;
  var s = 0;
  var l = 0.5 * (max + min);
  if (max != min) {
    if (max == normR) {
      h = 60 * (normG - normB) / (max - min);
    } else {
      if (max == normG) {
        h = 60 * (normB - normR) / (max - min) + 120;
      } else {
        if (max == normB) {
          h = 60 * (normR - normG) / (max - min) + 240;
        }
      }
    }
    if (0 < l && l <= 0.5) {
      s = (max - min) / (2 * l);
    } else {
      s = (max - min) / (2 - 2 * l);
    }
  }
  return [Math.round(h + 360) % 360, s, l];
};
goog.color.rgbArrayToHsl = function(rgb) {
  return goog.color.rgbToHsl(rgb[0], rgb[1], rgb[2]);
};
goog.color.hueToRgb_ = function(v1, v2, vH) {
  if (vH < 0) {
    vH += 1;
  } else {
    if (vH > 1) {
      vH -= 1;
    }
  }
  if (6 * vH < 1) {
    return v1 + (v2 - v1) * 6 * vH;
  } else {
    if (2 * vH < 1) {
      return v2;
    } else {
      if (3 * vH < 2) {
        return v1 + (v2 - v1) * (2 / 3 - vH) * 6;
      }
    }
  }
  return v1;
};
goog.color.hslToRgb = function(h, s, l) {
  var r = 0;
  var g = 0;
  var b = 0;
  var normH = h / 360;
  if (s == 0) {
    r = g = b = l * 255;
  } else {
    var temp1 = 0;
    var temp2 = 0;
    if (l < 0.5) {
      temp2 = l * (1 + s);
    } else {
      temp2 = l + s - s * l;
    }
    temp1 = 2 * l - temp2;
    r = 255 * goog.color.hueToRgb_(temp1, temp2, normH + 1 / 3);
    g = 255 * goog.color.hueToRgb_(temp1, temp2, normH);
    b = 255 * goog.color.hueToRgb_(temp1, temp2, normH - 1 / 3);
  }
  return [Math.round(r), Math.round(g), Math.round(b)];
};
goog.color.hslArrayToRgb = function(hsl) {
  return goog.color.hslToRgb(hsl[0], hsl[1], hsl[2]);
};
goog.color.validHexColorRe_ = /^#(?:[0-9a-f]{3}){1,2}$/i;
goog.color.isValidHexColor_ = function(str) {
  return goog.color.validHexColorRe_.test(str);
};
goog.color.normalizedHexColorRe_ = /^#[0-9a-f]{6}$/;
goog.color.isNormalizedHexColor_ = function(str) {
  return goog.color.normalizedHexColorRe_.test(str);
};
goog.color.rgbColorRe_ = /^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;
goog.color.isValidRgbColor_ = function(str) {
  var regExpResultArray = str.match(goog.color.rgbColorRe_);
  if (regExpResultArray) {
    var r = Number(regExpResultArray[1]);
    var g = Number(regExpResultArray[2]);
    var b = Number(regExpResultArray[3]);
    if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
      return [r, g, b];
    }
  }
  return [];
};
goog.color.prependZeroIfNecessaryHelper = function(hex) {
  return hex.length == 1 ? "0" + hex : hex;
};
goog.color.prependHashIfNecessaryHelper = function(str) {
  return str.charAt(0) == "#" ? str : "#" + str;
};
goog.color.rgbStyle_ = function(rgb) {
  return "rgb(" + rgb.join(",") + ")";
};
goog.color.hsvToRgb = function(h, s, brightness) {
  var red = 0;
  var green = 0;
  var blue = 0;
  if (s == 0) {
    red = brightness;
    green = brightness;
    blue = brightness;
  } else {
    var sextant = Math.floor(h / 60);
    var remainder = h / 60 - sextant;
    var val1 = brightness * (1 - s);
    var val2 = brightness * (1 - s * remainder);
    var val3 = brightness * (1 - s * (1 - remainder));
    switch(sextant) {
      case 1:
        red = val2;
        green = brightness;
        blue = val1;
        break;
      case 2:
        red = val1;
        green = brightness;
        blue = val3;
        break;
      case 3:
        red = val1;
        green = val2;
        blue = brightness;
        break;
      case 4:
        red = val3;
        green = val1;
        blue = brightness;
        break;
      case 5:
        red = brightness;
        green = val1;
        blue = val2;
        break;
      case 6:
      case 0:
        red = brightness;
        green = val3;
        blue = val1;
        break;
    }
  }
  return [Math.floor(red), Math.floor(green), Math.floor(blue)];
};
goog.color.rgbToHsv = function(red, green, blue) {
  var max = Math.max(Math.max(red, green), blue);
  var min = Math.min(Math.min(red, green), blue);
  var hue;
  var saturation;
  var value = max;
  if (min == max) {
    hue = 0;
    saturation = 0;
  } else {
    var delta = max - min;
    saturation = delta / max;
    if (red == max) {
      hue = (green - blue) / delta;
    } else {
      if (green == max) {
        hue = 2 + (blue - red) / delta;
      } else {
        hue = 4 + (red - green) / delta;
      }
    }
    hue *= 60;
    if (hue < 0) {
      hue += 360;
    }
    if (hue > 360) {
      hue -= 360;
    }
  }
  return [hue, saturation, value];
};
goog.color.rgbArrayToHsv = function(rgb) {
  return goog.color.rgbToHsv(rgb[0], rgb[1], rgb[2]);
};
goog.color.hsvArrayToRgb = function(hsv) {
  return goog.color.hsvToRgb(hsv[0], hsv[1], hsv[2]);
};
goog.color.hexToHsl = function(hex) {
  var rgb = goog.color.hexToRgb(hex);
  return goog.color.rgbToHsl(rgb[0], rgb[1], rgb[2]);
};
goog.color.hslToHex = function(h, s, l) {
  return goog.color.rgbArrayToHex(goog.color.hslToRgb(h, s, l));
};
goog.color.hslArrayToHex = function(hsl) {
  return goog.color.rgbArrayToHex(goog.color.hslToRgb(hsl[0], hsl[1], hsl[2]));
};
goog.color.hexToHsv = function(hex) {
  return goog.color.rgbArrayToHsv(goog.color.hexToRgb(hex));
};
goog.color.hsvToHex = function(h, s, v) {
  return goog.color.rgbArrayToHex(goog.color.hsvToRgb(h, s, v));
};
goog.color.hsvArrayToHex = function(hsv) {
  return goog.color.hsvToHex(hsv[0], hsv[1], hsv[2]);
};
goog.color.hslDistance = function(hsl1, hsl2) {
  var sl1, sl2;
  if (hsl1[2] <= 0.5) {
    sl1 = hsl1[1] * hsl1[2];
  } else {
    sl1 = hsl1[1] * (1.0 - hsl1[2]);
  }
  if (hsl2[2] <= 0.5) {
    sl2 = hsl2[1] * hsl2[2];
  } else {
    sl2 = hsl2[1] * (1.0 - hsl2[2]);
  }
  var h1 = hsl1[0] / 360.0;
  var h2 = hsl2[0] / 360.0;
  var dh = (h1 - h2) * 2.0 * Math.PI;
  return (hsl1[2] - hsl2[2]) * (hsl1[2] - hsl2[2]) + sl1 * sl1 + sl2 * sl2 - 2 * sl1 * sl2 * Math.cos(dh);
};
goog.color.blend = function(rgb1, rgb2, factor) {
  factor = goog.math.clamp(factor, 0, 1);
  return [Math.round(factor * rgb1[0] + (1.0 - factor) * rgb2[0]), Math.round(factor * rgb1[1] + (1.0 - factor) * rgb2[1]), Math.round(factor * rgb1[2] + (1.0 - factor) * rgb2[2])];
};
goog.color.darken = function(rgb, factor) {
  var black = [0, 0, 0];
  return goog.color.blend(black, rgb, factor);
};
goog.color.lighten = function(rgb, factor) {
  var white = [255, 255, 255];
  return goog.color.blend(white, rgb, factor);
};
goog.color.highContrast = function(prime, suggestions) {
  var suggestionsWithDiff = [];
  for (var i = 0; i < suggestions.length; i++) {
    suggestionsWithDiff.push({color:suggestions[i], diff:goog.color.yiqBrightnessDiff_(suggestions[i], prime) + goog.color.colorDiff_(suggestions[i], prime)});
  }
  suggestionsWithDiff.sort(function(a, b) {
    return b.diff - a.diff;
  });
  return suggestionsWithDiff[0].color;
};
goog.color.yiqBrightness_ = function(rgb) {
  return Math.round((rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000);
};
goog.color.yiqBrightnessDiff_ = function(rgb1, rgb2) {
  return Math.abs(goog.color.yiqBrightness_(rgb1) - goog.color.yiqBrightness_(rgb2));
};
goog.color.colorDiff_ = function(rgb1, rgb2) {
  return Math.abs(rgb1[0] - rgb2[0]) + Math.abs(rgb1[1] - rgb2[1]) + Math.abs(rgb1[2] - rgb2[2]);
};
goog.provide("uno.util.observer");
goog.require("goog.array");
goog.require("goog.events");
goog.require("uno.defs");
goog.require("uno.util.dom");
(function() {
  var util = uno.util;
  var handlers = [];
  var target = null;
  var targetBottom = null;
  var sharedObserver = null;
  util.observer.addHandler = function(handler) {
    if (!handler) {
      return;
    }
    if (handlers.indexOf(handler) === -1) {
      handlers.push(handler);
      observeIfNeeded();
    }
  };
  util.observer.removeHandler = function(handler) {
    if (!handler) {
      return;
    }
    var index = handlers.indexOf(handler);
    if (index > -1) {
      handlers.splice(index, 1);
      observeIfNeeded();
    }
  };
  function invokeHandlers() {
    var bottom = getBottom(target);
    if (targetBottom !== bottom) {
      targetBottom = bottom;
      handlers.forEach(function(handler) {
        handler();
      });
    }
  }
  function handleObservation(mutations) {
    goog.array.forEach(mutations, function(mutation) {
      goog.array.forEach(mutation.addedNodes, function(node) {
        if (util.dom.isImg(node) && !node.naturalHeight) {
          goog.events.listenOnce(node, "load", invokeHandlers);
        }
      });
    });
    invokeHandlers();
  }
  function getBottom(node) {
    if (!node || !node.lastChild) {
      return 0;
    }
    return node.lastChild.offsetTop + node.lastChild.offsetHeight;
  }
  function observeIfNeeded() {
    if (!sharedObserver) {
      if (!window || !window.MutationObserver) {
        throw new Error("MutationObserver is missing.");
      }
      sharedObserver = new MutationObserver(handleObservation);
    }
    sharedObserver.disconnect();
    goog.events.unlisten(window, "resize", invokeHandlers);
    goog.events.unlisten(window, "input", invokeHandlers);
    if (handlers.length > 0) {
      target = document.querySelector(uno.defs.containers.EDITOR_BODY_SELECTOR);
      targetBottom = getBottom(target);
      sharedObserver.observe(target, {childList:true, subtree:true});
      goog.events.listen(window, "resize", invokeHandlers);
      goog.events.listen(window, "input", invokeHandlers);
    }
  }
})();
goog.provide("uno.util.range");
goog.require("goog.debug.Logger");
goog.require("goog.editor.range");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.zoomscale");
(function() {
  var util = uno.util;
  var dom = util.dom;
  var log = goog.debug.Logger.getLogger("uno.util.range");
  function getViewPortRect(margin) {
    var rect = {left:0, top:0, width:window.innerWidth, height:window.innerHeight - margin.offset.height};
    if (margin.scroll.top > 0) {
      rect.top -= margin.scroll.top;
      rect.height += margin.scroll.top;
    }
    rect.bottom = rect.top + rect.height;
    rect.right = rect.left + rect.width;
    return rect;
  }
  function scrollRectIntoView(rect, placeOnTop, margin) {
    var transY = 0;
    var viewport = getViewPortRect(margin);
    var top = util.dom.scrollTop(document.body);
    if (placeOnTop === true) {
      transY = viewport.top - rect.top;
    } else {
      transY = viewport.bottom - rect.bottom;
    }
    top = Math.max(0, top - transY);
    util.dom.scrollTop(document.body, top);
  }
  util.range.atBeginningOfDiv = function(range) {
    if (range && range.getStartNode() && util.dom.compareTagName(range.getStartNode(), "div") && range.isCollapsed()) {
      if (range.getStartOffset() === 0) {
        return true;
      }
      var currentChild = null;
      for (var i = 0; i < range.getStartOffset(); i++) {
        currentChild = range.getStartNode().childNodes[i];
        if (currentChild.nodeType !== Node.TEXT_NODE || currentChild.textContent.length !== 0) {
          return false;
        }
      }
      return true;
    }
    return false;
  };
  util.range.getBoundingBoxesFromRange = function(rangeObject, optAbsolute, optKeepInvisible) {
    if (optAbsolute == null) {
      optAbsolute = false;
    }
    if (optKeepInvisible == null) {
      optKeepInvisible = false;
    }
    if (!rangeObject) {
      return null;
    }
    var boxes = rangeObject.getClientRects();
    if (!boxes || !boxes.length) {
      return null;
    }
    var lastBox = null;
    var matches = [];
    for (var i = 0; i < boxes.length; i++) {
      var match = {};
      var box = boxes[i];
      if (!optKeepInvisible && (box.width <= 1 || box.height <= 1)) {
        continue;
      }
      if (lastBox && box.left >= lastBox.left && box.top >= lastBox.top && box.right <= lastBox.right && box.bottom <= lastBox.bottom) {
        continue;
      }
      lastBox = box;
      match.top = lastBox.top;
      match.bottom = lastBox.bottom;
      match.left = lastBox.left;
      match.right = lastBox.right;
      match.width = lastBox.right - lastBox.left;
      match.height = lastBox.bottom - lastBox.top;
      var prev = matches.length - 1;
      if (prev > -1 && matches[prev].left <= match.right && match.left <= matches[prev].right && matches[prev].top <= match.bottom && match.top <= matches[prev].bottom) {
        var newMatch = {};
        newMatch.top = Math.max(matches[prev].top, match.top);
        newMatch.bottom = Math.min(matches[prev].bottom, match.bottom);
        newMatch.left = matches[prev].left;
        newMatch.right = match.right;
        newMatch.width = newMatch.right - newMatch.left;
        newMatch.height = newMatch.bottom - newMatch.top;
        matches[prev] = newMatch;
      } else {
        matches.push(match);
      }
    }
    if (optAbsolute) {
      matches = goog.array.map(matches, function(matchbox) {
        return util.dom.makeClientRect(matchbox, {absolute:true, zoomScale:uno.util.zoomscale.getZoom()});
      });
    }
    return matches;
  };
  util.range.getBoundingBoxesFromTextSelection = function(rangeObject, optAbsolute, optKeepInvisible) {
    if (optAbsolute == null) {
      optAbsolute = false;
    }
    if (optKeepInvisible == null) {
      optKeepInvisible = false;
    }
    if (!rangeObject) {
      return null;
    }
    var boxes = [];
    function addRectsToBoxes(range) {
      var rects = range.getClientRects();
      for (var i = 0; i < rects.length; i++) {
        boxes.push(rects[i]);
      }
    }
    if (rangeObject.startContainer === rangeObject.endContainer) {
      addRectsToBoxes(rangeObject);
    } else {
      var nodeFilter = function(node) {
        return rangeObject.intersectsNode(node) && rangeObject.startContainer !== node && rangeObject.endContainer !== node;
      };
      var startRange = document.createRange();
      startRange.setStart(rangeObject.startContainer, rangeObject.startOffset);
      startRange.setEndAfter(rangeObject.startContainer);
      addRectsToBoxes(startRange);
      var endRange = document.createRange();
      endRange.setStart(rangeObject.endContainer, 0);
      endRange.setEnd(rangeObject.endContainer, rangeObject.endOffset);
      addRectsToBoxes(endRange);
      var walker = document.createTreeWalker(rangeObject.commonAncestorContainer, NodeFilter.SHOW_TEXT, {acceptNode:nodeFilter}, false);
      var textNode;
      while (textNode = walker.nextNode()) {
        var range = document.createRange();
        range.selectNode(textNode);
        addRectsToBoxes(range);
      }
    }
    if (!boxes || !boxes.length) {
      return null;
    }
    if (optAbsolute) {
      boxes = goog.array.map(boxes, function(matchbox) {
        return util.dom.makeClientRect(matchbox, {absolute:true, zoomScale:uno.util.zoomscale.getZoom()});
      });
    }
    return boxes;
  };
  function unionOfClientRects(rects) {
    if (rects == null || rects.length < 1) {
      return null;
    }
    var firstRect = rects[0];
    var rect = {top:firstRect.top, left:firstRect.left, right:firstRect.right, bottom:firstRect.bottom};
    for (var i = 1; i < rects.length; i++) {
      var currentRect = rects[i];
      if (currentRect.width > 0 && currentRect.height > 0) {
        rect = {top:Math.min(rect.top, currentRect.top), left:Math.min(rect.left, currentRect.left), right:Math.max(rect.right, currentRect.right), bottom:Math.max(rect.bottom, currentRect.bottom)};
      }
    }
    rect.width = rect.right - rect.left;
    rect.height = rect.bottom - rect.top;
    return rect;
  }
  util.range.scrollSelectionIntoView = function(editor) {
    if (!editor.inEditMode()) {
      return;
    }
    log.fine("Requesting to scroll selection into view");
    var range = editor.getRange();
    if (range) {
      var rect = unionOfClientRects(range.getBrowserRangeObject().getClientRects());
      if (!rect) {
        var node = range.getFocusNode();
        if (node && node.getClientRects) {
          rect = unionOfClientRects(node.getClientRects());
        }
      }
      if (rect) {
        var viewport = getViewPortRect(editor.config.margin);
        if (viewport.top >= rect.top && viewport.bottom <= rect.bottom) {
        } else {
          if (viewport.top > rect.top) {
            log.fine("  ... performing scrolling to TOP");
            scrollRectIntoView(rect, true, editor.config.margin);
          } else {
            if (viewport.bottom < rect.bottom) {
              log.fine("  ... performing scrolling to BOTTOM");
              scrollRectIntoView(rect, false, editor.config.margin);
            }
          }
        }
      } else {
        if (util.dom.isEmpty(editor.field)) {
          log.fine("  ... performing scrolling the editor field into view");
          editor.field.scrollIntoView();
        }
      }
    }
  };
  util.range.commonAncestors = function(range, opt_selector, opt_root) {
    var startNode = range.getStartNode();
    var endNode = range.getEndNode();
    var getNonTextOrSelectorParent = function(node) {
      if (opt_selector) {
        var selectorNode = util.dom.parent(node, opt_selector, opt_root);
        if (selectorNode !== null) {
          return selectorNode;
        }
      }
      while (util.dom.isTextNode(node)) {
        node = node.parentNode;
      }
      return node;
    };
    startNode = getNonTextOrSelectorParent(startNode);
    endNode = getNonTextOrSelectorParent(endNode);
    if (startNode === endNode) {
      return [startNode, endNode];
    }
    var startParents = util.dom.ancestors(startNode);
    var endParents = util.dom.ancestors(endNode);
    if (startParents[0] !== endParents[0]) {
      return [startNode, endNode];
    }
    var i = 0;
    for (; i < startParents.length && i < endParents.length; i++) {
      if (startParents[i] !== endParents[i]) {
        break;
      }
    }
    var result = [startNode, endNode];
    if (i < startParents.length) {
      result[0] = startParents[i];
    }
    if (i < endParents.length) {
      result[1] = endParents[i];
    }
    return result;
  };
  util.range.forEachWord = function(range, transformFunc) {
    goog.iter.forEach(range, function(element) {
      if (element.nodeType !== Node.TEXT_NODE) {
        return;
      }
      var nodeText = element.nodeValue;
      if (nodeText == null || goog.string.isEmpty(nodeText)) {
        return;
      }
      var re = new RegExp(uno.defs.regex.WORD_CHARACTER, "g");
      var match = null, matchRange = null;
      while ((match = re.exec(nodeText)) != null) {
        var matchStart = match.index;
        var matchEnd = match.index + match[0].length;
        if (element === range.getStartNode() && matchEnd <= range.getStartOffset() || element === range.getEndNode() && matchStart >= range.getEndOffset()) {
          continue;
        }
        matchRange = document.createRange();
        matchRange.setStart(element, matchStart);
        matchRange.setEnd(element, matchEnd);
        transformFunc(match[0], matchRange);
      }
    });
  };
  util.range.selectNode = function(node) {
    var range = goog.dom.Range.createFromNodes(node.parentElement, util.dom.index(node), node.parentElement, util.dom.index(node) + 1);
    range.select();
  };
  util.range.selectNodeContents = function(node) {
    var range = goog.dom.Range.createFromNodeContents(node);
    range.select();
  };
  util.range.fromInfo = function(start, end) {
    var range = document.createRange();
    range.setStart(start.container, start.offset);
    if (end != null) {
      range.setEnd(end.container, end.offset);
    }
    return goog.dom.Range.createFromBrowserRange(range);
  };
  util.range.selectFromInfo = function(start, end) {
    var range = util.range.fromInfo(start, end);
    range.select();
    return range;
  };
  util.range.boundary = function(node, offset) {
    return util.dom.isElementNode(node) ? node.childNodes[offset] : node;
  };
  util.range.containsTagNames = function(tagNames, range) {
    return util.range.queryTagNames(tagNames, range) != null;
  };
  util.range.queryTagNames = function(tagNames, range) {
    if (range == null) {
      return;
    }
    if (!Array.isArray(tagNames)) {
      tagNames = [tagNames];
    }
    var selector = tagNames.join(",");
    var container = range.getContainer();
    if (container.querySelector == null || container.querySelector(selector) == null) {
      return;
    }
    var start = util.range.boundary(range.getStartNode(), range.getStartOffset());
    var end = util.range.boundary(range.getEndNode(), range.getEndOffset());
    var walker = new util.dom.TreeWalker(start, container);
    var result;
    if (util.dom.compareTagName(start, tagNames)) {
      result = start;
    }
    while (result == null && walker.current() && walker.current() !== end) {
      if (util.dom.compareTagName(walker.current(), tagNames)) {
        result = walker.current();
      } else {
        if (walker.current().contains(end)) {
          walker.next(true);
        } else {
          if (walker.current().querySelector) {
            result = walker.current().querySelector(selector);
          }
          walker.next(false);
        }
      }
    }
    if (result == null && util.dom.compareTagName(end.tagName, tagNames)) {
      result = end;
    }
    return result;
  };
  util.range.queryTagNamesAll = function(tagNames, range) {
    if (range == null) {
      return [];
    }
    if (!Array.isArray(tagNames)) {
      tagNames = [tagNames];
    }
    var selector = tagNames.join(",");
    var container = range.getContainer();
    if (container.querySelector == null || container.querySelector(selector) == null) {
      return [];
    }
    var start = util.range.boundary(range.getStartNode(), range.getStartOffset());
    var end = util.range.boundary(range.getEndNode(), range.getEndOffset());
    var walker = new util.dom.TreeWalker(start, container);
    var results = [];
    var nodeList;
    if (util.dom.compareTagName(start, tagNames)) {
      results.push(start);
    }
    while (walker.current() && walker.current() !== end) {
      if (util.dom.compareTagName(walker.current(), tagNames)) {
        results.push(walker.current());
      }
      if (walker.current().contains(end)) {
        walker.next(true);
      } else {
        if (walker.current().querySelector) {
          nodeList = walker.current().querySelectorAll(selector);
          goog.array.forEach(nodeList, function(node) {
            results.push(node);
          });
        }
        walker.next(false);
      }
    }
    if (util.dom.compareTagName(end.tagName, tagNames)) {
      results.push(end);
    }
    return results;
  };
  util.range.saveCursor = function(range) {
    if (!range) {
      return null;
    }
    var oldCursors = document.querySelectorAll('[id^="goog"]');
    goog.array.forEach(oldCursors, goog.dom.removeNode);
    var savedRange = range.saveUsingCarets();
    var start = document.querySelector("#" + savedRange.startCaretId_);
    var end = document.querySelector("#" + savedRange.endCaretId_);
    if (start && end) {
      util.dom.changeTagName(start, "en-cursor");
      util.dom.changeTagName(end, "en-cursor");
    }
    return savedRange;
  };
  util.range.clientRectsRanges = function(textNode) {
    if (!textNode || !util.dom.isTextNode(textNode) || !textNode.textContent) {
      return [];
    }
    var parentNode = textNode.parentNode;
    var offsets = [];
    var offset = 0;
    var top = null;
    var rects = null;
    var node = textNode;
    var measureRange = document.createRange();
    parentNode.normalize();
    measureRange.selectNodeContents(node);
    rects = measureRange.getClientRects();
    if (rects.length === 0) {
      return [];
    } else {
      if (rects.length === 1) {
        return [goog.dom.Range.createFromNodes(node, 0, node, node.length)];
      }
    }
    var oldWidth = parentNode.style.width;
    parentNode.style.width = parentNode.getBoundingClientRect().width + "px";
    for (var i = node.textContent.length - 1; i >= 0; i--) {
      var sibling = node.splitText(i + 1);
      if (sibling.textContent) {
        measureRange.selectNodeContents(sibling);
        rects = measureRange.getClientRects();
        if (top !== rects[0].top) {
          top = rects[0].top;
          offsets.push(i + 2);
        }
      }
    }
    parentNode.normalize();
    parentNode.style.width = oldWidth;
    offsets.push(0);
    var ranges = [];
    for (var j = offsets.length - 1; j > 0; j--) {
      ranges.push(goog.dom.Range.createFromNodes(textNode, offsets[j], textNode, offsets[j - 1]));
    }
    return ranges;
  };
  util.range.createFromPoints = function(x, y) {
    var range = document.caretRangeFromPoint(x, y);
    if (range) {
      return goog.dom.Range.createFromNodes(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
    }
    return null;
  };
  function normalizeInternal(direction, rangeNode, rangeOffset, collapsed, debug) {
    var node = rangeNode;
    var offset = rangeOffset;
    while (dom.isUneditable(node)) {
      var parent = node.parentNode;
      var startOffset = dom.index(node);
      node = node.parentNode;
    }
    digging: while (!(dom.isTextNode(node) || dom.isInlineObject(node))) {
      var childNodes = node.childNodes;
      var currentOffset = Math.min(childNodes.length, offset);
      var check = direction === 0 ? function() {
        return currentOffset < childNodes.length;
      } : function() {
        return currentOffset > 0;
      };
      while (check()) {
        var candidate = childNodes[currentOffset + direction];
        if (dom.isInlineObject(candidate) || (dom.isBlockObject(candidate) || candidate.tagName === "A") && !collapsed) {
          offset = currentOffset;
          break digging;
        }
        if (!dom.isUneditable(candidate) && candidate.tagName !== "COLGROUP") {
          offset = direction === 0 ? 0 : dom.isTextNode(candidate) ? candidate.textContent.length : candidate.childNodes.length;
          node = candidate;
          continue digging;
        }
        currentOffset += direction === 0 ? 1 : -1;
      }
      break;
    }
    if (debug && (rangeNode !== node || rangeOffset !== offset)) {
      var message = "normalize" + (direction === 0 ? "Forward" : "Backward") + " changed a range boundary from " + toDebugString(rangeNode, rangeOffset) + " to " + toDebugString(node, offset);
      log.info(message, (new Error).stack);
    }
    return {node:node, offset:offset};
  }
  util.range.normalize = function(range, debug) {
    if (!range) {
      return range;
    }
    if (debug === undefined) {
      debug = DEBUG;
    }
    var browserRange = range.getBrowserRangeObject();
    var collapsed = range.isCollapsed();
    var start = normalizeInternal(0, range.getStartNode(), range.getStartOffset(), collapsed, debug);
    if (collapsed) {
      return goog.dom.Range.createCaret(start.node, start.offset);
    }
    var end = normalizeInternal(-1, range.getEndNode(), range.getEndOffset(), collapsed, debug);
    return goog.dom.Range.createFromNodes(start.node, start.offset, end.node, end.offset);
  };
  util.range.truncateTrailingOpenTag = function(range) {
    if (range.isCollapsed()) {
      return util.range.normalize(range);
    }
    var endNode = range.getEndNode();
    var endOffset = range.getEndOffset();
    if (endOffset !== 0) {
      return util.range.normalize(range);
    }
    var current = endNode;
    var previousNode = current.previousSibling;
    while (util.dom.isUneditable(previousNode)) {
      previousNode = previousNode.previousSibling;
    }
    while (current && !previousNode) {
      current = current.parentNode;
      previousNode = current.previousSibling;
    }
    if (!previousNode) {
      return range;
    }
    range = goog.dom.Range.createFromNodes(range.getStartNode(), range.getStartOffset(), previousNode, previousNode.childNodes.length);
    return util.range.normalize(range);
  };
  function toDebugString(node, offset) {
    return "{ " + (node.outerHTML || "#" + node.textContent) + "::" + offset + " }";
  }
  util.range.print = function(range) {
    return range.isCollapsed() ? toDebugString(range.getStartNode(), range.getStartOffset()) : "[" + toDebugString(range.getStartNode(), range.getStartOffset()) + " -- " + toDebugString(range.getEndNode(), range.getEndOffset()) + "]";
  };
})();
goog.provide("uno.util.font.generic");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.style");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.font.generic");
  var util = uno.util;
  var generic = util.font.generic;
  generic.getSize = function(node) {
    var pxs = goog.style.getFontSize(node);
    return pxs;
  };
  generic.prepareSize = function(size) {
    if (goog.isString(size) && !isNaN(size) && !/[a-z]$/.test(size)) {
      size += "px";
    } else {
      if (typeof size === "number") {
        size += "px";
      }
    }
    return size;
  };
})();
goog.provide("uno.util.font.win");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.style");
goog.require("uno.util.font.generic");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.font.win");
  var util = uno.util;
  var generic = util.font.generic;
  var win = util.font.win;
  win.getSize = function(node) {
    var pxs = generic.getSize(node);
    var pts = util.font.pxsToPts(pxs);
    return pts;
  };
  win.prepareSize = function(size) {
    if (goog.isString(size) && !isNaN(size) && !/[a-z]$/i.test(size)) {
      size += "pt";
    } else {
      if (typeof size === "number") {
        size += "pt";
      }
    }
    return size;
  };
})();
goog.provide("uno.util.font");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.style");
goog.require("uno.util.font.generic");
goog.require("uno.util.font.win");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.font");
  var client = uno.util.font.generic;
  var util = uno.util;
  util.font.setClient = function(clientName) {
    client = uno.util.font[clientName] || uno.util.font.generic;
  };
  util.font.getSize = function(node) {
    return client.getSize(node);
  };
  util.font.getColor = function(node) {
    return goog.style.getComputedStyle(node, "color");
  };
  util.font.prepareSize = function(size) {
    return client.prepareSize(size);
  };
  util.font.sizeEquals = function(size1, size2) {
    size1 = util.font.prepareSize(size1);
    size2 = util.font.prepareSize(size2);
    if (size1 === size2) {
      return true;
    }
    if (size1.indexOf("px") > 0) {
      size1 = util.font.pxsToPts(size1) + "pt";
    }
    if (size2.indexOf("px") > 0) {
      size2 = util.font.pxsToPts(size2) + "pt";
    }
    return size1 === size2;
  };
  util.font.pxsToPts = function(pxs) {
    var div = goog.dom.createDom("div", {style:"position:absolute; top:-1000pt; height:100pt;"});
    goog.dom.append(document.body, div);
    var ratio = parseFloat(goog.style.getComputedStyle(div, "height"));
    goog.dom.removeNode(div);
    var pts = Math.round(parseFloat(pxs) * 100 / ratio);
    return pts;
  };
  util.font.normalizeFontSize = function(elem, size) {
    size = size || window.getComputedStyle(elem, null).getPropertyValue("font-size");
    elem.removeAttribute("size");
    elem.style.fontSize = size;
  };
  util.font.normalize = function(fontContainer, size) {
    util.font.normalizeFontSize(fontContainer, size);
    var ancestor = fontContainer;
    var outerFontContainer;
    while (!util.dom.isEnnote(ancestor) && ancestor.parentNode) {
      if (ancestor.tagName === "FONT") {
        outerFontContainer = ancestor;
      }
      ancestor = ancestor.parentNode;
    }
    var fontNodeList = outerFontContainer.querySelectorAll("font[size]");
    var fontContainers = Array.prototype.slice.call(fontNodeList);
    Array.prototype.forEach.call(fontContainers, function(elem) {
      util.font.normalizeFontSize(elem);
    });
  };
})();
goog.provide("uno.util.styles");
goog.require("goog.dom");
goog.require("goog.style");
goog.require("goog.array");
goog.require("goog.object");
goog.require("goog.string");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.font");
(function() {
  var util = uno.util;
  var dom = uno.util.dom;
  var styles = util.styles;
  var highlightBackgroundColor = uno.defs.highlight.COLOR;
  var knownAttributes = /data-.*|face|border|name|href|rev|start|title|color|class/;
  var fontSizeMap = {1:"11px", 2:"12px", 3:"14px", 4:"18px", 5:"24px", 6:"36px", 7:"48px"};
  var rxEscapeObj = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g;
  function rxEscape(value) {
    if (value instanceof RegExp) {
      return value.source;
    }
    return value.replace(rxEscapeObj, "\\$&");
  }
  var regexForAppDataNameCache = {};
  function regexForAppDataName(name) {
    var rx = regexForAppDataNameCache[name];
    if (!rx) {
      rx = new RegExp("(^|;)\\s*(" + rxEscape(name) + ")\\s*\\:\\s*(.*?)($|;)+", "gi");
      regexForAppDataName[name] = rx;
    } else {
      rx.lastIndex = 0;
    }
    return rx;
  }
  styles.rxEvernoteCustomStyleAttr = /^-(en|evernote)-/i;
  styles.rxEvernoteCustomDataAttr = /^data-(en|evernote)-/i;
  var metadataMarker = "data-en-has-metadata";
  styles.metadataImportSelectors = ['*[style*="-en-"]', '*[style*="-evernote-"]'];
  styles.metadataExportSelectors = ["*[" + metadataMarker + "]"];
  styles.stylesToIgnore = ["-evernote-editable"];
  styles.convertStylesToDataAttributes = function(el) {
    var styleString = el.getAttribute("style");
    var filteredStyle = "";
    var foundMetadata = false;
    goog.array.forEach(styleString.split(/\s*;\s*/), function(pair) {
      if (pair.length === 0) {
        return;
      }
      var keyValue = pair.match(/\s*([\w-]+)\s*\:(.*)/);
      var styleName = keyValue[1];
      var styleValue = goog.string.trim(keyValue[2]);
      if (styles.rxEvernoteCustomStyleAttr.test(styleName) && styles.stylesToIgnore.indexOf(styleName) === -1) {
        el.setAttribute("data" + styleName, styleValue);
        foundMetadata = true;
      } else {
        filteredStyle += pair + ";";
      }
    });
    if (foundMetadata) {
      el.setAttribute(metadataMarker, true);
      el.setAttribute("style", filteredStyle);
      if (goog.string.isEmpty(filteredStyle)) {
        el.removeAttribute("style");
      }
    }
  };
  styles.convertDataAttributesToStyles = function(el) {
    el.removeAttribute(metadataMarker);
    goog.array.forEachRight(el.attributes, function(attr) {
      if (styles.rxEvernoteCustomDataAttr.test(attr.name)) {
        styles.setStyle(el, attr.name.substr(4), attr.value);
        el.removeAttribute(attr.name);
      }
    });
  };
  styles.setMetadata = function(el, name, value) {
    if (name.indexOf("data") !== 0) {
      if (name.indexOf("-") !== 0) {
        name = "-" + name;
      }
      name = "data" + name;
    }
    if (value != null && value !== "") {
      el.setAttribute(metadataMarker, true);
    }
    el.setAttribute(name, value);
  };
  styles.hasMetadata = function(el) {
    return el && el.getAttribute(metadataMarker);
  };
  styles.getStyle = function(node, name) {
    var styleString = node.getAttribute("style");
    if (styleString == null) {
      return null;
    }
    name = goog.string.toSelectorCase(name);
    var match = regexForAppDataName(name).exec(styleString);
    return match === null ? null : match[3].trim();
  };
  styles.setStyle = function(node, name, value) {
    name = goog.string.toSelectorCase(name);
    var styleString = styles.removeStyle(node, name);
    if (value == null) {
      return null;
    }
    styleString = styleString.trim();
    if (styleString.length && styleString[styleString.length - 1] !== ";") {
      styleString += ";";
    }
    styleString = styleString + name + ":" + value + ";";
    node.setAttribute("style", styleString);
    return styleString;
  };
  styles.removeStyle = function(node, name) {
    name = goog.string.toSelectorCase(name);
    var styleString = node.getAttribute("style");
    if (styleString == null) {
      return "";
    }
    styleString = styleString.replace(regexForAppDataName(name), "$1").trim();
    if (styleString.length > 0) {
      node.setAttribute("style", styleString);
    } else {
      node.removeAttribute("style");
    }
    return styleString || "";
  };
  styles.createPendingStyles = function(editor) {
    editor.context.style.hasPendingStyles = true;
    editor.context.style.pendingStyles = {};
    editor.context.style.pendingStyles.state = goog.object.clone(editor.context.style.state);
    editor.context.style.pendingStyles.value = goog.object.clone(editor.context.style.value);
  };
  styles.clearPendingStyles = function(editor) {
    editor.context.style.hasPendingStyles = false;
    editor.context.style.pendingStyles = {state:{}, value:{}};
  };
  styles.parseStyleAttribute = function(style) {
    var result = {};
    goog.array.forEach((style || "").split(/\s*;\s*/), function(pair) {
      var keyValue = pair.match(/\s*([\w-]+)\s*:(.+)/);
      if (keyValue) {
        var styleName = keyValue[1];
        var styleValue = goog.string.trim(keyValue[2]);
        result[styleName] = styleValue;
      }
    });
    return result;
  };
  styles.toStyleObject = function(currentStyles, defaults) {
    var results = {};
    Object.keys(currentStyles || {}).forEach(function(key) {
      var value = currentStyles[key];
      if (value) {
        switch(key) {
          case "bold":
            results.bold = true;
            break;
          case "italic":
            results.italic = true;
            break;
          case "strikethrough":
            results.strikethrough = true;
            break;
          case "underline":
            results.underline = true;
            break;
          case "forecolor":
            results.color = defaults.fontColor === value ? "" : value;
            break;
          case "fontname":
            results["font-family"] = defaults.fontName === value || defaults.richTextFont === value ? "" : value;
            break;
          case "fontsize":
            var fontSize = util.font.prepareSize(value);
            results["font-size"] = util.font.sizeEquals(defaults.fontSize, fontSize) ? "" : fontSize;
            break;
          case "highlight":
            results["background-color"] = uno.defs.highlight.COLOR;
            break;
          default:
        }
      }
    });
    return results;
  };
  styles.addTempState = function(editor, name, state) {
    editor.context.hasTempStyles = true;
    editor.context.tempStyles.state[name] = state;
  };
  styles.addTempValue = function(editor, name, value) {
    editor.context.hasTempStyles = true;
    editor.context.tempStyles.value[name] = value;
  };
  styles.clearTempStyles = function(editor) {
    editor.context.hasTempStyles = false;
    editor.context.tempStyles = {state:{}, value:{}, enabled:{}};
  };
  styles.formattingForTempStyles = function(editor) {
    var tempStyles = editor.context.tempStyles;
    var result = {};
    Object.keys(tempStyles.state).forEach(function(key) {
      result[key] = tempStyles.state[key];
    });
    Object.keys(tempStyles.value).forEach(function(key) {
      result[key] = tempStyles.value[key];
    });
    return result;
  };
  styles.setInlineStyles = function(line, style, defaults) {
    var hadParent = true;
    if (dom.isTextNode(line) || dom.isImg(line)) {
      line = goog.dom.createDom("span", null, line);
      hadParent = false;
    }
    var fontNode = document.createElement("font");
    var node = goog.dom.findNode(line, function(n) {
      return dom.isTextNode(n) || dom.isImg(n);
    });
    if (!node) {
      return line;
    }
    var nodeWrapper = node.parentNode;
    if (style.state.bold) {
      node = goog.dom.createDom("b", null, node);
    }
    if (style.state.italic) {
      node = goog.dom.createDom("i", null, node);
    }
    if (style.state.underline) {
      node = goog.dom.createDom("u", null, node);
    }
    if (style.state.strikethrough) {
      node = goog.dom.createDom("strike", null, node);
    }
    if (style.state.subscript) {
      node = goog.dom.createDom("sub", null, node);
    }
    if (style.state.superscript) {
      node = goog.dom.createDom("sup", null, node);
    }
    if (style.state.highlight) {
      goog.style.setStyle(fontNode, "backgroundColor", highlightBackgroundColor);
    }
    if (!util.font.sizeEquals(style.value.fontsize, defaults.fontSize)) {
      goog.style.setStyle(fontNode, "fontSize", util.font.prepareSize(style.value.fontsize));
    }
    if (style.value.forecolor !== defaults.foreColor) {
      goog.style.setStyle(fontNode, "color", style.value.forecolor);
    }
    var regex = "^(normal|-webkit-standard|" + defaults.fontFamily + "|" + defaults.richTextFont + ")$";
    var fontFamilyRegex = new RegExp(regex, "i");
    if (!fontFamilyRegex.test(style.value.fontname)) {
      goog.style.setStyle(fontNode, "fontFamily", style.value.fontname);
    }
    if (fontNode.getAttribute("style")) {
      fontNode.appendChild(node);
      node = fontNode;
    }
    nodeWrapper.appendChild(node);
    return hadParent ? line : line.firstChild;
  };
  styles.mergeAttributes = function(fromNode, toNode, skipTagName, options) {
    options = options || {};
    if (options.allowedStyles) {
      options.allowedStyles = new RegExp("^(" + options.allowedStyles + ")$");
    }
    if (options.disallowedStyles) {
      options.disallowedStyles = new RegExp("^(" + options.disallowedStyles + ")$");
    }
    if (options.allowedAttrs) {
      options.allowedAttrs = new RegExp("^(" + options.allowedAttrs + ")$");
    }
    if (options.disallowedAttrs) {
      options.disallowedAttrs = new RegExp("^(" + options.disallowedAttrs + ")$");
    }
    var fromAttributes = fromNode.attributes || [];
    var toAttributes = toNode.attributes || [];
    var finalAttributes = {};
    if (dom.isTextNode(toNode)) {
      return;
    }
    styles.convertAttributesToStyle(fromNode);
    styles.convertAttributesToStyle(toNode);
    goog.array.forEach(goog.array.toArray(fromAttributes), function(attr) {
      if (attr.name !== "style" && knownAttributes.test(attr.name)) {
        finalAttributes[attr.name] = attr.value;
      }
    });
    goog.array.forEach(goog.array.toArray(toAttributes), function(attr) {
      if (attr.name !== "style") {
        if (knownAttributes.test(attr.name)) {
          finalAttributes[attr.name] = attr.value;
        }
        toNode.removeAttribute(attr.name);
      }
    });
    var fromStyle = styles.getNodeStyle(fromNode, skipTagName);
    var toStyle = styles.getNodeStyle(toNode, skipTagName);
    var finalStyle = {};
    Object.keys(fromStyle).forEach(function(key) {
      if (options.disallowedStyles && options.disallowedStyles.test(key)) {
        return;
      }
      if (options.allowedStyles && !options.allowedStyles.test(key)) {
        return;
      }
      finalStyle[key] = fromStyle[key];
    });
    Object.keys(toStyle).forEach(function(key) {
      if (options.disallowedStyles && options.disallowedStyles.test(key)) {
        return;
      }
      if (options.allowedStyles && !options.allowedStyles.test(key)) {
        return;
      }
      finalStyle[key] = toStyle[key];
    });
    var styleString = styles.getStyleString(finalStyle);
    if (styleString) {
      toNode.setAttribute("style", styleString);
    } else {
      if (dom.isElementNode(toNode)) {
        toNode.removeAttribute("style");
      }
    }
    Object.keys(finalAttributes).forEach(function(key) {
      if (options.disallowedAttrs && options.disallowedAttrs.test(key)) {
        return;
      }
      if (options.allowedAttrs && !options.allowedAttrs.test(key)) {
        return;
      }
      toNode.setAttribute(key, finalAttributes[key]);
    });
  };
  styles.getNodeStyle = function(node, skipTagName) {
    if (!node || dom.isTextNode(node)) {
      return {};
    }
    var styleAttribute = node.getAttribute("style");
    styleAttribute = styleAttribute ? styleAttribute.split(";") : [];
    styleAttribute = styleAttribute.filter(function(style) {
      return style.trim() || false;
    }).map(function(style) {
      var styleObject = style.split(":");
      var name = styleObject[0] ? styleObject[0].trim() : "";
      var value = styleObject[1] ? styleObject[1].trim() : "";
      return {name:name, value:value};
    });
    var style = {};
    if (!skipTagName) {
      var tagName = node.tagName.toLowerCase();
      if (tagName === "b" || tagName === "strong") {
        style.bold = true;
      } else {
        if (tagName === "i" || tagName === "em") {
          style.italic = true;
        } else {
          if (tagName === "u" || tagName === "ins") {
            style.underline = true;
          } else {
            if (tagName === "strike" || tagName === "s" || tagName === "del") {
              style.strikethrough = true;
            } else {
              if (tagName === "sub") {
                style.subscript = true;
              } else {
                if (tagName === "sup") {
                  style.superscript = true;
                } else {
                  if (tagName === "font" && node.getAttribute("color")) {
                    style.color = node.getAttribute("color");
                  } else {
                    if (tagName === "font" && node.getAttribute("face")) {
                      style["font-family"] = node.getAttribute("face");
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    styleAttribute.forEach(function(attr) {
      if (attr.name === "font-weight") {
        var value = parseInt(attr.value, 10);
        if (attr.value === "bold") {
          style.bold = true;
        } else {
          if (attr.value === "normal") {
            style.bold = false;
          } else {
            if (!isNaN(value)) {
              style.bold = value >= 500;
            }
          }
        }
      } else {
        if (attr.name === "font-style") {
          if (["italic", "oblique"].indexOf(attr.value) > -1) {
            style.italic = true;
          }
        } else {
          if (attr.name === "text-decoration") {
            if (attr.value.indexOf("line-through") > -1) {
              style.strikethrough = true;
            }
            if (attr.value.indexOf("underline") > -1) {
              style.underline = true;
            }
          } else {
            if (attr.name === "vertical-align" && ["top", "bottom", "middle"].indexOf(attr.value) === -1) {
              if (["sub"].indexOf(attr.value) > -1) {
                style.subscript = true;
              }
              if (["super"].indexOf(attr.value) > -1) {
                style.superscript = true;
              }
            } else {
              var supportedStyle = ".*";
              var regex = new RegExp("^(" + supportedStyle + ")$");
              if (regex.test(attr.name)) {
                style[attr.name] = attr.value;
              }
            }
          }
        }
      }
    });
    return style;
  };
  styles.getCascadedStyle = function(node) {
    var current = node;
    var nodes = [];
    var style = {};
    while (!dom.isBlockNode(current)) {
      nodes.push(current);
      current = current.parentNode;
    }
    goog.array.forEachRight(nodes, function(n) {
      goog.object.extend(style, styles.getNodeStyle(n));
    });
    return style;
  };
  styles.convertAttributesToStyle = function(node) {
    if (dom.isTextNode(node)) {
      return;
    }
    if (node.attributes.face) {
      var face = node.attributes.face.value;
      var fontFamily = goog.style.getStyle(node, "font-family");
      node.removeAttribute("face");
      if (!fontFamily) {
        goog.style.setStyle(node, "font-family", face);
      }
    }
    if (node.attributes.color) {
      var color = node.attributes.color.value;
      var fontColor = goog.style.getStyle(node, "color");
      node.removeAttribute("color");
      if (!fontColor) {
        goog.style.setStyle(node, "color", color);
      }
    }
    if (node.attributes.size) {
      var size = node.attributes.size.value;
      var fontSize = goog.style.getStyle(node, "font-size");
      node.removeAttribute("size");
      if (!fontSize) {
        goog.style.setStyle(node, "font-size", fontSizeMap[size]);
      }
    }
  };
  styles.getStyleString = function(nodeStyles) {
    var finalStyle = "";
    var textDecoration = "";
    Object.keys(nodeStyles).forEach(function(key) {
      var style = nodeStyles[key];
      if (style === "inherit" || style === "initial") {
        return;
      }
      if (key === "bold") {
        if (style) {
          finalStyle += "font-weight: bold; ";
        }
      } else {
        if (key === "background-color") {
          if (style !== "transparent") {
            finalStyle += "background-color: " + style + "; ";
          }
        } else {
          if (key === "italic") {
            finalStyle += "font-style: italic; ";
          } else {
            if (key === "underline") {
              textDecoration += "underline ";
            } else {
              if (key === "strikethrough") {
                textDecoration += "line-through ";
              } else {
                if (key === "superscript") {
                  finalStyle += "vertical-align: super; font-size: smaller; ";
                } else {
                  if (key === "subscript") {
                    finalStyle += "vertical-align: sub; font-size: smaller; ";
                  } else {
                    if (style) {
                      finalStyle += key + ": " + style + "; ";
                    }
                  }
                }
              }
            }
          }
        }
      }
    });
    if (textDecoration) {
      finalStyle += "text-decoration: " + textDecoration.trim() + "; ";
    }
    return finalStyle.trim();
  };
  styles.getNoteWidth = function(element) {
    if (!dom.isEnnote(element)) {
      element = document.querySelector(uno.defs.containers.EDITOR_BODY_SELECTOR);
    }
    if (!element) {
      return null;
    }
    var computedStyle = window.getComputedStyle(element);
    var padding = parseInt(computedStyle.paddingLeft, 10) * 2;
    return element.getBoundingClientRect().width - (isNaN(padding) ? 0 : padding);
  };
  styles.getDevicePixelRatio = function() {
    if ("devicePixelRatio" in window) {
      return window.devicePixelRatio;
    } else {
      if (window.matchMedia) {
        var testDensity = function(density) {
          var mediaQuery = ["-webkit-min", "min--moz", "min"].map(function(prefix) {
            return "(" + prefix + "device-pixel-ratio: " + density + ")";
          }).concat("(min-resolution: " + density + "dppx)").join(",");
          return !!window.matchMedia(mediaQuery).matches;
        };
        if (testDensity("2")) {
          return 2;
        } else {
          if (testDensity("1.5")) {
            return 1.5;
          } else {
            if (testDensity("1")) {
              return 1;
            } else {
              if (testDensity("0.75")) {
                return 0.75;
              }
            }
          }
        }
      }
    }
    return 1;
  };
  styles.hasInlineStyle = function(node) {
    var styleText = node.getAttribute("style");
    if (styleText == null || styleText === "") {
      return false;
    }
    var style = node.style;
    var inlineStyles = styles.inlineStyles;
    var result = Object.keys(style).some(function(key) {
      return isNaN(key) && style.hasOwnProperty(key) && style[key] !== "" && inlineStyles.indexOf(key) !== -1;
    });
    return result;
  };
  styles.hasLayoutStyle = function(node) {
    var styleText = node.getAttribute("style");
    if (styleText == null || styleText === "") {
      return false;
    }
    var style = node.style;
    var inlineStyles = styles.inlineStyles;
    var result = Object.keys(style).some(function(key) {
      return isNaN(key) && style.hasOwnProperty(key) && style[key] !== "" && (inlineStyles.indexOf(key) === -1 || key === "backgroundColor" || key === "fontSize");
    });
    return result;
  };
  styles.inlineStyles = ["alignmentBaseline", "backgroundColor", "baselineShift", "bottom", "breakAfter", "breakBefore", "breakInside", "color", "dominantBaseline", "fill", "fillOpacity", "fillRule", "fontFamily", "fontFeatureSettings", "fontKerning", "fontSize", "fontStretch", "fontStyle", "fontVariant", "fontVariantCaps", "fontVariantLigatures", "fontVariantNumeric", "fontWeight", "lineHeight", "textDecoration", "textDecorationColor", "textDecorationLine", "textDecorationSkip", "textDecorationStyle"];
})();
goog.provide("uno.util.table");
goog.require("goog.array");
goog.require("goog.color");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("goog.object");
goog.require("goog.style");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.observer");
goog.require("uno.util.range");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.table");
  var util = uno.util;
  var defs = uno.defs.table;
  var measureTable = null;
  var activeTable = null;
  var activeCell = null;
  var queryCache = null;
  util.table.State = {SELECTED:1 << 0, WHOLE_SELECTED:1 << 1, DRAGGABLE:1 << 2, MERGED:1 << 3, MERGE_CANDIDATE:1 << 4};
  util.table.Axis = {HORIZONTAL:"x", VERTICAL:"y"};
  util.table.for = function(node) {
    return goog.dom.getAncestor(node, util.dom.isTable, true);
  };
  util.table.getParagraphs = function(table) {
    return util.table.cellsForNode(table);
  };
  util.table.cellsForRange = function(range) {
    var td = goog.dom.getAncestor(range.getContainer(), util.dom.isTd, true);
    if (td) {
      return [td];
    }
    var tds = [];
    goog.iter.forEach(goog.iter.filter(range, function(node, _, iter) {
      return iter.isStartTag() && uno.util.dom.isTd(node);
    }), function(node) {
      tds.push(node);
    });
    return tds;
  };
  util.table.cellsForNode = function(root) {
    if (!root) {
      return [];
    }
    var table = null;
    if (util.dom.isTable(root)) {
      table = root;
    } else {
      if (util.dom.isEntable(root)) {
        table = util.table.query_(root, "table");
      } else {
        table = root.querySelector("table");
      }
    }
    if (!table) {
      return [];
    }
    return [].concat.apply([], goog.array.map(table.rows, function(row) {
      return [].slice.call(row.children);
    }));
  };
  util.table.upCell = function(node) {
    var td = goog.dom.getAncestor(node, util.dom.isTd, true);
    if (!td) {
      return null;
    }
    var matrix = util.table.matrix(goog.dom.getAncestor(td, util.dom.isTable));
    var info = util.table.infoForCell(td, matrix);
    return info.startRowIndex === 0 ? null : matrix[info.startRowIndex - 1][info.startColIndex].info.node;
  };
  util.table.downCell = function(node) {
    var td = goog.dom.getAncestor(node, util.dom.isTd, true);
    if (!td) {
      return null;
    }
    var matrix = util.table.matrix(goog.dom.getAncestor(td, util.dom.isTable));
    var info = util.table.infoForCell(td, matrix);
    return info.endRowIndex < matrix.length - 1 ? matrix[info.endRowIndex + 1][info.startColIndex].info.node : null;
  };
  util.table.prevCell = function(node, navigateByDOM) {
    return prevNextCell(node, navigateByDOM, -1);
  };
  util.table.nextCell = function(node, navigateByDOM) {
    return prevNextCell(node, navigateByDOM, 1);
  };
  util.table.darkenBorderColor = function(backgroundColor) {
    var obj = goog.color.parse(backgroundColor);
    var rgb = obj.type === "rgb" ? backgroundColor : goog.color.hexToRgb(obj.hex);
    return goog.color.rgbToHex.apply(goog.color, goog.color.darken(rgb, 0.2));
  };
  util.table.create = function(options) {
    options = options || {};
    options.rows = options.rows || 2;
    options.columns = options.columns || 2;
    options.align = options.align || "left";
    var bgColor = goog.color.isValidColor(options.cellColor || "") ? goog.color.parse(options.cellColor).hex : null;
    var borderColor = options.borderColor !== defs.BORDER_COLOR && goog.color.isValidColor(options.borderColor || "") ? options.borderColor : null;
    if (bgColor && !borderColor) {
      borderColor = util.table.darkenBorderColor(bgColor);
    }
    var colgroup = document.createElement("colgroup");
    var tbody = document.createElement("tbody");
    var width = "width: " + defs.CELL_WIDTH + "px;";
    var style = [borderColor && "border-color: " + borderColor, bgColor && "background-color: " + bgColor].filter(Boolean).join("; ");
    var table = goog.dom.createDom("table", null, [colgroup, tbody]);
    table.compat = true;
    for (var rowIndex = 0; rowIndex < options.rows; rowIndex++) {
      var tr = document.createElement("tr");
      tbody.appendChild(tr);
      for (var colIndex = 0; colIndex < options.columns; colIndex++) {
        if (rowIndex === 0) {
          colgroup.appendChild(goog.dom.createDom("col", {style:width}));
        }
        tr.appendChild(util.table.createEmptyTd({style:style}));
      }
    }
    util.table.setAlignment(table, options.align);
    return util.table.attachAdornments(table);
  };
  util.table.delete = function(target) {
    var isEntable = util.dom.isEntable(target);
    if (!isEntable && !util.dom.isTable(target) || !target.parentNode) {
      return false;
    }
    if (isEntable && util.table.getActive() === target) {
      util.table.setActive(null);
    }
    var tableIndex = util.dom.index(target);
    var tableParent = target.parentElement;
    goog.dom.removeNode(target);
    goog.dom.Range.createCaret(tableParent, tableIndex).select();
    return true;
  };
  util.table.getAlignment = function(table) {
    var marginLeft = table.style.marginLeft;
    var marginRight = table.style.marginRight;
    if (marginLeft === "auto" && marginRight === "auto") {
      return "center";
    } else {
      if (marginLeft === "auto") {
        return "right";
      }
    }
    return "left";
  };
  util.table.setAlignment = function(table, align) {
    table.style.marginLeft = align === "left" ? "" : "auto";
    table.style.marginRight = align === "center" ? "auto" : "";
  };
  util.table.createEmptyTd = function(attrs) {
    var td = goog.dom.createDom("td");
    attrs = attrs || {};
    if (attrs.style) {
      td.setAttribute("style", attrs.style);
    }
    if (attrs.class) {
      td.setAttribute("class", attrs.class);
    }
    if (attrs.colSpan > 1) {
      util.table.setColSpan(td, attrs.colSpan);
    }
    if (attrs.rowSpan > 1) {
      util.table.setRowSpan(td, attrs.rowSpan);
    }
    td.innerHTML = defs.CELL_HTML;
    return td;
  };
  util.table.insertTd = function(node, rowIndex, colIndex, table, optMatrix) {
    var matrix = optMatrix || util.table.matrix(table);
    var refNode = null;
    var info;
    while (info = (matrix[rowIndex][colIndex] || {}).info) {
      if (info.startRowIndex !== rowIndex || info.startColIndex !== colIndex) {
        colIndex = info.endColIndex + 1;
      } else {
        refNode = info.node;
        break;
      }
    }
    table.rows[rowIndex].insertBefore(node, refNode);
  };
  util.table.insertColumns = function(target, index, count) {
    var colgroup = util.table.query_(target, "colgroup");
    if (index < 0 || index > colgroup.children.length) {
      return false;
    }
    var isEntable = util.dom.isEntable(target);
    var table = isEntable ? util.table.query_(target, "table") : target;
    var matrix = util.table.matrix(table);
    var colIndex = Math.max(index - 1, 0);
    var refCol = colgroup.children[index] || null;
    var col = colgroup.children[colIndex];
    count = count || 1;
    for (var i = count; i > 0; i--) {
      colgroup.insertBefore(col.cloneNode(), refCol);
    }
    matrix.forEach(function(row, rowIndex) {
      var info = row[colIndex].info;
      var cell = info.node;
      if (info.startRowIndex !== rowIndex) {
        return;
      }
      if (index !== colIndex && info.startColIndex < index && info.endColIndex >= index) {
        util.table.setColSpan(cell, cell.colSpan + count);
        return;
      }
      for (var j = count; j > 0; j--) {
        var newTd = util.table.createEmptyTd({style:cell.getAttribute("style"), rowSpan:cell.rowSpan});
        util.table.insertTd(newTd, rowIndex, index, table, matrix);
      }
    });
    if (isEntable) {
      util.table.normalizeCellBorders(table);
      util.table.layout(target);
    }
    return true;
  };
  util.table.insertRows = function(target, index, count) {
    var isEntable = util.dom.isEntable(target);
    var table = isEntable ? util.table.query_(target, "table") : target;
    if (index < 0 || index > table.rows.length) {
      return false;
    }
    var matrix = util.table.matrix(table);
    var rowIndex = Math.max(index - 1, 0);
    var tbody = table.rows[0].parentElement;
    var refRow = table.rows[index] || null;
    count = count || 1;
    for (var c = count; c > 0; c--) {
      var newRow = goog.dom.createDom("tr");
      tbody.insertBefore(newRow, refRow);
      matrix[rowIndex].forEach(function(obj, colIndex) {
        var info = obj.info;
        var cell = info.node;
        if (info.startColIndex !== colIndex) {
          return;
        }
        if (index !== rowIndex && info.startRowIndex < index && info.endRowIndex >= index) {
          util.table.setRowSpan(cell, cell.rowSpan + count);
          return;
        }
        var newTd = util.table.createEmptyTd({style:cell.getAttribute("style"), colSpan:cell.colSpan});
        newTd.style.height = "";
        newRow.appendChild(newTd);
      });
    }
    if (isEntable) {
      util.table.normalizeCellBorders(table);
      util.table.updateAdornments(target, util.table.Axis.HORIZONTAL);
      util.table.layoutMenuButton();
    }
    return true;
  };
  util.table.deleteColumns = function(target, indexes) {
    var isEntable = util.dom.isEntable(target);
    var table = isEntable ? util.table.query_(target, "table") : target;
    if (!table || !indexes || indexes.length === 0) {
      return false;
    }
    var matrix = util.table.matrix(table);
    indexes = processDeleteIndexes(indexes, 0, matrix[0].length - 1);
    if (!indexes) {
      return false;
    }
    if (indexes.length === matrix[0].length) {
      return util.table.delete(target);
    }
    var cols = util.table.query_(target, "colgroup").children;
    indexes.forEach(function(colIndex) {
      matrix.forEach(function(row, rowIndex) {
        var info = row[colIndex].info;
        var td = info.node;
        if (info.startRowIndex === rowIndex) {
          if (info.startColIndex === colIndex) {
            if (td.colSpan > 1) {
              util.table.setColSpan(td, td.colSpan - 1);
              util.table.insertTd(td, rowIndex, colIndex + 1, table, matrix);
            } else {
              td.remove();
            }
          } else {
            util.table.setColSpan(td, td.colSpan - 1);
          }
        }
        row.splice(colIndex, 1);
      });
      cols[colIndex].remove();
    });
    if (isEntable) {
      util.table.normalizeCellBorders(table);
      util.table.layout(target);
    }
    return true;
  };
  util.table.deleteRows = function(target, indexes) {
    var isEntable = util.dom.isEntable(target);
    var table = isEntable ? util.table.query_(target, "table") : target;
    if (!table || !indexes || indexes.length === 0) {
      return false;
    }
    var matrix = util.table.matrix(table);
    indexes = processDeleteIndexes(indexes, 0, matrix.length - 1);
    if (!indexes) {
      return false;
    }
    if (indexes.length === matrix.length) {
      return util.table.delete(target);
    }
    indexes.forEach(function(rowIndex) {
      matrix[rowIndex].forEach(function(obj, colIndex) {
        var info = obj.info;
        var td = info.node;
        if (info.startColIndex === colIndex) {
          if (info.startRowIndex === rowIndex) {
            if (td.rowSpan > 1) {
              util.table.setRowSpan(td, td.rowSpan - 1);
              util.table.insertTd(td, rowIndex + 1, colIndex, table, matrix);
            } else {
              td.remove();
            }
          } else {
            util.table.setRowSpan(td, td.rowSpan - 1);
          }
        }
      });
      table.rows[rowIndex].remove();
      matrix.splice(rowIndex, 1);
    });
    if (isEntable) {
      util.table.normalizeCellBorders(table);
      util.table.updateAdornments(target, util.table.Axis.HORIZONTAL);
      util.table.layoutMenuButton();
    }
    return true;
  };
  util.table.mergeable = function(nodes, optMatrix) {
    if (nodes.length <= 1) {
      return false;
    }
    var matrix = optMatrix || util.table.matrix(goog.dom.getAncestor(nodes[0], util.dom.isTable));
    var infos = util.table.infosForMerge(nodes, matrix);
    return !!infos;
  };
  util.table.unmergeable = function(nodes) {
    for (var i = 0, l = nodes.length; i < l; i++) {
      if (nodes[i].rowSpan > 1 || nodes[i].colSpan > 1) {
        return true;
      }
    }
    return false;
  };
  util.table.mergeCells = function(nodes, optMatrix) {
    if (nodes.length <= 1) {
      return null;
    }
    var table = goog.dom.getAncestor(nodes[0], util.dom.isTable);
    var matrix = optMatrix || util.table.matrix(table);
    var infos = util.table.infosForMerge(nodes, matrix);
    if (!infos) {
      return null;
    }
    var firstInfo = infos[0];
    var targetCell = firstInfo.node;
    var empty = util.dom.isEmpty(targetCell);
    var colSpan = 1;
    var rowSpan = 1;
    infos.forEach(function(info) {
      var cell = info.node;
      if (!cell.parentNode || cell === targetCell) {
        return;
      }
      colSpan = Math.max(info.endColIndex - firstInfo.startColIndex + 1, colSpan);
      rowSpan = Math.max(info.endRowIndex - firstInfo.startRowIndex + 1, rowSpan);
      goog.dom.removeNode(cell);
      if (util.dom.isEmpty(cell)) {
        return;
      }
      if (empty) {
        empty = false;
        targetCell.innerHTML = cell.innerHTML;
      } else {
        var lastTargetChild = targetCell.lastChild;
        var lastMovedChild = null;
        goog.array.forEachRight(cell.childNodes, function(child) {
          lastTargetChild.parentNode.insertBefore(child, lastTargetChild.nextSibling);
          lastMovedChild = child;
        });
        if (util.dom.isInlineNode(lastTargetChild) && util.dom.isInlineNode(lastMovedChild)) {
          lastTargetChild.parentNode.insertBefore(document.createTextNode(" "), lastTargetChild.nextSibling);
        }
      }
    });
    util.table.setColSpan(targetCell, colSpan);
    util.table.setRowSpan(targetCell, rowSpan);
    var enTable = goog.dom.getAncestor(table, util.dom.isEntable);
    if (enTable) {
      util.table.normalizeCellBorders(table);
      util.table.layout(enTable);
    }
    return targetCell;
  };
  util.table.splitCell = function(node, optMatrix) {
    if (node.rowSpan <= 1 && node.colSpan <= 1) {
      return [node];
    }
    var table = goog.dom.getAncestor(node, util.dom.isTable);
    var matrix = optMatrix || util.table.matrix(table);
    var info = util.table.infoForCell(node, matrix);
    var nodes = [node];
    node.style.height = "";
    var style = node.getAttribute("style");
    for (var i = 0; i < node.rowSpan; i++) {
      for (var j = 0; j < node.colSpan; j++) {
        if (i > 0 || j > 0) {
          var newTd = util.table.createEmptyTd({style:style});
          nodes.push(newTd);
          util.table.insertTd(newTd, info.startRowIndex + i, info.startColIndex + j, table, matrix);
        }
      }
    }
    util.table.setColSpan(node, 1);
    util.table.setRowSpan(node, 1);
    var enTable = goog.dom.getAncestor(table, util.dom.isEntable);
    if (enTable) {
      util.table.normalizeCellBorders(table);
    }
    return nodes;
  };
  util.table.splitCells = function(tds) {
    if (tds.length === 0) {
      return [];
    }
    var nodes = [];
    goog.array.forEach(tds, function(td) {
      nodes = nodes.concat(util.table.splitCell(td));
    });
    return nodes;
  };
  util.table.setColSpan = function(td, value) {
    if (td.colSpan !== value) {
      if (value > 1) {
        td.colSpan = value;
      } else {
        td.removeAttribute("colspan");
      }
    }
  };
  util.table.setRowSpan = function(td, value) {
    if (td.rowSpan !== value) {
      if (value > 1) {
        td.rowSpan = value;
        td.style.height = (value * 2 - 2) * defs.CELL_PADDING + value * defs.CELL_LINE_HEIGHT + "px";
      } else {
        td.removeAttribute("rowspan");
        td.style.height = "";
      }
    }
  };
  util.table.cellForStructureChange = function(range) {
    if (!range) {
      return null;
    }
    var cell = util.table.getActiveCell();
    if (cell) {
      return cell;
    }
    var table = null;
    var nested = false;
    var node = range.getStartNode();
    while (node && node.parentNode) {
      if (util.dom.isTable(node)) {
        if (table) {
          nested = true;
          break;
        }
        table = node;
      } else {
        if (util.dom.isTd(node)) {
          cell = node;
        }
      }
      node = node.parentNode;
    }
    if (nested || !cell || goog.dom.getAncestor(range.getEndNode(), util.dom.isTable) !== table) {
      return null;
    }
    return cell;
  };
  util.table.matrix = function(table, opt) {
    opt = opt || {selection:false};
    if (util.dom.isEntable(table)) {
      table = util.table.query_(table, "table");
    }
    if (!util.dom.isTable(table)) {
      return null;
    }
    var matrix = [];
    var rowCount = table.rows.length;
    var getWithDefault = function(arr, index, def) {
      var obj = arr[index];
      if (!obj) {
        obj = def;
        arr[index] = obj;
      }
      return obj;
    };
    goog.array.forEach(table.rows, function(tr, trIndex) {
      var row = getWithDefault(matrix, trIndex, []);
      var colIndex = 0;
      goog.array.forEach(tr.children, function(td, tdIndex) {
        var colSpan = td.colSpan;
        var rowSpan = Math.min(rowCount - trIndex, td.rowSpan);
        while (row[colIndex]) {
          colIndex += 1;
        }
        var info = {startRowIndex:trIndex, endRowIndex:trIndex + rowSpan - 1, startColIndex:colIndex, endColIndex:colIndex + colSpan - 1, nodeRowIndex:trIndex, nodeColIndex:tdIndex, node:td, state:0};
        if (opt.selection && td.classList.contains("selected")) {
          info.state |= util.table.State.SELECTED;
        }
        if (rowSpan > 1 || colSpan > 1) {
          info.state |= util.table.State.MERGED;
        }
        var obj = getWithDefault(row, tdIndex, {});
        obj.origin = info;
        for (var c = colSpan; c > 0; c--) {
          obj = getWithDefault(row, colIndex, {});
          obj.info = info;
          for (var r = 1; r < rowSpan; r++) {
            var nextRow = getWithDefault(matrix, trIndex + r, []);
            obj = getWithDefault(nextRow, colIndex, {});
            obj.info = info;
          }
          colIndex += 1;
        }
      });
    });
    return matrix;
  };
  util.table.rowIndex = function(td, next, optMatrix) {
    var info = util.table.infoForCell(td, optMatrix);
    return next ? info.endRowIndex + 1 : info.startRowIndex;
  };
  util.table.colIndex = function(td, next, optMatrix) {
    var info = util.table.infoForCell(td, optMatrix);
    return next ? info.endColIndex + 1 : info.startColIndex;
  };
  util.table.infoForCell = function(td, optMatrix) {
    if (!util.dom.isTd(td)) {
      return null;
    }
    var matrix = optMatrix || util.table.matrix(goog.dom.getAncestor(td, util.dom.isTable));
    var info = matrix[util.dom.index(td.parentNode)][util.dom.index(td)].origin;
    if (!info || info.node !== td) {
      throw new Error("Failed to get info object for a td", td, matrix);
    }
    return info;
  };
  util.table.infosForMerge = function(tds, matrix) {
    if (tds.length <= 1) {
      return null;
    }
    var startRowIndex = Infinity;
    var startColIndex = Infinity;
    var endRowIndex = 0;
    var endColIndex = 0;
    var infos = [];
    var info;
    tds.forEach(function(cell) {
      info = util.table.infoForCell(cell, matrix);
      startRowIndex = Math.min(info.startRowIndex, startRowIndex);
      startColIndex = Math.min(info.startColIndex, startColIndex);
      endRowIndex = Math.max(info.endRowIndex, endRowIndex);
      endColIndex = Math.max(info.endColIndex, endColIndex);
      info.state |= util.table.State.MERGE_CANDIDATE;
    });
    for (var rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
      for (var colIndex = startColIndex; colIndex <= endColIndex; colIndex++) {
        info = matrix[rowIndex][colIndex].info;
        if (!(info.state & util.table.State.MERGE_CANDIDATE)) {
          return null;
        }
        if (info.startRowIndex === rowIndex && info.startColIndex === colIndex) {
          infos.push(info);
        }
      }
    }
    return infos;
  };
  util.table.expandIntoRectIndexes = function(matrix, startRowIndex, endRowIndex, startColIndex, endColIndex) {
    loop: while (true) {
      for (var rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
        for (var colIndex = startColIndex; colIndex <= endColIndex; colIndex++) {
          var info = matrix[rowIndex][colIndex].info;
          if (info.startRowIndex < startRowIndex || info.startColIndex < startColIndex || info.endRowIndex > endRowIndex || info.endColIndex > endColIndex) {
            startRowIndex = Math.min(info.startRowIndex, startRowIndex);
            startColIndex = Math.min(info.startColIndex, startColIndex);
            endRowIndex = Math.max(info.endRowIndex, endRowIndex);
            endColIndex = Math.max(info.endColIndex, endColIndex);
            continue loop;
          }
        }
      }
      break;
    }
    return {startRowIndex:startRowIndex, endRowIndex:endRowIndex, startColIndex:startColIndex, endColIndex:endColIndex};
  };
  util.table.isProcessedRange = function(range, rangeState) {
    return range && rangeState && range.isCollapsed() === rangeState.isCollapsed && range.getStartNode() === rangeState.startNode && range.getEndNode() === rangeState.endNode;
  };
  util.table.processRange = function(range, noteEnTables, source) {
    var startNode = range.getStartNode();
    var endNode = range.getEndNode();
    var isCollapsed = range.isCollapsed();
    var isMulticlick = source === "multiclick";
    var isArrowSelection = source === "arrowkey";
    var startAncestor = goog.dom.getAncestor(startNode, util.dom.isEntable, true);
    var endAncestor = goog.dom.getAncestor(endNode, util.dom.isEntable, true);
    var enTable = startAncestor && startAncestor === endAncestor ? startAncestor : null;
    if (isArrowSelection) {
      enTable = goog.dom.getAncestor(range.getAnchorNode(), util.dom.isEntable, true);
    }
    var cell = enTable ? goog.dom.getAncestor(range.getAnchorNode(), util.dom.isTd, true) : null;
    if (!cell) {
      enTable = null;
    }
    if (!enTable && (startAncestor || endAncestor)) {
      var newStartNode = null;
      var newStartOffset = 0;
      var newEndNode = null;
      var newEndOffset = 0;
      if (startAncestor && startAncestor !== startNode) {
        newStartNode = startAncestor;
        newStartOffset = 0;
      } else {
        newStartNode = startNode;
        newStartOffset = range.getStartOffset();
      }
      if (endAncestor && endAncestor !== endNode) {
        newEndNode = endAncestor;
        newEndOffset = endAncestor.childNodes.length;
      } else {
        newEndNode = endNode;
        newEndOffset = range.getEndOffset();
      }
      if (newStartNode) {
        if (range.isReversed()) {
          goog.dom.Range.createFromNodes(newEndNode, newEndOffset, newStartNode, newStartOffset).select();
        } else {
          goog.dom.Range.createFromNodes(newStartNode, newStartOffset, newEndNode, newEndOffset).select();
        }
        range = goog.dom.Range.createFromWindow();
        startNode = range.getStartNode();
        endNode = range.getEndNode();
      }
    }
    var isSelection = false;
    var focusCell = undefined;
    if (enTable && cell && !range.isCollapsed()) {
      var tmpFocusCell = goog.dom.getAncestor(range.getFocusNode(), util.dom.isTd, true);
      if (cell !== tmpFocusCell) {
        var nextCell = util.table.nextCell(cell);
        if (isMulticlick && nextCell === tmpFocusCell && range.getFocusOffset() === 0) {
          var node = range.getFocusNode();
          while (node && node !== tmpFocusCell) {
            node = node.previousSibling ? null : node.parentNode;
          }
          if (node) {
            tmpFocusCell = cell;
          }
        }
        focusCell = tmpFocusCell;
        isSelection = true;
      }
    }
    goog.array.forEach(noteEnTables, function(node) {
      var contained = range.containsNode(node, true);
      if (enTable || !contained) {
        node.classList.remove("selected");
      } else {
        if (contained) {
          node.classList.add("selected");
        }
      }
    });
    return {startNode:startNode, endNode:endNode, isCollapsed:isCollapsed, isSelection:isSelection, enTable:enTable, cell:cell, focusCell:focusCell};
  };
  util.table.createKeyState = function(enTable, cell, event) {
    return {scrollLeft:util.table.query_(enTable, ".container").scrollLeft, keyCode:event.keyCode, shiftKey:event.shiftKey, cell:cell, enTable:enTable};
  };
  util.table.navigateByKeyState = function(keyState) {
    if (keyState.shiftKey) {
      return false;
    }
    var KeyCodes = goog.events.KeyCodes;
    var atEnd = false;
    var isCell = true;
    var targetNode;
    var getTableSibling = function(enTable, fnName) {
      var node = enTable[fnName];
      while (node && node.childNodes.length === 0) {
        node = node[fnName];
      }
      return enTable === node ? null : node;
    };
    if (keyState.keyCode === KeyCodes.UP) {
      targetNode = util.table.upCell(keyState.cell);
      atEnd = true;
      if (!targetNode) {
        isCell = false;
        targetNode = getTableSibling(keyState.enTable, "previousSibling");
      }
    } else {
      if (keyState.keyCode === KeyCodes.DOWN) {
        targetNode = util.table.downCell(keyState.cell);
        if (!targetNode) {
          isCell = false;
          targetNode = getTableSibling(keyState.enTable, "nextSibling");
        }
      } else {
        if (keyState.keyCode === KeyCodes.LEFT) {
          targetNode = util.table.prevCell(keyState.cell);
          atEnd = true;
        } else {
          if (keyState.keyCode === KeyCodes.RIGHT) {
            targetNode = util.table.nextCell(keyState.cell);
          }
        }
      }
    }
    if (!targetNode) {
      return false;
    }
    goog.dom.Range.createCaret(targetNode, atEnd ? targetNode.childNodes.length : 0).select();
    if (isCell) {
      util.table.setActive(keyState.enTable, targetNode);
      util.table.query_(keyState.enTable, ".container").scrollLeft = keyState.scrollLeft;
      util.table.scrollCellIntoView(targetNode);
    } else {
      util.table.setActive();
    }
    return true;
  };
  util.table.navigatedFocusSelectionCell = function(keyState) {
    if (!keyState.shiftKey) {
      return null;
    }
    var KeyCodes = goog.events.KeyCodes;
    var matrix = util.table.matrix(keyState.enTable);
    var info = util.table.infoForCell(keyState.cell, matrix);
    if (keyState.scrollLeft !== undefined) {
      util.table.query_(keyState.enTable, ".container").scrollLeft = keyState.scrollLeft;
    }
    if (keyState.keyCode === KeyCodes.UP && info.startRowIndex > 0) {
      return matrix[info.startRowIndex - 1][info.startColIndex].info.node;
    } else {
      if (keyState.keyCode === KeyCodes.DOWN && info.endRowIndex < matrix.length - 1) {
        return matrix[info.endRowIndex + 1][info.startColIndex].info.node;
      } else {
        if (keyState.keyCode === KeyCodes.LEFT && info.startColIndex > 0) {
          return matrix[info.startRowIndex][info.startColIndex - 1].info.node;
        } else {
          if (keyState.keyCode === KeyCodes.RIGHT && info.endColIndex < matrix[0].length - 1) {
            return matrix[info.startRowIndex][info.endColIndex + 1].info.node;
          }
        }
      }
    }
    return null;
  };
  util.table.navigateInto = function(range, direction) {
  };
  util.table.getActive = function() {
    return activeTable;
  };
  util.table.getActiveCell = function() {
    return activeCell;
  };
  var fixMissingAdornments = function(enTable) {
    if (util.dom.getTagName(enTable) === "en-table" && !enTable.querySelector("en-adornments")) {
      var table = enTable.querySelector("table");
      if (table) {
        enTable.appendChild(goog.dom.createDom("en-adornments", {contentEditable:"false"}));
        enTable.setAttribute("data-lazy", 1);
        util.table.generateAdornments(enTable);
        util.table.updateWidth(enTable);
      }
    }
    return enTable;
  };
  util.table.setActive = function(enTable, cell) {
    enTable = fixMissingAdornments(enTable);
    if (!enTable && !activeTable || enTable && !util.dom.isEntable(enTable)) {
      return;
    }
    if (enTable !== activeTable) {
      if (activeTable) {
        activeTable.classList.remove("active");
        activeTable = null;
        util.observer.removeHandler(updateActiveTableAdornmentRows);
      }
      if (enTable) {
        activeTable = enTable;
        activeTable.classList.add("active");
        util.table.layout(enTable, true);
        util.observer.addHandler(updateActiveTableAdornmentRows);
      }
    }
    if (cell !== activeCell) {
      if (cell && (!activeTable || !goog.dom.getAncestor(cell, function(node) {
        return node === activeTable;
      }))) {
        throw new Error("Active cell is not part of active table:", activeTable);
      }
      activeCell = cell;
      util.table.layoutMenuButton();
    }
  };
  util.table.setLine = function(enTable, index, axis) {
    enTable = fixMissingAdornments(enTable);
    enTable.classList.remove("xline-visible");
    enTable.classList.remove("yline-visible");
    if (axis) {
      enTable.classList.add(axis + "line-visible");
      var selector = "." + axis + "line";
      var line = util.table.query_(enTable, selector);
      if (axis === util.table.Axis.HORIZONTAL) {
        var top = 0;
        if (index > 0) {
          var row = util.table.query_(enTable, "table").rows[index - 1];
          top = row.offsetTop + row.offsetHeight;
        }
        line.style.top = (top === 0 ? top - 5 : top - 7) + "px";
      } else {
        var left = 0;
        if (index > 0) {
          var cols = util.table.query_(enTable, "colgroup").children;
          left = goog.array.reduce(cols, function(sum, col, i) {
            return i < index ? sum + parseInt(col.style.width, 10) : sum;
          }, 0);
        }
        line.style.left = (left === 0 ? left - 5 : left - 7) + "px";
      }
    }
  };
  util.table.handleToObject = function(node) {
    var index = util.dom.index(node);
    var axis = node.parentNode.parentNode.parentNode.classList.contains("columns") ? util.table.Axis.VERTICAL : util.table.Axis.HORIZONTAL;
    return {axis:axis, index:index};
  };
  util.table.insertionToObject = function(node) {
    var parent = node.parentNode;
    var index = parent.classList.contains("insertions") ? util.dom.index(node) + 1 : 0;
    var axis = parent.classList.contains("columns") || parent.parentNode.parentNode.classList.contains("columns") ? util.table.Axis.VERTICAL : util.table.Axis.HORIZONTAL;
    return {axis:axis, index:index};
  };
  util.table.scrollCellIntoView = function(targetCell) {
    if (!util.dom.isTd(targetCell)) {
      return;
    }
    var enTable = goog.dom.getAncestor(targetCell, util.dom.isEntable);
    var container = util.table.query_(enTable, ".container");
    var offset = 16;
    var offsetLeft = targetCell.offsetLeft;
    var offsetWidth = targetCell.offsetWidth;
    if (container.scrollLeft > offsetLeft) {
      container.scrollLeft -= container.scrollLeft - offsetLeft + offset;
      util.table.translateX(enTable);
    } else {
      if (container.scrollLeft + container.clientWidth < offsetLeft + offsetWidth) {
        container.scrollLeft += offsetLeft + offsetWidth - container.scrollLeft - container.clientWidth + offset;
        util.table.translateX(enTable);
      }
    }
  };
  util.table.translateX = function(enTable) {
    if (!util.dom.isEntable(enTable) || enTable.getAttribute("data-lazy")) {
      return;
    }
    var container = util.table.query_(enTable, ".container");
    var transAttr = container.style.transform === undefined ? "webkitTransform" : "transform";
    var left = container.scrollLeft;
    var scrollWidth = container.scrollWidth;
    var offsetWidth = container.offsetWidth;
    util.table.query_(enTable, ".columns .handles").style[transAttr] = "translateX(" + -left + "px)";
    util.table.query_(enTable, ".columns .insertions").style[transAttr] = "translateX(" + -left + "px)";
    util.table.query_(enTable, ".content").style[transAttr] = "translateX(" + -left + "px)";
    util.table.query_(enTable, ".lscroll").style.opacity = Math.max(Math.min(1, left / 10), 0);
    util.table.query_(enTable, ".rscroll").style.opacity = Math.max(Math.min(1, (scrollWidth - offsetWidth - left) / 10), 0);
    var thumb = util.table.query_(enTable, ".scrollbar-thumb");
    var scale = offsetWidth / scrollWidth;
    if (scale >= 1) {
      thumb.parentNode.style.display = "";
    } else {
      thumb.parentNode.style.display = "block";
      thumb.style.width = offsetWidth * scale + "px";
      thumb.style[transAttr] = "translateX(" + left * scale + "px)";
    }
  };
  util.table.layout = function(enTable, generateMissingAdornemnts) {
    var width = util.table.updateWidth(enTable);
    if (generateMissingAdornemnts || enTable.getAttribute("data-lazy") && enTable.clientWidth < width) {
      util.table.generateAdornments(enTable);
      util.table.updateWidth(enTable);
    }
    util.table.updateAdornments(enTable);
    util.table.translateX(enTable);
    util.table.layoutMenuButton();
  };
  util.table.layoutMenuButton = function() {
    var button = document.querySelector(".en-cell-btn");
    if (!activeCell || !activeTable) {
      if (button) {
        button.remove();
      }
      return;
    }
    if (!button) {
      button = goog.dom.createDom("div", {class:"en-cell-btn"});
    }
    button.style.top = activeCell.offsetTop + 5 + "px";
    button.style.left = activeCell.offsetLeft + activeCell.offsetWidth - 23 + "px";
    activeTable.querySelector(".content").appendChild(button);
  };
  util.table.equalizeColumns = function(enTable, indexes) {
    if (indexes.length < 2) {
      return;
    }
    var cols = util.table.query_(enTable, "colgroup").children;
    var widths = util.table.getColumnsMinWidth(enTable);
    var totalWidth = 0;
    var columns = [];
    widths.forEach(function(width, index) {
      if (indexes.indexOf(index) > -1) {
        totalWidth += parseInt(cols[index].style.width, 10);
        columns.push({index:index, minWidth:width});
      }
    });
    var sumWidth = 0;
    var avg = totalWidth / indexes.length;
    columns.sort(function(a, b) {
      return b.minWidth - a.minWidth;
    }).forEach(function(obj, n) {
      var width = obj.minWidth;
      if (width > avg) {
        sumWidth += width;
        avg = (totalWidth - sumWidth) / (indexes.length - n - 1);
      } else {
        width = avg;
      }
      cols[obj.index].style.width = Math.round(width) + "px";
    });
    util.table.layout(enTable);
  };
  util.table.fitNote = function(enTable) {
    var tableWidth = enTable ? parseInt(enTable.style.width, 10) : null;
    if (isNaN(tableWidth) || !tableWidth) {
      return false;
    }
    var cols = util.table.query_(enTable, "colgroup").children;
    var noteWidth = util.styles.getNoteWidth();
    var scale = noteWidth / tableWidth;
    var remainder = 0;
    var objs = util.table.getColumnsMinWidth(enTable).map(function(width, index) {
      return {index:index, minWidth:width, width:parseInt(cols[index].style.width, 10)};
    });
    objs.sort(function(a, b) {
      return b.minWidth - a.minWidth;
    }).forEach(function(obj, n) {
      var width = obj.width * scale - remainder;
      if (width < obj.minWidth) {
        remainder += (obj.minWidth - width) / (cols.length - n - 1);
        width = obj.minWidth;
      }
      cols[obj.index].style.width = Math.floor(width) + "px";
    });
    util.table.layout(enTable);
    return true;
  };
  util.table.fitColumnContent = function(enTable, colIndex) {
    var width = util.table.getColumnContentWidth(enTable, colIndex);
    if (width === null) {
      return false;
    }
    util.table.setColumnWidth(enTable, colIndex, width);
    return true;
  };
  util.table.fitColumnIfNeeded = function(enTable, index) {
    var colWidth = util.table.getColumnsMinWidth(enTable, index);
    var colgroup = util.table.query_(enTable, "colgroup");
    var currentWidth = parseInt(colgroup.children[index].style.width, 10) || 0;
    if (colWidth[index] && colWidth[index] > currentWidth) {
      util.table.setColumnWidth(enTable, index, colWidth[index]);
    }
  };
  util.table.getColumnsMinWidth = function(enTable, colIndex) {
    var table = util.table.query_(enTable, "table");
    var matrix = util.table.matrix(table);
    var left = null;
    var selector = ["ul", "ol", "object", ".en-media-file"].join(",");
    var widths = [];
    for (var c = 0, l = matrix[0].length; c < l; c++) {
      widths[c] = colIndex === undefined || colIndex === c ? defs.CELL_MIN_WIDTH : null;
    }
    goog.array.forEach(table.querySelectorAll(selector), function(node) {
      var cell = goog.dom.getAncestor(node, util.dom.isTd);
      var info = util.table.infoForCell(cell, matrix);
      if (colIndex !== undefined && info.startColIndex !== colIndex) {
        return;
      }
      if (!left) {
        left = cell.getBoundingClientRect().left;
      }
      var width = widths[info.startColIndex];
      if (node.classList.contains("en-media-file")) {
        width = Math.max(node.offsetWidth, width);
      } else {
        if (node.tagName === "OBJECT") {
          width = Math.max(node.getBoundingClientRect().left - left + 12, width);
        } else {
          width = Math.max(node.getBoundingClientRect().left - left + 76, width);
        }
      }
      widths[info.startColIndex] = Math.ceil(width);
    });
    return widths;
  };
  util.table.getColumnContentWidth = function(enTable, colIndex) {
    if (!measureTable) {
      measureTable = goog.dom.createDom("table", {class:"en-measure-table"});
      measureTable.innerHTML = "<tbody><tr><td></td></tr></tbody>";
    }
    var table = util.table.query_(enTable, "table");
    var matrix = util.table.matrix(table);
    var width = defs.CELL_MIN_WIDTH;
    var empty = true;
    var measureCell = measureTable.rows[0].firstChild;
    enTable.parentNode.appendChild(measureTable);
    matrix.forEach(function(row, rowIndex) {
      var info = row[colIndex].info;
      var cell = info.node;
      if (info.startColIndex < colIndex || info.startRowIndex < rowIndex) {
        return;
      }
      if (!util.dom.isEmpty(cell)) {
        measureCell.innerHTML = cell.innerHTML;
        measureCell.setAttribute("style", cell.getAttribute("style"));
        width = Math.max(measureCell.offsetWidth, width);
        empty = false;
      }
    });
    measureTable.remove();
    return empty ? null : Math.min(width, util.styles.getNoteWidth());
  };
  util.table.setColumnWidth = function(enTable, colIndex, width) {
    var colgroup = util.table.query_(enTable, "colgroup");
    colgroup.children[colIndex].style.width = Math.max(width, defs.CELL_MIN_WIDTH) + "px";
    util.table.layout(enTable);
    util.table.setLine(enTable);
  };
  util.table.updateWidth = function(enTable, width) {
    if (!util.dom.isEntable(enTable)) {
      return;
    }
    var table = util.table.query_(enTable, "table");
    if (!table) {
      return;
    }
    if (!width) {
      var colgroup = util.table.query_(enTable, "colgroup");
      if (!colgroup) {
        return;
      }
      width = 0;
      goog.array.forEach(colgroup.children, function(col) {
        width += parseInt(col.style.width, 10);
      });
    }
    var widthStr = width + "px";
    enTable.style.width = widthStr;
    table.style.width = widthStr;
    if (!enTable.getAttribute("data-lazy")) {
      util.table.query_(enTable, ".columns .handles").style.width = widthStr;
      util.table.query_(enTable, ".columns .insertions").style.width = widthStr;
      util.table.query_(enTable, ".content").style.width = widthStr;
    }
    return width;
  };
  util.table.updateAdornments = function(enTable, axis) {
    if (!util.dom.isEntable(enTable) || enTable.getAttribute("data-lazy")) {
      return;
    }
    var table = util.table.query_(enTable, "table");
    if (axis !== util.table.Axis.VERTICAL) {
      var rowHandles = util.table.query_(enTable, ".rows .handles");
      var rowInsertions = util.table.query_(enTable, ".rows .insertions");
      var rowCount = table.rows.length;
      goog.array.forEach(table.rows, function(tr, index) {
        var height = tr.getBoundingClientRect().height;
        var handle = rowHandles.children[index];
        if (!handle) {
          handle = goog.dom.createDom("div", {class:"handle"});
          rowHandles.appendChild(handle);
        }
        handle.style.height = height + "px";
        var insertion = rowInsertions.children[index];
        if (!insertion) {
          insertion = goog.dom.createDom("div", {class:"insertion"}, goog.dom.createDom("div", {class:"insertion-shape"}));
          rowInsertions.appendChild(insertion);
        }
        insertion.style.marginTop = height - 18 + "px";
      });
      if (rowHandles.children.length - rowCount > 0) {
        goog.array.forEachRight([].slice.call(rowHandles.children, rowCount), goog.dom.removeNode);
        goog.array.forEachRight([].slice.call(rowInsertions.children, rowCount), goog.dom.removeNode);
      }
    }
    if (axis !== util.table.Axis.HORIZONTAL) {
      var colgroup = util.table.query_(enTable, "colgroup");
      var colHandles = util.table.query_(enTable, ".columns .handles");
      var colInsertions = util.table.query_(enTable, ".columns .insertions");
      var colCount = colgroup.children.length;
      goog.array.forEach(colgroup.children, function(col, index) {
        var width = parseInt(col.style.width, 10);
        var handle = colHandles.children[index];
        if (!handle) {
          handle = goog.dom.createDom("div", {class:"handle"});
          colHandles.appendChild(handle);
        }
        handle.style.width = width + "px";
        var insertion = colInsertions.children[index];
        if (!insertion) {
          insertion = goog.dom.createDom("div", {class:"insertion"}, goog.dom.createDom("div", {class:"insertion-shape"}));
          colInsertions.appendChild(insertion);
        }
        insertion.style.marginLeft = width - 18 + "px";
      });
      if (colHandles.children.length - colCount > 0) {
        goog.array.forEachRight([].slice.call(colHandles.children, colCount), goog.dom.removeNode);
        goog.array.forEachRight([].slice.call(colInsertions.children, colCount), goog.dom.removeNode);
      }
    }
  };
  util.table.attachAdornments = function(table) {
    if (!util.table.isCompatible(table) || goog.dom.getAncestor(table, util.dom.isEntable)) {
      return table;
    }
    var placeholder = null;
    var inDOMTree = !!table.parentNode;
    if (inDOMTree) {
      placeholder = goog.dom.createDom("div");
      goog.dom.replaceNode(placeholder, table);
    }
    var enTable = goog.dom.createDom("en-table", {"data-lazy":1}, [goog.dom.createDom("div", {class:"container"}, table), goog.dom.createDom("en-adornments", {contentEditable:"false"})]);
    enTable.style.marginLeft = table.style.marginLeft;
    enTable.style.marginRight = table.style.marginRight;
    table.style.marginLeft = "";
    table.style.marginRight = "";
    util.table.updateWidth(enTable);
    if (inDOMTree) {
      goog.dom.replaceNode(enTable, placeholder);
    }
    return enTable;
  };
  util.table.generateAdornments = function(enTable) {
    if (!enTable.getAttribute("data-lazy")) {
      return;
    }
    enTable.removeAttribute("data-lazy");
    var adornments = util.table.query_(enTable, "en-adornments");
    if (adornments == null) {
      log.warning("Expected adornments not found for table", enTable);
      return;
    }
    adornments.appendChild(goog.dom.createDom("div", {class:"columns"}, [goog.dom.createDom("div", {class:"handles-container"}, goog.dom.createDom("div", {class:"handles"})), goog.dom.createDom("div", {class:"insertions-container"}, goog.dom.createDom("div", {class:"insertions"})), goog.dom.createDom("div", {class:"insertion"}, goog.dom.createDom("div", {class:"insertion-shape"}))]));
    adornments.appendChild(goog.dom.createDom("div", {class:"rows"}, [goog.dom.createDom("div", {class:"handles-container"}, goog.dom.createDom("div", {class:"handles"})), goog.dom.createDom("div", {class:"insertions-container"}, goog.dom.createDom("div", {class:"insertions"})), goog.dom.createDom("div", {class:"insertion"}, goog.dom.createDom("div", {class:"insertion-shape"}))]));
    adornments.appendChild(goog.dom.createDom("div", {class:"content-container"}, [goog.dom.createDom("div", {class:"content"}, [goog.dom.createDom("div", {class:"xline"}), goog.dom.createDom("div", {class:"yline"})]), goog.dom.createDom("div", {class:"lscroll"}), goog.dom.createDom("div", {class:"rscroll"})]));
    adornments.appendChild(goog.dom.createDom("div", {class:"scrollbar"}, goog.dom.createDom("div", {class:"scrollbar-thumb"})));
    adornments.appendChild(goog.dom.createDom("div", {class:"en-table-btn"}));
  };
  util.table.clearAdornments = function(enTable, legacyCompatible) {
    if (!util.dom.isEntable(enTable)) {
      return enTable;
    }
    var table = enTable.querySelectorAll("table")[0];
    if (!util.dom.isTable(table)) {
      return enTable;
    }
    table.style.marginLeft = enTable.style.marginLeft;
    table.style.marginRight = enTable.style.marginRight;
    var colgroup, tableWidth, widths;
    if (legacyCompatible) {
      colgroup = enTable.querySelectorAll("colgroup")[0];
      widths = goog.array.map(colgroup.children, function(col) {
        return parseInt(col.style.width, 10);
      });
      table.style.borderCollapse = "collapse";
      table.style.width = "";
      table.style.minWidth = "100%";
    }
    goog.dom.removeNode(table.querySelector("cursor-proxy"));
    goog.dom.replaceNode(table, enTable);
    var getWidthStr = function(from, length) {
      var width = 0;
      for (var i = from; i < from + length; i++) {
        width += widths[i];
      }
      return width + "px";
    };
    var matrix = util.table.matrix(table);
    matrix.forEach(function(row, rowIndex) {
      row.forEach(function(obj, colIndex) {
        var info = obj.info;
        var td = info.node;
        if (info.startRowIndex > rowIndex || info.startColIndex > colIndex) {
          return;
        }
        var borderWidth = td.style.borderWidth || "1px";
        var borderStyle = td.style.borderStyle || "solid";
        var borderColor = td.style.borderColor || defs.BORDER_COLOR;
        if (legacyCompatible) {
          td.style.width = getWidthStr(info.startColIndex, info.endColIndex - info.startColIndex + 1);
          if (!td.style.padding) {
            td.style.padding = defs.CELL_PADDING + "px";
          }
        }
        td.style.border = [borderWidth, borderStyle, borderColor].join(" ");
      });
    });
    return table;
  };
  util.table.migrateToEnTable = function(table) {
    if (goog.dom.getAncestor(table, util.dom.isEntable) || !util.table.isCompatible(table, true)) {
      return false;
    }
    util.table.normalizeColgroup(table, true, true);
    util.table.normalizeStyles(table);
    util.table.flatten(table);
    util.table.normalizeCellBorders(table);
    var enTable = util.table.attachAdornments(table);
    util.table.normalizeDOMPlacement(enTable);
    util.table.layout(enTable);
    return true;
  };
  util.table.flatten = function(table) {
    var childTables;
    var colgroup = util.table.query_(table, "colgroup");
    while ((childTables = goog.array.filter(table.querySelectorAll("table"), function(node) {
      return goog.dom.getAncestor(node, util.dom.isTable) === table;
    })).length > 0) {
      var expansions = [];
      childTables.forEach(function(childTable) {
        var info = processTableForExpansion(childTable, expansions);
        if (info.addRowCount) {
          util.table.insertRows(table, info.insertRowIndex, info.addRowCount);
        }
        if (info.addColCount) {
          var col = colgroup.children[info.endColIndex];
          var width = Math.ceil(parseInt(col.style.width, 10) / (info.addColCount + 1));
          col.style.width = Math.max(width, defs.CELL_MIN_WIDTH) + "px";
          util.table.insertColumns(table, info.insertColIndex, info.addColCount);
        }
        var rootMatrix = util.table.matrix(table);
        var rootInfo = null;
        var rowOffset = info.beforeHTML ? 1 : 0;
        if (info.afterHTML) {
          rootInfo = rootMatrix[info.endRowIndex + info.rowCount - 1][info.startColIndex].info;
          rootInfo.node.innerHTML = info.afterHTML;
        }
        info.matrix.forEach(function(row, rowIndex) {
          row.forEach(function(obj, colIndex) {
            rootInfo = rootMatrix[rowIndex + info.startRowIndex + rowOffset][colIndex + info.startColIndex].info;
            rootInfo.node.innerHTML = obj.info.node.innerHTML;
          });
        });
        var exp = {startRowIndex:info.startRowIndex, startColIndex:info.startColIndex, endRowIndex:info.startRowIndex + info.rowCount - 1, endColIndex:info.startColIndex + info.colCount - 1, rowCount:info.rowCount, colCount:info.colCount};
        expansions.push(exp);
        if (info.afterHTML) {
          rootInfo = rootMatrix[exp.endRowIndex][exp.startColIndex].info;
          rootInfo.node.innerHTML = info.afterHTML;
          mergeColumnTdsAfterFlattening(rootMatrix, exp.endRowIndex, exp.endRowIndex, exp.startColIndex, exp.endColIndex);
        }
        if (info.beforeHTML) {
          mergeColumnTdsAfterFlattening(rootMatrix, exp.startRowIndex, exp.startRowIndex, exp.startColIndex, exp.endColIndex);
        }
      });
    }
  };
  util.table.isMSTable = function(table) {
    var tableMSO = (table.getAttribute("style") || "").indexOf("mso-") > -1;
    if (tableMSO) {
      return true;
    }
    var col = table.querySelector("col");
    return col ? (col.getAttribute("style") || "").indexOf("mso-") > -1 : false;
  };
  util.table.isCompatible = function(table, loose) {
    if (table.compat !== undefined) {
      return table.compat;
    }
    table.compat = true;
    if (!util.dom.isTable(table)) {
      table.compat = false;
    } else {
      if (table.tBodies.length === 0 || table.rows.length === 0) {
        table.compat = false;
      } else {
        if (table.querySelectorAll("tfoot").length > 1 || table.querySelectorAll("thead").length > 1) {
          table.compat = false;
        } else {
          if (goog.dom.getAncestor(table, util.dom.isTable)) {
            table.compat = false;
          } else {
            if (!loose && table.querySelector("table")) {
              table.compat = false;
            } else {
              if (!loose && util.table.isMSTable(table)) {
                table.compat = true;
              } else {
                if (!loose && (table.cellPadding || table.cellSpacing || table.border)) {
                  table.compat = false;
                } else {
                  if (!loose && table.style.borderColor === "transparent") {
                    table.compat = false;
                  }
                }
              }
            }
          }
        }
      }
    }
    return table.compat;
  };
  util.table.normalize = function(root, skipStyleManipulation) {
    var tables = util.dom.isTable(root) ? [root] : root.querySelectorAll("table");
    goog.array.forEach(tables, function(table) {
      var isCompatible = util.table.isCompatible(table);
      util.table.normalizeStructure(table);
      if (!skipStyleManipulation && isCompatible) {
        util.table.normalizeColgroup(table, true);
        util.table.normalizeStyles(table);
        util.table.normalizeCellBorders(table);
      } else {
        util.table.normalizeColgroup(table);
      }
    });
  };
  util.table.normalizeStructure = function(table) {
    if (table.tBodies.length === 0) {
      table.appendChild(document.createElement("tbody"));
    }
    var tBody = table.tBodies[0];
    goog.array.forEachRight(tBody.childNodes || [], function(child) {
      if (!util.dom.isTr(child)) {
        goog.dom.removeNode(child);
      }
    });
    if (tBody.childNodes.length === 0) {
      tBody.innerHTML = "<tr><td>" + defs.CELL_HTML + "</td></tr>";
      return;
    }
    if (table.tHead) {
      goog.array.forEachRight(table.tHead.childNodes || [], function(child) {
        if (util.dom.isTr(child)) {
          goog.dom.insertSiblingBefore(child, tBody.firstChild);
        }
      });
    }
    if (table.tFoot) {
      goog.array.forEachRight(table.tFoot.childNodes || [], function(child) {
        if (util.dom.isTr(child)) {
          goog.dom.insertSiblingAfter(child, tBody.lastChild);
        }
      });
    }
    goog.array.forEachRight(table.childNodes || [], function(child) {
      if (!util.dom.isTbody(child) && !util.dom.isColgroup(child)) {
        goog.dom.removeNode(child);
      }
    });
    goog.array.forEach(table.rows, function(tr) {
      goog.array.forEachRight(tr.childNodes || [], function(child) {
        if (util.dom.isTd(child) || util.dom.isTh(child)) {
          if (util.dom.isTh(child)) {
            child = util.dom.changeTagName(child, "td");
          }
          if (util.dom.isEmpty(child)) {
            child.innerHTML = defs.CELL_HTML;
          }
        } else {
          goog.dom.removeNode(child);
        }
      });
    });
    var matrix = util.table.matrix(table);
    var colCount = Math.max.apply(null, matrix.map(function(row) {
      return row.length;
    }));
    if (colCount === 0 && matrix.length > 0) {
      table.rows[0].appendChild(util.table.createEmptyTd());
      matrix = util.table.matrix(table);
    }
    matrix.forEach(function(row, rowIndex) {
      for (var colIndex = 0; colIndex < colCount; colIndex++) {
        if (row[colIndex] === undefined) {
          util.table.insertTd(util.table.createEmptyTd(), rowIndex, colIndex, table, matrix);
        }
      }
    });
  };
  util.table.normalizeColgroup = function(table, normalizeToPixel, layoutCalculation) {
    var colgroup = util.table.query_(table, "colgroup");
    var matrix = util.table.matrix(table);
    var colEquations = [];
    var colWidthUnit = colgroup ? null : parseWidth(matrix[0][0].info.node.style.width).unit;
    var colCount = matrix[0].length;
    var debug = false;
    if (layoutCalculation) {
      colWidthUnit = "px";
    }
    if (layoutCalculation && !normalizeToPixel) {
      throw new Error("Invalid combination of normalizeToPixel=false and layoutCalculation=true.");
    }
    for (var rowIndex = 0; rowIndex < matrix.length; rowIndex++) {
      for (var colIndex = 0, row = matrix[rowIndex]; colIndex < row.length; colIndex++) {
        var info = row[colIndex].info;
        if (info.startRowIndex > rowIndex || info.startColIndex > colIndex) {
          continue;
        }
        var td = info.node;
        if (colWidthUnit || layoutCalculation) {
          var obj = parseWidth(td.style.width);
          var value = layoutCalculation ? td.offsetWidth : obj.value;
          if (!layoutCalculation && value && obj.unit !== colWidthUnit) {
            colWidthUnit = null;
            colEquations = [];
          } else {
            if (value) {
              colEquations.push([value].concat(goog.array.repeat(0, td.colSpan).map(function(_, i) {
                return i + info.startColIndex;
              })));
            }
          }
        }
        if (!layoutCalculation) {
          td.style.width = "";
          td.style.minWidth = "";
          td.style.maxWidth = "";
        }
      }
    }
    if (layoutCalculation) {
      for (var rowIndex = 0; rowIndex < matrix.length; rowIndex++) {
        for (var colIndex = 0, row = matrix[0]; colIndex < row.length; colIndex++) {
          var info = row[colIndex].info;
          if (info.startRowIndex > rowIndex || info.startColIndex > colIndex) {
            continue;
          }
          var td = info.node;
          td.style.width = "";
          td.style.minWidth = "";
          td.style.maxWidth = "";
        }
      }
    }
    var styleWidths = [];
    var tableWidthObj = parseWidth(table.style.width);
    if (!tableWidthObj.unit && table.hasAttribute("width")) {
      tableWidthObj = parseWidth(table.getAttribute("width"));
    }
    if (colgroup && !layoutCalculation) {
      styleWidths = calculateStyleWidthsFromColgroup(colCount, tableWidthObj, colgroup, normalizeToPixel);
      debug && console.log("[normalizeColgroup] calculateStyleWidthsFromColgroup");
    } else {
      if (colEquations.length > 0) {
        styleWidths = calculateStyleWidthsFromEquations(colCount, tableWidthObj, colWidthUnit, colEquations, normalizeToPixel);
        debug && console.log("[normalizeColgroup] calculateStyleWidthsFromEquations");
      } else {
        if (normalizeToPixel || tableWidthObj.unit === "px") {
          styleWidths = calculateStyleWidthsFromRatio(colCount, tableWidthObj);
          debug && console.log("[normalizeColgroup] calcualteStyleWidthsFromRatio");
        } else {
          debug && console.log("[normalizeColgroup] ignoring width calculation");
        }
      }
    }
    var newColgroup = document.createElement("colgroup");
    for (var i = 0; i < colCount; i++) {
      var col = document.createElement("col");
      col.style.width = styleWidths[i] || "";
      newColgroup.appendChild(col);
    }
    goog.dom.removeNode(colgroup);
    goog.dom.insertSiblingBefore(newColgroup, table.tBodies[0]);
  };
  util.table.normalizeStyles = function(table) {
    var matrix = util.table.matrix(table);
    var marginLeft = table.style.marginLeft === "auto" ? "auto" : "";
    var marginRight = table.style.marginRight === "auto" ? "auto" : "";
    table.removeAttribute("border");
    table.removeAttribute("align");
    table.removeAttribute("valign");
    table.removeAttribute("bordercolor");
    table.removeAttribute("cellspacing");
    table.removeAttribute("cellpadding");
    table.style.borderCollapse = "";
    table.style.border = "";
    table.style.width = "";
    table.style.minWidth = "";
    table.style.maxWidth = "";
    table.style.padding = "";
    table.style.margin = "";
    table.style.marginLeft = marginLeft;
    table.style.marginRight = marginRight;
    goog.array.forEach(table.rows, function(tr) {
      if (tr.hasAttribute("style")) {
        tr.style.border = "";
        tr.style.margin = "";
        tr.style.paddig = "";
        tr.style.height = "";
        tr.style.minHeight = "";
        tr.style.maxHeight = "";
      }
    });
    matrix.forEach(function(row, rowIndex) {
      row.forEach(function(obj, colIndex) {
        var info = obj.info;
        var td = info.node;
        if (info.startRowIndex > rowIndex || info.startColIndex > colIndex) {
          return;
        }
        var backgroundColor = td.style.backgroundColor;
        td.style.background = "";
        td.style.backgroundColor = goog.color.isValidColor(backgroundColor) ? backgroundColor : "";
        var borderColor = td.style.borderColor;
        td.style.border = "";
        td.style.borderColor = goog.color.isValidColor(borderColor) ? borderColor : "";
        td.style.padding = "";
        td.style.margin = "";
        td.style.width = "";
        td.style.minWidth = "";
        td.style.maxWidth = "";
        td.style.minHeight = "";
        td.style.maxHeight = "";
        if (td.colSpan === 1) {
          td.removeAttribute("colSpan");
        }
        util.table.setRowSpan(td, td.rowSpan);
        td.removeAttribute("width");
        td.removeAttribute("align");
        td.removeAttribute("valign");
      });
    });
  };
  util.table.normalizeCellBorders = function(table, optMatrix) {
    var matrix = optMatrix || util.table.matrix(table);
    goog.array.forEach(table.rows, function(row, rowIndex) {
      var td = row.firstChild;
      if (td) {
        td.style.borderLeftStyle = matrix[rowIndex][0].info.node === td ? "" : "none";
      }
    });
  };
  util.table.normalizeDOMPlacement = function(enTable) {
    var prev = enTable.previousElementSibling;
    if (util.dom.isDiv(prev) && util.dom.isBr(prev.firstChild) && prev.children.length === 1) {
      prev.remove();
    }
    var next = enTable.nextElementSibling;
    if (util.dom.isBr(next)) {
      next.remove();
    }
    var invalidSibling = function(node) {
      return !node || node.classList && node.classList.contains("en-code") || util.dom.isEntable(node) || util.dom.isHr(node);
    };
    if (invalidSibling(enTable.previousElementSibling)) {
      goog.dom.insertSiblingBefore(goog.dom.createDom("div", null, document.createElement("br")), enTable);
    }
    if (invalidSibling(enTable.nextElementSibling)) {
      goog.dom.insertSiblingAfter(goog.dom.createDom("div", null, document.createElement("br")), enTable);
    }
  };
  util.table.query_ = function(owner, selector) {
    if (!queryCache || queryCache.owner !== owner) {
      queryCache = {owner:owner};
    }
    var node = queryCache[selector];
    if (!node || !node.parentNode) {
      node = owner.querySelector(selector);
      queryCache[selector] = node;
    }
    return node;
  };
  function updateActiveTableAdornmentRows() {
    if (activeTable) {
      util.table.updateAdornments(activeTable, util.table.Axis.HORIZONTAL);
    }
  }
  function calculateStyleWidthsFromColgroup(colCount, tableWidthObj, colgroup, normalizeToPixel) {
    if (colCount !== colgroup.children.length) {
      return goog.array.repeat(normalizeToPixel ? defs.CELL_WIDTH : null, colCount);
    }
    var colFlexIndexes = [];
    var colWidthSum = 0;
    var unit = normalizeToPixel ? "px" : tableWidthObj.unit;
    var tableWidth;
    var widths = [];
    if (tableWidthObj.unit === "%") {
      tableWidth = tableWidthObj.value * (util.styles.getNoteWidth() - 1);
    } else {
      if (tableWidthObj.unit === "px") {
        tableWidth = tableWidthObj.value;
      } else {
        tableWidth = util.styles.getNoteWidth();
      }
    }
    goog.array.forEach(colgroup.children, function(col, i) {
      var colWidthStr = col.getAttribute("width") || col.style.width;
      var colWidthObj = parseWidth(colWidthStr);
      var width;
      if (colWidthStr === "*") {
        colFlexIndexes.push(i);
        unit = "px";
        width = 0;
      } else {
        if (colWidthObj.unit === "%" && normalizeToPixel) {
          width = tableWidth * colWidthObj.value;
        } else {
          if (colWidthObj.unit === "%") {
            unit = "%";
            width = colWidthObj.value;
          } else {
            if (colWidthObj.unit === "px" || normalizeToPixel) {
              unit = "px";
              width = colWidthObj.value || defs.CELL_WIDTH;
            }
          }
        }
      }
      colWidthSum += width;
      for (var j = parseInt(col.getAttribute("span"), 10) || 1; j > 0; j--) {
        widths.push(width);
      }
    });
    if (!unit) {
      return goog.array.repeat(defs.CELL_WIDTH, colCount);
    }
    var flexCount = colFlexIndexes.length;
    var flexTotal = unit === "%" ? 1 : tableWidth;
    var flexWidth = Math.max(0, flexTotal - colWidthSum);
    colFlexIndexes.forEach(function(i) {
      widths[i] = Math.round(flexWidth / flexCount);
    });
    var styleWidths = [];
    for (var i = 0; i < colCount; i++) {
      var width;
      if (unit === "px" && normalizeToPixel) {
        width = Math.max(widths[i] || defs.CELL_WIDTH, defs.CELL_MIN_WIDTH);
      } else {
        if (unit === "px") {
          width = widths[i] || defs.CELL_WIDTH;
        } else {
          width = widths[i] * 100;
        }
      }
      styleWidths.push(Math.round(width) + unit);
    }
    return styleWidths;
  }
  function calculateStyleWidthsFromEquations(colCount, tableWidthObj, colWidthUnit, colEquations, normalizeToPixel) {
    var change = true;
    var divide = false;
    var tableWidth;
    var widthIndexCount = 0;
    var widths = [];
    if (tableWidthObj.unit === "%") {
      tableWidth = tableWidthObj.value * (util.styles.getNoteWidth() - 1);
    } else {
      if (tableWidthObj.unit === "px") {
        tableWidth = tableWidthObj.value;
      } else {
        tableWidth = util.styles.getNoteWidth();
      }
    }
    colEquations.sort(function(a, b) {
      return b.length - a.length;
    });
    while (change && widthIndexCount < colCount) {
      change = false;
      goog.array.forEachRight(colEquations, function(eq, i) {
        if (eq.length > 2) {
          for (var j = eq.length - 1; j > 0; j--) {
            var wval = widths[eq[j]];
            if (wval) {
              change = true;
              eq[0] -= wval;
              eq.splice(j, 1);
            }
          }
        }
        if (divide || eq.length === 2) {
          for (var l = eq.length - 1, j = l; j > 0; j--) {
            if (!widths[eq[j]]) {
              change = true;
              widthIndexCount += 1;
              widths[eq[j]] = eq[0] / l;
            }
          }
          colEquations.splice(i, 1);
        }
      });
      if (!change && !divide) {
        divide = true;
        change = true;
      }
    }
    for (var i = 0; i < colCount; i++) {
      var width = widths[i];
      if (colWidthUnit === "px" && normalizeToPixel) {
        widths[i] = Math.max(width || defs.CELL_WIDTH, defs.CELL_MIN_WIDTH);
      } else {
        if (colWidthUnit === "px") {
          widths[i] = width || defs.CELL_WIDTH;
        } else {
          if (colWidthUnit === "%" && width) {
            widths[i] = tableWidth * width;
          } else {
            if (colWidthUnit === "%" || !width) {
              widths[i] = defs.CELL_WIDTH;
            }
          }
        }
      }
    }
    return widths.map(function(width) {
      return Math.round(width) + "px";
    });
  }
  function calculateStyleWidthsFromRatio(colCount, tableWidthObj) {
    var noteWidth = util.styles.getNoteWidth() - 1;
    var styleWidths = [];
    var width = null;
    if (tableWidthObj.unit === "%") {
      width = noteWidth * tableWidthObj.value / colCount;
    } else {
      if (tableWidthObj.unit === "px") {
        width = tableWidthObj.value / colCount;
      } else {
        width = defs.CELL_WIDTH;
      }
    }
    for (var i = 0; i < colCount; i++) {
      styleWidths.push(Math.round(Math.max(width, defs.CELL_MIN_WIDTH)) + "px");
    }
    return styleWidths;
  }
  function processDeleteIndexes(indexes, lowerBound, upperBound) {
    var inBounds = goog.array.every(indexes, function(index) {
      return index >= lowerBound && index <= upperBound;
    });
    if (!inBounds) {
      return null;
    }
    return indexes.slice().sort(function(a, b) {
      return b - a;
    });
  }
  function parseWidth(val) {
    if (val && val.indexOf("%") > -1) {
      return {unit:"%", value:parseInt(val, 10) / 100};
    } else {
      if (val && (val.indexOf("px") > -1 || val.indexOf("pt") > -1 || !isNaN(parseInt(val, 10)))) {
        return {unit:"px", value:parseInt(val, 10)};
      }
    }
    return {unit:null, value:null};
  }
  function prevNextCell(node, navigateByDOM, direction) {
    var td = goog.dom.getAncestor(node, util.dom.isTd, true);
    if (!td) {
      return null;
    }
    var matrix = util.table.matrix(goog.dom.getAncestor(td, util.dom.isTable));
    var info = util.table.infoForCell(td, matrix);
    var maxColIndex = matrix[0].length - 1;
    var maxRowIndex = matrix.length - 1;
    var rowIndex = info.startRowIndex;
    var colIndex = info.startColIndex;
    while (true) {
      if (direction < 0 && colIndex === 0) {
        rowIndex += direction;
        colIndex = maxColIndex;
      } else {
        if (direction > 0 && colIndex >= maxColIndex) {
          rowIndex += direction;
          colIndex = 0;
        } else {
          colIndex += direction;
        }
      }
      if (rowIndex < 0 || rowIndex > maxRowIndex) {
        break;
      }
      var itInfo = matrix[rowIndex][colIndex].info;
      if (!navigateByDOM && itInfo !== info || navigateByDOM && itInfo !== info && itInfo.startRowIndex === rowIndex) {
        return itInfo.node;
      }
    }
    return null;
  }
  function mergeColumnTdsAfterFlattening(matrix, startRowIndex, endRowIndex, startColIndex, endColIndex) {
    for (var rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
      var tds = [];
      for (var colIndex = startColIndex; colIndex <= endColIndex; colIndex++) {
        var info = matrix[rowIndex][colIndex].info;
        if (info.startRowIndex === rowIndex && info.startColIndex === colIndex) {
          tds.push(info.node);
        }
      }
      util.table.mergeCells(tds);
    }
  }
  function mergeRowTdsAfterFlattening(matrix, startRowIndex, endRowIndex, startColIndex, endColIndex) {
    for (var colIndex = startColIndex; colIndex <= endColIndex; colIndex++) {
      var tds = [];
      for (var rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
        var info = matrix[rowIndex][colIndex].info;
        if (info.startRowIndex === rowIndex && info.startColIndex === colIndex) {
          tds.push(info.node);
        }
      }
      util.table.mergeCells(tds);
    }
  }
  function mergeTdsAfterFlattening(matrix, expansions) {
  }
  function processTableForExpansion(table, expansions) {
    var td = goog.dom.getAncestor(table, util.dom.isTd);
    var cellInfo = util.table.infoForCell(td);
    var matrix = util.table.matrix(table);
    var afterHTML = null;
    var beforeHTML = null;
    var rowOffset = 0;
    var nextNode = util.dom.nextNodeDescendants(table, td);
    if (nextNode) {
      var afterNodeSplit = goog.editor.node.splitDomTreeAt(nextNode, nextNode, td);
      if (!util.dom.isEmptyContent(afterNodeSplit)) {
        afterHTML = afterNodeSplit.innerHTML;
        rowOffset += 1;
      }
    }
    goog.editor.node.splitDomTreeAt(table, table, td);
    if (!util.dom.isEmptyContent(td)) {
      beforeHTML = td.innerHTML;
      rowOffset += 1;
    }
    var info = {matrix:matrix, beforeHTML:beforeHTML, afterHTML:afterHTML, startRowIndex:cellInfo.startRowIndex, endRowIndex:cellInfo.endRowIndex, startColIndex:cellInfo.startColIndex, endColIndex:cellInfo.endColIndex, rowCount:matrix.length + rowOffset, colCount:matrix[0].length, insertRowIndex:cellInfo.endRowIndex + 1, insertColIndex:cellInfo.endColIndex + 1, addRowCount:matrix.length - 1 + rowOffset, addColCount:matrix[0].length - 1};
    var rowExp = expansions.reduce(function(prev, cur) {
      return !prev && cur.startRowIndex === info.startRowIndex || prev && prev.rowCount < cur.rowCount && cur.startRowIndex === info.startRowIndex ? cur : prev;
    }, null);
    if (rowExp) {
      info.addRowCount = Math.max(0, info.addRowCount + 1 - (rowExp.rowCount - (rowExp.startRowIndex - info.startRowIndex)));
      if (info.addRowCount) {
        info.insertRowIndex = Math.max(rowExp.endRowIndex + 1, info.insertRowIndex);
      }
    }
    var colExp = expansions.reduce(function(prev, cur) {
      return !prev && cur.startColIndex === info.startColIndex || prev && prev.colCount < cur.colCount && cur.startColIndex === info.startColIndex ? cur : prev;
    }, null);
    if (colExp) {
      info.addColCount = Math.max(0, info.addColCount + 1 - (colExp.colCount - (colExp.startColIndex - info.startColIndex)));
      if (info.addColCount) {
        info.insertColIndex = Math.max(colExp.endColIndex + 1, info.insertColIndex);
      }
    }
    return info;
  }
  function mergeExpansions(expansions, info) {
    var addition = {startRowIndex:info.startRowIndex, startColIndex:info.startColIndex, endRowIndex:info.startRowIndex + info.rowCount - 1, endColIndex:info.startColIndex + info.colCount - 1, rowCount:info.rowCount, colCount:info.colCount};
    var index = goog.array.findIndex(expansions, function(obj) {
      return obj.startRowIndex === addition.startRowIndex && obj.startColIndex === addition.startColIndex && (obj.rowCount < addition.rowCount || obj.colCount < addition.colCount);
    });
    if (index > -1) {
      var exp = expansions[index];
      exp.endRowIndex = Math.max(exp.endRowIndex, addition.endRowIndex);
      exp.endColIndex = Math.max(exp.endColIndex, addition.endColIndex);
      exp.rowCount = Math.max(exp.rowCount, addition.rowCount);
      exp.colCount = Math.max(exp.colCount, addition.colCount);
    } else {
      expansions.push(addition);
    }
  }
})();
goog.provide("uno.util.table.selection");
goog.require("goog.debug.Logger");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("uno.util.dom");
goog.require("uno.util.range");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.table.selection");
  var util = uno.util;
  var State = util.table.State;
  var Axis = util.table.Axis;
  var model = null;
  util.table.selection.isActive = function(enTable) {
    return !!(model && !model.activationTimer && (enTable === undefined || model.enTable === enTable));
  };
  util.table.selection.isPending = function(enTable) {
    return !!(model && model.activationTimer && (enTable === undefined || model.enTable === enTable));
  };
  util.table.selection.create = function(enTable, multirange, anchorCell, focusCell, axis) {
    var matrix = util.table.matrix(enTable, {selection:true});
    var info = !anchorCell ? findSelectedInfo(matrix) : null;
    util.table.selection.clear();
    if (!anchorCell) {
      if (!info) {
        enTable.classList.remove("multirange");
        return false;
      }
      anchorCell = info.node;
    }
    enTable.classList.add("multirange");
    var timer = setTimeout(function() {
      util.range.selectNodeContents(model.cursorProxy);
      model.activationTimer = setTimeout(function() {
        if (model) {
          model.activationTimer = null;
        }
      }, 10);
    }, 10);
    model = {enTable:enTable, cursorProxy:createCursorProxy(enTable), multirange:multirange, activationTimer:timer, anchorCell:anchorCell, colVector:createVector(util.table.query_(enTable, ".columns .handles").children), rowVector:createVector(util.table.query_(enTable, ".rows .handles").children), matrix:util.table.matrix(enTable)};
    if (info) {
      return applyDiff(model, matrix, true);
    }
    return util.table.selection.selectTo(focusCell || anchorCell, axis);
  };
  util.table.selection.selectTo = function(focusCell, axis) {
    if (!model) {
      throw new Error("Calling util.table.selection.selectTo on inactive model.");
    }
    var matrix = util.table.matrix(model.enTable);
    if (!axis && model.anchorCell === focusCell) {
      util.table.infoForCell(focusCell, matrix).state |= State.SELECTED;
      util.table.setActive(model.enTable, focusCell);
      return applyDiff(model, matrix);
    }
    var aInfo = util.table.infoForCell(model.anchorCell, matrix);
    var fInfo = model.anchorCell === focusCell ? aInfo : util.table.infoForCell(focusCell, matrix);
    var startRowIndex = axis === Axis.VERTICAL ? 0 : Math.min(aInfo.startRowIndex, fInfo.startRowIndex);
    var endRowIndex = axis === Axis.VERTICAL ? matrix.length - 1 : Math.max(aInfo.endRowIndex, fInfo.endRowIndex);
    var startColIndex = axis === Axis.HORIZONTAL ? 0 : Math.min(aInfo.startColIndex, fInfo.startColIndex);
    var endColIndex = axis === Axis.HORIZONTAL ? matrix[0].length - 1 : Math.max(aInfo.endColIndex, fInfo.endColIndex);
    setSelectedInRect(matrix, startRowIndex, endRowIndex, startColIndex, endColIndex, true);
    if (axis === Axis.VERTICAL) {
      focusCell = model.matrix[0][fInfo.startColIndex].info.node;
    } else {
      if (axis === Axis.HORIZONTAL) {
        focusCell = model.matrix[fInfo.startRowIndex][0].info.node;
      }
    }
    util.table.setActive(model.enTable, focusCell);
    return applyDiff(model, matrix);
  };
  util.table.selection.toggleAt = function(focusCell, axis) {
    if (!model) {
      throw new Error("Calling util.table.selection.toggleAt on inactive model.");
    }
    var matrix = cloneMatrix(model.enTable, model.matrix);
    var info = util.table.infoForCell(focusCell, matrix);
    if (!axis) {
      info.state ^= State.SELECTED;
      util.table.setActive(model.enTable, focusCell);
      return applyDiff(model, matrix);
    }
    var vert = axis === Axis.VERTICAL;
    var state = vert ? model.colVector[info.startColIndex].state : model.rowVector[info.startRowIndex].state;
    var selected = !(state & State.WHOLE_SELECTED);
    var startRowIndex = vert ? 0 : info.startRowIndex;
    var endRowIndex = vert ? matrix.length - 1 : info.endRowIndex;
    var startColIndex = !vert ? 0 : info.startColIndex;
    var endColIndex = !vert ? matrix[0].length - 1 : info.endColIndex;
    setSelectedInRect(matrix, startRowIndex, endRowIndex, startColIndex, endColIndex, selected);
    focusCell = vert ? model.matrix[0][info.startColIndex].info.node : model.matrix[info.startRowIndex][0].info.node;
    util.table.setActive(model.enTable, focusCell);
    return applyDiff(model, matrix);
  };
  util.table.selection.clear = function() {
    if (!util.table.selection.isActive()) {
      return;
    }
    clearTimeout(model.activationTimer);
    applyDiff(model, util.table.matrix(model.enTable));
    model.multirange.clear();
    model.cursorProxy.remove();
    model.enTable.classList.remove("multirange");
    model = null;
  };
  util.table.selection.getColumnIndexes = function(state) {
    if (!model) {
      return [];
    }
    return model.colVector.map(function(obj, index) {
      return obj.state & (state || State.SELECTED) ? index : null;
    }).filter(goog.isDefAndNotNull);
  };
  util.table.selection.getRowIndexes = function(state) {
    if (!model) {
      return [];
    }
    return model.rowVector.map(function(obj, index) {
      return obj.state & (state || State.SELECTED) ? index : null;
    }).filter(goog.isDefAndNotNull);
  };
  util.table.selection.getCells = function() {
    if (!model) {
      return [];
    }
    var nodes = [];
    model.matrix.forEach(function(row, rowIndex) {
      row.forEach(function(obj, colIndex) {
        var info = obj.info;
        if (info.state & State.SELECTED && info.startRowIndex === rowIndex && info.startColIndex === colIndex) {
          nodes.push(info.node);
        }
      });
    });
    return nodes;
  };
  util.table.selection.getPasteCell = function() {
    if (!model) {
      return null;
    }
    var rowIndexes = util.table.selection.getRowIndexes();
    var colIndexes = util.table.selection.getColumnIndexes();
    if (rowIndexes.length === 0 || colIndexes.length === 0) {
      return null;
    }
    return model.matrix[rowIndexes[0]][colIndexes[0]].info.node;
  };
  function applyDiff(mod, matrix, force) {
    var hasSelection = false;
    var clen = mod.colVector.length;
    var rlen = mod.rowVector.length;
    var colSelectedCounts = goog.array.repeat(0, clen);
    var rowSelectedCounts = goog.array.repeat(0, rlen);
    var colOverlapIndexes = goog.array.repeat(undefined, clen);
    var rowOverlapIndexes = goog.array.repeat(undefined, rlen);
    mod.matrix.forEach(function(row, rowIndex) {
      row.forEach(function(obj, colIndex) {
        var info = obj.info;
        var state = matrix[rowIndex][colIndex].info.state;
        var selected = state & State.SELECTED;
        var root = info.startRowIndex === rowIndex && info.startColIndex === colIndex;
        if (root && (force || (info.state & State.SELECTED) !== selected)) {
          var cell = info.node;
          var range = goog.dom.Range.createFromNodes(cell, 0, cell, cell.childNodes.length);
          mod.multirange.toggleTextRange(range, selected);
          cell.classList.toggle("selected", selected);
          info.state = state;
        }
        if (selected) {
          hasSelection = true;
          colSelectedCounts[colIndex] += 1;
          rowSelectedCounts[rowIndex] += 1;
          storeOverlapIndexes(colOverlapIndexes, colIndex, info.startColIndex, info.endColIndex);
          storeOverlapIndexes(rowOverlapIndexes, rowIndex, info.startRowIndex, info.endRowIndex);
        }
      });
    });
    applyVectorDiff(mod.colVector, colSelectedCounts, colOverlapIndexes, rlen);
    applyVectorDiff(mod.rowVector, rowSelectedCounts, rowOverlapIndexes, clen);
    return hasSelection;
  }
  function applyVectorDiff(vector, selectedCounts, overlapIndexes, length) {
    overlapIndexes = overlapIndexes.map(function(obj) {
      return Object.keys(obj || {}).map(function(key) {
        return parseInt(key, 10);
      });
    });
    var compare = function(i) {
      return selectedCounts[i] === length;
    };
    vector.forEach(function(obj, index) {
      var state = 0;
      var count = selectedCounts[index];
      if (count === length) {
        state |= State.WHOLE_SELECTED;
        if (goog.array.every(overlapIndexes[index], compare)) {
          state |= State.DRAGGABLE;
        }
      }
      if (count > 0) {
        state |= State.SELECTED;
      }
      obj.state = state;
      obj.node.classList.toggle("wselected", state & State.WHOLE_SELECTED);
      obj.node.classList.toggle("selected", state & State.SELECTED);
      obj.node.classList.toggle("draggable", state & State.DRAGGABLE);
    });
  }
  function storeOverlapIndexes(arr, index, startIndex, endIndex) {
    if (startIndex === index && endIndex === index) {
      return;
    }
    var obj = arr[index];
    if (!obj) {
      obj = {};
      arr[index] = obj;
    }
    for (var i = startIndex; i <= endIndex; i++) {
      if (i !== index) {
        obj[i] = true;
      }
    }
  }
  function findSelectedInfo(matrix) {
    var info = null;
    for (var i = 0, il = matrix.length; i < il; i++) {
      for (var j = 0, jl = matrix[i].length; j < jl; j++) {
        var obj = matrix[i][j];
        if (obj.info.state & State.SELECTED) {
          info = obj.info;
          break;
        }
      }
      if (info) {
        break;
      }
    }
    return info;
  }
  function setSelectedInRect(matrix, startRowIndex, endRowIndex, startColIndex, endColIndex, selected) {
    var indexes = util.table.expandIntoRectIndexes(matrix, startRowIndex, endRowIndex, startColIndex, endColIndex);
    for (var rowIndex = indexes.startRowIndex; rowIndex <= indexes.endRowIndex; rowIndex++) {
      for (var colIndex = indexes.startColIndex; colIndex <= indexes.endColIndex; colIndex++) {
        if (selected) {
          matrix[rowIndex][colIndex].info.state |= State.SELECTED;
        } else {
          matrix[rowIndex][colIndex].info.state &= ~State.SELECTED;
        }
      }
    }
  }
  function cloneMatrix(enTable, matrix) {
    var newMatrix = util.table.matrix(enTable);
    matrix.forEach(function(row, rowIndex) {
      row.forEach(function(obj, colIndex) {
        newMatrix[rowIndex][colIndex].info.state = obj.info.state;
      });
    });
    return newMatrix;
  }
  function createVector(nodesOrVector) {
    return goog.array.map(nodesOrVector, function(obj) {
      return {node:util.dom.isElementNode(obj) ? obj : obj.node, state:0};
    });
  }
  function createCursorProxy(enTable) {
    var node = enTable.querySelector(".cursor-proxy");
    if (!node) {
      node = goog.dom.createDom("cursor-proxy");
      node.innerHTML = "&nbsp;";
      enTable.querySelector("table").appendChild(node);
    }
    return node;
  }
})();
goog.provide("uno.util.copy.table");
goog.require("uno.defs");
goog.require("uno.util.table");
goog.require("uno.util.table.selection");
(function() {
  var util = uno.util;
  var defs = uno.defs;
  util.copy.table.getPastableHtml = function() {
    var selectedCells = util.table.selection.getCells();
    if (selectedCells.length === 0) {
      return "";
    } else {
      if (selectedCells.length === 1) {
        return selectedCells[0].innerHTML;
      }
    }
    var table = util.table.getActive().querySelector("table").cloneNode(true);
    var cols = table.querySelector("colgroup").children;
    var matrix = util.table.matrix(table, {selection:true});
    var colIndexes = util.table.selection.getColumnIndexes();
    var rowIndexes = util.table.selection.getRowIndexes();
    var indexes = util.table.expandIntoRectIndexes(matrix, rowIndexes[0], goog.array.peek(rowIndexes), colIndexes[0], goog.array.peek(colIndexes));
    var proxy = table.querySelector("cursor-proxy");
    if (proxy) {
      proxy.remove();
    }
    goog.array.forEachRight(matrix, function(row, rowIndex) {
      if (!(indexes.startRowIndex <= rowIndex && rowIndex <= indexes.endRowIndex)) {
        table.rows[rowIndex].remove();
      } else {
        goog.array.forEachRight(row, function(obj, colIndex) {
          var info = obj.info;
          if (!info.node.style.borderWidth) {
            info.node.style.borderWidth = "1px";
          }
          if (!info.node.style.borderStyle) {
            info.node.style.borderStyle = "solid";
          }
          if (!info.node.style.borderColor) {
            info.node.style.borderColor = "#ccc";
          }
          if (info.startRowIndex > rowIndex && info.startColIndex > colIndex) {
            return;
          }
          if (!(indexes.startColIndex <= colIndex && colIndex <= indexes.endColIndex)) {
            info.node.remove();
          } else {
            if (info.state & util.table.State.SELECTED) {
              info.node.classList.remove("selected");
            } else {
              info.node.innerHTML = defs.table.CELL_HTML;
            }
          }
        });
      }
    });
    goog.array.forEachRight(matrix[0], function(row, colIndex) {
      if (!(indexes.startColIndex <= colIndex && colIndex <= indexes.endColIndex)) {
        cols[colIndex].remove();
      }
    });
    return table.outerHTML;
  };
})();
goog.provide("uno.util.copy.rich");
(function() {
  var util = uno.util;
  var dom = util.dom;
  util.copy.rich.copy = function(root, options) {
    var addMarker = options.addMarker || typeof options.addMarker === "undefined";
    var node = root.childNodes.length === 1 && dom.isDiv(root.firstChild) ? root.firstChild : root;
    if (addMarker) {
      goog.array.some(node.childNodes, function(element) {
        if (dom.isElementNode(element)) {
          util.styles.setStyle(element, "-en-clipboard", "true");
          return true;
        }
        return false;
      });
    }
    return node.innerHTML;
  };
})();
goog.provide("uno.util.canvas");
goog.require("goog.debug.Logger");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.canvas");
  var util = uno.util;
  util.canvas.create = function(width, height) {
    var canvas = document.createElement("canvas");
    var ratio = util.styles.getDevicePixelRatio();
    canvas.width = width * ratio;
    canvas.height = height * ratio;
    canvas.style.width = width + "px";
    canvas.style.height = height + "px";
    var ctx = canvas.getContext("2d");
    ctx.scale(ratio, ratio);
    ctx.save();
    ctx.fillStyle = "#fff";
    ctx.fillRect(0, 0, width, height);
    ctx.restore();
    return canvas;
  };
  util.canvas.width = function(canvas) {
    return parseFloat(canvas.style.width) || canvas.width;
  };
  util.canvas.height = function(canvas) {
    return parseFloat(canvas.style.height) || canvas.height;
  };
  util.canvas.fillText = function(ctx, text, x, y, width) {
    if (text) {
      var len = text.length - 4;
      var metrics = ctx.measureText(text);
      while (metrics.width > width && len > 0) {
        text = text.substring(0, len) + "...";
        len--;
        metrics = ctx.measureText(text);
      }
      ctx.fillText(text, x, y);
    }
  };
  util.canvas.rad = function(deg) {
    return deg * Math.PI / 180;
  };
})();
goog.provide("uno.components.ImageResizer");
goog.require("goog.dom");
goog.require("goog.events");
goog.require("goog.style");
goog.require("uno.util.dom");
goog.require("uno.util.styles");
goog.require("uno.util.table");
goog.require("uno.util.zoomscale");
(function() {
  var BORDER_WIDTH = 2;
  var MIN_WIDTH = 50 + BORDER_WIDTH * 2;
  var util = uno.util;
  var ImageResizer = uno.components.ImageResizer = function(editor) {
    this.resizing = false;
    this.editor_ = editor;
    this.target_ = null;
    this.meta_ = null;
    this.frame_ = goog.dom.createDom("div", {class:"en-imageresizer-frame"});
    this.element = goog.dom.createDom("div", {class:"en-imageresizer-trigger"});
    goog.events.listen(this.element, "mousedown", handleResizeStart.bind(this));
    goog.events.listen(window, "mousemove", handleResizeChange.bind(this));
    goog.events.listen(window, "mouseup", handleResizeEnd.bind(this));
    goog.events.listen(window, "contextmenu", handleContextMenu.bind(this));
  };
  Object.defineProperty(ImageResizer.prototype, "attached", {get:function() {
    return !!this.target_;
  }});
  ImageResizer.prototype.attach = function(img) {
    if (this.resizing || !img) {
      return;
    }
    this.detach();
    this.element.style.display = "block";
    this.target_ = img;
    this.layout();
  };
  ImageResizer.prototype.detach = function() {
    if (this.resizing) {
      return;
    }
    this.element.style.display = "none";
    this.frame_.remove();
    this.target_ = null;
  };
  ImageResizer.prototype.layout = function() {
    if (!this.target_) {
      return false;
    }
    var zoom = uno.util.zoomscale.getZoom();
    var rect = this.target_.getBoundingClientRect();
    if (!rect.width || !rect.height) {
      return false;
    }
    this.element.style.zoom = zoom;
    this.element.style.top = rect.top + rect.height + util.dom.scrollTop(document.body) / zoom + "px";
    this.element.style.left = rect.left + rect.width + util.dom.scrollLeft(document.body) / zoom + "px";
    return true;
  };
  function handleResizeEnd(evt) {
    if (!this.meta_) {
      return;
    }
    evt.preventDefault();
    evt.stopPropagation();
    if (this.meta_.width) {
      this.target_.setAttribute("width", this.meta_.width);
      this.target_.setAttribute("data-width", this.meta_.width);
    }
    this.frame_.remove();
    this.meta_ = null;
    this.resizing = false;
    document.documentElement.classList.remove("nwse-resizing");
    this.layout();
    var enTable = goog.dom.getAncestor(this.target_, util.dom.isEntable);
    if (enTable) {
      util.table.layout(enTable);
    }
    this.editor_.execCommand("focus", true);
    this.editor_.dispatchChange();
  }
  function handleResizeChange(evt) {
    if (!this.meta_) {
      return;
    }
    evt.preventDefault();
    evt.stopPropagation();
    var d = this.meta_;
    var x = evt.clientX - d.rect.left;
    var y = evt.clientY - d.rect.top;
    var scaleX = x / d.fromPoint.x;
    var scaleY = y / d.fromPoint.y;
    var belowDiagonal = d.ratio > Math.abs(x / y);
    var scaledWidth = belowDiagonal ? d.rect.height * scaleY * d.ratio : scaleX * d.rect.width;
    var width = Math.round(Math.max(Math.min(scaledWidth, d.maxWidth), d.minWidth));
    var height = width / d.ratio;
    if (this.meta_.width !== width) {
      this.meta_.width = width;
      this.frame_.style.width = width + "px";
      this.frame_.style.height = height + "px";
    }
  }
  function handleResizeStart(evt) {
    if (!this.target_) {
      return;
    }
    evt.preventDefault();
    evt.stopPropagation();
    this.resizing = true;
    var zoom = uno.util.zoomscale.getZoom();
    var noteWidth = uno.util.styles.getNoteWidth(this.editor_.field);
    var rect = this.target_.getBoundingClientRect();
    this.frame_.style.zoom = zoom;
    this.frame_.style.top = rect.top + util.dom.scrollTop(document.body) / zoom + "px";
    this.frame_.style.left = rect.left + util.dom.scrollLeft(document.body) / zoom + "px";
    this.frame_.style.width = rect.width + "px";
    this.frame_.style.height = rect.height + "px";
    var tdWidth = Infinity;
    var td = goog.dom.getAncestor(this.target_, util.dom.isTd);
    if (td) {
      tdWidth = td.getBoundingClientRect().width - 20;
    }
    this.meta_ = {fromPoint:{x:evt.clientX - rect.left, y:evt.clientY - rect.top}, rect:rect, ratio:this.target_.naturalWidth / this.target_.naturalHeight, width:null, maxWidth:Math.min(this.target_.naturalWidth, noteWidth, tdWidth), minWidth:MIN_WIDTH};
    this.element.parentNode.appendChild(this.frame_);
    if (!this.target_.getAttribute("width")) {
      this.meta_.rect.width += BORDER_WIDTH;
      this.meta_.rect.height += BORDER_WIDTH;
    }
    document.documentElement.classList.add("nwse-resizing");
  }
  function handleContextMenu(evt) {
    if (this.resizing) {
      evt.preventDefault();
    }
  }
})();
goog.provide("uno.util.img");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.classlist");
goog.require("uno.components.ImageResizer");
goog.require("uno.util.dom");
goog.require("uno.util.observer");
goog.require("uno.util.styles");
goog.require("uno.util.tools");
goog.require("uno.util.zoomscale");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.img");
  var util = uno.util;
  var dom = util.dom;
  var STRUCTTYPES = uno.defs.structuretypes;
  var selectedImage = null;
  var toolbarImage = null;
  var toolbarHandler = null;
  var resizer = null;
  var toolbar = null;
  var scrollableCandidate = null;
  var scrollableTimeout = null;
  var toolsHiddenByScroll = false;
  util.img.all = function(root) {
    return root.querySelectorAll("img.en-media-image");
  };
  util.img.convertMediaToSlug = function(enmedia, props, editor) {
    var img = new Image;
    goog.dom.classlist.addAll(img, ["en-media", "en-media-image"]);
    img.setAttribute("data-hash", props.hash);
    img.setAttribute("data-type", props.type);
    img.setAttribute("data-url", props.url);
    if (props.elementId) {
      img.id = props.elementId;
    }
    if (props.width != null) {
      img.setAttribute("width", props.width);
    }
    if (props.height != null && editor.hasForeignSource()) {
      img.setAttribute("height", props.height);
    }
    if (img.getAttribute("width")) {
      img.setAttribute("data-width", img.getAttribute("width"));
    }
    if (typeof props.overlayOpacity !== "undefined") {
      img.style.opacity = 1 - parseInt(props.overlayOpacity, 10);
    }
    if (props.overlayImageURL) {
      img.src = props.overlayImageURL;
      img.style.backgroundImage = "url(" + props.url + ")";
      img.style.backgroundSize = "cover";
    } else {
      img.src = props.url;
    }
    goog.dom.replaceNode(img, enmedia);
    return img;
  };
  util.img.preloadTools = function(editor) {
    util.img.preloadToolbar(editor.config);
    util.img.preloadResizer(editor);
  };
  util.img.preloadToolbar = function(config) {
    if (toolbar) {
      toolbar.remove();
      toolbar = null;
    }
    if (!config.images.annotate) {
      return;
    }
    toolbar = goog.dom.createDom("div", {class:"en-imagebar"});
    util.tools.append(toolbar);
    var factoryButton = function(type) {
      var node = goog.dom.createDom("div", {class:"en-imagebar-button en-imagebar-" + type, "data-command":type});
      goog.events.listen(node, "click", function() {
        if (toolbarImage && toolbarHandler) {
          toolbarHandler(toolbarImage, this.getAttribute("data-command"));
        }
      });
      toolbar.appendChild(node);
    };
    if (config.images.annotate) {
      factoryButton("annotate");
    }
  };
  util.img.preloadResizer = function(editor) {
    if (resizer) {
      resizer.element.remove();
      resizer = null;
    }
    if (!editor.config.images.resize) {
      return;
    }
    resizer = new uno.components.ImageResizer(editor);
    util.tools.append(resizer.element);
  };
  util.img.createImage = function(src) {
    var img = new Image;
    if (src != null) {
      img.src = src;
    }
    return img;
  };
  util.img.convertClientElementToSlug = function(img) {
    return img;
  };
  util.img.isToolbarButton = function(node) {
    return goog.dom.classlist.contains(node, "en-imagebar-button");
  };
  util.img.isImage = function(node) {
    return node && goog.dom.classlist.contains(node, "en-media-image");
  };
  util.img.isResource = function(node) {
    return util.img.isImage(node);
  };
  util.img.isSelected = function(nodeOrRange) {
    if (!selectedImage) {
      return false;
    }
    if (util.dom.isElementNode(nodeOrRange)) {
      return nodeOrRange === selectedImage;
    } else {
      if (nodeOrRange && nodeOrRange.isCollapsed && !nodeOrRange.isCollapsed()) {
        var anchorNode = nodeOrRange.getAnchorNode();
        var focusNode = nodeOrRange.getFocusNode();
        if (anchorNode === focusNode && anchorNode.children) {
          for (var i = 0, l = anchorNode.children.length; i < l; i++) {
            if (anchorNode.children[i] === selectedImage) {
              return true;
            }
          }
        }
      }
    }
    return false;
  };
  util.img.setToolbar = function(img, handler) {
    if (!toolbar || selectedImage || img === toolbarImage || !img && !toolbarImage) {
      return;
    }
    toolbarImage = img;
    toolbarHandler = handler;
    if (img) {
      scrollableCandidate = getScrollableCandidate(img);
      toolbar.style.display = "block";
      util.img.layoutToolbar();
      util.observer.addHandler(util.img.layoutToolbar);
    } else {
      scrollableCandidate = null;
      toolbar.style.display = "none";
      util.observer.removeHandler(util.img.layoutToolbar);
    }
  };
  util.img.setSelected = function(img) {
    if (resizer && resizer.resizing || img === selectedImage || !img && !selectedImage) {
      return;
    }
    if (selectedImage) {
      selectedImage.classList.remove("en-media-selected");
      selectedImage = null;
    }
    if (img) {
      util.img.setToolbar(null);
      scrollableCandidate = getScrollableCandidate(img);
      selectedImage = img;
      selectedImage.classList.add("en-media-selected");
      goog.dom.Range.createFromNodeContents(img).select();
    } else {
      scrollableCandidate = null;
    }
    if (resizer && img) {
      resizer.attach(img);
      util.observer.addHandler(util.img.layoutResizer);
    } else {
      if (resizer) {
        resizer.detach();
        util.observer.removeHandler(util.img.layoutResizer);
      }
    }
  };
  util.img.hideToolsOnScrollIfNeeded = function(scrollingTarget) {
    if (!scrollableCandidate || scrollingTarget !== scrollableCandidate) {
      return;
    } else {
      if (!toolsHiddenByScroll) {
        document.documentElement.classList.add("scrolling-x");
        toolsHiddenByScroll = true;
      }
    }
    clearTimeout(scrollableTimeout);
    scrollableTimeout = setTimeout(function() {
      util.img.layoutResizer();
      util.img.layoutToolbar();
      document.documentElement.classList.remove("scrolling-x");
      toolsHiddenByScroll = false;
    }, 200);
  };
  util.img.layoutResizer = function() {
    if (!resizer || !selectedImage || resizer.resizing || !resizer.attached) {
      return;
    }
    if (!resizer.layout()) {
      util.img.setSelected(null);
    }
  };
  util.img.layoutToolbar = function() {
    if (!toolbar || !toolbarImage) {
      return;
    }
    var rect = toolbarImage.getBoundingClientRect();
    if (!rect.width || !rect.height) {
      util.img.setToolbar(null);
    } else {
      var zoom = util.zoomscale.getZoom();
      toolbar.style.zoom = zoom;
      toolbar.style.top = rect.top + util.dom.scrollTop(document.body) / zoom + "px";
      toolbar.style.left = rect.left + "px";
    }
  };
  util.img.getSelectedImage = function() {
    return selectedImage;
  };
  util.img.removeOverlay = function(img) {
    if (util.img.isResource(img) && !!img.style.backgroundImage) {
      img.src = img.getAttribute("data-url");
      img.style.backgroundImage = "";
      img.style.backgroundSize = "";
    }
  };
  util.img.loadAsync = function(src) {
    return new Promise(function(resolve, reject) {
      var img = document.createElement("img");
      img.src = src;
      goog.events.listenOnce(img, "load", function() {
        resolve(img);
      });
      goog.events.listenOnce(img, "error", reject);
    });
  };
  util.img.loadFromClientAsync = function(src, client) {
    var fixtures = client && client.fixtures ? client.fixtures.map : null;
    if (fixtures && fixtures[src]) {
      return new Promise(function(resolve, reject) {
        var img = new Image;
        img.crossOrigin = "Anonymous";
        img.src = fixtures[src];
        goog.events.listenOnce(img, "load", function() {
          resolve(img);
        });
        goog.events.listenOnce(img, "error", reject);
      });
    } else {
      return util.img.loadAsync(src);
    }
  };
  util.img.ratioResizeIfNeeded = function(node) {
    return new Promise(function(resolve) {
      var ratio = util.styles.getDevicePixelRatio();
      if (!util.dom.isImg(node) || !node.parentNode || node.hasAttribute("width") || ratio === 1) {
        resolve(false);
        return;
      }
      var resize = function() {
        var width = Math.round(node.naturalWidth / ratio);
        node.setAttribute("width", width);
        node.setAttribute("data-width", width);
        resolve(node);
      };
      if (node.naturalWidth) {
        resize();
      } else {
        goog.events.listenOnce(node, "load", resize);
      }
    });
  };
  function getScrollableCandidate(node) {
    while (node !== document.body) {
      if (getComputedStyle(node).overflowX !== "visible") {
        return node;
      }
      node = node.parentNode;
    }
    return null;
  }
  util.img.isDraggable = function(node) {
    return util.img.isImage(node);
  };
  util.img.isDroppableTarget = function(node) {
    return true;
  };
  util.img.prepareForDrag = function(state, options) {
    state.itemTypes = [STRUCTTYPES.RESOURCE];
  };
  util.img.getDraggedItems = function(image) {
    return [image];
  };
  util.img.handleDrop = function(event, state, editor) {
    if (state.dropRange) {
      state.dropRange.select();
      var lastInsertedImage;
      goog.array.forEach(state.draggedItems, function(img) {
        var parent = img.parentNode;
        lastInsertedImage = img;
        state.dropRange.insertNode(img);
        if (dom.isEmpty(parent)) {
          util.paragraph.remove(parent);
        }
      });
      if (lastInsertedImage) {
        editor.selectEnd(lastInsertedImage);
      }
    }
  };
})();
goog.provide("uno.i18n.ar");
uno.i18n.ar.textEntries = {"Not available offline":"\u0644\u0627 \u064a\u062a\u0648\u0641\u0631 \u062f\u0648\u0646 \u0627\u062a\u0635\u0627\u0644 \u0628\u0627\u0644\u0625\u0646\u062a\u0631\u0646\u062a", "Not available":"\u063a\u064a\u0631 \u0645\u062a\u0627\u062d", "Tap to request access":"\u0627\u0636\u063a\u0637 \u0644\u0637\u0644\u0628 \u0627\u0644\u0648\u0635\u0648\u0644", "Click to request access":"\u0627\u0636\u063a\u0637 \u0644\u0637\u0644\u0628 \u0627\u0644\u0648\u0635\u0648\u0644", "Open":"\u0641\u062a\u062d", 
"Copy link":"\u0646\u0633\u062e \u0627\u0644\u0631\u0627\u0628\u0637", "Google Drive":"\u062c\u0648\u062c\u0644 \u062f\u0631\u0627\u064a\u0641", "Google Docs":"\u0645\u0633\u062a\u0646\u062f\u0627\u062a \u062c\u0648\u062c\u0644", "Google Sheets":"\u0623\u0648\u0631\u0627\u0642 \u062c\u0648\u062c\u0644", "Google Slides":"\u0634\u0631\u0627\u0626\u062d \u062c\u0648\u062c\u0644", "PDF":"PDF", "Word Document":"\u0645\u0633\u062a\u0646\u062f Word", "Excel Spreadsheet":"\u062c\u062f\u0648\u0644 \u0628\u064a\u0627\u0646\u0627\u062a Excel", 
"Modified":"\u062a\u0645 \u062a\u0639\u062f\u064a\u0644\u0647", "Connect":"\u0627\u062a\u0635\u0627\u0644", "Connect to see more":"\u0627\u0631\u0628\u0637 \u0627\u0644\u062d\u0633\u0627\u0628 \u0644\u0627\u0633\u062a\u0639\u0631\u0627\u0636 \u0627\u0644\u0645\u0632\u064a\u062f", "Connect Google account":"\u0631\u0628\u0637 \u062d\u0633\u0627\u0628 \u062c\u0648\u062c\u0644", "Title not available":"\u0627\u0644\u0639\u0646\u0648\u0627\u0646 \u063a\u064a\u0631 \u0645\u062a\u0627\u062d", "Open containing folder":"\u0641\u062a\u062d \u0627\u0644\u0645\u062c\u0644\u062f \u0627\u0644\u0631\u0626\u064a\u0633\u064a", 
"Cell Background":"\u062e\u0644\u0641\u064a\u0629 \u0627\u0644\u062e\u0644\u064a\u0629", "Cell Alignment":"\u0645\u062e\u0627\u0630\u0627\u0629 \u0627\u0644\u062e\u0644\u064a\u0629", "Align content to top":"\u0645\u062d\u0627\u0630\u0627\u0629 \u0627\u0644\u0645\u062d\u062a\u0648\u0649 \u0644\u0644\u0623\u0639\u0644\u0649", "Align content to center":"\u0645\u062d\u0627\u0630\u0627\u0629 \u0627\u0644\u0645\u062d\u062a\u0648\u0649 \u0644\u0644\u0648\u0633\u0637", "Align content to bottom":"\u0645\u062d\u0627\u0630\u0627\u0629 \u0627\u0644\u0645\u062d\u062a\u0648\u0649 \u0644\u0644\u0623\u0633\u0641\u0644", 
"Distribute Columns Evenly":"\u062a\u0648\u0632\u064a\u0639 \u0627\u0644\u0623\u0639\u0645\u062f\u0629 \u0628\u0627\u0644\u062a\u0633\u0627\u0648\u064a", "Match Note Width":"\u0645\u0637\u0627\u0628\u0642\u0629 \u0639\u0631\u0636 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629", "Delete Selected Column(s)":"\u062d\u0630\u0641 \u0627\u0644\u0623\u0639\u0645\u062f\u0629 \u0627\u0644\u0645\u062d\u062f\u062f\u0629", "Delete Selected Row(s)":"\u062d\u0630\u0641 \u0627\u0644\u0635\u0641\u0648\u0641 \u0627\u0644\u0645\u062d\u062f\u062f\u0629", 
"Delete Table":"\u062d\u0630\u0641 \u0627\u0644\u062c\u062f\u0648\u0644", "Merge Cells":"\u062f\u0645\u062c \u0627\u0644\u062e\u0644\u0627\u064a\u0627", "Unmerge Cells":"\u0625\u0644\u063a\u0627\u0621 \u062f\u0645\u062c \u0627\u0644\u062e\u0644\u0627\u064a\u0627", "Find text in note":"\u0627\u0644\u0628\u062d\u062b \u0639\u0644\u0649 \u0646\u0635 \u0641\u064a \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629", "Next":"\u0627\u0644\u062a\u0627\u0644\u064a", "Previous":"\u0627\u0644\u0633\u0627\u0628\u0642", 
"Match case":"\u0645\u0637\u0627\u0628\u0642\u0629 \u0627\u0644\u062d\u0627\u0644\u0629", "Replace with":"\u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0628\u0640", "Replace":"\u0627\u0633\u062a\u0628\u062f\u0627\u0644", "Replace All":"\u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0627\u0644\u0643\u0644", "No matches found":"\u0644\u0627 \u062a\u0648\u062c\u062f \u0646\u062a\u0627\u0626\u062c \u0645\u0637\u0627\u0628\u0642\u0629", "Match":"\u0645\u0637\u0627\u0628\u0642\u0629", "of":"\u0645\u0646"};
goog.provide("uno.i18n.cs");
uno.i18n.cs.textEntries = {"Not available offline":"Offline nen\u00ed dostupn\u00fd", "Not available":"Nen\u00ed k dispozici", "Tap to request access":"Klepnut\u00edm vy\u017e\u00e1dejte p\u0159\u00edstup", "Click to request access":"Kliknut\u00edm vy\u017e\u00e1dejte p\u0159\u00edstup", "Open":"Otev\u0159\u00edt", "Copy link":"Kop\u00edrovat odkaz", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Dokument aplikace Word", 
"Excel Spreadsheet":"Tabulka v aplikaci Excel", "Modified":"Zm\u011bn\u011bno", "Connect":"P\u0159ipojit", "Connect to see more":"Chcete-li zobrazit v\u00edce, p\u0159ipojte se", "Connect Google account":"P\u0159ipojit \u00fa\u010det Google", "Title not available":"N\u00e1zev nen\u00ed k dispozici", "Open containing folder":"Otev\u0159\u00edt slo\u017eku se soubory", "Cell Background":"Pozad\u00ed bu\u0148ky", "Cell Alignment":"Zarovn\u00e1n\u00ed bu\u0148ky", "Align content to top":"Zarovnat nahoru", 
"Align content to center":"Zarovnat na st\u0159ed", "Align content to bottom":"Zarovnat dol\u016f", "Distribute Columns Evenly":"Rozd\u011blit sloupce rovnom\u011brn\u011b", "Match Note Width":"P\u0159izp\u016fsobit \u0161\u00ed\u0159ku pozn\u00e1mky", "Delete Selected Column(s)":"Odstranit vybran\u00e9 sloupce", "Delete Selected Row(s)":"Odstranit vybran\u00e9 \u0159\u00e1dky", "Delete Table":"Odstranit tabulku", "Merge Cells":"Slou\u010dit bu\u0148ky", "Unmerge Cells":"Zru\u0161it slou\u010den\u00ed bun\u011bk", 
"Find text in note":"Naj\u00edt text v pozn\u00e1mce", "Next":"Dal\u0161\u00ed", "Previous":"P\u0159edchoz\u00ed", "Match case":"Rozli\u0161ovat mal\u00e1 a velk\u00e1 p\u00edsmena", "Replace with":"Nahradit za", "Replace":"Nahradit", "Replace All":"Nahradit v\u0161e", "No matches found":"Nebyly nalezeny \u017e\u00e1dn\u00e9 shody", "Match":"Dle", "of":"z"};
goog.provide("uno.i18n.da");
uno.i18n.da.textEntries = {"Not available offline":"Ikke tilg\u00e6ngelig offline", "Not available":"Ikke tilg\u00e6ngelig", "Tap to request access":"Tryk for at anmode om adgang", "Click to request access":"Klik for at anmode om adgang", "Open":"\u00c5bn", "Copy link":"Kopi\u00e9r link", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Word-dokument", "Excel Spreadsheet":"Excel-regneark", "Modified":"\u00c6ndret", 
"Connect":"Opret forbindelse", "Connect to see more":"Opret forbindelse for at se mere", "Connect Google account":"Tilslut Google-konto", "Title not available":"Titel ikke tilg\u00e6ngelig", "Open containing folder":"\u00c5bn indeholdende mappe", "Cell Background":"Cellebaggrund", "Cell Alignment":"Cellejustering", "Align content to top":"Juster indhold til toppen", "Align content to center":"Juster indhold til midten", "Align content to bottom":"Juster indhold til bunden", "Distribute Columns Evenly":"Fordel kolonner j\u00e6vnt", 
"Match Note Width":"Match notebredde", "Delete Selected Column(s)":"Slet valgte kolonne(r)", "Delete Selected Row(s)":"Slet valgte r\u00e6kker(r)", "Delete Table":"Slet tabel", "Merge Cells":"Sammenflet celler", "Unmerge Cells":"Fortyd sammenfletning af celler", "Find text in note":"Find tekst i note", "Next":"N\u00e6ste", "Previous":"Forrige", "Match case":"Match store/sm\u00e5 bogstaver", "Replace with":"Erstat med", "Replace":"Erstat", "Replace All":"Erstat alle", "No matches found":"Ingen match fundet", 
"Match":"Match", "of":"af"};
goog.provide("uno.i18n.de");
uno.i18n.de.textEntries = {"Not available offline":"Nicht offline verf\u00fcgbar", "Not available":"Nicht verf\u00fcgbar", "Tap to request access":"F\u00fcr Zugriff tippen", "Click to request access":"F\u00fcr Zugriff klicken", "Open":"\u00d6ffnen", "Copy link":"Link kopieren", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Tabellen", "Google Slides":"Google Pr\u00e4sentationen", "PDF":"PDF", "Word Document":"Word-Dokument", "Excel Spreadsheet":"Excel-Tabelle", 
"Modified":"Ge\u00e4ndert", "Connect":"Verkn\u00fcpfen", "Connect to see more":"Verkn\u00fcpfen f\u00fcr erweiterte Ansicht", "Connect Google account":"Google-Konto verkn\u00fcpfen", "Title not available":"Titel nicht verf\u00fcgbar", "Open containing folder":"\u00dcbergeordneten Ordner \u00f6ffnen", "Cell Background":"Zellenhintergrund", "Cell Alignment":"Zellenausrichtung", "Align content to top":"Inhalt oben ausrichten", "Align content to center":"Inhalt zentriert ausrichten", "Align content to bottom":"Inhalt unten ausrichten", 
"Distribute Columns Evenly":"Spalten gleichm\u00e4\u00dfig verteilen", "Match Note Width":"An Notizbreite anpassen", "Delete Selected Column(s)":"Ausgew\u00e4hlte Spalten l\u00f6schen", "Delete Selected Row(s)":"Ausgew\u00e4hlte Zeilen l\u00f6schen", "Delete Table":"Tabelle l\u00f6schen", "Merge Cells":"Zellen verbinden", "Unmerge Cells":"Zellverbund aufheben", "Find text in note":"Text in Notiz suchen", "Next":"Weiter", "Previous":"Zur\u00fcck", "Match case":"Gro\u00df-/Kleinschreibung beachten", 
"Replace with":"Ersetzen durch", "Replace":"Ersetzen", "Replace All":"Alle ersetzen", "No matches found":"Es wurden keine \u00dcbereinstimmungen gefunden", "Match":"Treffer", "of":"von"};
goog.provide("uno.i18n.en");
uno.i18n.en.textEntries = {"Not available offline":"Not available offline", "Not available":"Not available", "Tap to request access":"Tap to request access", "Click to request access":"Click to request access", "Open":"Open", "Copy link":"Copy link", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Word Document", "Excel Spreadsheet":"Excel Spreadsheet", "Modified":"Modified", "Connect":"Connect", 
"Connect to see more":"Connect to see more", "Connect Google account":"Connect Google account", "Title not available":"Title not available", "Open containing folder":"Open containing folder", "Cell Background":"Cell Background", "Cell Alignment":"Cell Alignment", "Align content to top":"Align content to top", "Align content to center":"Align content to center", "Align content to bottom":"Align content to bottom", "Distribute Columns Evenly":"Distribute Columns Evenly", "Match Note Width":"Match Note Width", 
"Delete Selected Column(s)":"Delete Selected Column(s)", "Delete Selected Row(s)":"Delete Selected Row(s)", "Delete Table":"Delete Table", "Merge Cells":"Merge Cells", "Unmerge Cells":"Unmerge Cells", "Find text in note":"Find text in note", "Next":"Next", "Previous":"Previous", "Match case":"Match case", "Replace with":"Replace with", "Replace":"Replace", "Replace All":"Replace All", "No matches found":"No matches found", "Match":"Match", "of":"of"};
goog.provide("uno.i18n.es");
uno.i18n.es.textEntries = {"Not available offline":"No disponible sin conexi\u00f3n", "Not available":"No disponible", "Tap to request access":"Pulsa para solicitar acceso", "Click to request access":"Haz clic para solicitar acceso", "Open":"Abrir", "Copy link":"Copiar enlace", "Google Drive":"Google Drive", "Google Docs":"Documentos de Google", "Google Sheets":"Hojas de c\u00e1lculo de Google", "Google Slides":"Presentaciones de Google", "PDF":"PDF", "Word Document":"Documento Word", "Excel Spreadsheet":"Hoja de c\u00e1lculo Excel", 
"Modified":"Modificado", "Connect":"Conectar", "Connect to see more":"Con\u00e9ctate para ver m\u00e1s", "Connect Google account":"Conectar cuenta de Google", "Title not available":"T\u00edtulo no disponible", "Open containing folder":"Abrir carpeta archivadora de contenidos", "Cell Background":"Fondo de la celda", "Cell Alignment":"Alineaci\u00f3n de la celda", "Align content to top":"Alinear contenido a la parte superior", "Align content to center":"Alinear contenido al centro", "Align content to bottom":"Alinear contenido a la parte inferior", 
"Distribute Columns Evenly":"Distribuir columnas uniformemente", "Match Note Width":"Coincidir con el ancho de nota", "Delete Selected Column(s)":"Eliminar columna(s) seleccionada(s)", "Delete Selected Row(s)":"Eliminar fila(s) seleccionada(s)", "Delete Table":"Eliminar Tabla", "Merge Cells":"Combinar celdas", "Unmerge Cells":"Anular la combinaci\u00f3n de celdas", "Find text in note":"Encuentra texto en una nota", "Next":"Siguiente", "Previous":"Anterior", "Match case":"Coincidir may\u00fasculas y min\u00fasculas", 
"Replace with":"Reemplazar con", "Replace":"Reemplazar", "Replace All":"Reemplazar todo", "No matches found":"No se encontraron coincidencias", "Match":"Coincidencia", "of":"de"};
goog.provide("uno.i18n.fi");
uno.i18n.fi.textEntries = {"Not available offline":"Ei k\u00e4ytett\u00e4viss\u00e4 offline", "Not available":"Ei k\u00e4ytett\u00e4viss\u00e4", "Tap to request access":"Pyyd\u00e4 k\u00e4ytt\u00f6oikeus napauttamalla", "Click to request access":"Napsauta pyyt\u00e4\u00e4ksesi k\u00e4ytt\u00f6oikeuksia", "Open":"Avaa", "Copy link":"Kopioi linkki", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Word-asiakirja", 
"Excel Spreadsheet":"Excel-laskentataulukko", "Modified":"Muokattu", "Connect":"Yhdist\u00e4", "Connect to see more":"Yhdist\u00e4 n\u00e4hd\u00e4ksesi enemm\u00e4n", "Connect Google account":"Yhdist\u00e4 Google-tili", "Title not available":"Otsikko ei saatavilla", "Open containing folder":"Avaa tallennuskansio", "Cell Background":"Solun tausta", "Cell Alignment":"Solun tasaus", "Align content to top":"Tasaa sis\u00e4lt\u00f6 yl\u00e4osaan", "Align content to center":"Tasaa sis\u00e4lt\u00f6 keskelle", 
"Align content to bottom":"Tasaa sis\u00e4lt\u00f6 alaosaan", "Distribute Columns Evenly":"Muuta sarakkeet tasalevyisiksi", "Match Note Width":"T\u00e4sm\u00e4\u00e4 muistiinpanon leveys", "Delete Selected Column(s)":"Poista valitut sarakkeet", "Delete Selected Row(s)":"Poista valitut rivit", "Delete Table":"Poista taulukko", "Merge Cells":"Yhdist\u00e4 solut", "Unmerge Cells":"Pura solujen yhdist\u00e4minen", "Find text in note":"Etsi teksti\u00e4 muistiinpanosta", "Next":"Seuraava", "Previous":"Edellinen", 
"Match case":"Sama kirjainkoko", "Replace with":"Korvaa kohteella", "Replace":"Korvaa", "Replace All":"Korvaa kaikki", "No matches found":"Osumia ei l\u00f6ytynyt", "Match":"Osuma", "of":"/"};
goog.provide("uno.i18n.fr");
uno.i18n.fr.textEntries = {"Not available offline":"Non disponible hors-ligne", "Not available":"Indisponible", "Tap to request access":"Appuyez pour demander l'acc\u00e8s", "Click to request access":"Cliquez pour demander l'acc\u00e8s", "Open":"Ouvrir", "Copy link":"Copier le lien", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Document Word", "Excel Spreadsheet":"Feuille de calcul Excel", 
"Modified":"Modifi\u00e9", "Connect":"Connecter", "Connect to see more":"Connectez-vous pour en voir davantage", "Connect Google account":"Connecter un compte Google", "Title not available":"Titre non disponible", "Open containing folder":"Ouvrir le dossier conteneur", "Cell Background":"Arri\u00e8re-plan de cellule", "Cell Alignment":"Alignement de cellule", "Align content to top":"Aligner le contenu en haut", "Align content to center":"Aligner le contenu au centre", "Align content to bottom":"Aligner le contenu en bas", 
"Distribute Columns Evenly":"Uniformiser la largeur des colonnes", "Match Note Width":"Respecter la largeur de la note", "Delete Selected Column(s)":"Supprimer la ou les colonne(s) s\u00e9lectionn\u00e9e(s)", "Delete Selected Row(s)":"Supprimer la ou les ligne(s) s\u00e9lectionn\u00e9e(s)", "Delete Table":"Supprimer le tableau", "Merge Cells":"Fusionner les cellules", "Unmerge Cells":"Annuler Fusionner les cellules", "Find text in note":"Trouver du texte dans la note", "Next":"Suivant", "Previous":"Pr\u00e9c\u00e9dent", 
"Match case":"Respecter la casse", "Replace with":"Remplacer par", "Replace":"Remplacer", "Replace All":"Tout remplacer", "No matches found":"Aucune correspondance trouv\u00e9e", "Match":"Correspondance", "of":"de"};
goog.provide("uno.i18n.id");
uno.i18n.id.textEntries = {"Not available offline":"Tidak tersedia offline", "Not available":"Tidak tersedia", "Tap to request access":"Tekan untuk meminta akses", "Click to request access":"Klik untuk meminta akses", "Open":"Buka", "Copy link":"Salin tautan", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Dokumen Word", "Excel Spreadsheet":"Lembar Lajur Excel", "Modified":"Diubah", "Connect":"Sambungkan", 
"Connect to see more":"Sambungkan untuk melihat lebih banyak", "Connect Google account":"Sambungkan akun Google", "Title not available":"Judul tidak tersedia", "Open containing folder":"Buka map yang menampung", "Cell Background":"Latar Belakang Sel", "Cell Alignment":"Perataan Sel", "Align content to top":"Ratakan konten ke atas", "Align content to center":"Ratakan konten ke tengah", "Align content to bottom":"Ratakan konten ke bawah", "Distribute Columns Evenly":"Distribusikan Kolom Merata", "Match Note Width":"Sesuaikan Lebar Catatan", 
"Delete Selected Column(s)":"Hapus Kolom yang Dipilih", "Delete Selected Row(s)":"Hapus Baris yang Dipilih", "Delete Table":"Hapus Tabel", "Merge Cells":"Gabungkan Sel", "Unmerge Cells":"Batalkan Penggabungan Sel", "Find text in note":"Temukan teks dalam catatan", "Next":"Berikutnya", "Previous":"Sebelumnya", "Match case":"Sama persis", "Replace with":"Gantikan dengan", "Replace":"Ganti", "Replace All":"Ganti Semua", "No matches found":"Tidak ditemukan yang cocok", "Match":"Cocokkan", "of":"dari"};
goog.provide("uno.i18n.it");
uno.i18n.it.textEntries = {"Not available offline":"Non disponibile offline", "Not available":"Non disponibile", "Tap to request access":"Tocca per richiedere accesso", "Click to request access":"Clicca per richiedere accesso", "Open":"Apri", "Copy link":"Copia link", "Google Drive":"Google Drive", "Google Docs":"Documenti Google", "Google Sheets":"Fogli Google", "Google Slides":"Presentazioni Google", "PDF":"PDF", "Word Document":"Documento di Word", "Excel Spreadsheet":"Foglio di lavoro di Excel", 
"Modified":"Modificato", "Connect":"Connettiti", "Connect to see more":"Connettitti per vedere di pi\u00f9", "Connect Google account":"Collega account Google", "Title not available":"Titolo non disponibile", "Open containing folder":"Apri cartella contenente", "Cell Background":"Sfondo cella", "Cell Alignment":"Allineamento cella", "Align content to top":"Allineare il contenuto in alto", "Align content to center":"Allineare contenuto al centro", "Align content to bottom":"Allineare il contenuto in basso", 
"Distribute Columns Evenly":"Distribuire colonne uniformemente", "Match Note Width":"Adegua alla larghezza della nota", "Delete Selected Column(s)":"Eliminare colonne selezionate", "Delete Selected Row(s)":"Eliminare righe selezionate", "Delete Table":"Eliminare Tabella", "Merge Cells":"Unire celle", "Unmerge Cells":"Annulla unione celle", "Find text in note":"Find text in note", "Next":"Next", "Previous":"Previous", "Match case":"Maiuscola/minuscola corrispondente", "Replace with":"Sostituisci con", 
"Replace":"Replace", "Replace All":"Sostituisci tutto", "No matches found":"Nessuna corrispondenza trovata", "Match":"Confronta", "of":"di"};
goog.provide("uno.i18n.ja");
uno.i18n.ja.textEntries = {"Not available offline":"\u30aa\u30d5\u30e9\u30a4\u30f3\u3067\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093", "Not available":"\u5229\u7528\u3067\u304d\u307e\u305b\u3093", "Tap to request access":"\u30bf\u30c3\u30d7\u3067\u30a2\u30af\u30bb\u30b9\u6a29\u3092\u30ea\u30af\u30a8\u30b9\u30c8", "Click to request access":"\u30af\u30ea\u30c3\u30af\u3067\u30a2\u30af\u30bb\u30b9\u6a29\u3092\u30ea\u30af\u30a8\u30b9\u30c8", "Open":"\u958b\u304f", "Copy link":"\u30ea\u30f3\u30af\u3092\u30b3\u30d4\u30fc", 
"Google Drive":"Google \u30c9\u30e9\u30a4\u30d6", "Google Docs":"Google \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8", "Google Sheets":"Google \u30b9\u30d7\u30ec\u30c3\u30c9\u30b7\u30fc\u30c8", "Google Slides":"Google \u30b9\u30e9\u30a4\u30c9", "PDF":"PDF", "Word Document":"Word \u6587\u66f8", "Excel Spreadsheet":"Excel \u30b9\u30d7\u30ec\u30c3\u30c9\u30b7\u30fc\u30c8", "Modified":"\u5909\u66f4", "Connect":"\u63a5\u7d9a", "Connect to see more":"\u63a5\u7d9a\u3057\u3066\u8a73\u7d30\u3092\u898b\u308b", "Connect Google account":"Google \u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u63a5\u7d9a", 
"Title not available":"\u30bf\u30a4\u30c8\u30eb\u3092\u8868\u793a\u3067\u304d\u307e\u305b\u3093", "Open containing folder":"\u30d5\u30a9\u30eb\u30c0\u3092\u958b\u304f", "Cell Background":"\u30bb\u30eb\u306e\u80cc\u666f", "Cell Alignment":"\u30bb\u30eb\u306e\u914d\u7f6e", "Align content to top":"\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u4e0a\u5074\u306b\u914d\u7f6e", "Align content to center":"\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u4e2d\u592e\u306b\u914d\u7f6e", "Align content to bottom":"\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u4e0b\u5074\u306b\u914d\u7f6e", 
"Distribute Columns Evenly":"\u5217\u306e\u5e45\u3092\u5747\u7b49\u5316", "Match Note Width":"\u30ce\u30fc\u30c8\u306e\u5e45\u306b\u5408\u308f\u305b\u308b", "Delete Selected Column(s)":"\u9078\u629e\u3057\u305f\u5217\u3092\u524a\u9664", "Delete Selected Row(s)":"\u9078\u629e\u3057\u305f\u884c\u3092\u524a\u9664", "Delete Table":"\u8868\u3092\u524a\u9664", "Merge Cells":"\u30bb\u30eb\u3092\u7d50\u5408", "Unmerge Cells":"\u30bb\u30eb\u306e\u7d50\u5408\u3092\u89e3\u9664", "Find text in note":"\u30ce\u30fc\u30c8\u5185\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u691c\u7d22", 
"Next":"\u6b21", "Previous":"\u524d", "Match case":"\u5927\u6587\u5b57\u3068\u5c0f\u6587\u5b57\u3092\u533a\u5225\u3059\u308b", "Replace with":"\u6b21\u3068\u7f6e\u63db:", "Replace":"\u7f6e\u63db", "Replace All":"\u3059\u3079\u3066\u7f6e\u63db", "No matches found":"\u8a72\u5f53\u306a\u3057", "Match":"\u4e00\u81f4", "of":"/"};
goog.provide("uno.i18n.ko");
uno.i18n.ko.textEntries = {"Not available offline":"\uc624\ud504\ub77c\uc778\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc74c", "Not available":"\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4", "Tap to request access":"\ub20c\ub7ec\uc11c \uc561\uc138\uc2a4 \uc694\uccad", "Click to request access":"\ud074\ub9ad\ud558\uc5ec \uc561\uc138\uc2a4 \uc694\uccad", "Open":"\uc5f4\uae30", "Copy link":"\ub9c1\ud06c \ubcf5\uc0ac", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", 
"Google Slides":"Google \ud504\ub808\uc820\ud14c\uc774\uc158", "PDF":"PDF", "Word Document":"Word \ubb38\uc11c", "Excel Spreadsheet":"Excel \uc2a4\ud504\ub808\ub4dc\uc2dc\ud2b8", "Modified":"\uc218\uc815", "Connect":"\uc5f0\uacb0", "Connect to see more":"\ub354 \ubcf4\ub824\uba74 \uc5f0\uacb0\ud558\uc138\uc694", "Connect Google account":"Google \uacc4\uc815 \uc5f0\uacb0", "Title not available":"\uc81c\ubaa9 \uc54c \uc218 \uc5c6\uc74c", "Open containing folder":"\ud3ec\ud568 \ud3f4\ub354 \uc5f4\uae30", 
"Cell Background":"\uc140 \ubc30\uacbd", "Cell Alignment":"\uc140 \uc815\ub82c", "Align content to top":"\uc704\ucabd \ub9de\ucda4", "Align content to center":"\uac00\uc6b4\ub370 \ub9de\ucda4", "Align content to bottom":"\uc544\ub798\ucabd \ub9de\ucda4", "Distribute Columns Evenly":"\uc5f4 \ub108\ube44\ub97c \uac19\uac8c", "Match Note Width":"\ub178\ud2b8 \ud3ed\uc5d0 \ub9de\ucda4", "Delete Selected Column(s)":"\uc120\ud0dd\ud55c \uc5f4 \uc0ad\uc81c", "Delete Selected Row(s)":"\uc120\ud0dd\ud55c \ud589 \uc0ad\uc81c", 
"Delete Table":"\ud45c \uc0ad\uc81c", "Merge Cells":"\uc140 \ud569\uce58\uae30", "Unmerge Cells":"\uc140 \ud569\uce58\uae30 \ucde8\uc18c", "Find text in note":"\ub178\ud2b8\uc5d0\uc11c \ud14d\uc2a4\ud2b8 \ucc3e\uae30", "Next":"\ub2e4\uc74c", "Previous":"\uc774\uc804", "Match case":"\ub300\uc18c\ubb38\uc790 \uc77c\uce58", "Replace with":"\ubc14\uafb8\uae30", "Replace":"\ubc14\uafb8\uae30", "Replace All":"\ubaa8\ub450 \ubc14\uafb8\uae30", "No matches found":"\uc77c\uce58 \ud56d\ubaa9\uc774 \uc5c6\uc2b5\ub2c8\ub2e4", 
"Match":"\uc77c\uce58", "of":"\uc758"};
goog.provide("uno.i18n.ms");
uno.i18n.ms.textEntries = {"Not available offline":"Tidak tersedia di luar talian", "Not available":"Tidak tersedia", "Tap to request access":"Ketik untuk meminta akses", "Click to request access":"Klik untuk meminta akses", "Open":"Buka", "Copy link":"Salin pautan", "Google Drive":"Google Drive", "Google Docs":"Dokumen Google", "Google Sheets":"Helaian Google", "Google Slides":"Slaid Google", "PDF":"PDF", "Word Document":"Dokumen Word", "Excel Spreadsheet":"Hamparan Excel", "Modified":"Diubah suai", 
"Connect":"Sambung", "Connect to see more":"Sambung untuk melihat lebih banyak", "Connect Google account":"Sambung ke akaun Google", "Title not available":"Tajuk tidak tersedia", "Open containing folder":"Buka folder yang mengandungi", "Cell Background":"Latar Belakang Sel", "Cell Alignment":"Penjajaran Sel", "Align content to top":"Jajarkan kandungan ke atas", "Align content to center":"Jajarkan kandungan ke tengah", "Align content to bottom":"Jajarkan kandungan ke bawah", "Distribute Columns Evenly":"Jajarkan Lajur Secara Sama Rata", 
"Match Note Width":"Padankan Lebar Nota", "Delete Selected Column(s)":"Padamkan Lajur Dipilih", "Delete Selected Row(s)":"Padamkan Baris Dipilih", "Delete Table":"Padam Jadual", "Merge Cells":"Gabung Sel", "Unmerge Cells":"Leraikan Sel", "Find text in note":"Dapatkan teks dalam nota", "Next":"Seterusnya", "Previous":"Sebelumnya", "Match case":"Kes sepadan", "Replace with":"Gantikan dengan", "Replace":"Ganti", "Replace All":"Gantikan Semua", "No matches found":"Padanan tidak ditemui", "Match":"Padan", 
"of":"daripada"};
goog.provide("uno.i18n.nl");
uno.i18n.nl.textEntries = {"Not available offline":"Niet offline beschikbaar", "Not available":"Niet beschikbaar", "Tap to request access":"Tik om toegang aan te vragen", "Click to request access":"Klik om toegang aan te vragen", "Open":"Open", "Copy link":"Kopieer link", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Word-document", "Excel Spreadsheet":"Excel-spreadsheet", "Modified":"Aangepast", 
"Connect":"Koppel", "Connect to see more":"Koppel om meer te zien", "Connect Google account":"Koppel Google account", "Title not available":"Titel niet beschikbaar", "Open containing folder":"Open bijbehorende map", "Cell Background":"Achtergrond cel", "Cell Alignment":"Uitlijning cel", "Align content to top":"Lijn content bovenin uit", "Align content to center":"Lijn content uit in het midden", "Align content to bottom":"Lijn content onderin uit", "Distribute Columns Evenly":"Verdeel kolommen gelijkmatig", 
"Match Note Width":"Pas notitiebreedte aan", "Delete Selected Column(s)":"Verwijder geselecteerde kolom(men)", "Delete Selected Row(s)":"Verwijder geselecteerde rij(en)", "Delete Table":"Verwijder tabel", "Merge Cells":"Voeg cellen samen", "Unmerge Cells":"Voeg cellen niet meer samen", "Find text in note":"Zoek naar tekst in notitie", "Next":"Volgende", "Previous":"Vorige", "Match case":"Hoofdlettergevoelig", "Replace with":"Vervang met", "Replace":"Vervang", "Replace All":"Vervang alles", "No matches found":"Geen overeenkomsten gevonden", 
"Match":"Treffer", "of":"van"};
goog.provide("uno.i18n.no");
uno.i18n.no.textEntries = {"Not available offline":"Ikke tilgjengelig offline", "Not available":"Ikke tilgjengelig", "Tap to request access":"Trykk for \u00e5 be om tilgang", "Click to request access":"Klikk for \u00e5 be om tilgang", "Open":"\u00c5pne", "Copy link":"Kopier lenke", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Word-dokument", "Excel Spreadsheet":"Excel regneark", "Modified":"Modifisert", 
"Connect":"Koble til", "Connect to see more":"Koble til for \u00e5 se mer", "Connect Google account":"Koble til Google-konto", "Title not available":"Tittel ikke tilgjengelig", "Open containing folder":"\u00c5pne mappe med innhold", "Cell Background":"Cellebakgrunn", "Cell Alignment":"Cellejustering", "Align content to top":"Toppjuster innhold", "Align content to center":"Midtstill innhold", "Align content to bottom":"Bunnjuster innhold", "Distribute Columns Evenly":"Distribuer kolonner jevnt", "Match Note Width":"Tilpass notatbredde", 
"Delete Selected Column(s)":"Slett valgt(e) kolonne(r)", "Delete Selected Row(s)":"Slett valgt(e) rad(er)", "Delete Table":"Slett tabell", "Merge Cells":"Sl\u00e5 sammen celler", "Unmerge Cells":"Del celler", "Find text in note":"Finn tekst i notat", "Next":"Neste", "Previous":"Forrige", "Match case":"Skill mellom store/sm\u00e5 bokstaver", "Replace with":"Erstatt med", "Replace":"Erstatt", "Replace All":"Erstatt alle", "No matches found":"Finner ingen treff", "Match":"Treff", "of":"i"};
goog.provide("uno.i18n.pl");
uno.i18n.pl.textEntries = {"Not available offline":"Niedost\u0119pne w trybie offline", "Not available":"Niedost\u0119pne", "Tap to request access":"Dotknij, aby za\u017c\u0105da\u0107 dost\u0119pu", "Click to request access":"Kliknij, aby poprosi\u0107 o dost\u0119p", "Open":"Otw\u00f3rz", "Copy link":"Kopiuj \u0142\u0105cze", "Google Drive":"Dysk Google", "Google Docs":"Dokumenty Google", "Google Sheets":"Arkusze Google", "Google Slides":"Prezentacje Google", "PDF":"PDF", "Word Document":"Dokument Word", 
"Excel Spreadsheet":"Arkusz Excel", "Modified":"Edytowany", "Connect":"Po\u0142\u0105cz", "Connect to see more":"Po\u0142\u0105cz, aby zobaczy\u0107 wi\u0119cej", "Connect Google account":"Po\u0142\u0105cz z kontem Google", "Title not available":"Nazwa jest niedost\u0119pna", "Open containing folder":"Otw\u00f3rz folder zawieraj\u0105cy", "Cell Background":"T\u0142o kom\u00f3rki", "Cell Alignment":"Wyr\u00f3wnanie kom\u00f3rki", "Align content to top":"Wyr\u00f3wnaj zawarto\u015b\u0107 do g\u00f3ry", 
"Align content to center":"Wyr\u00f3wnaj zawarto\u015b\u0107 do \u015brodka", "Align content to bottom":"Wyr\u00f3wnaj zawarto\u015b\u0107 do do\u0142u", "Distribute Columns Evenly":"Roz\u0142\u00f3\u017c kolumny r\u00f3wnomiernie", "Match Note Width":"Dopasuj do szeroko\u015bci notatki", "Delete Selected Column(s)":"Usu\u0144 zaznaczon\u0105 kolumn\u0119", "Delete Selected Row(s)":"Usu\u0144 zaznaczony wiersz", "Delete Table":"Usu\u0144 tabel\u0119", "Merge Cells":"Po\u0142\u0105cz kom\u00f3rki", 
"Unmerge Cells":"Roz\u0142\u0105cz kom\u00f3rki", "Find text in note":"Poszukaj tekstu w notatce", "Next":"Dalej", "Previous":"Wstecz", "Match case":"Uwzgl\u0119dnij wielko\u015b\u0107 liter", "Replace with":"Zamie\u0144 na", "Replace":"Zamie\u0144", "Replace All":"Zamie\u0144 wszystko", "No matches found":"Nie znaleziono dopasowa\u0144", "Match":"Dopasowanie", "of":"z"};
goog.provide("uno.i18n.pt_BR");
uno.i18n.pt_BR.textEntries = {"Not available offline":"N\u00e3o dispon\u00edvel offline", "Not available":"N\u00e3o est\u00e1 dispon\u00edvel", "Tap to request access":"Toque para solicitar acesso", "Click to request access":"Clique para solicitar acesso", "Open":"Abrir", "Copy link":"Copiar link", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Planilhas do Google", "Google Slides":"Apresenta\u00e7\u00f5es do Google", "PDF":"PDF", "Word Document":"Documento do Word", 
"Excel Spreadsheet":"Planilha do Excel", "Modified":"Modificado em", "Connect":"Conectar", "Connect to see more":"Conecte-se para ver mais", "Connect Google account":"Conectar conta do Google", "Title not available":"T\u00edtulo n\u00e3o dispon\u00edvel", "Open containing folder":"Abrir pasta de destino", "Cell Background":"Fundo da C\u00e9lula", "Cell Alignment":"Alinhamento da C\u00e9lula", "Align content to top":"Alinhar conte\u00fado no topo", "Align content to center":"Alinhar conte\u00fado no centro", 
"Align content to bottom":"Alinhar conte\u00fado embaixo", "Distribute Columns Evenly":"Distribuir Colunas Igualmente", "Match Note Width":"Igualar Largura da Coluna", "Delete Selected Column(s)":"Excluir Coluna(s) Selecionada(s)", "Delete Selected Row(s)":"Excluir Linha(s) Selecionada(s)", "Delete Table":"Excluir Tabela", "Merge Cells":"Mesclar C\u00e9lulas", "Unmerge Cells":"Desfazer Mesclagem de C\u00e9lulas", "Find text in note":"Encontrar texto na nota", "Next":"Pr\u00f3ximo", "Previous":"Anterior", 
"Match case":"Correspondentes", "Replace with":"Substituir por", "Replace":"Substituir", "Replace All":"Substituir Todos", "No matches found":"Nenhuma ocorr\u00eancia encontrada", "Match":"Combinar", "of":"de"};
goog.provide("uno.i18n.pt");
uno.i18n.pt.textEntries = {"Not available offline":"Indispon\u00edvel no modo off-line", "Not available":"Indispon\u00edvel", "Tap to request access":"Toque para solicitar acesso", "Click to request access":"Clique para solicitar acesso", "Open":"Abrir", "Copy link":"Copiar liga\u00e7\u00e3o", "Google Drive":"Google Drive", "Google Docs":"Documentos do Google", "Google Sheets":"Folhas de c\u00e1lculo do Google", "Google Slides":"Apresenta\u00e7\u00f5es do Google", "PDF":"PDF", "Word Document":"Documento do Word", 
"Excel Spreadsheet":"Tabela do Excel", "Modified":"Modificado em", "Connect":"Ligar", "Connect to see more":"Ligue para ver mais", "Connect Google account":"Ligar \u00e0 conta Google", "Title not available":"T\u00edtulo indispon\u00edvel", "Open containing folder":"Abrir pasta de destino", "Cell Background":"Fundo da c\u00e9lula", "Cell Alignment":"Alinhamento da c\u00e9lula", "Align content to top":"Alinhar conte\u00fado no topo", "Align content to center":"Alinhar conte\u00fado ao centro", "Align content to bottom":"Alinhar conte\u00fado no fundo", 
"Distribute Columns Evenly":"Distribuir colunas uniformemente", "Match Note Width":"Ajustar largura da nota", "Delete Selected Column(s)":"Eliminar a(s) coluna(s) selecionada(s)", "Delete Selected Row(s)":"Eliminar a(s) linha(s) selecionada(s)", "Delete Table":"Eliminar tabela", "Merge Cells":"Fundir c\u00e9lulas", "Unmerge Cells":"Desfazer c\u00e9lulas fundidas", "Find text in note":"Encontrar texto na nota", "Next":"Seguinte", "Previous":"Anterior", "Match case":"Correspondentes", "Replace with":"Substituir por", 
"Replace":"Substituir", "Replace All":"Substituir Todos", "No matches found":"N\u00e3o foram encontrados resultados", "Match":"Corresponde", "of":"de"};
goog.provide("uno.i18n.ru");
uno.i18n.ru.textEntries = {"Not available offline":"\u041d\u0435\u0442 \u043e\u0444\u043b\u0430\u0439\u043d-\u0434\u043e\u0441\u0442\u0443\u043f\u0430", "Not available":"\u041d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d", "Tap to request access":"\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430", "Click to request access":"\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430", 
"Open":"\u041e\u0442\u043a\u0440\u044b\u0442\u044c", "Copy link":"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 Word", "Excel Spreadsheet":"\u0422\u0430\u0431\u043b\u0438\u0446\u0430 Excel", "Modified":"\u0418\u0437\u043c\u0435\u043d\u0435\u043d", 
"Connect":"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c", "Connect to see more":"\u0412\u043e\u0439\u0442\u0438 \u0432 Google Drive", "Connect Google account":"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u043a\u043a\u0430\u0443\u043d\u0442 Google", "Title not available":"\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e", "Open containing folder":"\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043f\u043a\u0443", 
"Cell Background":"\u0424\u043e\u043d \u044f\u0447\u0435\u0439\u043a\u0438", "Cell Alignment":"\u0412\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u044f\u0447\u0435\u0439\u043a\u0438", "Align content to top":"\u0412\u044b\u0440\u043e\u0432\u043d\u044f\u0442\u044c \u043f\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u043c\u0443 \u043a\u0440\u0430\u044e", "Align content to center":"\u0412\u044b\u0440\u043e\u0432\u043d\u044f\u0442\u044c \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443", 
"Align content to bottom":"\u0412\u044b\u0440\u043e\u0432\u043d\u044f\u0442\u044c \u043f\u043e \u043d\u0438\u0436\u043d\u0435\u043c\u0443 \u043a\u0440\u0430\u044e", "Distribute Columns Evenly":"\u0412\u044b\u0440\u043e\u0432\u043d\u044f\u0442\u044c \u0448\u0438\u0440\u0438\u043d\u0443 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432", "Match Note Width":"\u0420\u0430\u0437\u043c\u0435\u0440 \u043f\u043e \u0448\u0438\u0440\u0438\u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u043a\u0438", "Delete Selected Column(s)":"\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446", 
"Delete Selected Row(s)":"\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443", "Delete Table":"\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443", "Merge Cells":"\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u044f\u0447\u0435\u0439\u043a\u0438", "Unmerge Cells":"\u0420\u0430\u0437\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u044f\u0447\u0435\u0439\u043a\u0438", 
"Find text in note":"\u041d\u0430\u0445\u043e\u0434\u0438\u0442\u0435 \u0442\u0435\u043a\u0441\u0442 \u0432 \u0437\u0430\u043c\u0435\u0442\u043a\u0435", "Next":"\u0414\u0430\u043b\u0435\u0435", "Previous":"\u041d\u0430\u0437\u0430\u0434", "Match case":"\u0421 \u0443\u0447\u0435\u0442\u043e\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430", "Replace with":"\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430", "Replace":"\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c", "Replace All":"\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0435", 
"No matches found":"\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b", "Match":"\u0421\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435", "of":"\u0438\u0437"};
goog.provide("uno.i18n.sv");
uno.i18n.sv.textEntries = {"Not available offline":"Ej tillg\u00e4nglig offline", "Not available":"Ej tillg\u00e4ngligt", "Tap to request access":"Tryck f\u00f6r att beg\u00e4ra \u00e5tkomst", "Click to request access":"Klicka f\u00f6r att beg\u00e4ra \u00e5tkomst", "Open":"\u00d6ppna", "Copy link":"Kopiera l\u00e4nk", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Word-dokument", "Excel Spreadsheet":"Excel-kalkylblad", 
"Modified":"\u00c4ndrad", "Connect":"Anslut", "Connect to see more":"Anslut n\u00e4r du vill se mer", "Connect Google account":"Anslut Google-konto", "Title not available":"Titeln finns inte", "Open containing folder":"\u00d6ppna objektets mapp", "Cell Background":"Cellbakgrund", "Cell Alignment":"Celljustering", "Align content to top":"Justera inneh\u00e5ll upp\u00e5t", "Align content to center":"Justera inneh\u00e5ll \u00e5t mitten", "Align content to bottom":"Justera inneh\u00e5ll ned\u00e5t", 
"Distribute Columns Evenly":"F\u00f6rdela kolumner j\u00e4mnt", "Match Note Width":"Matcha anteckningens bredd", "Delete Selected Column(s)":"Radera markerade kolumner", "Delete Selected Row(s)":"Radera markerade rader", "Delete Table":"Radera tabell", "Merge Cells":"Sammanfoga celler", "Unmerge Cells":"Separera celler", "Find text in note":"Hitta text i anteckning", "Next":"N\u00e4sta", "Previous":"F\u00f6reg\u00e5ende", "Match case":"Matcha gemener/VERSALER", "Replace with":"Ers\u00e4tt med", "Replace":"Ers\u00e4tt", 
"Replace All":"Ers\u00e4tt alla", "No matches found":"Inga tr\u00e4ffar hittades", "Match":"Tr\u00e4ff", "of":"av"};
goog.provide("uno.i18n.th");
uno.i18n.th.textEntries = {"Not available offline":"\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e15\u0e2d\u0e19\u0e2d\u0e2d\u0e1f\u0e44\u0e25\u0e19\u0e4c\u0e44\u0e14\u0e49", "Not available":"\u0e44\u0e21\u0e48\u0e21\u0e35", "Tap to request access":"\u0e41\u0e15\u0e30\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e02\u0e2d\u0e40\u0e02\u0e49\u0e32\u0e16\u0e36\u0e07", "Click to request access":"\u0e04\u0e25\u0e34\u0e4a\u0e01\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e02\u0e2d\u0e40\u0e02\u0e49\u0e32\u0e16\u0e36\u0e07", 
"Open":"\u0e40\u0e1b\u0e34\u0e14", "Copy link":"\u0e04\u0e31\u0e14\u0e25\u0e2d\u0e01\u0e25\u0e34\u0e07\u0e01\u0e4c", "Google Drive":"Google Drive", "Google Docs":"Google Docs", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"\u0e40\u0e2d\u0e01\u0e2a\u0e32\u0e23 Word", "Excel Spreadsheet":"\u0e2a\u0e40\u0e1b\u0e23\u0e14\u0e0a\u0e35\u0e17 Excel", "Modified":"\u0e1b\u0e23\u0e31\u0e1a\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e41\u0e25\u0e49\u0e27", "Connect":"\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d", 
"Connect to see more":"\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e14\u0e39\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e15\u0e34\u0e21", "Connect Google account":"\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d\u0e1a\u0e31\u0e0d\u0e0a\u0e35 Google", "Title not available":"\u0e44\u0e21\u0e48\u0e21\u0e35\u0e0a\u0e37\u0e48\u0e2d", "Open containing folder":"\u0e40\u0e1b\u0e34\u0e14\u0e41\u0e1f\u0e49\u0e21\u0e40\u0e2d\u0e01\u0e2a\u0e32\u0e23\u0e17\u0e35\u0e48\u0e40\u0e01\u0e47\u0e1a", 
"Cell Background":"\u0e1e\u0e37\u0e49\u0e19\u0e2b\u0e25\u0e31\u0e07\u0e02\u0e2d\u0e07\u0e0a\u0e48\u0e2d\u0e07\u0e15\u0e32\u0e23\u0e32\u0e07", "Cell Alignment":"\u0e01\u0e32\u0e23\u0e08\u0e31\u0e14\u0e41\u0e19\u0e27\u0e02\u0e2d\u0e07\u0e0a\u0e48\u0e2d\u0e07\u0e15\u0e32\u0e23\u0e32\u0e07", "Align content to top":"\u0e08\u0e31\u0e14\u0e41\u0e19\u0e27\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e44\u0e27\u0e49\u0e14\u0e49\u0e32\u0e19\u0e1a\u0e19\u0e2a\u0e38\u0e14", "Align content to center":"\u0e08\u0e31\u0e14\u0e41\u0e19\u0e27\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e44\u0e27\u0e49\u0e15\u0e23\u0e07\u0e01\u0e25\u0e32\u0e07", 
"Align content to bottom":"\u0e08\u0e31\u0e14\u0e41\u0e19\u0e27\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e44\u0e27\u0e49\u0e14\u0e49\u0e32\u0e19\u0e25\u0e48\u0e32\u0e07\u0e2a\u0e38\u0e14", "Distribute Columns Evenly":"\u0e17\u0e33\u0e43\u0e2b\u0e49\u0e0a\u0e48\u0e2d\u0e07\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c\u0e21\u0e35\u0e02\u0e19\u0e32\u0e14\u0e40\u0e17\u0e48\u0e32\u0e01\u0e31\u0e19\u0e2b\u0e21\u0e14", "Match Note Width":"\u0e08\u0e31\u0e14\u0e04\u0e27\u0e32\u0e21\u0e01\u0e27\u0e49\u0e32\u0e07\u0e02\u0e2d\u0e07\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e43\u0e2b\u0e49\u0e1e\u0e2d\u0e14\u0e35", 
"Delete Selected Column(s)":"\u0e25\u0e1a\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c\u0e17\u0e35\u0e48\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e44\u0e27\u0e49", "Delete Selected Row(s)":"\u0e25\u0e1a\u0e41\u0e16\u0e27\u0e17\u0e35\u0e48\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e44\u0e27\u0e49", "Delete Table":"\u0e25\u0e1a\u0e15\u0e32\u0e23\u0e32\u0e07", "Merge Cells":"\u0e23\u0e27\u0e21\u0e40\u0e0b\u0e25\u0e25\u0e4c", "Unmerge Cells":"\u0e41\u0e22\u0e01\u0e40\u0e0b\u0e25\u0e25\u0e4c", "Find text in note":"\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e43\u0e19\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e22\u0e48\u0e2d", 
"Next":"\u0e16\u0e31\u0e14\u0e44\u0e1b", "Previous":"\u0e01\u0e48\u0e2d\u0e19\u0e2b\u0e19\u0e49\u0e32\u0e19\u0e35\u0e49", "Match case":"\u0e15\u0e23\u0e07\u0e15\u0e32\u0e21\u0e15\u0e31\u0e27\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e43\u0e2b\u0e0d\u0e48-\u0e40\u0e25\u0e47\u0e01", "Replace with":"\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48\u0e14\u0e49\u0e27\u0e22", "Replace":"\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48", "Replace All":"\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14", "No matches found":"\u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48\u0e15\u0e23\u0e07\u0e01\u0e31\u0e19", 
"Match":"\u0e15\u0e23\u0e07", "of":"\u0e02\u0e2d\u0e07"};
goog.provide("uno.i18n.tr");
uno.i18n.tr.textEntries = {"Not available offline":"\u00c7evrimd\u0131\u015f\u0131 kullan\u0131lamaz", "Not available":"Eri\u015fim sa\u011flanam\u0131yor", "Tap to request access":"Eri\u015fim talebi i\u00e7in t\u0131klay\u0131n", "Click to request access":"Eri\u015fim talebi i\u00e7in t\u0131klay\u0131n", "Open":"A\u00e7", "Copy link":"Ba\u011flant\u0131y\u0131 kopyala", "Google Drive":"Google Drive", "Google Docs":"Google Dok\u00fcmanlar", "Google Sheets":"Google E-Tablolar", "Google Slides":"Google Slaytlar", 
"PDF":"PDF", "Word Document":"Word Belgesi", "Excel Spreadsheet":"Excel Tablosu", "Modified":"De\u011fi\u015ftirildi", "Connect":"Ba\u011flan", "Connect to see more":"Daha fazla g\u00f6rmek i\u00e7in ba\u011flan\u0131n", "Connect Google account":"Google hesab\u0131na ba\u011flan\u0131n", "Title not available":"Ba\u015fl\u0131\u011fa eri\u015filemiyor", "Open containing folder":"Bulundu\u011fu klas\u00f6r\u00fc a\u00e7", "Cell Background":"H\u00fccre Arka Plan\u0131", "Cell Alignment":"H\u00fccre Hizalama", 
"Align content to top":"\u0130\u00e7eri\u011fi \u00fcste yasla", "Align content to center":"\u0130\u00e7eri\u011fi ortaya hizala", "Align content to bottom":"\u0130\u00e7eri\u011fi alta yasla", "Distribute Columns Evenly":"S\u00fctunlar\u0131 E\u015fit Olarak Da\u011f\u0131t", "Match Note Width":"Not Geni\u015fli\u011fini E\u015fle", "Delete Selected Column(s)":"Se\u00e7ili S\u00fctunlar\u0131 Sil", "Delete Selected Row(s)":"Se\u00e7ili Sat\u0131rlar\u0131 Sil", "Delete Table":"Tabloyu Sil", "Merge Cells":"H\u00fccreleri Birle\u015ftir", 
"Unmerge Cells":"H\u00fccreleri \u00c7\u00f6z", "Find text in note":"Not i\u00e7indeki metni bulun", "Next":"\u0130leri", "Previous":"\u00d6nceki", "Match case":"B\u00fcy\u00fck k\u00fc\u00e7\u00fck harf e\u015fle\u015ftir", "Replace with":"\u015eununla de\u011fi\u015ftir:", "Replace":"De\u011fi\u015ftir", "Replace All":"T\u00fcm\u00fcn\u00fc De\u011fi\u015ftir", "No matches found":"E\u015fle\u015fme bulunamad\u0131", "Match":"E\u015fle\u015ftir", "of":"/"};
goog.provide("uno.i18n.uk");
uno.i18n.uk.textEntries = {"Not available offline":"\u041d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u0432 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u043c\u0443 \u0440\u0435\u0436\u0438\u043c\u0456", "Not available":"\u041d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439", "Tap to request access":"\u0422\u043e\u0440\u043a\u043d\u0456\u0442\u044c\u0441\u044f, \u0449\u043e\u0431 \u043e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f", 
"Click to request access":"\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u043e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f", "Open":"\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438", "Copy link":"\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u043f\u043e\u0441\u0438\u043b\u0430\u043d\u043d\u044f", "Google Drive":"\u0414\u0438\u0441\u043a Google", "Google Docs":"\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438 Google", 
"Google Sheets":"\u0422\u0430\u0431\u043b\u0438\u0446\u044f Google", "Google Slides":"\u041f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0456\u044f Google", "PDF":"PDF", "Word Document":"\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 Word", "Excel Spreadsheet":"\u0422\u0430\u0431\u043b\u0438\u0446\u044f Excel", "Modified":"\u0417\u043c\u0456\u043d\u0435\u043d\u0438\u0439", "Connect":"\u041f\u0456\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0438\u0441\u044f", "Connect to see more":"\u041f\u0456\u0434\u043a\u043b\u044e\u0447\u0456\u0442\u044c, \u0449\u043e\u0431 \u0434\u0456\u0437\u043d\u0430\u0442\u0438\u0441\u044f \u0431\u0456\u043b\u044c\u0448\u0435", 
"Connect Google account":"\u041f\u0456\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0438 \u043e\u0431\u043b\u0456\u043a\u043e\u0432\u0438\u0439 \u0437\u0430\u043f\u0438\u0441 Google", "Title not available":"\u041d\u0430\u0437\u0432\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430", "Open containing folder":"\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u043f\u0430\u043f\u043a\u0443", "Cell Background":"\u0424\u043e\u043d \u043a\u043b\u0456\u0442\u0438\u043d\u043a\u0438", "Cell Alignment":"\u0412\u0438\u0440\u0456\u0432\u043d\u044e\u0432\u0430\u043d\u043d\u044f \u0443 \u043a\u043b\u0456\u0442\u0438\u043d\u0446\u0456", 
"Align content to top":"\u0412\u0438\u0440\u0456\u0432\u043d\u044f\u0442\u0438 \u0437\u0430 \u0432\u0435\u0440\u0445\u043d\u0456\u043c \u043a\u0440\u0430\u0454\u043c", "Align content to center":"\u0412\u0438\u0440\u0456\u0432\u043d\u044f\u0442\u0438 \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443", "Align content to bottom":"\u0412\u0438\u0440\u0456\u0432\u043d\u044f\u0442\u0438 \u0437\u0430 \u043d\u0438\u0436\u043d\u0456\u043c \u043a\u0440\u0430\u0454\u043c", "Distribute Columns Evenly":"\u0412\u0438\u0440\u0456\u0432\u043d\u044f\u0442\u0438 \u0448\u0438\u0440\u0438\u043d\u0443 \u0441\u0442\u043e\u0432\u043f\u0446\u0456\u0432", 
"Match Note Width":"\u0412\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u043d\u043e \u0434\u043e \u0448\u0438\u0440\u0438\u043d\u0438 \u043d\u043e\u0442\u0430\u0442\u043a\u0438", "Delete Selected Column(s)":"\u0412\u0438\u0434\u0430\u043b\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0439 \u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c", "Delete Selected Row(s)":"\u0412\u0438\u0434\u0430\u043b\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0439 \u0440\u044f\u0434\u043e\u043a", 
"Delete Table":"\u0412\u0438\u0434\u0430\u043b\u0438\u0442\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044e", "Merge Cells":"\u041e\u0431'\u0454\u0434\u043d\u0430\u0442\u0438 \u043a\u043b\u0456\u0442\u0438\u043d\u043a\u0438", "Unmerge Cells":"\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438 \u043e\u0431\u2019\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u043a\u043b\u0456\u0442\u0438\u043d\u043e\u043a", "Find text in note":"\u0428\u0443\u043a\u0430\u0442\u0438 \u0432 \u043d\u043e\u0442\u0430\u0442\u0446\u0456", 
"Next":"\u0412\u043f\u0435\u0440\u0435\u0434", "Previous":"\u041d\u0430\u0437\u0430\u0434", "Match case":"\u0417 \u0443\u0440\u0430\u0445\u0443\u0432\u0430\u043d\u043d\u044f\u043c \u0440\u0435\u0433\u0456\u0441\u0442\u0440\u0443", "Replace with":"\u0417\u0430\u043c\u0456\u043d\u0438\u0442\u0438 \u043d\u0430", "Replace":"\u0417\u0430\u043c\u0456\u043d\u0438\u0442\u0438", "Replace All":"\u0417\u0430\u043c\u0456\u043d\u0438\u0442\u0438 \u0432\u0441\u0456", "No matches found":"\u0417\u0431\u0456\u0433\u0456\u0432 \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e", 
"Match":"\u0417\u0431\u0456\u0433", "of":"\u0437"};
goog.provide("uno.i18n.vi");
uno.i18n.vi.textEntries = {"Not available offline":"Kh\u00f4ng d\u00f9ng \u0111\u01b0\u1ee3c \u1edf ch\u1ebf \u0111\u1ed9 ngo\u1ea1i tuy\u1ebfn", "Not available":"Kh\u00f4ng c\u00f3 s\u1eb5n", "Tap to request access":"Nh\u1ea5p \u0111\u1ec3 y\u00eau c\u1ea7u quy\u1ec1n truy c\u1eadp", "Click to request access":"Nh\u1ea5p \u0111\u1ec3 y\u00eau c\u1ea7u quy\u1ec1n truy c\u1eadp", "Open":"M\u1edf", "Copy link":"Sao ch\u00e9p li\u00ean k\u1ebft", "Google Drive":"Google Drive", "Google Docs":"Google Docs", 
"Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"T\u00e0i li\u1ec7u Word", "Excel Spreadsheet":"B\u1ea3ng t\u00ednh Excel", "Modified":"\u0110\u00e3 s\u1eeda \u0111\u1ed5i", "Connect":"K\u1ebft n\u1ed1i", "Connect to see more":"K\u1ebft n\u1ed1i \u0111\u1ec3 xem chi ti\u1ebft", "Connect Google account":"K\u1ebft n\u1ed1i v\u1edbi t\u00e0i kho\u1ea3n Google", "Title not available":"Ti\u00eau \u0111\u1ec1 kh\u00f4ng c\u00f3 s\u1eb5n", "Open containing folder":"M\u1edf th\u01b0 m\u1ee5c ch\u1ee9a", 
"Cell Background":"H\u00ecnh n\u1ec1n c\u1ee7a \u00f4", "Cell Alignment":"C\u0103n ch\u1ec9nh \u00f4", "Align content to top":"C\u0103n ch\u1ec9nh n\u1ed9i dung l\u00ean tr\u00ean c\u00f9ng", "Align content to center":"C\u0103n ch\u1ec9nh n\u1ed9i dung v\u00e0o trung t\u00e2m", "Align content to bottom":"C\u0103n ch\u1ec9nh n\u1ed9i dung xu\u1ed1ng d\u01b0\u1edbi c\u00f9ng", "Distribute Columns Evenly":"Ph\u00e2n b\u1ed1 c\u00e1c c\u1ed9t \u0111\u1ec1u nhau", "Match Note Width":"Kh\u1edbp chi\u1ec1u r\u1ed9ng ghi ch\u00fa", 
"Delete Selected Column(s)":"X\u00f3a (nh\u1eefng) c\u1ed9t \u0111\u00e3 ch\u1ecdn", "Delete Selected Row(s)":"X\u00f3a (nh\u1eefng) h\u00e0ng \u0111\u00e3 ch\u1ecdn", "Delete Table":"X\u00f3a b\u1ea3ng", "Merge Cells":"H\u1ee3p nh\u1ea5t \u00f4", "Unmerge Cells":"H\u1ee7y h\u1ee3p nh\u1ea5t \u00f4", "Find text in note":"T\u00ecm v\u0103n b\u1ea3n trong ghi ch\u00fa", "Next":"Ti\u1ebfp theo", "Previous":"Tr\u01b0\u1edbc", "Match case":"Kh\u1edbp ch\u1eef hoa/th\u01b0\u1eddng", "Replace with":"Thay th\u1ebf b\u1eb1ng", 
"Replace":"Thay th\u1ebf", "Replace All":"Thay th\u1ebf T\u1ea5t c\u1ea3", "No matches found":"Kh\u00f4ng so kh\u1edbp n\u00e0o \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y", "Match":"Kh\u1edbp", "of":"c\u1ee7a"};
goog.provide("uno.i18n.zh_CN");
uno.i18n.zh_CN.textEntries = {"Not available offline":"\u672a\u79bb\u7ebf\u7684\u7b14\u8bb0\u672c", "Not available":"\u4e0d\u53ef\u7528", "Tap to request access":"\u70b9\u51fb\u7533\u8bf7\u6743\u9650", "Click to request access":"\u70b9\u51fb\u7533\u8bf7\u6743\u9650", "Open":"\u6253\u5f00", "Copy link":"\u590d\u5236\u94fe\u63a5", "Google Drive":"Google Drive", "Google Docs":"Google\u6587\u6863", "Google Sheets":"Google Sheets", "Google Slides":"Google Slides", "PDF":"PDF", "Word Document":"Word\u6587\u6863", 
"Excel Spreadsheet":"Excel\u6570\u636e\u8868\u683c", "Modified":"\u5df2\u4fee\u6539", "Connect":"\u8fde\u63a5", "Connect to see more":"\u8fde\u63a5\u67e5\u770b\u66f4\u591a", "Connect Google account":"\u8fde\u63a5Google\u5e10\u6237", "Title not available":"\u6807\u9898\u4e0d\u53ef\u7528", "Open containing folder":"\u6253\u5f00\u5305\u542b\u7684\u6587\u4ef6\u5939", "Cell Background":"\u5355\u5143\u683c\u80cc\u666f", "Cell Alignment":"\u5355\u5143\u683c\u5bf9\u9f50", "Align content to top":"\u9876\u7aef\u5bf9\u9f50", 
"Align content to center":"\u5c45\u4e2d\u5bf9\u9f50", "Align content to bottom":"\u5e95\u90e8\u5bf9\u9f50", "Distribute Columns Evenly":"\u5e73\u5747\u5206\u5e03\u5404\u5217", "Match Note Width":"\u5339\u914d\u7b14\u8bb0\u5bbd\u5ea6", "Delete Selected Column(s)":"\u5220\u9664\u9009\u4e2d\u7684\u5217", "Delete Selected Row(s)":"\u5220\u9664\u9009\u4e2d\u7684\u884c", "Delete Table":"\u5220\u9664\u8868\u683c", "Merge Cells":"\u5408\u5e76\u5355\u5143\u683c", "Unmerge Cells":"\u53d6\u6d88\u5408\u5e76\u5355\u5143\u683c", 
"Find text in note":"\u5728\u7b14\u8bb0\u4e2d\u641c\u7d22\u6587\u5b57", "Next":"\u4e0b\u4e00\u6761", "Previous":"\u4e0a\u4e00\u6761", "Match case":"\u5339\u914d\u5927\u5c0f\u5199", "Replace with":"\u66ff\u6362\u4e3a", "Replace":"\u66ff\u6362", "Replace All":"\u66ff\u6362\u5168\u90e8", "No matches found":"\u627e\u4e0d\u5230\u7b26\u5408\u9879\u76ee", "Match":"\u5339\u914d", "of":"\u7684"};
goog.provide("uno.i18n.zh_TW");
uno.i18n.zh_TW.textEntries = {"Not available offline":"\u4e0d\u53ef\u96e2\u7dda\u5b58\u53d6", "Not available":"\u4e0d\u9069\u7528", "Tap to request access":"\u9ede\u64ca\u4ee5\u8acb\u6c42\u5b58\u53d6", "Click to request access":"\u9ede\u64ca\u4ee5\u8acb\u6c42\u5b58\u53d6", "Open":"\u958b\u555f", "Copy link":"\u8907\u88fd\u9023\u7d50", "Google Drive":"Google \u96f2\u7aef\u786c\u789f", "Google Docs":"Google \u6587\u4ef6", "Google Sheets":"Google \u8a66\u7b97\u8868", "Google Slides":"Google \u7c21\u5831", 
"PDF":"PDF", "Word Document":"Word \u6587\u4ef6", "Excel Spreadsheet":"Excel \u8a66\u7b97\u8868", "Modified":"\u5df2\u4fee\u6539", "Connect":"\u9023\u7d50", "Connect to see more":"\u9023\u7d50\u4ee5\u770b\u5230\u66f4\u591a", "Connect Google account":"\u9023\u7d50 Google \u5e33\u6236", "Title not available":"\u7121\u6a19\u984c", "Open containing folder":"\u958b\u555f\u6240\u5c6c\u8cc7\u6599\u593e", "Cell Background":"\u8868\u683c\u5132\u5b58\u683c\u80cc\u666f\u984f\u8272", "Cell Alignment":"\u5132\u5b58\u683c\u5167\u6587\u5b57\u5c0d\u9f4a", 
"Align content to top":"\u9f4a\u9802", "Align content to center":"\u7f6e\u4e2d\u5c0d\u9f4a", "Align content to bottom":"\u9f4a\u5e95", "Distribute Columns Evenly":"\u5e73\u5747\u5206\u4f48\u6b04\u4f4d", "Match Note Width":"\u7b26\u5408\u8a18\u4e8b\u5bec", "Delete Selected Column(s)":"\u522a\u9664\u9078\u53d6\u7684\u6b04", "Delete Selected Row(s)":"\u522a\u9664\u9078\u53d6\u7684\u5217", "Delete Table":"\u522a\u9664\u8868\u683c", "Merge Cells":"\u5408\u4f75\u5132\u5b58\u683c", "Unmerge Cells":"\u53d6\u6d88\u5408\u4f75\u5132\u5b58\u683c", 
"Find text in note":"\u641c\u5c0b\u8a18\u4e8b\u88e1\u7684\u6587\u5b57", "Next":"\u4e0b\u4e00\u500b", "Previous":"\u4e0a\u4e00\u9801", "Match case":"\u7b26\u5408\u5927\u5c0f\u5beb", "Replace with":"\u53d6\u4ee3\u70ba", "Replace":"\u53d6\u4ee3", "Replace All":"\u5168\u90e8\u53d6\u4ee3", "No matches found":"\u627e\u4e0d\u5230\u7b26\u5408\u9805\u76ee", "Match":"\u7b26\u5408", "of":"\u5171"};
goog.provide("uno.i18n.en_XA");
uno.i18n.en_XA.textEntries = {"Not available offline":"[Not available offline xxxxxxxxx]", "Not available":"[Not available xxxxxxxx]", "Tap to request access":"[Tap to request access xxxxxxxxx]", "Click to request access":"[Click to request access xxxxxxxxxx]", "Open":"[Open xxx]", "Copy link":"[Copy link xxxxxxxx]", "Google Drive":"[Google Drive xxxxxxx]", "Google Docs":"[Google Docs xxxxxx]", "Google Sheets":"[Google Sheets xxxxxxxx]", "Google Slides":"[Google Slides xxxxxxxx]", "PDF":"[PDF xx]", 
"Word Document":"[Word Document xxxxxxxx]", "Excel Spreadsheet":"[Excel Spreadsheet xxxxxxxxxx]", "Modified":"[Modified xxxxxxx]", "Connect":"[Connect xxxxxx]", "Connect to see more":"[Connect to see more xxxxxxxxxx x]", "Connect Google account":"[Connect Google account xxxxxxxxxx]", "Title not available":"[Title not available xxxxxxxxxx x]", "Open containing folder":"[Open containing folder xxxxxxxxxx]", "Cell Background":"[Cell Background xxxxxxxxx]", "Cell Alignment":"[Cell Alignment xxxxxxxx]", 
"Align content to top":"[Align content to top xxxxxxxxx]", "Align content to center":"[Align content to center xxxxxxxxxx]", "Align content to bottom":"[Align content to bottom xxxxxxxxxx]", "Distribute Columns Evenly":"[Distribute Columns Evenly xxxxxxxxxx ]", "Match Note Width":"[Match Note Width xxxxxxxxxx]", "Delete Selected Column(s)":"[Delete Selected Column(s) xxxxxxxxxx ]", "Delete Selected Row(s)":"[Delete Selected Row(s) xxxxxxxxxx]", "Delete Table":"[Delete Table xxxxxxx]", "Merge Cells":"[Merge Cells xxxxxx]", 
"Unmerge Cells":"[Unmerge Cells xxxxxxxx]", "Find text in note":"[Find text in note xxxxxxxxxx]", "Next":"[Next xxx]", "Previous":"[Previous xxxxxxx]", "Match case":"[Match case xxxxxx]", "Replace with":"[Replace with xxxxxxx]", "Replace":"[Replace xxxxxx]", "Replace All":"[Replace All xxxxxx]", "No matches found":"[No matches found xxxxxxxxxx]", "Match":"[Match xxxx]", "of":"[of x]"};
goog.provide("uno.i18n.all");
goog.require("uno.i18n.ar");
goog.require("uno.i18n.cs");
goog.require("uno.i18n.da");
goog.require("uno.i18n.de");
goog.require("uno.i18n.en");
goog.require("uno.i18n.es");
goog.require("uno.i18n.fi");
goog.require("uno.i18n.fr");
goog.require("uno.i18n.id");
goog.require("uno.i18n.it");
goog.require("uno.i18n.ja");
goog.require("uno.i18n.ko");
goog.require("uno.i18n.ms");
goog.require("uno.i18n.nl");
goog.require("uno.i18n.no");
goog.require("uno.i18n.pl");
goog.require("uno.i18n.pt_BR");
goog.require("uno.i18n.pt");
goog.require("uno.i18n.ru");
goog.require("uno.i18n.sv");
goog.require("uno.i18n.th");
goog.require("uno.i18n.tr");
goog.require("uno.i18n.uk");
goog.require("uno.i18n.vi");
goog.require("uno.i18n.zh_CN");
goog.require("uno.i18n.zh_TW");
goog.require("uno.i18n.en_XA");
uno.i18n.all.textEntries = {"ar":uno.i18n.ar.textEntries, "cs":uno.i18n.cs.textEntries, "da":uno.i18n.da.textEntries, "de":uno.i18n.de.textEntries, "en":uno.i18n.en.textEntries, "es":uno.i18n.es.textEntries, "fi":uno.i18n.fi.textEntries, "fr":uno.i18n.fr.textEntries, "id":uno.i18n.id.textEntries, "it":uno.i18n.it.textEntries, "ja":uno.i18n.ja.textEntries, "ko":uno.i18n.ko.textEntries, "ms":uno.i18n.ms.textEntries, "nl":uno.i18n.nl.textEntries, "no":uno.i18n.no.textEntries, "pl":uno.i18n.pl.textEntries, 
"pt_BR":uno.i18n.pt_BR.textEntries, "pt":uno.i18n.pt.textEntries, "ru":uno.i18n.ru.textEntries, "sv":uno.i18n.sv.textEntries, "th":uno.i18n.th.textEntries, "tr":uno.i18n.tr.textEntries, "uk":uno.i18n.uk.textEntries, "vi":uno.i18n.vi.textEntries, "zh_CN":uno.i18n.zh_CN.textEntries, "zh_TW":uno.i18n.zh_TW.textEntries, "en_XA":uno.i18n.en_XA.textEntries};
goog.provide("uno.util.loc");
goog.require("uno.i18n.all");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.loc");
  var util = uno.util;
  util.loc.init = function(locale) {
    util.loc.locale = locale;
    if (!util.loc.locale) {
      util.loc.locale = "en";
    }
    util.loc.locale = util.loc.locale.replace(/-/g, "_");
    Object.keys(uno.i18n.all.textEntries).forEach(function(lang) {
      var value = uno.i18n.all.textEntries[lang];
      util.loc.addTranslation(lang, value);
    });
  };
  util.loc.defaultLocale = "en";
  util.loc.translation = null;
  util.loc.translations = {};
  util.loc.missingLocales = {};
  util.loc.missingStrings = {};
  util.loc.addTranslation = function(locale, translation) {
    util.loc.translations[locale] = translation;
    util.loc.missingStrings[locale] = {};
  };
  util.loc.loadTranslation = function(locale) {
    if (locale) {
      util.loc.locale = locale;
    }
    if (util.loc.locale == null) {
      log.warning("Language locale has not been configured. Defaulting to " + util.loc.defaultLocale);
      util.loc.locale = util.loc.defaultLocale;
    }
    util.loc.locale = util.loc.locale.replace(/-/g, "_");
    if (util.loc.missingLocales[util.loc.locale]) {
      return;
    }
    if (util.loc.translation !== null && util.loc.translation === util.loc.translations[util.loc.locale]) {
      return;
    }
    util.loc.translation = util.loc.translations[util.loc.locale];
    if (util.loc.translation == null) {
      log.info("There are no translations available for the " + util.loc.locale + " locale");
      util.loc.missingLocales[util.loc.locale] = true;
      if (util.loc.locale.indexOf("_") !== -1) {
        util.loc.locale = util.loc.locale.substr(0, util.loc.locale.indexOf("_"));
        util.loc.translation = util.loc.translations[util.loc.locale];
        if (util.loc.translation == null) {
          log.warning("There are also no translations for the fallback locale " + util.loc.locale);
          util.loc.missingLocales[util.loc.locale] = true;
        }
      }
    }
    if (util.loc.translation != null) {
      log.fine("Using text for " + util.loc.locale);
      Object.keys(util.loc.translation).forEach(function(key) {
        var text = util.loc.translation[key];
        if (text === "") {
          util.loc.translation[key] = null;
        }
      });
      util.loc.missingStrings[locale] = util.loc.missingStrings[locale] || {};
    }
  };
  util.loc.t = function(text, placeholders) {
    var result;
    if (util.loc.translation == null) {
      util.loc.loadTranslation(util.loc.locale);
    }
    if (util.loc.missingLocales[util.loc.locale]) {
      result = text;
    } else {
      if (util.loc.translation[text] == null) {
        if (util.loc.missingStrings[util.loc.locale] == null) {
          log.warning("No missingStrings object defined for " + util.loc.locale);
        }
        if (util.loc.missingStrings[util.loc.locale][text] == null) {
          log.warning("The " + util.loc.locale + ' locale does not have a translation for "' + text + '"');
          util.loc.missingStrings[util.loc.locale][text] = true;
        }
        result = text;
      } else {
        result = util.loc.translation[text];
      }
    }
    if (placeholders) {
      result = util.loc.replace(result, placeholders);
    }
    return result;
  };
  util.loc.replace = function(text, placeholders) {
    Object.keys(placeholders).forEach(function(token) {
      var value = placeholders[token];
      text = text.replace(new RegExp("{{" + token + "}}", "g"), value);
    });
    return text;
  };
})();
goog.provide("uno.util.attachment");
goog.require("uno.defs");
goog.require("uno.util.loc");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.attachment");
  var defs = uno.defs;
  var util = uno.util;
  var dom = util.dom;
  var STRUCTTYPES = uno.defs.structuretypes;
  util.attachment.CLASS_PREFIX = "en-attach-icon-";
  util.attachment.isAttachment = function(node) {
    return goog.dom.classes.has(node, "en-media-file");
  };
  util.attachment.getIconInfoFromFile = function(displayType, mime, fileName) {
    var fileType;
    if (typeof mime === "string" || typeof fileName === "string") {
      if (mime) {
        fileType = util.attachment.getFileTypeFromMime(mime);
      }
      if (!fileType && fileName) {
        var extension = fileName.match(/^.+\.([0-9a-z]+)$/i);
        if (extension) {
          fileType = extensionToFileType[extension[1]];
        }
      }
    }
    return util.attachment.CLASS_PREFIX + (fileType || "generic");
  };
  util.attachment.getBase64IconFromMime = function(mime) {
    if (mime) {
      var fileType = util.attachment.getFileTypeFromMime(mime);
      if (fileType) {
        var base64Img = extensionIconBase64[fileType];
        if (base64Img) {
          return base64Img;
        }
      }
      return extensionIconBase64.unknown;
    }
    return false;
  };
  util.attachment.isDraggable = function(node) {
    if (!node || dom.isTextNode(node)) {
      return false;
    }
    return util.attachment.isAttachment(node);
  };
  util.attachment.isDroppableTarget = function(node) {
    return true;
  };
  util.attachment.prepareForDrag = function(state, options) {
    state.itemTypes = [STRUCTTYPES.RESOURCE];
  };
  util.attachment.getDraggedItems = function(attachment) {
    return [attachment];
  };
  util.attachment.handleDrop = function(event, state, editor) {
    if (state.dropRange) {
      state.dropRange.select();
      var lastInsertedImage;
      goog.array.forEach(state.draggedItems, function(attachment) {
        var parent = attachment.parentNode;
        lastInsertedImage = attachment;
        state.dropRange.insertNode(attachment);
        if (dom.isEmpty(parent)) {
          util.paragraph.remove(parent);
        }
      });
      if (lastInsertedImage) {
        editor.selectEnd(lastInsertedImage);
      }
    }
  };
  var extensionToFileType = {"pdf":"pdf", "djvu":"pdf", "wav":"audio", "aiff":"audio", "flac":"audio", "ogg":"audio", "ac3":"audio", "mp3":"audio", "avi":"video", "mp4":"video", "mpg":"video", "mpeg":"video", "vob":"video", "pptx":"ppt", "ppt":"ppt", "sdd":"ppt", "odp":"ppt", "doc":"word", "dot":"word", "docx":"word", "odt":"word", "xls":"excel", "xlsx":"excel", "ods":"excel", "csv":"excel", "zip":"zip", "zipx":"zip", "gz":"zip", "tgz":"zip", "rar":"zip", "iso":"zip", "tar":"zip", "mar":"zip", "bz2":"zip", 
  "cab":"zip", "arc":"zip", "dmg":"zip", "jar":"zip", "war":"zip", "7z":"zip", "svg":"svg", "svgz":"svg", "ai":"svg", "cdr":"svg", "wmf":"svg", "drw":"svg", "eps":"svg", "emz":"svg", "odg":"svg", "pic":"svg", "sda":"svg", "swf":"svg", "sketch":"svg", "cad":"3d", "skp":"3d", "stl":"3d", "123dx":"3d", "anim":"3d", "3d":"3d", "3dr":"3d", "3ds":"3d", "dwg":"3d", "dxf":"3d", "pfb":"font", "ttf":"font", "otf":"font", "pages":"pages", "rtf":"pages", "txt":"pages", "numbers":"num", "keynote":"keynote", "key":"keynote", 
  "psd":"edit", "ptg":"edit", "skba":"edit", "pxm":"edit", "xcf":"edit"};
  var mimeToFileType = {"application/pdf":"pdf", "application/mspowerpoint":"ppt", "application/powerpoint":"ppt", "application/vnd.ms-powerpoint":"ppt", "application/x-mspowerpoint":"ppt", "application/vnd.oasis.opendocument.presentation":"ppt", "application/vnd.openxmlformats-officedocument.presentationml.slideshow":"ppt", "application/msword":"word", "application/vnd.oasis.opendocument.text":"word", "application/vnd.openxmlformats-officedocument.wordprocessingml.document":"word", "application/excel":"excel", 
  "application/vnd.ms-excel":"excel", "application/x-excel":"excel", "text/csv":"excel", "application/vnd.oasis.opendocument.spreadsheet":"excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"excel", "application/zip":"zip", "application/x-compress":"zip", "application/x-compressed":"zip", "application/x-zip-compressed":"zip", "multipart/x-zip":"zip", "application/x-gzip":"zip", "application/x-rar-compressed":"zip", "application/x-gtar":"zip", "application/vnd.ms-cab-compressed":"zip", 
  "application/x-apple-diskimage":"zip", "application/x-7z-compressed":"zip", "image/svg+xml":"svg", "application/postscript":"svg", "windows/metafile":"svg", "application/drafting":"svg", "image/pict":"svg", "application/x-shockwave-flash":"svg", "application/x-koan":"3d", "application/sla":"3d", "x-world/x-3dmf":"3d", "application/acad":"3d", "application/dxf":"3d", "application/rtf":"pages", "application/x-rtf":"pages", "text/richtext":"pages", "application/vnd.apple.pages":"pages", "application/x-iwork-pages-sffpages":"pages", 
  "application/vnd.apple.numbers":"numbers", "application/x-iwork-numbers-sffnumbers":"numbers", "application/vnd.apple.keynote":"keynote", "application/x-iwork-keynote-sffkey":"keynote", "application/vnd.google-apps.document":"gdocs", "application/vnd.google-apps.spreadsheet":"gsheets", "application/vnd.google-apps.presentation":"gslides", "unknown":"unknown"};
  var extensionIconBase64 = {"zip":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iIzhGOEM4QSIgZD0iTS0yNTcsNDEwaC0xNmMtMS4xMDUsMC0yLTAuODk1LTItMnYtMjJjMC0xLjEwNSwwLjg5NS0yLDItMmg4djJoLTJ2MmgydjJoLTJ2MmgydjJoLTJ2MmgydjJoLTJ2NGg0di0yaC0ydi0yaDJ2LTJoLTJ2LTJoMnYtMmgtMnYtMmgydi0yaC0ydi0yaDJ2LTJoNmMxLjEwNSwwLDIsMC44OTUsMiwydjIyQy0yNTUsNDA5LjEwNS0yNTUuODk1LDQxMC0yNTcsNDEweiIvPjwvc3ZnPg==", 
  "video":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0FENzZBOCIgZD0iTS0yNTMsNDA3aC0yNGMtMS4xMDUsMC0yLTAuODk1LTItMnYtMTZjMC0xLjEwNSwwLjg5NS0yLDItMmgyNGMxLjEwNSwwLDIsMC44OTUsMiwydjE2Qy0yNTEsNDA2LjEwNS0yNTEuODk1LDQwNy0yNTMsNDA3eiBNLTI3NSwzOTBoLTJ2MmgyVjM5MHogTS0yNzUsMzk0aC0ydjJoMlYzOTR6IE0tMjc1LDM5OGgtMnYyaDJWMzk4eiBNLTI3NSw0MDJoLTJ2MmgyVjQwMnogTS0yNTcsMzg5aC0xNnYxNmgxNlYzODl6IE0tMjUzLDM5MGgtMnYyaDJWMzkweiBNLTI1MywzOTRoLTJ2MmgyVjM5NHogTS0yNTMsMzk4aC0ydjJoMlYzOTh6IE0tMjUzLDQwMmgtMnYyaDJWNDAyeiBNLTI1OCw0MDRoLTE0di0xNGgxNFY0MDR6Ii8+PC9zdmc+", 
  "unknown":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0YyRjJGMiIgZD0iTS0yNTMuMTE0LDM5NS40NTljMi4yOTUtMy42NTYsMC45MzMtOC4zMy0zLjA0Mi0xMC40NGMtMy45NzUtMi4xMS05LjA1Ny0wLjg1OC0xMS4zNTIsMi43OTdjLTIuMjk1LDMuNjU2LTcuMDE5LDExLjE4LTguNjg4LDEzLjgzOWMtMS42NjksMi42NTgtMC42NzksNi4wNTcsMi4yMTIsNy41OTJjMi44OTEsMS41MzUsNi41ODcsMC42MjQsOC4yNTYtMi4wMzRjMS42NjktMi42NTksNy42NDUtMTIuMTc3LDguNjg4LTEzLjgzOWMxLjA0My0xLjY2MSwwLjQyNC0zLjc4Ni0xLjM4Mi00Ljc0NWMtMS44MDctMC45NTktNC4xMTctMC4zOS01LjE2LDEuMjcyYy0xLjA0NCwxLjY2MS04LjI3MSwxMy4xNzMtOC42ODksMTMuODM4Yy0wLjQxNywwLjY2NS0wLjE2OSwxLjUxNCwwLjU1NCwxLjg5OGMwLjcyMiwwLjM4NCwxLjY0NiwwLjE1NiwyLjA2NC0wLjUwOGMwLjQxNy0wLjY2NSw4LjQ3OS0xMy41MDcsOC42ODgtMTMuODM5YzAuMjA4LTAuMzMyLDAuNjctMC40NDYsMS4wMzItMC4yNTRjMC4zNjEsMC4xOTIsMC40ODUsMC42MTcsMC4yNzYsMC45NDljLTAuMjA5LDAuMzMyLTcuODUzLDEyLjUwOS04LjY4OCwxMy44MzhjLTAuODM0LDEuMzI5LTIuNjgyLDEuNzg1LTQuMTI4LDEuMDE3Yy0xLjQ0NS0wLjc2Ny0xLjk0LTIuNDY3LTEuMTA2LTMuNzk2YzAuODM1LTEuMzI5LDcuMjI4LTExLjUxMiw4LjY4OC0xMy44MzhjMS40Ni0yLjMyNiw0LjY5NS0zLjEyMyw3LjIyNC0xLjc4YzIuNTI5LDEuMzQzLDMuMzk2LDQuMzE3LDEuOTM2LDYuNjQzYy0xLjQ2MSwyLjMyNi01LjI0OSw4LjM2MS01LjY2Nyw5LjAyNWMtMC40MTcsMC42NjUtMC4xNjksMS41MTUsMC41NTQsMS44OThjMC43MjIsMC4zODQsMS42NDYsMC4xNTYsMi4wNjQtMC41MDhDLTI1OC4zNjMsNDAzLjgxOS0yNTUuNDA5LDM5OS4xMTQtMjUzLjExNCwzOTUuNDU5eiIvPjwvc3ZnPg==", 
  "pdf":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0Q1NTk0QSIgZD0iTS0yNTAuMzcsNDAzLjM2Yy0wLjgxNSwxLjczOC0yLjU0NCwyLjQ5Mi00LjUxNCwxLjk2NGMtMS40NTMtMC4zODgtMy4zMjYtMS41ODktNS4xMTYtMy4zMjRjLTIuMDg1LDAuMTYzLTQuMzc3LDAuMzAzLTcsMWMtMS45MDQsMy4wNjItNC4wNDgsNS42OTQtNS42NjIsNi41MzFjLTAuNjQyLDAuMzMyLTEuMjQ4LDAuNDctMS43OTgsMC40N2MtMC45NTgsMC0xLjc0NC0wLjQxOC0yLjI1NC0wLjk0NGMtMS42NDctMS43LTEuNzEtMy44NTYtMC4xNjQtNS42MjhjMS4yNDgtMS40MzEsMy44MTktMi40NDQsNi44NzgtMy40MjljMC45MDYtMS41OSwxLjc5OC0zLjY1NiwyLjU3Ni01LjUzOWMwLjI0Ni0wLjU5NSwwLjI0My0wLjk1NCwwLjQyNC0xLjQ2MWMtMS4yODMtMi4zOTItMi4xLTQuNzktMS44OTctNi4yNDdjMC4yMjgtMS42NDMsMS43NzYtMi43MTksMy41MDgtMi43NGMwLjAxOSwwLDAuMDM4LDAsMC4wNTcsMGMxLjgwMSwwLDMuNTIzLDEuMzc0LDMuOTk5LDMuMDk1YzAuMzcsMS4zNCwwLjIxNSwzLjQ4MS0wLjY2Nyw1Ljg5MmMxLjE0OSwxLjgwOCwyLjQ2NiwzLjEwNSwzLjg5MSw0LjcyN2MyLjY0NS0wLjAyOCw0LjkyOCwwLjMwMiw2LjI4MywxLjA5OUMtMjUwLjEyLDM5OS44My0yNDkuNTQ4LDQwMS42MDktMjUwLjM3LDQwMy4zNnogTS0yNzQuNDk0LDQwNi40NmMwLjQ5MywwLjQ0NCwxLjU0NC0wLjk3MiwyLjQ3NS0yLjQ3MkMtMjc0LjE4NSw0MDUuMzg5LTI3NC45ODgsNDA2LjAxNy0yNzQuNDk0LDQwNi40NnogTS0yNjUuMTIsMzg3LjI2M2MtMC4wNDQtMC4wMDQtMC4xNjgtMC4yNTQtMC4yNDMtMC4yNTNjLTAuNDY1LDAuMDE2LTAuNTI4LDAuNTA0LTAuNTMxLDAuNTA1Yy0wLjExNCwwLjI2MywwLjE2MiwwLjg1MiwwLjg5NCwyLjQ4NUMtMjY1LjAxMSwzODguMzU4LTI2NC45MjgsMzg3LjYzNy0yNjUuMTIsMzg3LjI2M3ogTS0yNjQuMDMxLDM5Ni4zNDRsLTEuMjUzLDIuNjY4bDMuMTExLTAuMzcyTC0yNjQuMDMxLDM5Ni4zNDR6IE0tMjU2LDQwMWMwLjY0MywwLjQyLDEuMTE2LDAuOTQ0LDEuODc5LDEuMDFjMC4wNjEtMC4xNjEsMC4wOTctMC4yODIsMC4xMTctMC4zNjdDLTI1NC40NDcsNDAxLjA3OS0yNTUuMDk3LDQwMS4wNzgtMjU2LDQwMXoiLz48L3N2Zz4=", 
  "audio":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iIzY4QkVCRCIgZD0iTS0yNTcsMzk2di0xYzAtMC41NTItMC40NDgtMS0xLTFzLTEsMC40NDgtMSwxdjRjMCwwLjU1MiwwLjQ0OCwxLDEsMXMxLTAuNDQ4LDEtMXYtMWg0Ljk1bDAsMGgyLjA1YzAuNTUyLDAsMSwwLjQ0OCwxLDFzLTAuNDQ4LDEtMSwxaC0yLjM2MmMtMS4zNTYsNS43MzEtNi40OTMsMTAtMTIuNjM4LDEwcy0xMS4yODItNC4yNjktMTIuNjM4LTEwSC0yODBjLTAuNTUyLDAtMS0wLjQ0OC0xLTFzMC40NDgtMSwxLTFoMi4wNWwwLDBoMy45NXYxYzAsMC41NTIsMC40NDgsMSwxLDFzMS0wLjQ0OCwxLTF2LTRjMC0wLjU1Mi0wLjQ0OC0xLTEtMXMtMSwwLjQ0OC0xLDF2MWgtMy45NWMwLjUxMy02LjcxMSw2LjEwOC0xMiwxMi45NS0xMnMxMi40MzcsNS4yODksMTIuOTUsMTJILTI1N3ogTS0yNjksMzkzYzAtMC41NTItMC40NDgtMS0xLTFzLTEsMC40NDgtMSwxdjhjMCwwLjU1MiwwLjQ0OCwxLDEsMXMxLTAuNDQ4LDEtMVYzOTN6IE0tMjY2LDM5MGMwLTAuNTUyLTAuNDQ4LTEtMS0xcy0xLDAuNDQ4LTEsMXYxNGMwLDAuNTUyLDAuNDQ4LDEsMSwxczEtMC40NDgsMS0xVjM5MHogTS0yNjMsMzk0YzAtMC41NTItMC40NDgtMS0xLTFzLTEsMC40NDgtMSwxdjZjMCwwLjU1MiwwLjQ0OCwxLDEsMXMxLTAuNDQ4LDEtMVYzOTR6IE0tMjYwLDM5MmMwLTAuNTUyLTAuNDQ4LTEtMS0xcy0xLDAuNDQ4LTEsMXYxMGMwLDAuNTUyLDAuNDQ4LDEsMSwxczEtMC40NDgsMS0xVjM5MnoiLz48L3N2Zz4=", 
  "ppt":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0YyOEEzMCIgZD0iTS0yNjQsNDAxYy0xLjI5MywwLTMsMC0zLDB2NmgtNHYtMTZoLTN2LTRjMCwwLDYuNTUxLDAsMTAsMGMzLjg2NiwwLDcsMy4xMzQsNyw3Uy0yNjAuMTM0LDQwMS0yNjQsNDAxeiBNLTI2NCwzOTFjLTAuNzk3LDAtMywwLTMsMHY2YzAsMCwyLjIwMywwLDMsMGMxLjY1NywwLDMtMS4zNDMsMy0zUy0yNjIuMzQzLDM5MS0yNjQsMzkxeiIvPjwvc3ZnPg==", 
  "word":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iIzQ0ODlBNyIgZD0iTS0yNTcsNDA3aC00bC00LTEzLjMzM0wtMjY5LDQwN2gtNGwtNi0yMGg0bDQsMTMuMzMzbDQtMTMuMzMzaDRsNCwxMy4zMzNsMi44LTkuMzMzaC0yLjh2LTRoOEwtMjU3LDQwN3oiLz48L3N2Zz4=", 
  "3d":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iIzY5NzU4QyIgZD0iTS0yNTMuNzU2LDQwNC41MzFsLTEwLjQ1Miw2LjI1Yy0wLjI0NCwwLjE0Ni0wLjUxOCwwLjIxOS0wLjc5MiwwLjIxOXMtMC41NDgtMC4wNzMtMC43OTItMC4yMTlsLTEwLjQ1Mi02LjI1Yy0wLjQ2OS0wLjI4LTAuNzU2LTAuNzg4LTAuNzU2LTEuMzM2di0xMi4zOWMwLTAuNTQ4LDAuMjg3LTEuMDU2LDAuNzU2LTEuMzM2bDEwLjQ1Mi02LjI1YzAuMjQ0LTAuMTQ2LDAuNTE4LTAuMjE5LDAuNzkyLTAuMjE5czAuNTQ4LDAuMDczLDAuNzkyLDAuMjE5bDEwLjQ1Miw2LjI1YzAuNDY5LDAuMjgsMC43NTYsMC43ODgsMC43NTYsMS4zMzZ2MTIuMzlDLTI1Myw0MDMuNzQzLTI1My4yODcsNDA0LjI1MS0yNTMuNzU2LDQwNC41MzF6IE0tMjczLDQwMC41MjlsMy45MS0yLjMzOGwxLjA5LDAuNjUydjEuMDI2bC00LjEyMywyLjQ2Nmw2LjEyMywzLjY2MXYtOC4zMzlsLTctNC4xODZWNDAwLjUyOXogTS0yNjQsMzg4LjAwNHY1LjA0bC0xLDAuNTk5bC0xLTAuNTk5di01LjA0bC02LjEyMywzLjY2MWw3LjEyMyw0LjI1OWw3LjEyMy00LjI1OUwtMjY0LDM4OC4wMDR6IE0tMjY0LDM5Ny42NTd2OC4zMzlsNi4xMjMtMy42NjFsLTQuMTIzLTIuNDY2di0xLjAyNmwxLjA5LTAuNjUybDMuOTEsMi4zMzh2LTcuMDU4TC0yNjQsMzk3LjY1N3oiLz48L3N2Zz4=", 
  "edit":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0JFQkVCRSIgZD0iTS0yNTUsNDA3aC00di00aDRWNDA3eiBNLTI2Myw0MDN2LTRoNHY0SC0yNjN6IE0tMjYzLDM5MWg0djRoLTRWMzkxeiBNLTI3MSwzOTV2LTRoNHY0SC0yNzF6IE0tMjY3LDQwM2gtNHYtNGg0VjQwM3ogTS0yNjcsMzk1aDR2NGgtNFYzOTV6IE0tMjYzLDQwN2gtNHYtNGg0VjQwN3ogTS0yNzUsNDA3di00aDR2NEgtMjc1eiBNLTI3NSwzOTl2LTRoNHY0SC0yNzV6IE0tMjc1LDM4N2g0djRoLTRWMzg3eiBNLTI2NywzODdoNHY0aC00VjM4N3ogTS0yNTUsMzg3djRoLTR2LTRILTI1NXogTS0yNTUsMzk1djRoLTR2LTRILTI1NXoiLz48L3N2Zz4=", 
  "excel":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iIzU3QTY3NCIgZD0iTS0yNTYsNDA3aC01bC00LjUtNi40MjlsLTEuNywyLjQyOWgyLjRsMi44LDRoLThoLTVsNy0xMGwtNy0xMGg1bDQuNSw2LjQyOUwtMjYxLDM4N2g1bC03LDEwTC0yNTYsNDA3eiBNLTI1NCw0MDNsLTEuOTY2LDIuNjIxTC0yNTcuOCw0MDNILTI1NHoiLz48L3N2Zz4=", 
  "font":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iIzg3ODhCRSIgZD0iTS0yNzAsMzkzdjJoMy4yMTRjLTEuNDgyLDQuNzUzLTMuMjYzLDEwLjQ1Ny0zLjI5NCwxMC41NjNjLTAuMTQ3LDAuNTAxLTAuNDk3LDAuODk5LTAuOTQyLDEuMTU0YzAuMDA3LTAuMDczLDAuMDIyLTAuMTQzLDAuMDIyLTAuMjE3YzAtMS4zODEtMS4xMTktMi41LTIuNS0yLjVzLTIuNSwxLjExOS0yLjUsMi41czEuMTE5LDIuNSwyLjUsMi41YzAuNzM5LDAsMi4yMTIsMCwzLjUsMGMyLjMwNiwwLDQuMjQ3LTEuNTYxLDQuODI1LTMuNjgzYzAuMDY1LTAuMjQxLDEuNzY2LTUuNjg3LDMuMjEyLTEwLjMxN0gtMjU4di0yaC0zLjMzOGMwLjc4Ny0yLjUyMywxLjM4Ni00LjQ0MiwxLjQtNC40OTZjMC4xMzUtMC41MywwLjQ5Ni0wLjk1MywwLjk2LTEuMjE4Yy0wLjAwNywwLjA3Mi0wLjAyMiwwLjE0MS0wLjAyMiwwLjIxNGMwLDEuMzgxLDEuMTE5LDIuNSwyLjUsMi41YzEuMzgxLDAsMi41LTEuMTE5LDIuNS0yLjVzLTEuMTE5LTIuNS0yLjUtMi41Yy0xLjEyLDAtMS45MDMsMC0zLjUsMGMtMi4zLDAtNC4yMzcsMS41NTMtNC44MjEsMy42NjhjLTAuMDIsMC4wNzQtMC4yMDEsMC44MDctMC42ODMsMi4yMTNjLTAuNTM2LDEuMjQ2LTEuNzczLDIuMTE5LTMuMjE1LDIuMTE5Qy0yNjksMzkzLTI3MCwzOTMtMjcwLDM5M3oiLz48L3N2Zz4=", 
  "keynote":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iIzU2QTBERCIgZD0iTS0yNTMsNDA5aC0yNGMtMS4xMDUsMC0yLTAuODk1LTItMnYtMjBjMC0xLjEwNSwwLjg5NS0yLDItMmgyNGMxLjEwNSwwLDIsMC44OTUsMiwydjIwQy0yNTEsNDA4LjEwNS0yNTEuODk1LDQwOS0yNTMsNDA5eiBNLTI1OCwzODhoLTE0djE4aDh2LTZoNlYzODh6IE0tMjYyLDQwMnY0bDQtNEgtMjYyeiBNLTI2OSwzOTZoOHYyaC04VjM5NnogTS0yNjksMzkyaDh2MmgtOFYzOTJ6IE0tMjY2LDQwMmgtM3YtMmgzVjQwMnoiLz48L3N2Zz4=", 
  "num":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0ZBQzI1RCIgZD0iTS0yNTguNSwzODZoLTEzYy0wLjgyOCwwLTEuNS0wLjY3Mi0xLjUtMS41czAuNjcyLTEuNSwxLjUtMS41aDEzYzAuODI4LDAsMS41LDAuNjcyLDEuNSwxLjVTLTI1Ny42NzIsMzg2LTI1OC41LDM4NnogTS0yNjAsMzg4bDQsMTRjLTIuOTU5LDEuNjgtNSwzLjk3Mi01LDhjMCwwLDAsMC4zMTYsMCwwLjVjMCwwLjgyOC0wLjY3MiwxLjUtMS41LDEuNXMtMS41LTAuNjcyLTEuNS0xLjVjMC0wLjQ2NiwwLTQuMzYzLDAtNy42ODRjMS4xNjMtMC40MTMsMi0xLjUxMiwyLTIuODE2YzAtMS42NTctMS4zNDMtMy0zLTNzLTMsMS4zNDMtMywzYzAsMS4zMDQsMC44MzcsMi40MDMsMiwyLjgxNmMwLDMuMzIxLDAsNy4yMTgsMCw3LjY4NGMwLDAuODI4LTAuNjcyLDEuNS0xLjUsMS41cy0xLjUtMC42NzItMS41LTEuNWMwLTAuMjA2LDAtMC41LDAtMC41YzAtNC4wMjgtMi4wNDEtNi4zMi01LThsNC0xNEgtMjYweiIvPjwvc3ZnPg==", 
  "svg":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0M1Qjc5RSIgZD0iTS0yNTQuNjcyLDM5My4yNDNjMS41NTMsMC41NSwyLjY3MiwyLjAxNiwyLjY3MiwzLjc1N2MwLDEuODYyLTEuMjc4LDMuNDEyLTMsMy44NTl2Ni40MThjMC41OTUsMC4zNDcsMSwwLjk4NSwxLDEuNzIzYzAsMS4xMDUtMC44OTUsMi0yLDJjLTEuMTA1LDAtMi0wLjg5NS0yLTJjMC0wLjczOCwwLjQwNS0xLjM3NiwxLTEuNzIzdi02LjQxOGMtMS43MjItMC40NDctMy0xLjk5Ny0zLTMuODU5YzAtMS4xNzYsMC41MTctMi4yMjMsMS4zMjUtMi45NTVjLTEuMTE2LTIuMzgzLTMuNTE5LTQuMDQ1LTYuMzI1LTQuMDQ1Yy0zLjg2NiwwLTcsMy4xMzQtNyw3czMuMTM0LDcsNyw3YzEuMTA0LDAsMiwwLjg5NSwyLDJzLTAuODk2LDItMiwyYy02LjA3NSwwLTExLTQuOTI1LTExLTExczQuOTI1LTExLDExLTExYzMuMTY3LDAsNS45OTYsMS4zNiw4LDMuNTA0di0yLjc4MWMtMC41OTUtMC4zNDctMS0wLjk4NS0xLTEuNzIzYzAtMS4xMDUsMC44OTUtMiwyLTJjMS4xMDUsMCwyLDAuODk1LDIsMmMwLDAuNzM4LTAuNDA1LDEuMzc2LTEsMS43MjN2NS43OTdDLTI1NC44OTIsMzkyLjc2MS0yNTQuNzY0LDM5Mi45OTMtMjU0LjY3MiwzOTMuMjQzeiIvPjwvc3ZnPg==", 
  "pages":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOmV2PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMjg1IDM3NyA0MCA0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMjg1IDM3NyA0MCA0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZmlsbD0iI0ZBQzI1RCIgZD0iTS0yNTguNSwzODZoLTEzYy0wLjgyOCwwLTEuNS0wLjY3Mi0xLjUtMS41czAuNjcyLTEuNSwxLjUtMS41aDEzYzAuODI4LDAsMS41LDAuNjcyLDEuNSwxLjVTLTI1Ny42NzIsMzg2LTI1OC41LDM4NnogTS0yNjAsMzg4bDQsMTRjLTIuOTU5LDEuNjgtNSwzLjk3Mi01LDhjMCwwLDAsMC4zMTYsMCwwLjVjMCwwLjgyOC0wLjY3MiwxLjUtMS41LDEuNXMtMS41LTAuNjcyLTEuNS0xLjVjMC0wLjQ2NiwwLTQuMzYzLDAtNy42ODRjMS4xNjMtMC40MTMsMi0xLjUxMiwyLTIuODE2YzAtMS42NTctMS4zNDMtMy0zLTNzLTMsMS4zNDMtMywzYzAsMS4zMDQsMC44MzcsMi40MDMsMiwyLjgxNmMwLDMuMzIxLDAsNy4yMTgsMCw3LjY4NGMwLDAuODI4LTAuNjcyLDEuNS0xLjUsMS41cy0xLjUtMC42NzItMS41LTEuNWMwLTAuMjA2LDAtMC41LDAtMC41YzAtNC4wMjgtMi4wNDEtNi4zMi01LThsNC0xNEgtMjYweiIvPjwvc3ZnPg=="};
  util.attachment.getFileTypeFromMime = function(mime) {
    mime = mime ? mime.toLowerCase() : null;
    var fileType = mimeToFileType[mime];
    if (!fileType) {
      if (mime.indexOf("image/") > -1) {
        fileType = "image";
      } else {
        if (mime.indexOf("audio/") > -1) {
          fileType = "audio";
        } else {
          if (mime.indexOf("video/") > -1) {
            fileType = "video";
          }
        }
      }
    }
    return fileType;
  };
  util.attachment.isThumbnailableMimeType = function(mimeType) {
    if (!mimeType) {
      return false;
    }
    if (mimeType.indexOf("image/") === 0) {
      return true;
    }
    return mimeType.indexOf("video/") === 0;
  };
  util.attachment.getFileTypeDescription = function(mimeType) {
    switch(mimeType) {
      case "application/vnd.google-apps.document":
        return util.loc.t("Google Docs");
      case "application/vnd.google-apps.spreadsheet":
        return util.loc.t("Google Sheets");
      case "application/vnd.google-apps.presentation":
        return util.loc.t("Google Slides");
      case "application/pdf":
        return util.loc.t("PDF");
      default:
        return null;
    }
  };
})();
goog.provide("uno.util.resource.generic");
goog.require("uno.util.canvas");
goog.require("uno.util.img");
goog.require("uno.util.attachment");
(function() {
  var generic = uno.util.resource.generic;
  var util = uno.util;
  var resourceFillStyle = "#8E8E93";
  var resourceFontStyle = '12px "Helvetica Neue", Helvetica, Arial, sans';
  generic.findResourcesInClientHtml = function(root, editor) {
    return [];
  };
  generic.findResourcesInClipboardHtml = function(root, editor) {
    return goog.array.filter(root.querySelectorAll("img:not(.en-todo):not(.en-crypt):not(.en-richlink)"), function(el) {
      return generic.dictFromClipboardElement(el, editor.context) != null;
    });
  };
  generic.convertMediaToSlug = function(enmedia, props, editor) {
    var slug;
    if (props.state && props.state === "loaded" && util.resource.isImage(props.type) || props.state == null && util.resource.isImage(props.type)) {
      slug = util.img.convertMediaToSlug(enmedia, props, editor);
    } else {
      slug = convertMediaToImage(enmedia, props, editor);
    }
    return slug;
  };
  function convertMediaToImage(enmedia, props, editor) {
    var img = util.resource.findByRef(props.reference, editor.field);
    if (img == null) {
      img = new Image;
      img.width = 160;
      img.height = 120;
      img.style.width = "162px";
      img.style.height = "122px";
      img.setAttribute("data-hash", props.hash);
      img.setAttribute("data-type", props.type);
    }
    var canvas = util.canvas.create(img.width, img.height);
    var ctx = canvas.getContext("2d");
    var padding = 10;
    if (props.state === "unloaded") {
      renderUnloadedResource(ctx, img, props, padding);
    } else {
      if (props.state === "loading") {
        renderLoadingResource(ctx, img, props, padding);
      } else {
        if (props.state === "loaded" || props.state == null) {
          renderFilename(ctx, img, props, padding);
          if (props.thumbnailURL == null) {
            props.thumbnailURL = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgd2lkdGg9IjQwcHgiIGhlaWdodD0iNDBweCIgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM6ZXY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEveG1sLWV2ZW50cyINCgkgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9Ii0yODUgMzc3IDQwIDQwIg0KCSBlbmFibGUtYmFja2dyb3VuZD0ibmV3IC0yODUgMzc3IDQwIDQwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNDQkQ5REYiIGQ9Ik0tMjUzLjExNCwzOTUuNDU5YzIuMjk1LTMuNjU2LDAuOTMzLTguMzMtMy4wNDItMTAuNDRjLTMuOTc1LTIuMTEtOS4wNTctMC44NTgtMTEuMzUyLDIuNzk3DQoJYy0yLjI5NSwzLjY1Ni03LjAxOSwxMS4xOC04LjY4OCwxMy44MzljLTEuNjY5LDIuNjU4LTAuNjc5LDYuMDU3LDIuMjEyLDcuNTkyYzIuODkxLDEuNTM1LDYuNTg3LDAuNjI0LDguMjU2LTIuMDM0DQoJYzEuNjY5LTIuNjU5LDcuNjQ1LTEyLjE3Nyw4LjY4OC0xMy44MzljMS4wNDMtMS42NjEsMC40MjQtMy43ODYtMS4zODItNC43NDVjLTEuODA3LTAuOTU5LTQuMTE3LTAuMzktNS4xNiwxLjI3Mg0KCWMtMS4wNDQsMS42NjEtOC4yNzEsMTMuMTczLTguNjg5LDEzLjgzOGMtMC40MTcsMC42NjUtMC4xNjksMS41MTQsMC41NTQsMS44OThjMC43MjIsMC4zODQsMS42NDYsMC4xNTYsMi4wNjQtMC41MDgNCgljMC40MTctMC42NjUsOC40NzktMTMuNTA3LDguNjg4LTEzLjgzOWMwLjIwOC0wLjMzMiwwLjY3LTAuNDQ2LDEuMDMyLTAuMjU0YzAuMzYxLDAuMTkyLDAuNDg1LDAuNjE3LDAuMjc2LDAuOTQ5DQoJYy0wLjIwOSwwLjMzMi03Ljg1MywxMi41MDktOC42ODgsMTMuODM4Yy0wLjgzNCwxLjMyOS0yLjY4MiwxLjc4NS00LjEyOCwxLjAxN2MtMS40NDUtMC43NjctMS45NC0yLjQ2Ny0xLjEwNi0zLjc5Ng0KCWMwLjgzNS0xLjMyOSw3LjIyOC0xMS41MTIsOC42ODgtMTMuODM4YzEuNDYtMi4zMjYsNC42OTUtMy4xMjMsNy4yMjQtMS43OGMyLjUyOSwxLjM0MywzLjM5Niw0LjMxNywxLjkzNiw2LjY0Mw0KCWMtMS40NjEsMi4zMjYtNS4yNDksOC4zNjEtNS42NjcsOS4wMjVjLTAuNDE3LDAuNjY1LTAuMTY5LDEuNTE1LDAuNTU0LDEuODk4YzAuNzIyLDAuMzg0LDEuNjQ2LDAuMTU2LDIuMDY0LTAuNTA4DQoJQy0yNTguMzYzLDQwMy44MTktMjU1LjQwOSwzOTkuMTE0LTI1My4xMTQsMzk1LjQ1OXoiLz4NCjwvc3ZnPg0K";
          }
          var thumbnail = new Image;
          thumbnail.src = props.thumbnailURL;
          editor.eventRegister.listenOnce(thumbnail, "load", function() {
            var newCanvas = util.canvas.create(img.width, img.height);
            var newCtx = newCanvas.getContext("2d");
            var image = util.resource.findByRef(props.reference, editor.field);
            renderLoadedResource(newCtx, img, props, padding, thumbnail);
            image.src = newCanvas.toDataURL();
          });
        }
      }
    }
    img.src = canvas.toDataURL();
    return img;
  }
  function renderLoadedResource(ctx, img, props, padding, thumbnail) {
    var dHeight = Math.min(thumbnail.height, 48);
    var dWidth = dHeight / thumbnail.height * thumbnail.width;
    ctx.drawImage(thumbnail, (img.width - dWidth) / 2, padding, dWidth, dHeight);
    renderFilename(ctx, img, props, padding);
  }
  function renderFilename(ctx, img, props, padding) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.filename != null) {
      var filename = props.filename;
      var len = filename.length - 4;
      var metrics = ctx.measureText(filename);
      while (metrics.width > img.width - padding * 2 && len > 0) {
        filename = props.filename.substring(0, len) + "...";
        len--;
        metrics = ctx.measureText(filename);
      }
      ctx.fillText(filename, img.width / 2, img.height * 0.75);
    }
    ctx.restore();
  }
  function renderUnloadedResource(ctx, img, props, padding) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.title != null) {
      ctx.save();
      ctx.fillStyle = "#167EFB";
      ctx.font = '700 14px "Helvetica Neue", Helvetica, Arial, sans';
      ctx.textAlign = "center";
      ctx.fillText(props.title, img.width / 2, img.height * 0.25);
      ctx.restore();
    }
    if (props.filesize != null) {
      ctx.fillText(props.filesize, img.width / 2, img.height * 0.75 + 15);
    }
    ctx.restore();
    renderFilename(ctx, img, props, padding);
  }
  function renderLoadingResource(ctx, img, props, padding) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.downloaded != null) {
      ctx.fillText(props.downloaded, img.width / 2, img.height * 0.75 + 15);
    }
    var progress = Math.max(Math.min(1, props.progress), 0);
    var cx = img.width / 2;
    var cy = img.height * 0.25;
    var radius = 25;
    ctx.lineWidth = 3;
    ctx.strokeStyle = "#dedede";
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false);
    ctx.stroke();
    ctx.fillStyle = "#dedede";
    ctx.beginPath();
    ctx.arc(cx, cy, radius, util.canvas.rad(360 * progress - 90), util.canvas.rad(270), false);
    ctx.lineTo(cx, cy);
    ctx.closePath();
    ctx.fill();
    ctx.restore();
    renderFilename(ctx, img, props, padding);
  }
  generic.formatForExport = function(html) {
    return html;
  };
  generic.dictFromElement = function(el) {
    return {};
  };
  generic.dictFromClipboardElement = function(el, context) {
    var dict;
    if (util.dom.compareTagName(el, "img")) {
      Object.keys(context.resources).some(function(key) {
        var res = context.resources[key];
        var src = el.getAttribute("src");
        var url = el.getAttribute("data-url");
        if (url && url === res.url || res.hash === src || res.url === src) {
          dict = res;
          return true;
        }
        return false;
      });
    }
    return dict;
  };
  generic.convertClientElementToSlug = function(el) {
    return el;
  };
  generic.convertSlugToClientElement = function(el) {
    var url = el.getAttribute("data-url");
    util.dom.removeDataAttributes(el);
    if (url) {
      el.setAttribute("data-url", url);
    }
    return el;
  };
  generic.convertSlugToClipboardElement = function(slug) {
    return slug;
  };
  generic.toggleObjectsInRange = function(range, dict) {
    return false;
  };
  generic.fixSlugInTableDimensions = function(table) {
    return false;
  };
  generic.applyPDFStyles = function(el) {
    return el;
  };
})();
goog.provide("uno.util.img.fixtures.generic");
(function() {
  var util = uno.util;
  var generic = util.img.fixtures.generic;
  generic.map = {"images/att_icon_drawings_40.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAyNJREFUaN7tmu9LE2EcwL+3uhuDnIMQemHdOURSktQVSlOEzXKSWHtl1AtfNAiCXpT044VRQS8qetE/IBRJUb4RX8RQX4Q4jAUTVDKYTufITVE5LtztNnbXi/EwKOY2n+25ze7z5nlxz33v+3z4Pvd8bwxAQ0ND4/+Fwg0QEG2m5tcsm+yCT7qW4WHqm3IcPnd0KD+pB/CdYYqVeMW7zmMXox7PiedPxl8stbeT1ZZGhxsAiYO38BLu2+3FFofQD1ZfOXXHao0MPet7VD8zQ0bXv2ALRBWn1gLUFoktkFTFZQOJ3Kp5OvLw/ewsqediCyw1aN9Jif3d1kZK5KETiCAlsmwFKoosJ5PZ5yGRkaHHN+/xhX9Hlq3AWCwSCYdzn68f5C7UfrBaVy/fDd/6GgoVKo+yFSiKXq/HAxCNbmyEQgCynEzmUpGmkTNfzv6ori6USOxG2u+32SwWRSGjLTOCEI8nEgA8nxpzxW73epeWqAN7KNsK/BujkWFoGsBkSo2kODQCEaRFHlVroQZDU1NLC0BFhc3W0wPAMBxXU5O+nkisrQUCAIIwNeV2A4ji/LzPl3t8JBKR79YuWYEmk9PZ3w9gNHZ39/ZmnqfX19XV1wNUVaVGQXC7x8cBeH5sbHQ09+cVWySxLYwqLpu4zCIcjr4+AIOhsbG5+SD3F2drExOItiouRmNXl8OBc39KYGVlYUQSE8gwLMtx+HFommXNZvw4hRKo2iGSiUBgYMDpzHxdlmVZlgHW1xcX/f7M82prW1stluLnS6wCE4lgcHUVP44kRaOxGKmss0NMIGpH8ONsb+/ukso6O8QEoj4OtSP5wvObmzs7AKIoCHt7JBXtD/F3IOrjJGllZXk5farSNMeZzamfqWQZIBZLbVVUcaUmTjWBCFFcWJibS4+IYHD/w6HUOHTfwqTRBGKiCcSk5BppUg1wodAqEBNNICb4f+04rbyC8/G42gvJmyPgg9uShBsGvwJdsKV0Tk+r7SNfqGsAylX8vLEF6t5Q15VfLhd1A3zKxORkqVYkyotqgAaAiQnqo+4cdcnlUjsvDQ0NjXLmD6E2U1wbu1pwAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwGxDoJAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMGpNUJgAAABMdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9hdHRfaWNvbl9kcmF3aW5nc180MC5zdmc7qb9bAAAAAElFTkSuQmCC", 
  "images/att_icon_forms_40.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAkhJREFUaN7tmk1IFGEYx/+jYZPjJQjpMGVIHTqkSATGugjZxT2I2MEVEjpsnpa61aLQFyTbsegUCB2ilD6OHlTIzwQD0Yg2IrqYpCwICzvDuLQznd4VDNmPd+Z9ndnndxvmnWee+fGfZ4ZhAIIgiOpF4S0w8ivS96mtqemviWf277Ex5Q6anSvhMFpwFfG6Oq8ab7vW+ePEx6Wl/kt3f56/19EhVtseNbwFCuJeYcj50NXltThGY1Z/qA6GQhOfn5xNPVpcFKPrf7gFFhInCdkiuQWKSlwxCiJXk9e/n15eFnVefoGHjMbMqe6jc+3tokQGTiBDlEjfCnQc2y5lHRP5puXx5W8X3Z+RvhWYTm9tmWbp608+PRM/9i4UevEg8Xb1xsaGW334VmAqtbKSyQDb25ubpgnYdj7vOMWPO9d5IXf8vq67JfKIbBGVYlmGkc8Da2uzszs7gGFYlmkC2axlGUaJRXp0HQDwsvI+fJvA/WiaqtbXAw0Nqqpp4s4bGIEM0SIDJ5AhSmRgBTK8Fhl4gQyvRPr2KVwpTCQAlPLaUwzhAoeHx8dbW/e2R0ej0fX1g/eXy/56B6Fp7iSxam5hr+D+Ip1IRCILC27cDHJIJicnw2GlYg+UQE6qdga6BSWQE5qBNAPlQjOQE0ogJzQDaQbKhQRywi/wC2bwPJeTfSFl0wNVGdzd5S3jwq8dzh/E5+dl+ygXJQo4vfx9cwusHVJu1t6KxZTXUPF+evrQJpL1lcZtDExN2QM1I8rXWEx2WwRBEH7mH7lv75z7XaiiAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwGxDoJAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMGpNUJgAAABJdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9hdHRfaWNvbl9mb3Jtc180MC5zdmfQaewzAAAAAElFTkSuQmCC", 
  "images/att_icon_gdocs_40.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAihJREFUaN7tmjFIG1EYx//v8KJRC6F0qR69QYqVji0SGq2IW4cOdlFXg2YS2kJpwaWLRSkdHCRLRuvQRcRJESWoEaGdVHRxESwuouBZk/TuOuhrQYRc/fLe5S7vN7/73seP//vucRygUCgU1QujFnjR+3nw15JpYtL5qL3NZFgbfrqZzk48xzIeRyKiGu9qfTSk/Vhbe/flZSzyrKNDrrZ/aOQKXNwwvrobPT2ixXGan9zd0toTiYk3cyeF9dVVKbZugCzwb+J8wm+R9ARKSlwpuMjx6fn7v1tyOVn70gVWGAZi37AXj8sSGTqBHFkiAyvQcRzHyzoucuzT7CsRMzKwAo+OTk9t2/t688G911p7IjF6Zzpn7R0clKuPwArc3NzfB4DDw+Nj275MpOuWfq4tbdq1LYZRLpE1fou4LZaVz7susLKyuwsAxeLFxdkZUCxa1vm5hwJPATQaBpZpfQQ2gdfR9bq6aBTQ9YaG+np5+4ZGIEe2yNAJ5MgSGVqBHNEiQy+QI0pkYN/Ct4WLBLxcekojXeDMTCpVKIir39+fTnv5tKHr0eilSBpVc4RFIT2BXhMSFFQCiVTtDCwXKoFE1AwkohJIJHAzsNISrBJIRM1AIiqBRJRAInSBWXRjW+TVWBAxbOB7Pk8tU45fOz6wgWzWbx//TR+bZX30vskC3VrNdKaSSaTYe/ZwcbFiE3nVlzuCHWYsLLAme8wZSCb9bkuhUCiCzB8kv8RReqfpewAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMBsQ6CQAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDBqTVCYAAAASXRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvYXR0X2ljb25fZ2RvY3NfNDAuc3Zncn/20gAAAABJRU5ErkJggg==", 
  "images/att_icon_gsheets_40.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAkJJREFUaN7tmE9IFFEcx79jq6Ss5EW0GFiyEqRLF0UZpYNXqUNRXaUlDfLgxVOdEiX2IGKQUl6CiL108k/oIVjcFuwSHowurjBIbnhZVhl215nXQZ5BKjvtb+Y9Z/d9bsM8fvPjw/f33swACoVCUb1o1AJN4x86HrdGIqGMZuHu/DyuYQT3+vowjsuI19X51fj9p5GZzpFkcvalkRq+1dsrVttfaqgFjsV9xAQO+/v9Fse5fqlxrnXbMIZfJHtmv6+tidF1ErLA48RJQrZIukBBiSsFF/nk91d9rjmVEvVcusBzRvv78FLL2+5uUSIrTiBHlMjACrRtxhyn9DoucvAg8e71jvd7ZGAFmmYut7fnfv3NN01d+jfDeLD5ORf7YZpe9RFYgcvLu7sbG0A6nc1mMoBtO46bRHYtXUnf+KnrXokMyRZRLtlsoWBZQDxumuvrAGBZxSLA2P5+oeCiwCS+ALpO7SOwCTxJfX1tLaBp4bDIl6oKEsgRK7ICBXLEiKxggRx/RQo/RLa2Bgampvyr39a2sDA6etodLvLoyvVhU4LAnsLlw0Uyxhi9mnSBZyXm36S6XeeehgYvRroK9kB/kZ5Atwnye+8sF+kC5Y2wN6gRJiI9gWqEiagRrnKkJzDoI6wSSER4As/+Vg0mKoFElEAidIHP8QsPvfgxJBb2CjEs5vPUOnSBeW0MnYmEbCH/i3YRjwB632SBh0WnHR3RKKZhYnF19dwmkvf1CUO4vbJiPwtdvXAnGpXdlkKhUASZPwFu9jieEVOZAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwGxDoJAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMGpNUJgAAABLdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9hdHRfaWNvbl9nc2hlZXRzXzQwLnN2Z4XZDF0AAAAASUVORK5CYII=", 
  "images/att_icon_gslides_40.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAmdJREFUaN7tmMFPE0EUh3/bZZfUAuEAmpQm3UQTo0kvGkhj4QJE9OLJREM4mV684En/DnowHghX45VrlxKDUAwHTNCDiSHQQL02FDbYrdvxsE4wCNh2pjPsOt9xM/PmvW/f7uwsoFAoFP8vGmuA40KhAiSTuIonwMICqigDY2O4Q3KAaXYqcf3TtW/TybU1817q+dvS6KhYbSdEmCNQcTfIK2BiotPiKNrwlfs3n2UybvHzm+nk6qoQW2fALpB2nCRki2QXKKjj/gUV+fP6l/GnH9bXRa3LLvCSQb5G528tp9OiRIZOIEWUyAALJMTzmhj1W6Rb3Hrw+Dv/d2RgBTYajlMqNT9eG469Ts1nMj/iHwsPH+3t8cojsAIJqVQWFwHPOzra3vavNNORemnQSt9NJHiJZP+QPl5aAggRIe0i6nXHAQDXPTxsZd7AwMwMoLXtIbAdeBrDiMUAwDR7e0WuGxqBFNEiQyeQIkpkaAVSOi2yS3RBjUZ//9QU4HmWlcv5pcXjLBFdt1wGdH1nZ3YWiEQODmz771FU5Mms1jab8xDegZ5nWXNzALs4imkODf15Qy6GijSMnh4eq0t4hP2C+dPdnUi0kgUfgcIf4dMYxsZGX1/78+v1kZFqVV7+od9EOo0SyIgSyIgSyIgSyIj0XVj2LsqKhA70Tw78qdX298VXI1wgPXLxE+mL0/XdXT+uWELzQ7VdotHJSfVDVSJKICPsAje1F4Dryi6kZYq4DdRqrGHYBerkPbCyIttHG7zjkTe7QEfrArJZFLEF2Pal7Uial42XQD6PPEkB2azstBQKhSLI/AJie9putJDt3wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMBsQ6CQAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDBqTVCYAAAAS3RFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvYXR0X2ljb25fZ3NsaWRlc180MC5zdmfYvJjpAAAAAElFTkSuQmCC", 
  "images/att_icon_maps_40.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAA6lJREFUaN7tml9IU1Ecx79XuxukmZBFD5YF/iuFysy0JYJWL2FGlPSPXhwFRkGtv1BU0ENFSQ8iPqgUjSL1xRhBCyLSpUzZi9AEoZStOXKFOPfn3u3u9CCXUW5s8247W93Py2H3nPu7v/Phd8899zJARkZG5v+FkRrgq6c+d8fjggJhH15nVHR3MyNkDXpra8kEcw2jCkWiEl/1vC57v9tgWH//zpsH5r17k6stSIbUAKI4PMNDXG1oSLQ4EaUmv2njBZXKfuveoRtbhoaSo2spkgWKFUdrArRFShaYrIqLhCjyx+a72usvhoeTdV3JAlMN1rSBK3BWVydL5D8nUCRZItNWICGBgCBEHieKtN+63XJ5Lv5rZNoK9Hrt9pmZ6McrNZv2FL5Uqb4dvDRz7qPFEq880lagx2M0GgyA222zWSxAICAI0VRkrrb87bYv+fnxEil5Iz05WV+/cychydEWnvl5nvf5gLm5xTZaGhqMRrOZWbaHFbQnLqJU7t6tUgErVzY2HjsGsGxRUUlJsN/nm5ycmADc7oGBvj6A40ZHP38O9ufkKBQsG/wdq8i0FZidfebM2bNAVtaRIydOhB+nUJSXb98ebF2u/n6tFlhY0Gq7u4Pjki2S2hooVlwkceHIyjp69PRpQKmsrKypWdoviszN/VNovKEmULxV/4bjxsZGRgCHo6WluRlwONTq5maA500mozFUnKamUHFEEi2SmkCWLSwsLl563Ons7GxrAwTh58/ZWUAQHI7ZWWB+vqPjyZPQcUpLI18vUSIproGBQCAQjziExBJHFBmvfQO1CvT7LZapqVATbG29cgXIzMzLW7t2sV23DsjJOX9eo4k+TiRWr45PJVKrQK93cPDDB4BlS0rKyoLHFYqKiqoqIC+vq6u3N/o4tKBWgR7Pu3c6HSAINpvVGvv5gmC322yAx6PX63S0ZkFRICE+H88DTmdPT0dH7Oc7nV1d7e0AITzP87RmkQLvwhw3NjY8HGzjPT7RUBcoEqmipFZsokgZgZHWNKlrZqJIGYEi4Z6qtJ+24Ug5gX6/1To9Her48vZ7iYb615i/IcTlWlgAfD6zeXwcIIQQQgBC3G6Xi3Z2S0k5gSK/ft28efEi7Swik3K3cLohC5SI9L92lJJH2EXzXWCZZMKEVo6TGkZ6Barxg9R9+kTbR6wwxwFyWHrekgVmPGVOku9qNXMKJqJ//z5VK1LMi9mKrYBez7zKqGQOqNW085KRkZFJZ34Dzg3IpkPczfMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDAbEOgkAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwak1QmAAAAEh0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2F0dF9pY29uX21hcHNfNDAuc3ZnIHRLhQAAAABJRU5ErkJggg==", 
  "images/att_src_icon_dropbox_28.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAQAAADYBBcfAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgIRBwMKqfdWAAACTklEQVQ4y8XUTWtUZxjG8d+ZqbpogokiTkkYo2aGdCNibdOVjnUhVmjiyoWKiLjV+hH0Ayi2q0JDS+2mpUI1CWoQdFELdl90MiFIEmNUfEvaGjUzTxfzZMa86U6f5X3d/+e6zn3OuXnXJ1lYClld9mjTijF39LmQjL7lntASvgszYf4ph19D2xscQ7dzGsoGDZkwhUYZOTlpphxILi4KhuNOSxVd93RejiY75Kk4kXyzAAzdzofUdX8t8RCfKUgq9s66RjC0uqXh2pIYdCowpSMZh1SsntJQrGHrHZYFax2Sj9WbSjQ6+ZpjyBoup7/3FCsUbEbFVdN2W4bbBjzHSkely9qSsVnHbunBOJLtNlfD+9CqKHfYBZ4pkdZVj7qbUgw04CYeOOcPN/QYQVFfVEvwZR1sZ6I2hBtG/OY+eOJ3Iy6ZidoEbKyDGf6NUrODso7YKkG7w7IOWR3Vf6AFPlj4vtZghZ02mPZxvOxTl+uzrNQdx2mI4BW9XoBhfytjWm/EYtd43XFYPuNxFEf94hPLrdTuipw//VfLk6l21xz7ydXEl7Z4qGirdTYZtCkmIHb11cELynnNUXyh3yMFsMorAzWwSTszemtgMurHVGytniE/uK2oR/G16hfS9CRjtTERWtzS+OaP/HPbmdSR3KtHldy1T7mgc0ms0zYqDlSxuT/yMWekSq55Mg9qtkOOiq+Tb2drc1fHV37WWDGo5H5cHWvl5aSYtD/pWyqPsCacDa8WWVY/hY/mdi62Hlt12WN9XI/D+l2sTvL9nv8BmADVTZAM0RgAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDAbEOgkAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwak1QmAAAAE90RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2F0dF9zcmNfaWNvbl9kcm9wYm94XzI4LnN2Z85N2HQAAAAASUVORK5CYII=", 
  "images/att_src_icon_evernote_28.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAQAAADYBBcfAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgIRBwMKqfdWAAACHElEQVQ4y8WUv2/TQBSAv7NpBZJDmwFhSKhSUYdIIJggDAhSNqhEwoSATkisQP8E+ANAgBiQioSACYmhJRUTajcoW1mqxigC1Q2BSgWSwFBiH0Oci+0mYYO32Hfvfe/X3T341yK2bskR8kyQIgk4fKTIjFj9ix+ZkA9lU0bFlc9lqk9EWeAphkuJD1SpAzFMLCx0qDMpZruC8jq30VZY4Hskj2HGSYPHlLi3BZQFXkhtgXc9ijhGDuFxvh3VB2WSZYz5nhhAlhzUyYgKgObv3sJY6YvBIjbEuBmIKEcou/q0qi3OAU5Q4xUb/EIqdIir6C4p4cA2AAropQB2EQedOJeATd7w1tf8wCajk+dBO9UzYCu/h1gjqVaDZALp2gBnoR1xDKpKeZSBUG07Av9VgP2d5pjwUykbAcMKDbYH1g2ARLCrAfkaiuaGLpcA8DpgBQyl/OR/14E4QyGnhm/drrFM2mTDVy7hsQ+T1+xkL0dCqZstaxVxDiyl9FiiyDSbHGaRdeUQfKtiB5zBTROP1DpKhQEG6TzFYcagyUsFilUea+QioMNBrtDkvdo5jQ6PhKPaBDLBMrH+l/w4p6BGRnwOHIdY4wJujmxPLMtJ8JhsYeGHfI07aDbzfItAccaxwOOGuB86UYWe4xkxjxI2X/zRsZs0FhrUuCyKPROSu+Rd+bvLsHoi94Qtu43HJHkmGPXHY5k5Zlud/L/yB60vvrbSswzaAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwGxDoJAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMGpNUJgAAABQdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9hdHRfc3JjX2ljb25fZXZlcm5vdGVfMjguc3ZnEE07QgAAAABJRU5ErkJggg==", 
  "images/att_src_icon_google_28.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAQAAADYBBcfAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgIRBwMKqfdWAAACHklEQVQ4y8XUu2tUURDH8c/daCFsIBYhK1nEqLsEhRSCJoXk0fnCRBsLgyAiWPn4E/QPUNRKEAS1EkQSYylGg4WvwkJCshIEo0YUH9kIQrJ7LHKzezcvO53mHn4z33Nmztwz/GuLlkpho177bZLFpHeGDETv/7JPaA7XwlxYbKVwJ2xa5cTQ55Z0ybi3phRRLyMnp46i/mhwWTCccVFqzLAfi/Jo0CNP2bnoyhIw9LkbUsOer1DELt2iskMLp8ZgyBqVfrQiBu26KWqNPsKaWL0gPZbAInu0IbjhS6w90yxX77yTkIobcKxkOLH7Ac/NItKdUB8qcTxkK6A+deOJK2mxzXYvwGYtFf2nAnV6q+BeCok0u7DTqBnQk7j6AuyrgluZqji3acIaWU9Bo+0V3xRsqYIZfsWuOrtB0RuvfQWd1sbeGWiuggnboQE8MSsY9ttva7Ul216utuOjfNq3GITPvuiIm1CJRXo+ugJOyGdi8LUuPLZHJpHH4/ibmY+upPqAXOx6adqEdTVY0at4lYOhKjiglLcezBkxorOm7hGzoMFW5tyvVEu47sS4e1a3w3Jci04lwWaj6lf/yTt0Ma01+pRoR/TBEaVu7Sti7Top65/Hah/yaZekCh75vghar0eOsrPR1QWtdnQcdFt92biCz/HoaJKXk2La0WhoxYRCY7gcZpcZVjfDhtrI5cZjVq/9WuLxOOGBwWjSf7c/JSjCkef4SfAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDAbEOgkAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwak1QmAAAAE50RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2F0dF9zcmNfaWNvbl9nb29nbGVfMjguc3ZnYkokAQAAAABJRU5ErkJggg==", 
  "images/checkbox_off.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwEAQAAACtm+1PAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgIRBwMKqfdWAAABKElEQVRo3u3YsYrCQBDG8VljdaCgfcDm6thdZxnfxwXJA1gtxLyAT6CdWpxFGjs7SSPbCdpKMAEbEewOlZvDNDtXfL9OJqvzJ1ZLBAAgSf01HKx938uShHZhSB+NhtPNLmVJkzRVnSgy1trKAYO173vX7Za+222ni7/a5PltFATj3uHw27jGnfOyJBFfnojoq9XyFnHMjdkA2oWh9O4/dL/PjersoZf/vDFudx4OHz7EzSb3XO2N7/rXECANAdIQIA0B0hAgDQHSECANAdIQIA0B0hAgDQHSECCNvxu9lOXj/ejTXaVr+/OZG/FvYJKmgis/UdlqVTlAdaKINnkuvTzNTydaal05wFhrb6MgIJrNSBeF88V1Uaj5dKqW3a75PB6d/z4AwFvujM5H5k1c2IwAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDAbEOgkAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwak1QmAAAAER0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2NoZWNrYm94X29mZi5zdmcAxvXwAAAAAElFTkSuQmCC", 
  "images/checkbox_on.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwEAYAAAAHkiXEAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAA09JREFUeNrtm19IU1Ecx793OVHClaaPEgT1FvrUQ0JdEnXKZFcqIRQFXxSkhxRyQuQGPeiD86GE/oCgSYELt5ljCkpvog+C4ZMgQSj0IDadBMvpTi/7rTTWPHavd7s7n8fdnXvu+X7GOb972AEEAoFAIBAIshHptA3tXb5Be1dp6cFjdknaHhqS7mAfudXVuIISbBUU6D0wzfiCLZTs7eEbdnBxft40bfLFFIdjqsK+MFWxtsZ7O24BFPzhbTzDk5UVvGEjUltRkd656EYRxtEcCp0rlm6yhbIyv1vp9rs3Nk7a3MTbH/3isz544juaMV5YeNiEt2gZHORtzi0gMdUIjjLJiqWtmhreZtwCDD/Hn5bP6MSwxcLbjF+AQFWEAJ0RAo7jwgfcW1pibsnD7vf3a92dEEDIALC8zJ6aH0Tf19YGrinv/E29vYxJM8zqcGjVrRAgA8DyMvtkNkejVVWBgM0WCIRCdDkQUF75OwYGtBKRvQJk4F/BH0cKsJdSR36+2o+RfQJkgCd4G7xMgdMJG3xQ+vrUfpzsESAD6RQ8YXwBMpCOwRPGFSAD6Rw8obmARD0dr681H1G8n8hMNGo2V1ama/CEdgLq4UWD00n1dKQnajf7a2rYa8nNuhYXVe9PBv6s4+fmGhs9nt3dZF/XO3hCfQHx4KfbG8Z8rS4XfUyB/GzZf5j73GpVTYQMZMJUkwzVBUgv4IOSvF5WTYQMZHLwhOoC2GWMorWnp/6616LsJt9LIRGxW7kj+20cU5MMGCF4QrM14KQigut1V4Pr4XBKETJgpOAJ7aug/xUhA0YMnjiz9wASkQgoCSSC1ohMKSdPS86Z9xgPqP6r16KM5uV9XG0I+y78vcuYqoz8fbvMDJ7Q7U34pFNTMjI9eEL3rQheEUYJntBdAJFKhNGCJ85+DUhBYrFe9SoKIpHEBYMFT6SdgAQGDfw4aTMFZStCgM4IATrDL4D+Hy84igsKfKlfHI/DLyB+MEHv8aYbbAczsM7O8rbjFkAnQuhggt4D1xs2hvP4sb0da48xk9TdzdueWwAdxaETIXBJLub0eFCGYXSGw3oHojnxcbJHyENkYiJ2I3ZgyikvD67frZsMbm7q/XgCgUAgEAgEmcEvuKRTfu/rKrQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDAbEOgkAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwak1QmAAAAEN0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2NoZWNrYm94X29uLnN2Z9Ts0gYAAAAASUVORK5CYII=", 
  "images/en-attach-icon-3d.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABkJJREFUaN7tWn9MU1cU/m6Ldcwl4lTG1OnEbbDhdBE18wcmzqlRJ46ZuOkoKGRgC7pSXlvQiIBO6C9+DGwZBgYUqovZMkEXXTaXSFQCwjYmajURZ9RhnYqZk6n03f0BF1kNKdpW1L3vn5f2vvOde77ed+855xUQIECAAAECBAwMyEBPoDcoJWStvzrI+NWqVaSYLsQ7mzf3jMWRAziYkVFk19mSP7RaAYAQSgd6zgMuoEyiDtKeCgrCTf6EWF9QgE9JCl6fP79Pg2B0EmttLSbSdfz1xETzPEOgqrW5eaDm/8gF5KScVF8xZMgti8gCqUpFL9Kp5HRqKrZiLmokkn4TVaIFoZ2d+J2ApJlMjhTy5t0laWnFxVptSsqNG0+VgJQSIp+uGp1TKpXS5yGl47VajIcDTQEBHnPyM6pJytWrpBUpdPeWLf6Xh6y5GVFQkI50pIPnnzgB4zdpjhtLJk8WaR1ieqawELGkFCNmz/aWv/twFPF4uaGBDOf9EJ+QYPrROIK72tDgaTciTxEpoEAu9fOTXVMvNobl54vyeDUNPHasv8LRFBxH4oULpBFWMiw62nmc3KFt1D88HKBalJw963JCM/AFzk2bRv8Rcfi8rk52jms3VFZUJNSnztv2w/Dhnorb7RUom5p8wLBg0SIsEJ1AZFkZruMS7P7+Lg2rEYj2jg76Hf2AlGq1vrccZ8lYnS53Ru4MZV1Hh0ymUhkM905Zs1mv5zhCko4mHc1529e341lxID2vVpPF5Bsao9EgHGfh5+vr0u8wjIK/3U7ewhGRKTratEK/W1m3f//Dxu/+CmwWrcCh8vJ+CzcR1fipulqcTo/Q10JCiiYbXki+lJHBhHNlzu5jdoyH8br03z1P+gtm8vLycnfD93FbwFjEYevIkX0LjCt4kefJFOTgvchIU4Jez3E7dwKwYZ/b3lH4icGiimpt7fq0bJl8nSrVYF25kjZBib2VlZiEkfhDdP9C6e8P7gIe2wP7RHcA9Ax0aMzJkU9XjTaWREUBXaezp9zIYzmpvmLpUp7Dxxis0/UpnIfhfQFjEEC2HD7M0hYailX0enm5TMKdNKYeOsROa2czGkHbqP/KlezqPM7sZBLupCGltpZKSACxV1eTbExE4ZgxPX69DPcfYRcwT9MnK9vDwu7LA2NJKZpmzxYd5K/QZ5qauk7JqiqRfdDyOwFJSdunZ1lU7+7axXji4jSa7OyhQ8XZ9LdB+zIzMY5X00C5HLEkBNd9fO7LA81D1vx1o6Dgsuxv1XNwOLwVn/dXILpqVlO9/mJybEWFY6yIdtYHB9MNOIeL+flohh2jeB5a8hnapFL+lbt7JfEtLbIAdb7h5ehodhVnO9J9dths2EhD6LL16xk343FMEr1/d+uECabL+jVcRH6+txNoBq+vQGf0lFrFAKBQyCTqIG282Yx8vkZ8srsWls2fjwgKoKysx3AjSQNwrxb+lhby2xMTi14a2Fr4kQvoDPMdnU0TbLNBAjGlCxf2dGOW03BcqKxk99GvSTXGREYW2XU2ZaPVCiD3cejGPJJHuDfYXib7Uh1kXJebK7vGdRjDOA7oetSL7Dob91FVlbNd7+8JoZTZMR7G+1QKyJoJxpKoKPF5nvhMP3UK9TScjlMoMI4sp5lZWQ9Myuy6eRivt9KkARNQ1qAy5vjV1rL0pacL02svozGhoQ9MzOwYj3Oa1O3X2/F5fw8sRRvdNGsWWiHGlLY2cg0W0qrRmMz6i8pGiwUPuZf9p5HaOmeOPJaT6hVLl/Jp5E+ywmQi2QDFrFneDs/7jzAr5V6FGqFKJUtnAM+25E0lBosqqqZGZEAVbqvVzK+3w3NfwO7uRp/jrJTrRBZ2WK2y7aogw5I9exJ3cFJ9xfjx7rpnPIyX+XFZyrma9yMT8Hv+DVSuXt3vCR1HOOaGhzvSyUxyuqVl7a/cZeOozZtZm8qVObuP2TEexuvSv1M7y93wPXZKsYbq7amDNjgWZmZCCSnscjlqUYpIsdg1Q1ejlNxBNE1VKFht2zPR7oYqlaCcZOXlAUSD2MBAl7RhiEGlw4EcWOBvMg0+dneb+EBaWh7ykETa2x8bAZ3xf2npCy+VngQBe0N4relhCC/WPYgn8a8dAgQIECBAgICBwr8VnItduBCehgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMPGM87MAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDCA0UsPAAAASXRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvZW4tYXR0YWNoLWljb24tM2Quc3ZnojGHtgAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-after_affects.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAA1VJREFUaN7tmF9IU1Ecx3/nrrmQWSmBU0duJcgcIhllkqBgKEhpDzoohw9CSj1EhNRSpCIjBy76Q6U9jGFbgpsvmS8+KZTLIkTBmSm5JETBWiiam+yeXryrVpfde3fvtofzeTmM+zvfc/jy2/eecwEIBAKBQCAQCAQCIdYgqYTduA/PYI0G3gYdeGZhgbXwuKwe6bTaYnQW6ZDXG29D+EJJJ00bAMrKxKtLTKQz8AX+inNKS0WrS1CkMzATfkAnh87iWpegiJ6BnLMvHIFZOP6yd3n2qFZLX0SpwU2TCW6iAcisqoJUKEKv09PBB+O4ZGUFTaBmVD00hCqDc1Sv2VxU3aDKfc9jfyxI0IFCM43fvLEax9xHQ2UlvkZdDr6amgIncoKzqQn0QMMDtRoywY0/yOXMb2zET3F5czNdIjsQNE9OjufYH868qahIPAOFZhrHeUzHUZ9wO/3I5cJWOAXflErO68xiK6hSUuh3qAX7Xa6xww6dZyg7O3EMFJppHOcxf1XexoWzYyQ1j6vQM5NJqIxoBoaybze0gV6j+adgC+7AtNcbGsPZmRfSYYPJOBawCjWizdbW5AH65LZVqYT7WAGFbW2seoVwF4bZ9WJmYMQMW4J9YBoZCY0CdVAHrML+jAy253uvyu202WIp6GpQFXRtbPg6fFb5eYuFdbkv0I3PZGXF38BIGXYOqdH86GhoFKiD+yAN2mUytudrVwIBdMvvd7vtdo8H49TVtPrtC1tbQvUisUs0AyNmGNUP8GfnBR0RdepE251kRN2BXLOPOd+FznnRZmGCIEIHhjKr5r+PGUPcdvB4MBagCwA2W5x9YiV6A5nMOggAgyLu7K8s/G0gOgvf4XYwyJZde+4lJeEbCoXeaTDonYGA1AZG/xKR6i7LootLYAAtLC2xTVuj/AgNtrRM1/X3T9clJYm+rzAE34UF33n5EnZHdquf+z36np7Q1U0kiouNxrw8xNuPKDowwrnvMzyG0zYbszG2kanjug71BPtkyZ2dkIsaYXl9XSwDhSLcQK7nvkjwPBcyX1GoY7gLKWpr422kcAN5n/sE1rGsUzRvvKQ7MTyMy+EQ/MzPRxUwga53dyMTGNCRxUXmZRM7KwkEAoFAIBAIBAIhVvwCu8u0NlezHZwAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAFR0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLWFmdGVyX2FmZmVjdHMuc3ZnZxRiigAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-animate.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAkJJREFUaN7tljFI3GAUx9+LXcohUengIBKRjm46CNKknQ8X0dymLo4K0smhpYXrUIrF0qWF4t2kp4NwOjlIooLDzR1FBymd9CK43uvS7ywnueT78qWXk/dbwpGX9yWPP797AAzDMAzDMAzDMP8b1N3whgrggGVhQC7ZFxdhdWRiBf2RkX7cBg8uLzs9CFWMdNo6jt667KJ9gMb7RtCo2bauuqyjP4FfcBoLMZIVty7jaHNgXPe1IuvCet11bZtI+kPn4YgO7u7gFp5CrlZrDNMMjq2v95d3Pvs/9/dVv1tzAlUTlX4SqQyvMJ/L0R5M4kvHwQ38Bc+q1fq3uR92sVhU7attgKpO67gLXTyEw7W12w/uVwfyeen31/Yiqk7LiAtpC4BmVldln3uS9GDhPgpokIYsq/U+jsJvuLp3G53DIPxTJ37fmAVwzi0r6V7Y11ep+D4+cPv19eysA1NThmEYZJ+cPHiwBybh+fi47HmaEtgmQctUpW3Pa15V+yRkYGB314PT07D75MFHOOvtle2beIBRDmu8MUxjwvfFVbVPVkmewFgOE8lrk8CMuFAW5QE23dfiNIFwn3CauLY6UdB04d++nR5MXBL+iYQnRgykDq5rD90vvvE2YNG3VOr0gKJQTmBazuo2F6o7MC1ndZkLpQcY5b6kdJsLFR0YnhDcoO/0qVQy3+6YxxOLi2F1wbu54EVtc5NWcAlfLyy0Pye7LpROYNy9L6rPY9kL5R0otfdF8fj2QoZhGIZhGIZhmPT5Aw6pDHQgp7roAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABOdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1hbmltYXRlLnN2Z76BYtsAAAAASUVORK5CYII=", 
  "images/en-attach-icon-audio.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABN1JREFUaN7tmW1IW2cUx8+5xpfiCyw4hJam7bLCOq0MFHWagt5E6Xzph7H4IVAEV2yyKQPrdCq+sc6KjrTr6MzSTXRFobGlipLO1NxofWvpcJuQDW11jNoWW1u2OkGU3bMPM260s5qbe+O63d/HwPM/5/yfk3OfhwdARkZGRkZGRua5BLcqsNHhIhfFxMA4P8PPZGfDEKpgKD0dkiANv9i5E4xwmWzbt68tsMAbmHv3LlwDFx25fRtVWAmXHA5mgMIwrrf3zI9sNVvtdv9nDTS97CIXJSWRlhIpsbISEBroRHa2aAFehAXoGBnBfZCJlsrKZgMbyAYODkpdl2QG1oKLXKRQ3DtBKlIdP44/Qxu1lpVJXZAH0gOA3mp9ZJmff2gpKurszM3NzV1eFjuO6AYW2e037TcjIlbGQn4IbrDb4QGEgyElxS+u/VOBLfAltgwPK7qWapdqs7I+zczcm7n38WOx9BmxhPR6m81mCwpamd1WEhx54cJWG+eB8uFtytdoVtwhZSFl3d1/bnBwsFj6ohmoPBZpjbSazTBO78F4erq367GewiA8JYXnMY3nDxwQK681pqGQ3k1NXSkJ+T4ovLFRLFmfDTSZOI7j4uJwCi5Tj9EoVKdZqU3QJoyOWq1pmJ4+PCxWgU8RgZ8wbxYWGrOcrc7WhARf5Xw2kM/FM6RpaoJRGILRgADJCn8CwR37GtXRhwwDZgyAjvp6X/MQbGBBARfNRavVqKR9UJuaKnnhT+Bzxy7BJMSz7JHJwV8csXv2+N1AJgyyIMtggGZgQYub/pp7W7hks3E1b0Ui3xiQaDD43UDoghLC+HipC5facPqGunF0/TqkM1CFiVAXEyNW4WLhteEzYKPa/fuFxlMIXWgZSPtJG6JWwwCw/jJHUJ4WltU+a8RYfNMX7Rz4f2XDDjy66Apy9o2M4DH6GhTJyZsV3nDn/YTRyHFOJ5G36zxXwOZltp1tX3+WbtiBzAukx6943tsECgpcdOWKRmN80D/ZPynBzULiuPQ6roBtY+M37MC1HbBAO7T/9fvRTs7EmcrL0Ql6euvpAynDkIthhoagigGY9d0Q5qPfp1CFCFVw51l6XsfdTbtgd3m55QOtWqtuaPA2P8EzkM/nk/ikixeFGrLZDvmbIXdw9upVofmuW8cMHsJDnZ1C1ws28OyCLk+XNzUF56AJP+7v33RAkQzx+a/6K0xDRV+f1cq6Wff0tN8NXBNI4qP4qIoKMAEHAoa14LhCN2I1Tz4ckrGlpsbnPHwV+Mypa9W13rgBSuhH7vRpoTp+++iY4BJ2m81WKxvNRl+/7qucaOfAh8XzxfPFpaWetwmvE5F41oEF5sEyOMjHRLRFtJWXiyUr+jntcJQj1hEbGhr6m2KHYkdXFxyG96lEpxPdkM2yatxyaRAb3JyT09KoidRELiyIJS/6TeTcXMZExsTi4tIi2tGek0NF+C0EnjoF32ENVnl/nvQaT5xX0ADmkyeXAPWM7eBBsY3z4LebgvEl7j53PyWFOiCMzldXYytcg1czMnwW9ny8GmAXOB0OWuCD6J26us97dXm6vLExqev69zysK5liULIsdMAEbFOroZMm4FFU1NoCPcaCcm6OGsgNZ2/dwgG6B5kuV0AbtmN7T89WPazLyMjIyMjIyDyn/AEId12K0jpz2AAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMPGM87MAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDCA0UsPAAAATHRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvZW4tYXR0YWNoLWljb24tYXVkaW8uc3ZnwuUY7QAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-dream_weaver.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAt1JREFUaN7tl19IU1Ecx7/HO6UCJQqhlIzWNiXowaeCCDRKjKReFlExqLWwXDcYRVrhZBNNIwi8zUI3SaQgFUvMeuihvRdmUBEb2h+miEjhPyL68+uhrsb04nbZvRflfF4O99zf+f3O+fK959wDcDgcDofD4XA4HI7esGQHBAKRiMtFlHCBC+wc7LOztIE8mIxE2FHkE+vvZy+FnelrJenss63jd0rGx40WQi2aC6iIhM3InZ7GdnYR651Od5dVCp7v7jZakGRJM6yyiE8YyczEWyrFjs7OwOGo6Gqy240WJFmME1DGDStaGYOHXDgSCjXtj4on67OzjZ5WophSrofbZgsG2dzWIPW+Dzkv5eQII8KgcN/hoGq6Sff8fvgxjI6MjLmBr7AaV7OyhBNUIKwRRTwFAK93qS0jvt5SpDqf5g4UDxWcars+OlpRYZVaY42NrJZ52HGvV3FAJczYVVam9bxShe6fMD03Nf2ItbcrBqzCHryzWNTmlyhKLhQVya3W69FdQHfXFnYXY2OKAfLhohIhjy6jvqZGbrVej/GHSIqQHUdVcGJ4vtXaiStGQCXHae3EZS9gvPPi32vtxGUvYKIO08qJy15AJeepjUsW3QW8/Tiy7syB3FzFgEJ8Q93UlN7zUovuAv5uZw9+fnc4FAOOYRThoSG1+VkD2mAOh+VW6/Wk/CoXzyJXuWKq9vlQhGF0LIynJ7jFbvT1YZu6er8+s2u44vPJz2nNFIVLu9+YlAu44K4ZA/AFINBuKgX+3oEXGRjGID5OTqab6CArlCQA/XiReF3ZcaLb2hDEvPOaN0WqXOZweMXsgQsIIIrTRKjDB+pwOsvL88tbWiYmkk0T77yl+lOFcQL+cxwe4Q3l2e1um60ytLGnJ9k0c85jVva/82Tkfq32RO0FFFgJemdmsA8PqXZggIrhYa/9ftNe+ppmtljUCieTqMO0diKHw+FwOBwOh8Ph6Mcf0DtKajHjm5cAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAFN0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLWRyZWFtX3dlYXZlci5zdmdrnj5XAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-editing.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAQAAAAm93DmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgEOITR0BZreAAAAQklEQVRIx2NgGAWjYBQQBozYBPf9h9BOjMTxkQETtV04+A1kxCdJStgNHS/TJwxH0yFJYDQdUg5G0+EoGAWjgD4AAAmEGiSYNnVwAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABOdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1lZGl0aW5nLnN2Z5Hsl2oAAAAASUVORK5CYII=", 
  "images/en-attach-icon-evernote.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAA7lJREFUaN7tmF1IW2cYx/9P0mVaA0O7sUDNlGBlrZ6MVTraQSnGldlYtkJVOkvN0Y6D0E2mrC1DScPoMPVCWFkhlWVL2iEt/ZhQ3FqmiV13sY15oRmxLe3E6karYhxLNhdzzrubxQshyOqJb+zO7+7AeZ+PH8/7ng9AQ0NDQ0NDQ2NNQmoHLHUENzlOV1Whk31D8tmz9Bp+wfDGjWrnCYVsNp+PFuu3YoCJcLlGUEE+uFxp9raITu2ANMBaYPd40iUuFUygIMQTJ5IiVyuv6gKRixfpZH7+ajWwlKRIQQiYRbjd6c6nvsDMwQ/x+PF0i3ySBSZJq0jVHyKCEAiIImNp19JJ5eu2ms2hPeX0afPkZNrzpWDtTuBe7JXbu7uFr4Ps7dP8zty1O4GPydLXn5XCfwLnsA3FsRjrRyN77/Jl2RnfpLdu2GAwxI4aDDk5OEdn6JwoAvgCzZEI3sWf0M/P8y47yTpumQsxx5zRKN1XfqMLdjuL6X7VhYuKwjWVZm/r7OzifS9jCPD7AQBb/X5Irs9c0Om2XNrFJrosFv1mvCKPOp14i53CwqFDq90GvwnswRWKXryoHKR6zGVlUYIMytiDB8svdMEFRQnXlJO39d499qZyhvo8Hl5tcJtA+Xrcre8/dizcVmn2ds7Oou3x4ihu3Tbd+1NT+g9ZUB5Z/T44noFP58utBsNKo2S7E/3629PTvLrgJlD/Eozso5KS/7pO+CCwT4THs9k+EDlsKih4qtfYEInE47z64CaQipUote3cudx9ZWXXyiRp/frkdajD1utDU9PoVxW53ofj4zNfRoKmBkXh1Qc3gcoktbM7+/cvFZREEG7dqqvLzY2fNP60UGi3p4pjbM4u+sOenc2rD24PEdqDCuooLY0X5pT97Xz0SPg44Ha8MzjIRnGHioeHcWDBg7smE5pwg0UaG0uvBn4Uu8NhKJiG9+bNn6ttVb4fjhxRnlVa6HWLBaA3eLy9Z/yXCNXjearfvp0Z2Sn597w8fEcv6PL6+uR9M9bYJ1lZurvP1Rifqa2lCyzIEufPLxfvyfsSSYUVATQwlneUthTYhobwLQ3p7ksSphCFoacnXBOuLbmUSNAga2GHKyt5lZm5Akdgw+dE0zEcHLvicPy1Y753YdzhkKWZV2NdjY3WsV2m8brdu1GMDuyoruZVZsZvYbX5/2zhNYImcIVoAleI+gIjuM3a+f1iT4kFXXg4MaF2WPUFtrHvWUiSMkbkv+Joiq7huiTxLkdDQ0NDQ0NDI0P4BxlTbqdWQMDGAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABPdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1ldmVybm90ZS5zdmdZOLbtAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-excel.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABHlJREFUaN7tmG1MW1Ucxp9zL7GoTDo0IxOpMidTcCDasBcCEgxGhZEtpMW2jLElRlFpaDeEDLagAxJeWhbJZDAFwkZLblEzthH1A3ElxrFgSMkgDmNQ2CRkOhkwBeXe4wd3/WC98tZeorm/j/c+93/O8+TknPO/gIKCgoKCgoKCgoKCgtwQXxfMmnDYCrUOBwqwkSYbDFI6OoMY2mQ0ct3GJ23TTudyx3l5q3PwUIvRSKPoFQy1t0uOU4NsTDocnMYo1J42mXztl/F1QcEcEM48l5eHVBShcWxMSke24l0S39Cg03FcUZFGs9T6Oh3HWb4MC6N7aCXurq+XFCaiEnuuX6cHAzr41/Pzfe3TbwG6XHp9VdWtW6SCXCSF2dm4C7PYx/Newu+QjKeCgxn3QhPfceaMTsdxOh3LStUtQxnKwDDEtDDFXmhrw1VkoD8kxEv4ETIwKQhMGz7AyZwcl0uvr9tx8+Z/JkCRjlHDppqjvb14Df1Ee/y4pDAZB6BLTCSlCy9p3iwokJJ9/fyWT2d/tVqJE0GYS0mR0tFq+hU4u9152bit9nRPj7/8+T1Akel96sK5j0tKcC/eRrHHI6UjPyGRXKuoyIrsuGo9EBsrPjfscnQVrY+Opn10M8KPHZMMrgkCLR4ausfyW1LQ/JEj/vb117zlGkgMQnAjmmf7+/EC+pAbGOglfIXkIWJ4WGhkT7FjO3eStoUb/A9uN8nFeoTGxHjpX0UN4ubnmV3oxY74eOdtY1DtpsFBuXz5fQWKOM8ZM6p+HhqiboTSD0tLJYWnaANGo6KYDL6ax8CAZHB3oPejlz5UUiJ3cCKyBSgSFTsStO7ZujpqwCwC/2WPOk+t4CMiJN9rSQlS3W6xntw+RGQP8M/TVBBoe4CaT8vJwRZ0QbuMU/IosSJ9akq4zFaxPXv3ivXk9iEi2x4ohT7bYSvUZmaS37GRJnd2LqZf7QXc18i+Ar0m4CGp9A2Vaq3nseL5r9XAS+4o/sZKOxh/sUZ74BI6CimW2cH4G9kDHPZEzs5ctFgW6yiQTuxgR0cl3y+xg/E3sgUoXqRJEiZJZnm5lE7sKIQu9i0WcXEr7WD+NwG+uLn7m/xulYrnMM6nOxySHcidjoJ9ELvJtNEo/pRgbqCGfcxkwifYhta5Oa/vGlGIAZUK79F45hmHIxcttAz/UN9P+P0akxXpDDz0tM2GONqMFKt12QXM+JzU22w0CHbhs4kJUokucq62dqV62kT6aXFrKxdssNse2L9/tf78tgL1F9qfOPh+UhJG6Y+IXsUelQw71Vss+IKeJTMez6IdjJT+Ns5CPzIyd+WXUDbBbPaVT5+vwN1ooQVQq1XbVeUBnYODeBiP4lJ4+KoLf49vsX18XAgXiviwtDSmjNWw82433qF2nFerF9MDOMkE8rzLlW22xQ0P+8qvz4//2Ims+xK1zc24BA0CEhJ8VliNEFwLDiaHyRhzeMMGWo3HSV9lJRGwDo/o9YvpObMpx2Y7ccLXfhUUFBQUFBQUFBQUFOTnD5IT87RPuiVFAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABMdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1leGNlbC5zdmfxydgVAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-flash_builder.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAlBJREFUaN7t1k9oknEYB/Dvz+lJnBBh5GIucFOhQ4tVWBFdGjHWovCYsDmik8QO4YIxsBUxgmC5iKDVdumwYBHuTwwGHarLYIcIfZV5eGUMysFS7GLTp0t6sKR8/TP48XzOz/s8r1+e3+sPYIwxxhhjjLFmE1ofVNVoNBYjatSL2Wwul8MhSu/3r3nl9c2ia/ZA2XCANeIAa6RvVOP9+iY1G29gjaQJsPgvrT5WjsbPZLPJY8rZ2J2NjeSbyA/l28REwpKwJCwWS73nShNgyRVappdGIy3Rcwx2d9MJkRS7Y2OGvtzy3pfNTfW+MqQMeTz1GidfgBVQEEbsmkw4TwPi2vx8vYKU5iJd9Q8fxDq+ZjIGr35d99puP+zrDHWGUqlq+0izgcXAxbT4RB/a2gBcgn90VFyGGUdyufJ6msVJHGpt/RnNHyen3691rjQBFrU/dA47h7e3bTaX6lidnKQw3Lg6Pl7xgRW8oK3+fq3zpAuwXKG9cGrPPDdXsaCHpjBit2vtL/1FWv/IsGZYa2kpePJ36d5fClREoGj/tkq/gTSdv0EPvN6KBSnxDCuJhNb+0gWYvK3MKDNWq6pGbbHeQAAm3ML1YLDiA2YcFJ/DYa3zGnaEm614zSGUTuM7nAMojDS2/qwXFzCL9+m0/qLoo4FQCB/xFkvVz5UmwP+WhII4UeEVMuK7z2d1O252BXZ2tLaT7ghXIn5vHOmxKiIeT4fb9bQrsLBQa1/5NnAKHcKdzYon4gCdjsfRg16hW1wsHtVaN44xxhhjjDHG9t8vz+jmi31f438AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAFR0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLWZsYXNoX2J1aWxkZXIuc3ZncTh8HwAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-font.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABBNJREFUaN7tmV9IW1ccx7+/28RSZxGprWVWbMaElHbV0BVj6SqaJvTF1I6ylTLdJBkrtezBqblRcQplSc320IeOUheHun/kpVqFYZLGWR0qtg91xclWJ+omjmxuDkXUJGcP475Yr2FbspPR+3kL93cO33zu+d3LORdQUFBQUFBQUFB4GiHeAf4uDofD0c9On2YXyYfS2lo6hp/ZeZ0O76AMmenpTww4iuPUsL6OcWhZ6r17ROgMV1ksoiiKRuPs7FMj0HnQeTCw0djI3sIlDDY3/9N52EV46brPV5ctBoq6TaZ/m0vgLSYajgOOA/3szJmo4vaiFnqvF3fgRcHamlwZvYcX2bN6fazyJbxASqVU9kl1tWzBDdzES+GwcJK+C2dVVMCMTrw8OChXzupwn+ZHRmKVL2EFujpcHd6j+/axSrxNt4qKZAvn2DRuDw3ZtDat8df5+fAtVSP7zGqVWhWv4wp+X16WVqjwOUyhK1ZrrHKqeIuSY+NR5LL6SEkJpaGBWQXZG80eCzkspatL+t0wXe02pM3MIBsATCYAKeiOX86EW4HXJq9NDv2yezfdYEfYrM0WrT6sFhpVJ7rjqGh7uL+Fm9CEnmPJyWrfrg9SJgsKhD6WwzJcLuzBBD7S6WQHfo+9SHr40N4mWopP5uXxys9NoMPhdAYCjMVrfrtdFIuLKe7/L+Fa+P8G9xaW8Hg8Ho9nx46pyz80p68tLMjuLERmQ9bMjAgRRc9rNERERPFbydFImBU4lTGVkf5mYaGsOIks+hFlXV28xUkkjEDkIQ/us2ejlUXu0wr7ht9bdzMJI5A0pMHNkhLZgkZcp6rFxY39q1phWX6n8V/DXaBjwjExYNbpWA1qUafRyBY+h09ZW29vE5pQRKEQ79wS3AXiEA6FuqO3Lsugj9GROK0rwV+ghdro69JS2esDGMOd1VW1VTCGAn19vONuhpvAq5r3LXd/y85GDoJYz82VLVyAmb71+2vKa8pN4ysrvPLKwU2g4A0PYPjcuWh1zESV2JN4rSsRs9MYaUWpkkMj1Ot2sxdQgFK9HrloxivDw5uP0oUTbElwm82sCmCVW0yYijR6NxJRZwofbiz19AAo5y1rK2K2E3Eedh4OdPr97DWUIdNg2HxdOp9TjQqX0FVeHg5FiHnn5jCDKahVW93IMrj8frtdzCz+0mjkLUqOmLUw82EUz+Tny12nCwD74tSp8B+R82y1vX0bcX8F66cKttjSwltQNGL3DGzHElq3OSo3w4ThnTsRRAtG5D/m0BQe43h9vc1r8xpGfT7egqIRsxaWnoHCV6Fp4Y3WVnqEegQLCzGOMXY1KemJARro4Q4GsYtexU8PHkTyMcDGWlrq99u0hpX+ft5iFBQUFBQUFBQUFLbjT7zJdhtwzFwbAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABLdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1mb250LnN2Z50G1j0AAAAASUVORK5CYII=", 
  "images/en-attach-icon-gdocs.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAihJREFUaN7tmjFIG1EYx//v8KJRC6F0qR69QYqVji0SGq2IW4cOdlFXg2YS2kJpwaWLRSkdHCRLRuvQRcRJESWoEaGdVHRxESwuouBZk/TuOuhrQYRc/fLe5S7vN7/73seP//vucRygUCgU1QujFnjR+3nw15JpYtL5qL3NZFgbfrqZzk48xzIeRyKiGu9qfTSk/Vhbe/flZSzyrKNDrrZ/aOQKXNwwvrobPT2ixXGan9zd0toTiYk3cyeF9dVVKbZugCzwb+J8wm+R9ARKSlwpuMjx6fn7v1tyOVn70gVWGAZi37AXj8sSGTqBHFkiAyvQcRzHyzoucuzT7CsRMzKwAo+OTk9t2/t688G911p7IjF6Zzpn7R0clKuPwArc3NzfB4DDw+Nj275MpOuWfq4tbdq1LYZRLpE1fou4LZaVz7susLKyuwsAxeLFxdkZUCxa1vm5hwJPATQaBpZpfQQ2gdfR9bq6aBTQ9YaG+np5+4ZGIEe2yNAJ5MgSGVqBHNEiQy+QI0pkYN/Ct4WLBLxcekojXeDMTCpVKIir39+fTnv5tKHr0eilSBpVc4RFIT2BXhMSFFQCiVTtDCwXKoFE1AwkohJIJHAzsNISrBJIRM1AIiqBRJRAInSBWXRjW+TVWBAxbOB7Pk8tU45fOz6wgWzWbx//TR+bZX30vskC3VrNdKaSSaTYe/ZwcbFiE3nVlzuCHWYsLLAme8wZSCb9bkuhUCiCzB8kv8RReqfpewAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMBsQ6CQAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDBqTVCYAAAATHRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvZW4tYXR0YWNoLWljb24tZ2RvY3Muc3ZnB2JdzQAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-generic.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAACidJREFUaN7tmXt8TGcax3/PmcnkOghaFSqT20i0rpmkaC2p6xLNolKCukcwCSIxEsIqRVyLKMalWyp8XNpE6bpU0hRRMknrGpMwM8lHrJYoIhfGzLN/NDl2M59+rIrF7vz+mc+c9znP+z7fc877e897ALvssssuu+yyy66XUvS8B/A46XTXIq9FurgAZYFVAyIi2J/UdGvgQMzjKvzati3CcRn9PDxwG99BcecO3NCeAvR6VlAf1mZk0Dj0ETw3bgw6oEz19DQY/m8A6pT65sZ1YWG4j6V0PiWF96ADxzVv/sQFjscybLFY8CeUUuDKlWWrZHs5LCkphLzIi6qqnnacLxxAna7gmHFSTAyv5VNQrVyJSeiPEEGwCUzHZYq8cQM/0nb2KC4mHUooWy7nvtyfE3x9f/e8naTG6cxMGurm5Xg0NFSl8tB6aCsqXnqAunoFJYaNPXvyIN5BkoMHbQBUUE8knDiB1tbzQh+NRuXeUt5iZHY2ERER86MLkO9c1LtpU14mXLC6xMXRJSzCm1Om8EbEYYxEIuY7AgsN2ro1KLFlK0XeyJEvLcDjNy9tvrRZLnesIqPT7gsX8A+M4HWvvy4G5NEhStuz515kSbRx6tChbtte69Wiib8/CiQPhSZTp9Ji1MfggAB254Yku3WL/i5sQ+sdO1QqP7OiX2rq6Z4FDU3jBgyg5pzInffssbkwPtxUyHrnnaCG/vU8R5048aTjlz5vgE4fC3LHMfPncwSP4Hf/BdxWmgJFUZHLdbO8PHv0aOFm0+MKS/fuVldKI5d9+xDGV3mfTMZhj3IxAGarBggNzcnSXzSlduoU1FU5QBERHZ0zTR9vHK/VAugPREXVnENdhOFcUfP/yQEKT3pCXenUpUubrySrVMjkI5ijVtdu573YxQPU6kqN02KnxRKJ9TbtgNOWLXgbVzlTJhMDc1AA06NHWNQFSLnp5Mk63WX/ot4dOtAwSUthzsaNNv3sZw0/6Nz5j9bxXweYyZmcyVKpUE6XhZZarc3cVP3IBl9T1vNO278fOy3hQtLCheJypUaNcRPpBoPjO/c9Be9GjZBPg6FITxfbg6CEggiwTLNM7dChSvEwvjK8sNBmQMVYBdfXXntpAMojPM55fRITAytGoW379mJD9TpO8obVVbg2ZUruN4XRRu7YkUt5KHo8euRqRKXCTnw8cWJ5X8l8YQ8RzeMOQMeOteOsCZQg7C0tdTJJfnJRvPqqzYCOYCTtKi9/4QHmTb94wFDp6cn3qRsuzJtXu5298T1tTEy0Ot1r+8sHN25YDfwDvafV2kz6cRiOpampKpXfGq8bhw9LnR32WtyTk3knEmBq0kQEHEqR1KugQFh09/DNqP37OY1HWaYOHGgzsKu4ytLTp194gJatkr3CqpQUJPBJnuXmJhaahOHIPXkyyFv5hef49esBeW6jwOnT8RZ/watbtxbjhtEQHLx1y9LUIZLbx8bmbivobFB36YJpnM5eY8eKHVXPiTSbK3B24kRAnivPrV8fndid3p4xo/a4SE9EDbdvf2EB6tpdGm1IeP99fAMNfxAaKjaYqTuNMZuxgKus7SdM0IUWDisuVii4HEexKSnJJlEqR7FCo5FbKg9XHv71V+thTqLeGzY8muuqtQnX0G3r1sDoljkK54wMjgRkkcuW4VWYWdO4sQhuIdKw9+JFwzS/8Z5f7Nr1wgE85VsYXRhdrx4CaBpVfPJJ7Xb2QgXPW75cpfI/5+Nz7hxe4a7WqNWr4YL56OHiIgaqUUzxx44FBiojvfps3lyRL23g4j9zJmLgjTcDAsQ4H2qLtaWlUhfh/MOY+PicNwujjUldu2IcPPDdhx+KcTWuPYsb0x21OjyciMhi+aN1PrN1oFDGMqnf4sUcC0f0b9as5jgtpR4wm0yyFpVjnCsXLNDpCleZDkREMFu7cat+/cQEJ9CcQh48sJYKKTQ+KupUan6WIcrXV0qSEEGTkFB73UKD+CKuxMa6taeVaH737u021pkYvn492uEeZI/uUCpCA9q9aZNqkn9/xaeZmU9dZ12Dy9EXNDT8FByMvtwUbhMm2ATMQLgQrVZX7JQWmc87OuID6zDuu2JF7TC6SOHwXLw4uNB3dYvE/HzpJskY4Zd163gLAkFOTmKgCrOgyMoKzFB6Kb7ctu32j5Ykh/dmz/4NnL+/mG8IFkHx88+yYffrk0ajqat66+xVrmZ9J6/vsUuhz8nho2gHx3btxI7SKQ1Dtm9XLVBqvE4NH54zuyDE2HrTJoTxeux7ZAKUTKtpcmFh2W6HFD7Qpo3rbvNuYMgQ8uK2MH32mdjhSpRDcf8+xSIHaNeO01iKNswwUHucPXMG0+AKk6OjmDeGsmh2RITqpDJSsX3Hjrqqu87uQHmuh1aBuDgbcNXu+fCytCGPmz5ddE8PjsXqMWPEBNVzk7U1jyTfiRNdm1WlyOq5utJZdqVeS5bU7o+cyImrFiwIDFRGKqDXo1LYidnr1tUGh3BaC8WhQ3UNrs4AnuR8NrJCwW+gBBlz5tgEPKF7Bs9tGey5+uhRUgvdzX4rViAMvqx95RURXLV7OpeZ51Z+uGRJTnaB2SQfNw5DOAXBISFivgok4duKCrTCTaF40qS6BldnAB1mCsdpcmIizmMYvJ2dxUIT8BX1+/77x7rnL3Cg5Js3SQs80MbF5a7RB5kq330XDXCFl48YIcbVrO8GUjqboqLKJM69nHu5u9NCGoUvk5Nrj4s24zY8P/roWe1E1xlAtqLzv7lnzfEjVg1fmDv3x05XYq/E+vgQIQSjExJsCl0G8M/Tp5cFyiJlkffucRYFY9D69bXv0Br3DByhzPZOOXZM0tesJXV0NP7Kc+Hn7i4mTKbW1PvsWcSULSxtaGtOLxxALKSe+MH2HdPxnPmcUHzmjOVz6+fCyD59bNxzNHXCloyMGvd063L/Bn07axZrOIbX+vmJ4H7HPbkvvU/f5eWJW/aLqBN9fO+edYF1nWXs2LEqlUqlUpnNzxrgU7uwrpn+jvGAwcBpuI5WXl5iQzofx3thYfQXevhAnZ2NKJTKLm3YwDPwZ8icnKyJwpaHFRMmUC8qcMyrX5+Uli+tJXl5tberHueeOp1+g35D48aAtIe0h9msUvn4+PjcufOswdWZdDH6gaa0pUtzcvR6o5FZ/I3XW4wpJSWi69oU/ts+XU50QR8jm0w253sVxBj54MHnXd/j9NR34GmP/DUl8kaNaJgw6cGis2dt9u1qOqp+A6n5z/H8LRwUCpuE1aYiybDkW1eqVB2Wt+rn7VxU9LxBPTOANcpzK0g2nQwIsHzKDXjb118jAN0Q7+PzHyfYBV8cuHbNOpb/Zi0PC3vL33+sj0ane96AHqc6/6gkfghfXqZ+EBAVxdexlnsPHkwldBpZSiWkfIj2ODjAi7ohSK/nrmgA+VdfWbUUaL6ekvLWZb81fmvu3n3eYOyyyy677LLLLrv+x/VP5iCYHXEHs4UAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAE50RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLWdlbmVyaWMuc3Znf25HpQAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-gsheets.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAkJJREFUaN7tmE9IFFEcx79jq6Ss5EW0GFiyEqRLF0UZpYNXqUNRXaUlDfLgxVOdEiX2IGKQUl6CiL108k/oIVjcFuwSHowurjBIbnhZVhl215nXQZ5BKjvtb+Y9Z/d9bsM8fvPjw/f33swACoVCUb1o1AJN4x86HrdGIqGMZuHu/DyuYQT3+vowjsuI19X51fj9p5GZzpFkcvalkRq+1dsrVttfaqgFjsV9xAQO+/v9Fse5fqlxrnXbMIZfJHtmv6+tidF1ErLA48RJQrZIukBBiSsFF/nk91d9rjmVEvVcusBzRvv78FLL2+5uUSIrTiBHlMjACrRtxhyn9DoucvAg8e71jvd7ZGAFmmYut7fnfv3NN01d+jfDeLD5ORf7YZpe9RFYgcvLu7sbG0A6nc1mMoBtO46bRHYtXUnf+KnrXokMyRZRLtlsoWBZQDxumuvrAGBZxSLA2P5+oeCiwCS+ALpO7SOwCTxJfX1tLaBp4bDIl6oKEsgRK7ICBXLEiKxggRx/RQo/RLa2Bgampvyr39a2sDA6etodLvLoyvVhU4LAnsLlw0Uyxhi9mnSBZyXm36S6XeeehgYvRroK9kB/kZ5Atwnye+8sF+kC5Y2wN6gRJiI9gWqEiagRrnKkJzDoI6wSSER4As/+Vg0mKoFElEAidIHP8QsPvfgxJBb2CjEs5vPUOnSBeW0MnYmEbCH/i3YRjwB632SBh0WnHR3RKKZhYnF19dwmkvf1CUO4vbJiPwtdvXAnGpXdlkKhUASZPwFu9jieEVOZAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwGxDoJAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMGpNUJgAAABOdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1nc2hlZXRzLnN2Z1sV6wcAAAAASUVORK5CYII=", 
  "images/en-attach-icon-gslides.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAAmdJREFUaN7tmMFPE0EUh3/bZZfUAuEAmpQm3UQTo0kvGkhj4QJE9OLJREM4mV684En/DnowHghX45VrlxKDUAwHTNCDiSHQQL02FDbYrdvxsE4wCNh2pjPsOt9xM/PmvW/f7uwsoFAoFP8vGmuA40KhAiSTuIonwMICqigDY2O4Q3KAaXYqcf3TtW/TybU1817q+dvS6KhYbSdEmCNQcTfIK2BiotPiKNrwlfs3n2UybvHzm+nk6qoQW2fALpB2nCRki2QXKKjj/gUV+fP6l/GnH9bXRa3LLvCSQb5G528tp9OiRIZOIEWUyAALJMTzmhj1W6Rb3Hrw+Dv/d2RgBTYajlMqNT9eG469Ts1nMj/iHwsPH+3t8cojsAIJqVQWFwHPOzra3vavNNORemnQSt9NJHiJZP+QPl5aAggRIe0i6nXHAQDXPTxsZd7AwMwMoLXtIbAdeBrDiMUAwDR7e0WuGxqBFNEiQyeQIkpkaAVSOi2yS3RBjUZ//9QU4HmWlcv5pcXjLBFdt1wGdH1nZ3YWiEQODmz771FU5Mms1jab8xDegZ5nWXNzALs4imkODf15Qy6GijSMnh4eq0t4hP2C+dPdnUi0kgUfgcIf4dMYxsZGX1/78+v1kZFqVV7+od9EOo0SyIgSyIgSyIgSyIj0XVj2LsqKhA70Tw78qdX298VXI1wgPXLxE+mL0/XdXT+uWELzQ7VdotHJSfVDVSJKICPsAje1F4Dryi6kZYq4DdRqrGHYBerkPbCyIttHG7zjkTe7QEfrArJZFLEF2Pal7Uial42XQD6PPEkB2azstBQKhSLI/AJie9putJDt3wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMlQxNzowNzowMy0wMzowMBsQ6CQAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDBqTVCYAAAATnRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvZW4tYXR0YWNoLWljb24tZ3NsaWRlcy5zdmc/q3XOAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-illustrator.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAaVJREFUaN7tlzFOw0AQRWcNHRVJQetcgYLScToK2kQU3AIJ4RMYIXEAOpcIt0iUOC5TwBHiNkVCRYmHAq9Bjs0ui3e9RvOaLfI9K3+Nvn8ACIIgCIIgCIIgTMNMX/iKl+CD6+YbFuTectmkcwYYOulotM+uIIEsk52/XgeB5yE2/T4chmGastbe2zHmXEE+de7fp77flq5rjBvI3vIDdjEet6XrGuMG4inb4KF4s2R1XWMsA2Wzr4pqFprC2AaqZprtWbhr6iKeaQgM4Pz3zwEAQBxFIv2//QqrZprtWajdQJ59cAILNnHdLcEDHOFTlpVnleK5co5laDdQlGHsDgfsOUn4qTqnK7QbKOpzuOes8Ho+56fqnK7Q/hH5nmF1ye3E+Wwn/tq8z5rzw5zHzryqRdsGymYf73dlz+tZFmrbwDKzbvGFrWoEhSE1tWMBE4m5ADOZWqMbbRuoK7Nsy0JtBurqb7b1wtYNFGbfX7EsC1s3UNj7zvAYbqKI/6VqOrlO9Z7eGijb+0Rz+tILWzdQlFHV3qeqsy0LCYIgCIIgCIIgzPEBODUacLLlyygAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAFJ0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLWlsbHVzdHJhdG9yLnN2Z5fOOiMAAAAASUVORK5CYII=", 
  "images/en-attach-icon-image.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABDRJREFUaN7tmW1IW2cUx//nRq2onVCLhZm4rozFVSuC0qqr26oRtOmGWEznIlUri45CGZ0gsxRxa2GUbogdolaX6YyCGVNWpYZIhy4v3dZSNOpa1M0l2tY2mwPFhWry7EPNPqyIL9ckZru/j7m5557zu+c893IfQEBAQEBAQEBA4P8I8Q3Q8YbRYflSLmd2MnC9DQ3sQ4SwqqgoXxe2KvvQSznT0yyUymBSqQriUySxkdevbzYcb4Eas+nc6Es2G36BnHWLxb72s276UY69NptSnWqKC4uO3myYAN6J/EucUpmaGhdHvG+Mp9BoTKaREcYgw2VMSSRQI5VPPP4C10p0m+CpG8v5ujB/RxDIE68LZHmkoOre3uVLpFj+Xixmv4tOusolEuThM9Rs/mnoKzy2Bq5KPRfsnC8rKxw6NJHw3swMzjz9uUP607RlorTUhaWz5LBafS1mvQgjzBOvdyCVORM4cWNjG37AcJZKJZJy0/Q5kSt/qYmMjY24AiDR11rWj/c7UIuzeD87myKcrdxlm81lX7pBDqsVV7APiVlZa51OH1ET9gwNcRWkoOrs7IWFoCCHIzQ0MJAUVB0RwfTUiueKilCJBsw/fOjpcry/Bm6WGCRANTgY8LGjmaLkcoXiCMVqFxZQiiRo3X9aXARQD21LSwczs5/ZwACLhsRpGBjwVFrbfw0sQRhlm0yOftdiQMmxY25x7QvGGktlQYHmgWly9OXZWY3dLB7Nu3u3Pc7YZIlMScmnFHqFpqY4iasI+enp/xmBq42g+3WGGDLw7enTeIx4hOh0ga1BT/7qOnq0pOLw7piS+fl2mXFu1FhczJw0SKKWFtzALPsmMhI61smqpFLMUgZd0unaag21Y+PJyW+bXr0QNz056al6vDfC6x9BoK+uDkAYKuvq3Ec0T8z9o7eVStaEA/jk6lX0sE5Ucc80AKvBAyTt3End3Air7OvrOGWwW7plsvwvDu8+kHPr1laX5fkOvEcKqjabNzqC7tPV7Dv2KwsORj97gRkuXkQ462RVItGa181BEasKD3f9xlnoeZ3OU+V5TmArwvH1nTuQLnc4z8vl7hFsKzKXjVgLC1cbQdZAXTSj13+lNb42FpyWVkxH6EVyOOgE9yP3ODMTt3EQtffvrzuPU9iBkF27/E/gSecfrtyMDKUyLS0+fm7O3XF0ED30QXMzelCOE8+OIKZwDvdCQ7lOimFvXrv2dASTkt6ZT1buvzA+zvaKYmguMxPp2EO5jx55LH9fC/xH3KfGd0eGjh9nmZTLdanVGx1B1iZ6i6vQ6zWamzeHhxMTC84cmojVjo2xCHrdqZDJ8CfOo95u97XITeP+7rfdvv95K98tfwr7i8itYvu/SG9z+Atc2eXydSEbZmVTiW8Y3gLd24N+I3JFHKcnKxWrVL5OR0BAQEBAQEBAwD/5GyeSAGFyRyxJAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABMdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1pbWFnZS5zdmf04cYdAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-indesign.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAi1JREFUaN7t2D9oE2EYBvDnjfFAShYDR0kQwaYS3ZwUXEXBlCJCCw4VkykBSSbNUNohHawpDlKwEQkngYKVEpS2FqtuLgrtIOIizWCshmiCtEUleH2dTsRwtJA/3we+v/U77h4e3vv47gAhhBBCCCGE6Dbq1I1rtXjcspjd1v3+XC4apbY9v9vPc3jafcP/jRTYIimwRVJgi6TAFnlVB9hN5Wl8pVAxTeMNYB9OJvkzh5GJRGiZDuBbfz+/xBiO9vSoyqdtgbVaImFZQ0NkMuy3+TxXUUTO53NOXjwKwFSdUsNX2CkOdY7DmpvjKooo+3yqc7nRZgKdV/WviZtBBw6+7abNBP7Z49wm7jau43mjQctYoS/pNEe9n3aqwWCnvjD2SpsJ5B2U8XNgAABwv3mdIjSFd+PjB0/OlK7MZrMASqozAxpNIN1CkY709bmt289s2ztbKKjO+S9tCkQNKb7n/jOAXhuVxoJ+e6I2BXKKw1hdX3cNOmoHPQ9GRlTnbMqlOoCDfuARLS0uuq3zEl/D8Uym/iqRsE6k018Hrw7mbwYCqnNrU2DjAoU9D6enycRFHNraaroghSzOGAaHmJGcnCTrV8Bjbmzs9h+w07QpsPdc7uzl3mqVF/gjv4jFUEcCCovZK20KdPjP343FbszP4z2v8unhYezDYzzZ3FSdy412BTqcIo3S/jyHQiG6hO/4MDFBdzCGU2trdAxlymxvq84phBBCCCGEEN33G5C1y4sYjzPRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABPdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1pbmRlc2lnbi5zdmcZmMqAAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-keynote.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAWJJREFUaN7t2b9Kw1AUBvBzxRfQtX+ERiwIfQAn3UvHZDVTtk7O0kDnPkAn09FMgkNXB8EnUHBIB5PJZ5Bel97BQqAnN80x6ffbD7n34+OUcokAAAAA4BAp7oDrRuMkGQ7VGfXU3XxOX3SiZ62W9EUKC2mqRlmm3tVg/RoEj+7t0/npcrnrODtA7yNyVpdpSiHd6+d2W/r+pXmhK9VP0/jb7/d+ut1dx47YH2pacMYNvenPToc7dlzV+eLY9x1HsRtflOdFUZJove/v8BsIfyBASwjQUmU7MI/trqp6t25DAy2JN1C6QbbQQEviDcQOPHDiDZRukC000JJ4A/N24HYzq/pvy4UGWhJvYNEdmDfn0YNOdBiSpxa0mkz2ff7GNLDq4IzaBygVnFHbAKWDM/hvIv/017As3J1c5E1kqkZZJn3R0m0elbhj7ADN819jgtwEp6/1xXocBNLHAQAAAIB6+AUQ7pEMC5OXngAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMPGM87MAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDCA0UsPAAAATnRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvZW4tYXR0YWNoLWljb24ta2V5bm90ZS5zdmfWvv9nAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-link.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABedJREFUaN7tmXtMU1ccx3+/3tuLmUMQhfmamiD8M6YLPnAbGgEfpDzcqBSjJqJkVZ6RTbdMwEdETdREtCCxc0CiIFSFQbUiimyAUxamg8Q4BNmwzkysIj620cc9+4dTCYSUttDKdr//NDnn3HN/59Nzzu97zgUQJEiQIEGCBAkalUJnB2CtNleVHqya7eXFdujnsB0pKbhZtJ80RkQQV6KBsd7e5oaLoQNOtrWR9/E9EKvVoo/hNJdx9KhCIpMtevX48f8OYOKLkpM1H0ml8ALy+Jn5+bgPNkOcq+uQO3gC4Sh//hwfkwKI2LBBcWV1YnBWaam9cYmcDcaSkteViK482LQJH0IZv+TMGavBUU2A80Q5bhzJwWry1tmzyUuLc65uiYqyN743FiAFRzLgEzyWmwsKiIEQNK8YkgLNoG1pQQkiWRAdzQaIE8XNU6bQX1oO02Ah+N+9a+64tx/iibGgzs+Xy4vkNWTiRFvjfOOWsCVwEIvZoG5oYOeJa0WHQ0Oz4FMMwmfPBusvPr6wsK5u/HhmBhuo97txAx7ADbjp62tucB/KIXLPnuyKmKKQVzt2WBvvGzMDhwpOr4RkPmzFCkvgqHJz165dtKirCx6Q63AzPX1Ag30wAfwiImyN2+kAkzWaVk2riwvPQyiOvXOH/UlcK/acOtVkMho5zsODTCbhoJ47Fzv10T2Jy5crlTLZsmXd3da+hw3gksTN9fUDKkphDsTPmjXqAFI7Qv54/tuYeRkZohL8G3QKhTHZoDXEtLYyp9kovbdWiw2ohcl5efw1LtVFvW1bskalqhvr6emsuPvL4Xugs+xIUlJxcXV1dDQAIoBKZa4ox1z87NatbK3s++B2f39rx+OwGThSdiShq3h3zQcrVw7WfAuUkRri7g7T8EPwz8zsX49j+BSIVattHdeIAxxpOyJagpd5eUFB6nWVqlLr4UGr5XKV6vJlNzdjo2Exn1pZOSD7xsIzmNnd3RPEV2KGQmHr+EZsCQ81qxqfspGmq5GRk5Y3b/uxWafbBbtgF/B8//7MdqSA3Wr4uqEB4iCL7PbxMf8RdxExJSHBMBPAlFVUxMlBIbpw6RIUkCSICAh4HRiUQDUh5ASuBl+pNOegTBYSW1Zm6ziHfQZaC45dZ1AzPXl5j+J9CkPq3NwG65faETyHR/iL27ebK1SQAwkXLpi2sh1G5tw5S+BwD3xHEuLj7QU37ABtBQcySIRjYWGiAyxv/Co42NJ7+IniHVBaU0PBGU+JI0wuGzeyHsYKJriiwhI4xakYfum048eHa9x2A6RZdagGmDlknMGapFIKjjZDL/iSiPbvp0t1sPd5Lmj6tX59VxcTYNKAe1ycs8CZ47b1QerjGD+DhvFraxuQVfuBowaYbvYGMekS69vboQDc4fc+S7c3WeBsbCBsWhrzhE3gTly7RquNDfpsw+zAQPgWU3Hn3r3990JHgbMbYNI3xVVX3TIzoQm7SGlaGi2nWVXsy2WK1i9cONiRi9oPUSc28ZKysgEz11o5GByVzUuYXmQO6LAN5xBperqls+qx8at3Bv1SXo6JJAT/WrWKGmSrA+m1IzSrOgocFWvrg31ugCv6lvdfcpZETxJyeVFTDamt5e4zL8nbKSlwCx/iO+Hh8IJcJPV9/Fs2tENnSwvuJi1Ycf58j57/GYMVCqVyjTLIW6dzFDi7AcLnUAhVhEAnuMK79geiVK5RBqFOl6w5dVTTeugQVnKTxmjLyw0GYyl3r73dZMIfjIEMI+4QHeYPTJ+OR8Zx/yTevq2USKIk2NPjaHBUtmfhRgiER/fu9S82b/JWip4ciBd3xiWnqornCSGksZFhWFavf/qU+4LR8WmdnaI76Eq2zp+vkEh8JD7OA2c3QPqxZkBF75nTkh2homfVoRpgR+9xlmRz1qPXSuQkCTNMamujh/zXIEeXHXE4QPM4ez/O0NuR0WpHbJXdJxGaRUe7HbFVw34bQ79ycX8yL3lr7EjvtRLNxs4GI0iQIEGCBAkS9B/Xv0R6xmS+OKmNAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABLdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1saW5rLnN2Z42m/5wAAAAASUVORK5CYII=", 
  "images/en-attach-icon-maps.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QICEQcDCqn3VgAAA6lJREFUaN7tml9IU1Ecx79XuxukmZBFD5YF/iuFysy0JYJWL2FGlPSPXhwFRkGtv1BU0ENFSQ8iPqgUjSL1xRhBCyLSpUzZi9AEoZStOXKFOPfn3u3u9CCXUW5s8247W93Py2H3nPu7v/Phd8899zJARkZG5v+FkRrgq6c+d8fjggJhH15nVHR3MyNkDXpra8kEcw2jCkWiEl/1vC57v9tgWH//zpsH5r17k6stSIbUAKI4PMNDXG1oSLQ4EaUmv2njBZXKfuveoRtbhoaSo2spkgWKFUdrArRFShaYrIqLhCjyx+a72usvhoeTdV3JAlMN1rSBK3BWVydL5D8nUCRZItNWICGBgCBEHieKtN+63XJ5Lv5rZNoK9Hrt9pmZ6McrNZv2FL5Uqb4dvDRz7qPFEq880lagx2M0GgyA222zWSxAICAI0VRkrrb87bYv+fnxEil5Iz05WV+/cychydEWnvl5nvf5gLm5xTZaGhqMRrOZWbaHFbQnLqJU7t6tUgErVzY2HjsGsGxRUUlJsN/nm5ycmADc7oGBvj6A40ZHP38O9ufkKBQsG/wdq8i0FZidfebM2bNAVtaRIydOhB+nUJSXb98ebF2u/n6tFlhY0Gq7u4Pjki2S2hooVlwkceHIyjp69PRpQKmsrKypWdoviszN/VNovKEmULxV/4bjxsZGRgCHo6WluRlwONTq5maA500mozFUnKamUHFEEi2SmkCWLSwsLl563Ons7GxrAwTh58/ZWUAQHI7ZWWB+vqPjyZPQcUpLI18vUSIproGBQCAQjziExBJHFBmvfQO1CvT7LZapqVATbG29cgXIzMzLW7t2sV23DsjJOX9eo4k+TiRWr45PJVKrQK93cPDDB4BlS0rKyoLHFYqKiqoqIC+vq6u3N/o4tKBWgR7Pu3c6HSAINpvVGvv5gmC322yAx6PX63S0ZkFRICE+H88DTmdPT0dH7Oc7nV1d7e0AITzP87RmkQLvwhw3NjY8HGzjPT7RUBcoEqmipFZsokgZgZHWNKlrZqJIGYEi4Z6qtJ+24Ug5gX6/1To9Her48vZ7iYb615i/IcTlWlgAfD6zeXwcIIQQQgBC3G6Xi3Z2S0k5gSK/ft28efEi7Swik3K3cLohC5SI9L92lJJH2EXzXWCZZMKEVo6TGkZ6Barxg9R9+kTbR6wwxwFyWHrekgVmPGVOku9qNXMKJqJ//z5VK1LMi9mKrYBez7zKqGQOqNW085KRkZFJZ34Dzg3IpkPczfMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDAbEOgkAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwak1QmAAAAEt0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLW1hcHMuc3ZnG68OzQAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-numbers.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoAgMAAADxkFD+AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACVBMVEUAAACBwVEAAADxS4cRAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgEOITR0BZreAAAAGklEQVQY02NgGAAgGkIZUzSEDCaIQWMmHQEAf2wRpOlkzi4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAE50RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLW51bWJlcnMuc3Znu00KjgAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-pages.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAA/NJREFUaN7tmm1oU2cUx/8nbyZanKwFKzrG2O7AKShDuw3am3RbXdNuig7HtjSusln24kCN2A41zg1rdemElFUqW9G2spZULQPHsDBo8kEZYaxOUSTCuk3bsha2pjNt3s6+NPlQF25r8tywcX9f8iHnnnP+/zzPvee5BNDQ0NDQ0NDIDyS6QPRF/23nl42NOIk9CLtceBQu/GgyCSs4hGY8HY1iG4ppwOMxXZbbOvr27xdVTryB/f47zkA4DCtu41RBgeh6afrxKy6Fw6ZquaZzdPFiUWV0woW48Qk1e73plSGaVJ2P+GXA6xVeT0Mjrwi/B85mumjg0hsTkkR3yWz44NatXOVNjibKuEiSzI+UU9eJUEgtPeLvgbMLvqALGCS7Pdd59e/r/6TDuc+rqEftgryE/0Zn7oXyw1jNv/2PDWS+vGLrVosFb2GYK2Q55wV2wk0/22zMwWBd3cKFaulSzcCEO1FhedNmwzq8R9sECFyDlbhosST2RAbuLRLwA2VANQOT1qQtaRW/xZLP89f0mHpbWTUDqZW+oFbxwugU+lGrnoHCxxhRY4sSao01wlegqLFFCbXGGuEGspnb+fvKSsXAmTMsnSc3xurr46t1T8Vsy5enPuk7In6ioWGuZ2q1xhphWzg1tsSCsYPmV8fHU0/JjI3MGGTcWFbWdejYsUxxsW8CgZrD9fVcyUyhpqaMDQziBqojEeM646dT5woLiZ773eeLRHKtU9gKTI8tCsalMLzCQXR3dCjHxUsNh86cUWwgPdbEdy9YYbWK0inMwPmPLYldiV2xmHKcoYAaE4k591HNRThYVSVKpzAD5zu2xFv16/VLa2sV43qwPh7Yvl1UH/NFmIH8Ayfp7IEDaCM3xsbHFeM3o42ko0dj3QGb075v3+zv0/c+mZvhOXJEsYGZuuk+BCF8DmT2n6hZuWxZbAQb8VNfHwpxh94pKVG6zmSS5c5OSvcXjfr9TiezYsFf4MZnV64YJWzi8i1biOTdXTeGh0XpEz7GpAQYixe8xHsrKmgturn9+vWc11lFLXjo2jWjpOs1fr5hg2jjUqh3lKNnQmdbJib4bZ0PXzkc+IvsKJ77wyAjY1iEhnic7eyiNQ4HUWlR+/FwWC1dqr8PNLlK/+h6d3CQWrmFay5cyDYffYwhnOvtNXnlZzt2XL2qth7VDUyRrKMPdT09PVnncfAQnvT58qUjfwYWxyd1jcFg1nm+1V9ESfZ5HpS8GWgGAIyMZJ2naeLkkpujo/nSkTcDicrpNKam7ns5EKLX+Pj09H0XZIgjqpJaqv4lXiXyZmCamf+wYACPo25yEq8nb9Jaj+eB4zQ0NDQ0NP4r/ANgmKYXDkKkbgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMPGM87MAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDCA0UsPAAAATHRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvZW4tYXR0YWNoLWljb24tcGFnZXMuc3ZnYpXRawAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-pdf.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABc1JREFUaN7tmGtMFFcYht9vQERA1LilddGoiJHuoqb1hraRiwJyjZCwsoApRkWjorZYtdXCaihWixVCJPUK0bgoE0sQBMULiLcQNCtUQQW0XqhcqlSqIsjO6Q8LbdxuWEEcTeb5eeY737z77JzZsweQkJCQkJCQkHgvIbEDdFBRHxrrdzMoiN0gezZ/zRo8ZDOgUyjgChnW3rtHcXQev6Wns7r2dOvHyclKnud5vq1N7NyiC6z0DBvntz80VIhi37NmrRYKaHGUjOair1GOuJyc+qMPrj2bEhzsTkUoQnu7WPk5sW7cARvGwtm5mJiuxHXW/4hx2BAQYKeSZ1plRkSInV98gfFQs612dq+Ok4yNpqTgYGPzaAybhQFqtdj5RReIFYihvNu3Xx1my5AlyPv1QwXC4MeYwXUbVMBHLhc7vvgCVSwCjYWFBuOTkUqHoqONLW26iTNY+Py52PFFF0hl5M4laLUGT5ovpeKwi4vRiW2oR1pVldj5RReoiM+wza2tqkImzuLUyZOmzmOtmIcPLl0SO7/oAjugSIoE4uNNDj5dOAPk5oqd+50RiItsKFfy4IGp5UKxmR22TZsmdux3R+BjnBV8Zs82tZxusU+RsH17peccT7/9zs5ixRZdIGMaaMBxuI31OL14scnz9uE7yK2smC1nKYzn+fLysDA/v0GD3nZ+0QVWqK7vKV3v7882wwlODg4GBXdQCnbnDjRsCyJv3Hj1MtsIG1rr5GT2F5sn7MzOvs0i4QZLy7eVX/T/wtdC1CG+mUVF0MAc6a6uBgX38TvdWr7c7D6n1dsUFOiPCbnc6pISaFCE9AEDDOo1iGJeWVnkTru4E6mpGI71rG9bG1dHA4S79fXWf7at7D/y7t1hMTzP8y0t763AX1ko/OHmxlWQWvD9n420BhGQNzZSJI3Eo0mTyAHx1CqTCReYhgUsWAAXxOGI6Uv+P31tcEuvxxLIsLi8HKkYAXlmpsVH3FX2bWrq6JQDKfnVzc3vvMCKr9SXffILC9l8JFKKm5tYOTpFxOIJ++H6df1m1qq/7OU11vFgQcG8e/e6nNfbwV6+3B0cOCWKhRXh4VTIXMlxzhwMgYBlSqXY4gxhGqbheaXy4Jj8ySpVV9Xmb/r2lXPVC30cXV2FlZROi9eswS8sWwjy9oYZAima4zAEghhaKJsFQ5abi+04B/sTJ1gBNaAsOdmgsBpytHp4mNy3p8F0LBKzMXCghaq1sDVp715osJMKgoK63bA/luJZXR0ayR3+Oh2U7DyeXbmCGkqiEp1O6Cv8gdO1teTG4gT7+np9qEVw++G6OjPNixl9mqOiKJGymTwxESH/fGGvK9oLbhhfU6OozViUt8nRsdcElq2a+6FnmbW1+az2mX36l5T0fEm+3tIxxtWL6nM+jgEB1MDGIy0tDY4URZsGDza5gYIykLdhg5K0yING01V5t/eB5sntO/s8jI01Jo6m4BEeNTXRBIzDzWPHjPWhJUyLZQ0NFj/r1yNs6dLu5unAeWrG5/nVOTlcqPlkoXHsWApkE3EhPb3z19dYjo4lrnoRYh2SkGDq/br9BFbYq3f4flNdzQpQhLJRozovNGAEvHQ6pOIUc1i1CglQkTw7G224jFgbm38bvDy+YlvIFQmBgc6lWtu82t47HLi+J3RP4Hm5XDhAy/URHh7YgSGCmUxGG+EO6HRO+zJ25VcXF788eTQ8wH3zAi3V43xjnzxhl6HEJWvrzobROMJijh/HVXxJFgoFK0QNNg0bZtCgnH1CFxMSlOqDq482rVvXW+J6m24vYXaeKmFbXGwwnoJA2urtbVRcESzQlJmpCNWXWs2MjRVbQE/ptkDKYg+5bStW0ARcw8SnT7ucoMFPiDx0qGVK/771bRERRDzP88bfSe8LPd7GVFSFR/s4urhgkzCUZqSksOHYARdnZ3yGqXCtqeECMB1fJCV93JKxKO/s7t1if2AJCQkJCQkJCQkAwN+G5UkRnhwXSQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMPGM87MAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDCA0UsPAAAASnRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9Vc2Vycy9kbWFydGluZXovZ2l0L3Vuby9pbWFnZXMvZW4tYXR0YWNoLWljb24tcGRmLnN2Z1JhdqAAAAAASUVORK5CYII=", 
  "images/en-attach-icon-photoshop.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAA4xJREFUaN7t2F9MU1ccB/DvrzbuAcEs08SQrVdjtwd9EFPUGFFoGRozCZGVBJqACg8+DB8kmTUQIVQwII74BzWYdLqQlEaROAlZtmmvBsIDDWicmsDmw20ibigZKsYHkJ8v3j5UrpcW24vkfB7vPfecc7/3/GsBQRAEQRAEQRCERKNYHywqCgQUhTnqBx9gA3599QrfYR1dGB7GD7QXR7u7zbbJjsn9Z860/bf93urR0VGjg5mtxAeogY/iCtW8fIl6Osdfl5b6L9pJquroMDogPSajO6CiIyjg2uRkyucj2Hb5cuE+mZV6p9PofumZNwGG+eCAhYiGkE43vN6Cgp6kJz8vX250t7SY41Vxe7vDIUn03hJR6P3zi9CPqammm+YyLi8u5hXopVyPB0+4jrsWLw4XlLiJL6WkLPp2Kmey5cABXAGA6mqt9lw35LTQg7w8buVKrjl4EEPYiW3p6ViLIPKSkmLtr56Ej0B/Wc6YpWlkxOezH5ekxkb6FxncpR0M/cMSftu1S+t+4eHAV4rS0MBebuYl167BjGX4KTNztsHNleFTeDp7ykstbW1a97kMO5ButUZeV0ccKfgFcLuN6r/hAeqhEurHDLt9eKoaLG5r4GzRlKkfHSUlABSUz1Agk//H00eP0BdxfRPMsNhsGJi5Xh7jJdi8ZYv/j+yN0khfH+Ik4SNQ3URcLvmQorjdGDIVI7m2VvOB+9iLpV1d0bZD35s20GemuL/fvDlIvycLaZT1/DlAn5tzrNb2/XZKvfDsWbj9gUB+yCPLOIFy3pOVpVmP+svnIvbQeDCI17wOp5qb2zOyayxj0X+YSPNvDXQhgBAzjcMz7SstjQwu7F0QuvWpu7Ea9FnayoPXrxceDzQrtvr6hRPguxFHDzHBZqfT53acXLm5s1OruDqCeD3uIv/YsWiboztIQ2dlpeuFzEqn9jFJT+IDtGEcpyYmcJJ20zeDg5hAL7k8HnWq6gUXyX/IUSENVFVRK9kxkJvLLXSWKmU53I6O6Uk46WpFRayvE7c1MNaT/cdW1CpzaFVGBm6xzLd6eiLvq39i+K2O85ZLKSnR1j9/pnCccMObYVTH70Mafg6MVRSngMcfKkSNOI2/gkEA52Ppx4IfgXrYRWt42Sx2cw2f7AicsybqpcG6Ov+X9r8tv3d3x1rNwg9Q3Y2HkEu3+/vVETfX4ARBEARBEARBEIzzFtJFcqPCIPVgAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABQdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1waG90b3Nob3Auc3ZnqlocOAAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-ppt.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAkdJREFUaN7t1z9oE1EcB/Dvu4QM0csSS22gInJokQ5pzSYVBxGEKlW6SRxOFyehpAkugTSoJEMRMzlUKKmDIQQh7SgORQSh6bWIyGGLWCxYIpheW6g0+XWKFOOpmL6kJ7/PeH/e7/e+vHd/AMYYY4wxxhhrNSFr4PX1dDoYJNq3RqOw4N/cpDJFEDJNVEUJt2ZmlENipfY8kzk8NXpjcXRtrTWx7elL1sD7HaDtBK7Di7uWhQQ9REDX1f7YB2Mgn5ddt05pVSFZ6Cm28EBVqVN8w5NcziqltODs8HCr6js+wB9URDEvBEaERd6JCat0/2hwtqNDdllpW9jOn7a2zxeNGoZo6GvrZOp939lAoFrBu1pXOExp0S1qY2O4ipdY9ngaBrpAV8ifTPrexHoWXsTjsubjmBXoNWM9869WV9UvsWsL+VRKRGmFlN8EcwxdIjQ4KLsvxwTY0PiA2PGIyUm782JbZNGvadL7aHcQ/0oE3ePf/S6X7QUWkqTJ/wpwbIDVws6I8iwctjtPR8gUuaUl2X242x3E32p4idxBN9USCQAfsfyLG16LbTpdLMru68C9hZue0Hkch1GpAMoJ1xlNU0uR0NxcuSyrnmO3cAMLafQRYYiKtbe6Lju4OsdsYTuivuKG6FJtStfVeCy72FsotKq+YwIUt8U9XNzYwCkaxznTpMe4TF+np9GpfHI/ymTUeCRr9MpfcT87cAHa/YkAAAwAwE2k9xz73N5+/59nYJtwgE3iAJvEATaJA2SMMcYYY4wxx9kFEeHOUD7gGgAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAEp0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLXBwdC5zdmfQBvLPAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-premier.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAsVJREFUaN7t111IU2EYB/D/W0MvnHZlF7twfdgHqRQ4KDE1IiPB2kUrCFJiXVjhXNLHiECnUigWOLekAvvAELJlyrSFCV2EQheBVJNaiZ1dGJgXihrkx54ucl44D1PHdiY8v5uN95xne/jzvO/ZAMYYY4wxxhiLNrHWQkmy2TweolUXduKIyJyeFg/RQG6vFzW0H4e7u2dL4p/PXbHbt49efLv3zuio0sGsVPQDlGukEpfgnZykHeIEWo1G7c0yd9oLp1PpgELZoHQDAVSFJuxMTEQufcPptjbpVmOB55TBoHRfocRMgItSYMYeIUQv5SCjufnXo8aC76bkZKXbkqOK1AdrtWZzWpoIOiJ81+ydX5s1Giql+3Nni4rEceoSw9XV5IID83FxgfvoCRJwMilp1kGXZwdMJgBu2Csq5L7P57F98gzr9VSJGlwvL0curMKl00GPXvqYkLDWfkOJ+gSm1Jv0u8+PjGi1Ze70+Lo6colC2iofDNxwkqawUO6yJDWMDzbV1pIa7/CnowN3cRDWvLyVBhcuxbewcIgLqmctLbI36NCE8dTUpcuBiQPEU8qzWJTqX/EAQ5JQj8/BT/vFraqwiJ2BK+b0n5t/U1yMUlhxYJnrvzGMnKGhoPUUqHE7MxMAMLNMXRY2++Ozs7Uj5jMZqf39kWo/6hMYeIhIUmPBl78WCxIxhpqqKtmCTXRDOFyuoHUz9mFGrZYri3RwARGbQLkf2gT/z/n/b4+JHwC54FiuXhyCFdaJCVX+XPbGo3Y7+gC8jHQcq6f8Fl7KBxsGifytoo2mjUZN1lXdrpKxMaXbkhMzDxGxMHGkEg/oscGwJassP/11e7vSfYUS/Qm0YQBxU1PinujBK68XOv978aGrK7BVY33ilor6P5Egfdi28BqTZ1woMbOF1ysOMEwcYJg4wDBxgIwxxhhjjDG27vwD838BsbHlHVwAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDFUMTQ6MzM6NTItMDM6MDDxjPOzAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAwgNFLDwAAAE50RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2VuLWF0dGFjaC1pY29uLXByZW1pZXIuc3ZnI/o/aQAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-svg.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAABgtJREFUaN7tmWtMFFcUx/93FnalBTREEYVilEfFNtYiaXlqsSosEoRq1dpqxbWLghq1FbWC8V1EYwkVAeWh0UBFQF6ytFUQBVYjNj5aBXlYWFARghAw4sLO7YeyaiAjZZkVNPv7tLlz7pw9/zn3zLlzAR06dOjQoUOHDl4p7sjzixfMmVMcl2eV4FtXV/y17GaiQKEo8s9dHP+nWMyXH73BDlRrSOgOBjExCEQ99TE3hx3qqQ/AbCS2RB4b+5+RpeVA3TCDHafWCMYwOu3Zs57DNBqLkapU8uVm0DJQbpGniFtvYkKD2A7BA19f6kUC6VQfH5hjLWZNnIgv8BBxFhbkOrJJMqV0HmmESKFAET1Dr5aVIQj5yE1PF7nqjepks7MdHGbNCghobVXfn1TjAOMUEEBN4cfi3Lme4wCAgoHHQV6fYCkpKSkGBmycUWj7rg0bUIF4mAUHwx5t+MrYWOMAJGQ3Hra0IJs9Rqfs2CFsNW3tUkRFOTg4OAQEdHYWF8tkCQmUqu1dXMTi5csJb3FrXcAr1rkVR9dYWHRNIrmCDzIzsQm2ENrba82hIWrIKrlcObnrqDLSx0dYordbX7+xUX2ZbwG1VgOfC7eZ8RQoLl/WunBq2jGORjs5CcV6rP7jkhJtu+O9BqqXatckktvenJkJO3oIH5ubc06gKELMo0doRyqeRkYinp1Mbp49+6Rcv1zQUFFh1NwSMuwiywKG/k8Sra2pDa6zBxYtwgNmGckMDKTxNARmI0b0um8o9sLUxuaNE/B5jTNCBNa/IuO2A9h++jRNVhbQIInEdeTccsmmtjYA5T0Ky4IXP2/dQh1sILt1q4CeoYl0/35hrcG7sDp1CnU0jYbMnq1twXrCWy1Qv1XZTbSG+evePc6XQ7dwzr97evrXLFxICCGEvCjy/aW0tLQ0NlZf/1lE4+f6tunpWIVfcc/bm8uevq/cRRuNjV1Hzi3pfmADgrcaqG5HOIXrXqo0WbmLBkkkAxVOjfptq5pKZnTelUphg0+x/fFjLnuyTvg3+SQp6dKlnJwEywkTho6A6j6Oi+4ax9eT74nQlNkm3GdoiEJkIeUVD6Y7QxkikMNMLi8Oya041mBlNegCkmWkCOF2dlzX6RLGgMpzcvgWTg17UpVOp4aFYSxG47aJSd9/GK5YaWpK4pi9bMSePZr65S8Dj0GEmDFjOA3udLyDqOpqvoV77t8LHmiZObPfE5toICbOmKGpX/4y0I1OI1L+GtR++18PEb7pvfftC3oBGYjSvBbz10hbkT8oc/8+Z4Cr9MyZYM1rTZ+MJIdRlp/f73nHYYDj589r6pa/JTwHnvTB7dtc10kls5J2cLcXA/a/gv2RWbd1KwrwAzwaGvqcsA3TUfHwIbtUNQUeISGa+uUvA7/HarIkK4szwF+Qj+lr1hQ1ZTrH7zMy4ltAl91eNstGV1V1rRYIVO5OTriIaKw8caKXYfd4V5rAUZXm7Ozm5u29vFbz2sx/I+1EDzGh1dVYh8+QMXx4L8M7ZDVMUlOdJR6V/nMXLOCrH+RC219jeMtApzrP91b83NyMBjKF7A8P5zS0o4fQPH9+Sfxv1omZKSlXrHMrTkZq/jlrsOH9a4yyULQIew8ehCMJgEdpKadht5Cqf0iLcnhlZUlynl98VmioPC3PLyHP3r6AFtCoLw0NB1ugvuBdQHfiTvxJRwczrksk8PL1xWGYk+/q6rjsaSGaoBo1ilpSKWnauZM1o1Lcv3ZNWNKRZyBua9PWYdCQFVCNU513xbc36uuZQtU85kNHxz4zkotA1NOjFhZM+cuHQUMHrR8qqYVUMqIaMtbNjRzHBTp9yxZE4AJ8X5xhvKm8tlM59dJ2PiLeJ7EKC2PXqtxEsvHjEQFPKvP3h4wcoUszMlCLJOSXlRExosnG9nayEVfwVKEgtURCAqXS/+tP/lPe5gTL3ls7rnFNGbStl7YpviG7m+BeWYl2VGHJSzsgQ1jhRFWVy0di2+UF1tYD9fP2nguHo4NcFIl6DpNVSMJ8oZAvN2+tgFRIw9irUqm6C9C0FOjQoUOHDh06hir/AiiIlR7+WsuxAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABKdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi1zdmcuc3ZnEPfmHQAAAABJRU5ErkJggg==", 
  "images/en-attach-icon-unknown.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAQAAAB2Z6ylAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgEOITR0BZreAAAEXElEQVRYw+2Xf0jTeRjHn9Vma2myXDfKQLEy7cf98UUikpE/Ku+usLOzo1RGgXkSVtCd6FEEWUwOEQJ/BLY7HNY/RhnMJLmUlNqhdIuC7CY1pZo3nM7v93mm+WP5uT/u/GxTOoTbjIO9YbC9v5/xvL7P9/Pe8xlAWGGFFdb/S0NFKhUJhYX0bVsb1jkciIyRIIqU2dOD7ZWVopiQ8MngaOWhQ1j29i0iYx999Xq9FFtVxZhSuaRwqDxzBv/48CEAxj48TN8/eUIKm23BNUNn51CRSrUkcFLSvn0BAGOPHuFMaipjMtncmvHudevoy+pq7PV659ZRlskUcriR7Kgo/O7NG19nbt1iTC73FGzfjnajkeDxY4o3myVLXh4AAOXn5ATczExqakgBqfrqVd6R04ODw82RkVJNVhaapqbm7z+y1tQAAODZa9e4d7apKWRw0u6UFP9HhoaDB93u6Oi59CIyho7ZWf/3YpMgiE2CwAHTX78OCRxjcjnmWq3+jxYAANPq6vyLi6Jajc67d7knFBaOZEdF8c+l4+MhAUTDuXO+oqI4kbh+PX6xa5f//pL0+/dLljVrsMvp5Gvzc3Ik/caN/kkPOtzY+bg4yifiRUdOnWJMocD658+5V3/zJgAA9ly/zj2FzcaYQoH20lLfzbW2Bh2Q4s1mXkBtsTC2bBkJ5eXcWzk66rFrtVSs0/E96Jid9RRkZJCg0eCoy8W7/POxY8GFs+bm8sfTMj3t+WXHDlFMSKDS8XH/fcZYRAT29fX5vMZGAAASGhv593978YKx5cuDBjfatno1Gt694wXaKyv/Ltrayr3fu7sZk8nIevGi77duZISsa9eSdc+egI5+np4e1O7h0fp63hH9wICzfdUqyZKXx0FMU1Nk3boVkzdvRsP799w/odcztmIFDr18yT1zQ0NQ4STLzp0BE+DogQPzE4qxly4xJpPhiQcPuNf88CFjMhnmXL7MvS6nUxTV6qDBMSaXY+HTp7x7FTduAACg3Wjknqa/nzGlEpuPH+cgtZOTJCQloX3LFqydnAxdMBaT0J8yM9EQE4P24WG+1njhAmMyGRo6O7n34/37QYUbY/HxWD4xsaiEZplMgQmNiKBvTp70nxpBP7CiuaGBF/21q2tBQkddLhI0Gk9BRoZ/R6lYp/PYtVrSut0cUFtWFlQ4AAD/wU8sLU2ybNq0MKFKJWn6++cnFEuuXPHN6mfPGFMogg/YMTMzV0QU1WrJUlLCi/7Q0fFvCaWKw4ex1+ulfCJpd0pK0OEAAOhru9032LOzSdBo8M7t27T33r2J/g0bPNpt2/zPfvMTSoJG43ZHR4cEDgCAYquqOGCdw0HFOt3cNbFJEOj04GDIEroYoSEmJuAA+s8UIf3AQMCJedTlGjsfF7fkgAAAVJGcTMKrVx/9K1nncIRqj8kWu3CoSKWKjC8ulhmPHIE/ExNhr0IBn9lsoGhpmc6urY35CvGTdC+ssMIK67/pL7RiGH8PMWDpAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABOdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi11bmtub3duLnN2Z6GswhUAAAAASUVORK5CYII=", 
  "images/en-attach-icon-video.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAAT1JREFUaN7t2L9qwlAUBvBzQ0fHbip9AJ+h0N1JpJCpm3mACgpdxEUw4J6sQlHxD3QoPoEP4CMUXZzr4ORxMYKD5B5PSAx8v/ne5OTkywlcIgAAAAAAgLQZ6YbFc7s9eqtWaU8DUwlD/uZPei0Ws36QuzHtTXe7daZmzRXPq036K3e2XNpud8T3C/jf2QVB7hsXMVTgTql0PPAvNcNQuv3p3hvaLq/Xfd91jTjpSZnPW63xmDl24Qf16K9cph/Z9eUNjGnQrYKtHyQht16cbb22xJ8wXFMnMO1kPVq9SKCSuoHRTMn6Z5FVvUigEmagEhKohBmohAQqYQYqIYFKmIFKSKBSajPwURKa9AyUN/B8gmt7Lpibn8yQvuhlsyEiX7JN/AlHR9+XRubduXFmxw1+97ysywEAAAAAAIh3ArpqtUPQiWzvAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABMdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi12aWRlby5zdmdWktNKAAAAAElFTkSuQmCC", 
  "images/en-attach-icon-word.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAA1NJREFUaN7tl19IU1Ecx7/nbimrhxgSmtRLOSeF9FBPOSlxzomKTy7HqIdECgrfaloJQzJZ0EtgD0HQH22hYIhTp60ynEFEgQSy6WsP/bNhhGF67+np7sHb8dw7u66H83kZ3Ht+n3t/v23n3i8gEAgEAoFAIBAIBNsNMVrgvngzP9KTSiFJu3GgtHTjeVosHyUJp/P5wyvulr6FBb3eqv5wcnDQ6bTcx4gsJ5OsdTy/2x0ORyKUGp5EJ37gUioVrw72+D+Wlektk4xeh7rofjI2OsoU9lu9Srix0ajX8pquybv5ddn6uZwnj3GN3RfzfowWkBZlkc5Go6zz1A8b6WtoMNzAHdIND78uaz+vrzTyqcTui4XhAdqbDw5ZhmZmUIDj5OrSkmbBGC3EnsrK6jM34g+eFhTwfPX1vb0DA3Y7mhFATUUF9wYM+nnQEBxwpNNr31aSe9tmZ00f4NCQz+fzyTK9ji6sTE1pFhxDG2wWizRobd7h8Hh4vtVVQqTyujqkkUKr1cq9AY4/Hg8G/X5C1E+AUhwOBFg6EiLnkJiYmEYIVWR93fQBZgrLyZwSZ+8Zygd6RHLr2KsmSDv0rDPJr/QrA+SQ8b0vM4dsC/Oq5ct0LhaDHU7c+8s39xntNOr1nkQIL6n2l6Uep28Qw3htraZe9Zrst7XSd/LXycltH+DYWGdnIJBOI4+cRk0isfE8CWERi3a7Ffn0E1wuzYV/2pJfApWV6jrNBc7iBd7PzGTrV4/z/Jk+tnuAmUYi+EUvbPJUfiI5SIX2qSntRIkyzH6a0gi9RfzRaLZ+KJIMG/uvq/q32v+WBygVy0XW8ZER5oISvKXfm5o0x9vJLnRt9jqivAKiUbP9W+3fcBJhoTehKB7LPukEIczEwUgEZvuzZcu/wEwDOhMKN3EwEoHZ/pwPUHdC4SQOViIw25/zAa5jlRQhkVDf7DULftNHeOZysRIHLxGY7c/5ADNv8oW4TRpiMc0CNWkwEgcvEZjtz/kAM0JOQmGhNxGY7Tfc778WUpcStM6Pj+MUhuFdW+MWGEwEZvtzPsB4vKPD51texjSZx10de43BRGC2P+cDVOElCJVsE4HZfr2YNkBugsiQXSIw2y8QCAQCgUAgEAgE/y9/AJdeW0KXQPvpAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABLdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi13b3JkLnN2ZznjsuoAAAAASUVORK5CYII=", 
  "images/en-attach-icon-zip.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAYAAADcbmQuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABaAAAAWgBwI7h9AAAAB3RJTUUH4QIBDiE0dAWa3gAAATpJREFUaN7t2TFKA0EYxfG3i3gCwSJJbyFYWHmGSEpBiO3aWLiwBLxCElyLFNkTCNZCIK32NoKVVdKIXQ7g2CQWA0LI9wWf7PsdYJh9/JlmAREREZF/KfE+sOwOFoNFu41uchkOqgpvOMZ1o7HpeXleFL1e8nPPshwO+/0Q1j7gAVc4nM9xi056l2X5STEtppOJ1/em3gPiPdkNz+OxdTg3ZxjhtdnEHo6+PqvK+/idrV14Q+bifvOIfZy3WgCAF7/P9S+wZvwLNIqL21qRTlSgEV2B7MXFVKARXYF6A2uGrkD24mIq0IiuQL2BNUNXIHtxMRVoRD/gqsi4TBb0A7KjewPZ37yYCjTSgEYa0EgDGmlAI/8BV/9h2ZziA/ezmfex/gMuf2DTDLkcLlykT7jJsr++joiIiAiJb63Fj8rw/YGYAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABKdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9lbi1hdHRhY2gtaWNvbi16aXAuc3ZnpS9YEgAAAABJRU5ErkJggg==", 
  "images/loading_progress.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYEAQAAAAa7ikwAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgIRBwMKqfdWAAABrElEQVRIx+VUPW+CUBR9NO37AW/gB7g0TUjsZkPiRAedusgg/IB2beJfaJpG090OTrhAQtJJhzIgD1efAeLm3BCWjq2prwPBKsiXiUt7Rl7OPffcew8A/CvgK9vGgWUdTwBTijGlZTgn8Q+eCCHhZNkTESpaRFURUlVJUlUIcwVWC1EEiqKs2qY577BsXnG9y7LMnWkyzHAIQKuVK3B2MRqBpeuCCsdR3jCyRPQuy34/Ggbocxy4dV0AxuNClucdliW64xBCKdEdJxoXDiwLDyaTaCwachxNo1RDjqN3892miswUSYq/ay+yfHDxCJ6I0Pyz3fbE5PJUFcJwscWP4ShgNiOp2Tbt8/zOa4Dx5XW9nlXg+cO2mUGM94Tx/XvI21wRfVivE+xJfqiY8z08o1wYjwdPRGimSNK+JR+S+B3knSnhZDnKSVYYT9KKU94wQIXjwNJ14WuY0HnNtslb+Dctk/jEWLZTvE0khFJCfheYlvhMB6tFsxl1zkwFodrz/bRmqj3fZ6aCEDn5umk0CjiAMFxsspu4g23XaYkvhTSBLJyWUggwLhK+v4UfFhgQTvHqSuIAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDItMDJUMTc6MDc6MDMtMDM6MDAbEOgkAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTAyLTAyVDE3OjA3OjAzLTAzOjAwak1QmAAAAEh0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vVXNlcnMvZG1hcnRpbmV6L2dpdC91bm8vaW1hZ2VzL2xvYWRpbmdfcHJvZ3Jlc3Muc3ZnMH2+vAAAAABJRU5ErkJggg==", 
  "images/overflow_menu.svg":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAMEAQAAABd5xOiAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAAAFoAAABaAHAjuH0AAAAHdElNRQfhAgEOITR0BZreAAAAaUlEQVQI12PujW9rc8vYuNHNnJubsUf282eGfB4eBtXPn5kYUidNYpj45cv/j5MmMSADxj4LFZX/jn5+jPs3bWLsOXPnDsMBZWWGuNu3mRiq/v+HKWNh+uTp+e+lr+8/vk2bUAxgJs5SACVPNeDSTb9iAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAyLTAxVDE0OjMzOjUyLTAzOjAw8YzzswAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMi0wMVQxNDozMzo1Mi0wMzowMIDRSw8AAABFdEVYdHN2ZzpiYXNlLXVyaQBmaWxlOi8vL1VzZXJzL2RtYXJ0aW5lei9naXQvdW5vL2ltYWdlcy9vdmVyZmxvd19tZW51LnN2Z/dX7d8AAAAASUVORK5CYII=", 
  "images/attachment_play.png":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAyklEQVR42mNgGAWjYBSMglFAPuju7j4AxBe7urqsB4WDenp6/kPxPyCe0tnZyTuYHASiHwFDzHswOAgFAx21vK2tTXSwOOgf1FFvgHTsoAghtNDa2d7erjBYHARLW1+ADitoaGhgGvAQQgutE0CsM1gcBAutX0BHxQyKEEIKqZWDxkGgIgGYlkQG0kH0KzRJcBB9qhVCoQIMkWt0rXgJ5KSm3Nxc9gEvqWle1pDgIPqUxgQaaN/pXl8RCCFPoGMCR9vOo2AUjILhDAAx5rxAD1XOQAAAAABJRU5ErkJggg==", "images/attachment_open.png":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAElSURBVEjH7ZEvSENRFMZ/T6YwtjJBDIIGTQNBsUwEowYxObMTNFmvYFi27EaHWSzaTBrEICIaxD0ZCIsGQWzCXjNYDL63++e8YRB5Xzznu7/znXMhU6Y/pMDe0hUOmTG27thSz/HSgGPIrgUD8+wkSy5QIU0vJzzBBecADFNn0GSQgo7U6fflllgQgXSJcQJQYax8omtUVQR8miclbqTneCWkRUvHR1xRJdDL9sjJY2+SN7jOWGGIS9aAERmoaPAcs06Jayps6zfKMlCvnthgjBumARiVrtarSfa5Zcpn839/kT2vx5koT+R4F8lBizQILb17mvLVmqyqWclSPtAEj7rN+4/Kg6r3A4IcKRL5v79PUNfh/UgDOqBjcb7Q+K30mf6dvgCbwjKQ6CfPoAAAAABJRU5ErkJggg=="};
})();
goog.provide("uno.util.img.fixtures.android");
goog.require("uno.util.img.fixtures.generic");
(function() {
  var util = uno.util;
  var generic = util.img.fixtures.generic;
  var fixtures = util.img.fixtures.android;
  fixtures.map = generic.map;
})();
goog.provide("uno.util.resource.android");
goog.require("uno.util.canvas");
goog.require("uno.util.dom");
goog.require("uno.util.resource.generic");
goog.require("uno.util.img");
goog.require("uno.util.img.fixtures.android");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.resource.android");
  var util = uno.util;
  var android = util.resource.android;
  var generic = util.resource.generic;
  var resourceFillStyle = "#8E8E93";
  var resourceFontStyle = '12px "Helvetica Neue", Helvetica, Arial, sans';
  var resourceHeight = 60;
  var resourceWidth = 320;
  android.findResourcesInClientHtml = function(root) {
    return [];
  };
  android.findResourcesInClipboardHtml = function(root) {
    return root.querySelectorAll("img:not(.en-todo):not(.en-crypt):not(.en-richlink)");
  };
  android.convertMediaToSlug = function(enmedia, props, editor) {
    var slug;
    if (util.resource.isImage(props.type)) {
      slug = util.img.convertMediaToSlug(enmedia, props, editor);
    } else {
      slug = convertMediaToImage(enmedia, props, editor);
    }
    return slug;
  };
  function convertMediaToImage(enmedia, props, editor) {
    var img = util.resource.findByRef(props.reference, editor.field);
    if (img == null) {
      img = new Image;
      img.width = resourceWidth;
      img.height = resourceHeight;
      img.style.width = resourceWidth + "px";
      img.style.height = "auto";
      img.setAttribute("data-hash", props.hash);
      img.setAttribute("data-type", props.type);
    }
    var canvas = util.canvas.create(resourceWidth, resourceHeight);
    var ctx = canvas.getContext("2d");
    if (props.state === "unloaded") {
      renderUnloadedResource(ctx, img, props);
    } else {
      if (props.state === "loading") {
        renderLoadingResource(ctx, img, props);
      } else {
        if (props.state === "loaded" || !props.state) {
          var asyncRenderers = [renderMenuAsync(ctx, img, props), renderActionBtnAsync(ctx, img, props), renderThumbnailAsync(ctx, img, props)];
          Promise.all(asyncRenderers).then(function(results) {
            renderFilenameAndSize(ctx, img, props);
            var canvasData = canvas.toDataURL();
            var loadedImage = util.resource.findByRef(props.reference, editor.field);
            if (loadedImage && loadedImage.src === "") {
              loadedImage.src = canvasData;
              setUpHandlers(loadedImage, editor);
              util.resource.fixSlugInTableDimensions(loadedImage);
            } else {
              img.src = canvasData;
              setUpHandlers(img, editor);
              util.resource.fixSlugInTableDimensions(img);
            }
          });
        }
      }
    }
    return img;
  }
  function renderUnloadedResource(ctx, img, props) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.title != null) {
      ctx.save();
      ctx.fillStyle = "#167EFB";
      ctx.font = '700 14px "Helvetica Neue", Helvetica, Arial, sans';
      ctx.textAlign = "center";
      ctx.fillText(props.title, resourceWidth / 2, resourceHeight * 0.25);
      ctx.restore();
    }
    if (props.filesize != null) {
      ctx.fillText(props.filesize, resourceWidth / 2, resourceHeight * 0.75 + 15);
    }
    ctx.restore();
    renderFilenameAndSize(ctx, img, props);
  }
  function renderLoadingResource(ctx, img, props) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.downloaded != null) {
      ctx.fillText(props.downloaded, resourceWidth / 2, resourceHeight * 0.75 + 15);
    }
    var progress = Math.max(Math.min(1, props.progress), 0);
    var cx = resourceWidth / 2;
    var cy = resourceHeight * 0.25;
    var radius = 25;
    ctx.lineWidth = 3;
    ctx.strokeStyle = "#dedede";
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false);
    ctx.stroke();
    ctx.fillStyle = "#dedede";
    ctx.beginPath();
    ctx.arc(cx, cy, radius, util.canvas.rad(360 * progress - 90), util.canvas.rad(270), false);
    ctx.lineTo(cx, cy);
    ctx.closePath();
    ctx.fill();
    ctx.restore();
    renderFilenameAndSize(ctx, img, props);
  }
  function setUpHandlers(img, editor) {
    goog.events.listen(img, "click", function(event) {
      event.preventDefault();
      event.stopPropagation();
      var target = event.target;
      if (isOverMenu(event)) {
        EN.notification("showOptions", {href:target.getAttribute("data-href"), module:"resource"});
      } else {
        var evt = {type:"linkclick", target:target, data:{action:undefined, eventType:"tap", hash:util.resource.hashFor(target), href:util.resource.urlFor(target), mime:util.resource.mimeTypeFor(target), module:"resource", reference:util.resource.referenceFor(target)}};
        editor.dispatchEvent(evt);
      }
    });
  }
  function renderFilenameAndSize(ctx, img, props) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "left";
    var x = 70;
    var y = Math.floor(resourceHeight / 2) - 5;
    if (props.filename != null) {
      var filename = props.filename;
      var len = filename.length - 4;
      var metrics = ctx.measureText(filename);
      while (metrics.width > resourceWidth && len > 0) {
        filename = props.filename.substring(0, len) + "...";
        len--;
        metrics = ctx.measureText(filename);
      }
      ctx.fillText(filename, x, y);
    }
    if (props.filesize != null) {
      y += 20;
      ctx.fillText(props.filesize, x, y);
    }
    ctx.restore();
  }
  function renderActionBtnAsync(ctx, img, props) {
    var fileType = util.attachment.getFileTypeFromMime(props.type);
    var btnSrc = "images/attachment_open.png";
    if (fileType === "audio" || fileType === "video") {
      btnSrc = "images/attachment_play.png";
    }
    return util.img.loadFromClientAsync(btnSrc, {fixtures:util.img.fixtures.android}).then(function(loadedImg) {
      var x = resourceWidth - loadedImg.width - 20;
      var y = Math.floor(resourceHeight / 2 - loadedImg.height / 2);
      ctx.drawImage(loadedImg, x, y);
    });
  }
  function renderMenuAsync(ctx, img, props) {
    return util.img.loadFromClientAsync("images/overflow_menu.svg", {fixtures:util.img.fixtures.android}).then(function(loadedImg) {
      var x = resourceWidth - loadedImg.width / 2 - 10;
      var y = Math.floor(resourceHeight / 2 - loadedImg.height / 2);
      ctx.drawImage(loadedImg, x, y);
    });
  }
  function renderThumbnailAsync(ctx, img, props) {
    var thumbSrc = util.attachment.getBase64IconFromMime(props.type);
    return util.img.loadAsync(thumbSrc).then(function(loadedImg) {
      var x = 10;
      var y = Math.floor(resourceHeight / 2) - loadedImg.height / 2;
      ctx.drawImage(loadedImg, x, y);
    });
  }
  function isOverMenu(event) {
    var target = event.target;
    var box = goog.style.getBounds(target);
    var overMenu = event.target === target && event.clientX > box.left + box.width - 46 && event.clientY <= box.top + 55;
    return overMenu;
  }
  android.dictFromElement = function(el) {
    return {};
  };
  android.dictFromClipboardElement = function(el, context) {
    return generic.dictFromClipboardElement(el, context);
  };
  android.formatForExport = function(html) {
    return html;
  };
  android.convertClientElementToSlug = function(el) {
    return el;
  };
  android.convertSlugToClientElement = function(el) {
    return generic.convertSlugToClientElement(el);
  };
  android.convertSlugToClipboardElement = function(slug) {
    return slug;
  };
  android.toggleObjectsInRange = function(range, clonedObjects) {
    return false;
  };
  android.fixSlugInTableDimensions = function(slug) {
    var parentTd = goog.dom.getAncestor(slug, util.dom.isTd);
    if (parentTd) {
      var parentTable = goog.dom.getAncestor(slug, util.dom.isEntable);
      var colIndex = util.table.colIndex(parentTd);
      util.table.fitColumnIfNeeded(parentTable, colIndex);
    }
  };
  android.applyPDFStyles = function(el) {
    return el;
  };
})();
goog.provide("uno.util.resource.ios");
goog.require("uno.util.dom");
goog.require("uno.util.resource.generic");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.resource.ios");
  var util = uno.util;
  var ios = util.resource.ios;
  var generic = util.resource.generic;
  var resourceFillStyle = "#8E8E93";
  var resourceFontStyle = '12px "Helvetica Neue", Helvetica, Arial, sans';
  ios.findResourcesInClientHtml = function(root) {
    return [];
  };
  ios.findResourcesInClipboardHtml = function(root) {
    return root.querySelectorAll("img:not(.en-todo):not(.en-crypt):not(.en-richlink)");
  };
  ios.convertMediaToSlug = function(enmedia, props, editor) {
    var slug;
    if (util.resource.isImage(props.type)) {
      slug = util.img.convertMediaToSlug(enmedia, props, editor);
    } else {
      slug = convertMediaToImage(enmedia, props, editor);
    }
    return slug;
  };
  function convertMediaToImage(enmedia, props, editor) {
    var img = util.resource.findByRef(props.reference, editor.field);
    if (img == null) {
      img = new Image;
      img.width = 160;
      img.height = 120;
      img.style.width = "160px";
      img.style.height = "120px";
      img.setAttribute("data-hash", props.hash);
      img.setAttribute("data-type", props.type);
    }
    var canvas = util.canvas.create(img.width, img.height);
    var ctx = canvas.getContext("2d");
    var padding = 10;
    if (props.state === "unloaded") {
      renderUnloadedResource(ctx, img, props, padding);
    } else {
      if (props.state === "loading") {
        renderLoadingResource(ctx, img, props, padding);
      } else {
        if (props.state === "loaded" || props.state == null) {
          renderFilename(ctx, img, props, padding);
          if (props.thumbnailURL != null) {
            var thumbnail = new Image;
            thumbnail.src = props.thumbnailURL;
            editor.eventRegister.listenOnce(thumbnail, "load", function() {
              var canvas = util.canvas.create(img.width, img.height);
              var ctx = canvas.getContext("2d");
              var image = util.resource.findByRef(props.reference, editor.field);
              renderLoadedResource(ctx, img, props, padding, thumbnail);
              image.src = canvas.toDataURL();
            });
          }
        }
      }
    }
    img.src = canvas.toDataURL();
    return img;
  }
  function renderUnloadedResource(ctx, img, props, padding) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.title != null) {
      ctx.save();
      ctx.fillStyle = "#167EFB";
      ctx.font = '700 14px "Helvetica Neue", Helvetica, Arial, sans';
      ctx.textAlign = "center";
      ctx.fillText(props.title, img.width / 2, img.height * .25);
      ctx.restore();
    }
    if (props.filesize != null) {
      ctx.fillText(props.filesize, img.width / 2, img.height * .75 + 15);
    }
    ctx.restore();
    renderFilename(ctx, img, props, padding);
  }
  function renderLoadingResource(ctx, img, props, padding) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.downloaded != null) {
      ctx.fillText(props.downloaded, img.width / 2, img.height * .75 + 15);
    }
    var progress = Math.max(Math.min(1, props.progress), 0);
    var cx = img.width / 2;
    var cy = img.height * .25;
    var radius = 25;
    ctx.lineWidth = 3;
    ctx.strokeStyle = "#dedede";
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false);
    ctx.stroke();
    ctx.fillStyle = "#dedede";
    ctx.beginPath();
    ctx.arc(cx, cy, radius, util.canvas.rad(360 * progress - 90), util.canvas.rad(270), false);
    ctx.lineTo(cx, cy);
    ctx.closePath();
    ctx.fill();
    ctx.restore();
    renderFilename(ctx, img, props, padding);
  }
  function renderLoadedResource(ctx, img, props, padding, thumbnail) {
    var dHeight = Math.min(thumbnail.height, 48);
    var dWidth = dHeight / thumbnail.height * thumbnail.width;
    ctx.drawImage(thumbnail, (img.width - dWidth) / 2, padding, dWidth, dHeight);
    renderFilename(ctx, img, props, padding);
  }
  function renderFilename(ctx, img, props, padding) {
    ctx.save();
    ctx.fillStyle = resourceFillStyle;
    ctx.font = resourceFontStyle;
    ctx.textAlign = "center";
    if (props.filename != null) {
      var filename = props.filename;
      var len = filename.length - 4;
      var metrics = ctx.measureText(filename);
      while (metrics.width > img.width - padding * 2 && len > 0) {
        filename = props.filename.substring(0, len) + "...";
        len--;
        metrics = ctx.measureText(filename);
      }
      ctx.fillText(filename, img.width / 2, img.height * .75);
    }
    ctx.restore();
  }
  ios.decorateMedia = function(enmedia, props) {
    enmedia.setAttribute("data-url", props.url);
    goog.dom.append(enmedia, goog.dom.createDom("en-ux", {}, [goog.dom.createDom("span", {class:"en-resource-progress"}, goog.dom.createDom("span", {class:"en-resource-progress-fill"}, goog.dom.createDom("span", {class:"en-resource-progress-mask"}))), goog.dom.createDom("span", {class:"en-resource-icon"}, goog.dom.createDom("img", {src:props.thumbnailURL})), goog.dom.createDom("span", {class:"en-resource-title"}, props.title), goog.dom.createDom("span", {class:"en-resource-name"}, props.filename), 
    goog.dom.createDom("span", {class:"en-resource-value"}, props.state == "loading" ? props.downloaded : props.filesize)]));
    if (props.state) {
      goog.dom.classes.add(enmedia, props.state);
    }
    if (props.state === "loading") {
      var value = Math.max(Math.min(1, props.progress), 0);
      var halfValue = value > 0.5 ? value - 0.5 : value;
      var progressFill = enmedia.querySelector(".en-resource-progress-fill");
      goog.style.setStyle(progressFill, "-webkit-transform", "rotate(" + 360 * value + "deg)");
      var progressMask = progressFill.children[0];
      goog.style.setStyle(progressMask, "-webkit-transform", "rotate(" + -180 * halfValue * 2 + "deg)");
      goog.style.setStyle(progressMask, "background", value * 2 <= 1 ? "#fff" : "#dedede");
    }
    if (props.overlayOpacity > 0) {
      goog.dom.classes.add(enmedia, "overlayed");
      var overlay = goog.dom.createDom("span", {class:"en-resource-overlay"});
      overlay.style.backgroundColor = "rgba(0, 0, 0, " + props.overlayOpacity + ")";
      enmedia.appendChild(overlay);
    }
    return enmedia;
  };
  ios.dictFromElement = function(el) {
    return {};
  };
  ios.dictFromClipboardElement = function(el, context) {
    var dict;
    if (util.dom.compareTagName(el, "img")) {
      dict = context.resources[el.getAttribute("src")];
    } else {
      log.severe("ios resource from clipboard is not an img");
      if (el) {
        log.info("ios.dictFromClipboardElement received " + el.tagName);
      }
    }
    return dict;
  };
  ios.formatForExport = function(html) {
    return html;
  };
  ios.convertClientElementToSlug = function(el) {
    return el;
  };
  ios.convertSlugToClientElement = function(el) {
    var url = el.getAttribute("data-url");
    util.dom.removeDataAttributes(el);
    el.setAttribute("src", url);
    return el;
  };
  ios.convertSlugToClipboardElement = function(el) {
    return el;
  };
  ios.toggleObjectsInRange = function(range, clonedObjects) {
    return false;
  };
  ios.fixSlugInTableDimensions = function(table) {
    return false;
  };
  ios.applyPDFStyles = function(el) {
    return el;
  };
})();
goog.provide("uno.util.resource.mac");
goog.require("uno.util.dom");
(function() {
  var util = uno.util;
  var mac = uno.util.resource.mac;
  var rxEmbedImplicitVoidTags = /<embed([^>]*[^/]\s*)>/g;
  mac.findResourcesInClientHtml = function(root) {
    return goog.array.filter(root.querySelectorAll('img:not(.en-todo):not(.en-crypt):not(.en-richlink),embed[id^="en-media"]'), function(el) {
      return el;
    });
  };
  mac.findResourcesInClipboardHtml = function(root) {
    return mac.findResourcesInClientHtml(root);
  };
  mac.convertMediaToSlug = function(enmedia, props, editor) {
    var slug;
    if (util.resource.isImage(props.type)) {
      slug = util.img.convertMediaToSlug(enmedia, props, editor);
      if (!props.elementId) {
        props.elementId = mac.getElementId(props);
      }
    } else {
      if (util.resource.isPdf(props.type)) {
        slug = convertPdfMediaToSlug(enmedia, props);
      } else {
        slug = convertFileMediaToSlug(enmedia, props);
      }
    }
    if (props.elementId) {
      slug.id = props.elementId;
    }
    return slug;
  };
  mac.getElementId = function(props) {
    if (props) {
      return "en-media:" + props.type + ":" + props.hash + ":none:none";
    }
  };
  mac.dictFromElement = function(el) {
    var hash = el.getAttribute("data-hash");
    var mime = el.getAttribute("data-type");
    var url = el.getAttribute("data-url");
    var elementId = mac.getElementId({type:mime, hash:hash});
    var width = el.getAttribute("width");
    var dict;
    if (mime && hash && url && url.indexOf("evernotecid") > -1) {
      dict = {url:url, mime:mime || util.dom.compareTagName(el, "img") && "image/unknown", hash:hash, elementId:elementId};
    } else {
      var data = (el.getAttribute("id") || ":::").split(":");
      dict = {url:el.src, mime:data[1] || util.dom.compareTagName(el, "img") && "image/unknown", hash:data[2], elementId:el.getAttribute("id")};
    }
    if (width != null && width != "") {
      dict.width = width;
    }
    return dict;
  };
  mac.dictFromClipboardElement = function(el, context) {
    return mac.dictFromElement(el);
  };
  mac.formatForExport = function(html) {
    if (html == null) {
      return html;
    }
    return html.replace(rxEmbedImplicitVoidTags, "<embed $1 />");
  };
  function convertPdfMediaToSlug(enmedia, props) {
    var attr = {src:props.url, type:"evernote/x-pdf", id:"en-media:application/pdf:" + props.hash};
    ["style", "width", "height"].forEach(function(name) {
      if (props[name]) {
        attr[name] = props[name];
      }
    });
    return goog.dom.createDom("embed", attr);
  }
  function convertFileMediaToSlug(enmedia, props) {
    var attr = {src:props.url, type:"evernote/x-attachment", id:"en-media:evernote/x-attachment:" + props.hash};
    ["style", "width", "height", "id"].forEach(function(name) {
      if (props[name]) {
        attr[name] = props[name];
      }
    });
    return goog.dom.createDom("embed", attr);
  }
  mac.convertClientElementToSlug = function(el, props, editor) {
    if (util.resource.isImage(props.type)) {
      return util.img.convertClientElementToSlug(el, props, editor);
    }
    return el;
  };
  mac.convertSlugToClientElement = function(el) {
    util.dom.removeDataAttributes(el);
    return el;
  };
  mac.convertSlugToClipboardElement = function(slug) {
    return slug;
  };
  mac.toggleObjectsInRange = function(range, clonedObjects) {
    return false;
  };
  mac.fixSlugInTableDimensions = function(table) {
    return false;
  };
  mac.applyPDFStyles = function(el) {
    return el;
  };
})();
goog.provide("uno.util.resource.win");
goog.require("goog.array");
goog.require("uno.util.dom");
goog.require("uno.util.img");
(function() {
  var util = uno.util;
  var win = util.resource.win;
  win.findResourcesInClientHtml = function(root) {
    return goog.array.filter(root.querySelectorAll('img:not(.en-todo):not(.en-crypt):not(.en-richlink):not([src^="en-resource://database/pprotect:"]), object'), function(el) {
      return util.dom.compareTagName(el, "object") || !/\/check/i.test(el.src);
    });
  };
  win.findResourcesInClipboardHtml = function(root) {
    return win.findResourcesInClientHtml(root);
  };
  win.convertMediaToSlug = function(enmedia, props, editor) {
    if (util.resource.isImage(props.type)) {
      return util.img.convertMediaToSlug(enmedia, props, editor);
    } else {
      if (util.resource.isPdf(enmedia) && !props.attachment) {
        var slug = goog.dom.createDom("object", {data:props.url, type:props.type}, goog.dom.createDom("param", {name:"filename", value:props.filename}));
        if (props.width != null) {
          slug.setAttribute("width", props.width);
        }
        if (props.style != null) {
          slug.setAttribute("style", props.style);
        }
        if (props.height != null) {
          slug.setAttribute("height", props.height);
        }
        return slug;
      } else {
        var img = new Image;
        goog.dom.classlist.addAll(img, ["en-media", "en-media-file"]);
        img.src = props.url;
        img.dataset.type = props.type;
        img.dataset.filename = props.filename;
        img.dataset.width = props.width;
        img.dataset.height = props.height;
        goog.dom.replaceNode(img, enmedia);
        return img;
      }
    }
  };
  win.dictFromElement = function(el) {
    var mime = el.getAttribute("type");
    var url = el.getAttribute("data");
    var style = el.getAttribute("style");
    var width = el.getAttribute("width");
    var height = el.getAttribute("height");
    var paramFilename = el.querySelector("param[name=filename]") || (el.getAttribute("data-filename") ? {value:el.getAttribute("data-filename")} : null);
    var paramUrl = el.querySelector("param[name=data]");
    if (paramFilename) {
      paramFilename = paramFilename.value;
    }
    if (!url && paramUrl) {
      url = paramUrl.value;
    }
    var dict;
    if (url && (url.indexOf("loadpdf") > -1 || url.indexOf("en-resource") > -1)) {
      dict = {url:url, mime:mime || util.dom.compareTagName(el, "img") && "image/unknown"};
    } else {
      dict = {url:el.src, mime:el.getAttribute("type") || util.dom.compareTagName(el, "img") && "image/unknown"};
    }
    if (style) {
      dict.style = style;
    }
    if (width) {
      dict.width = width;
    }
    if (height && dict.mime.indexOf("image/") < 0) {
      dict.height = height;
    }
    if (paramFilename) {
      dict.filename = paramFilename;
    }
    if (util.resource.isPdf(el) && el.nodeName === "IMG") {
      dict.attachment = true;
    }
    return dict;
  };
  win.dictFromClipboardElement = function(el) {
    return win.dictFromElement(el);
  };
  win.formatForExport = function(html) {
    return html;
  };
  win.convertClientElementToSlug = function(el) {
    return el;
  };
  win.convertSlugToClientElement = function(el) {
    util.dom.removeDataAttributes(el);
    return el;
  };
  win.convertSlugToClipboardElement = function(slug) {
    return slug;
  };
  win.toggleObjectsInRange = function(range, clonedObjects) {
    clonedObjects = clonedObjects || [];
    var containerNode;
    if (range.isCollapsed()) {
      containerNode = range.getStartNode();
    } else {
      containerNode = range.getContainerElement();
    }
    if (util.dom.isTextNode(containerNode)) {
      return false;
    }
    var objects = containerNode.querySelectorAll("object");
    if (!!clonedObjects.length) {
      goog.array.forEach(objects, function(brokenObject) {
        var brokenObjectNodeAttrs = util.dom.attributes(brokenObject);
        goog.array.forEach(clonedObjects, function(clonedObject) {
          var clonedObjectAttrs = util.dom.attributes(clonedObject);
          if (brokenObjectNodeAttrs["data-reference"] === clonedObjectAttrs["data-reference"] && brokenObjectNodeAttrs["data-filename"] === clonedObjectAttrs["data-filename"] && brokenObjectNodeAttrs["data-url"] === clonedObjectAttrs["data-url"]) {
            brokenObject.parentNode.replaceChild(clonedObject, brokenObject);
          }
        });
      });
    } else {
      goog.array.forEach(objects, function(brokenObject) {
        clonedObjects.push(brokenObject.cloneNode(true));
      });
      return clonedObjects;
    }
    return false;
  };
  win.fixSlugInTableDimensions = function(table) {
    return false;
  };
  win.applyPDFStyles = function(el) {
    el.height = window.innerHeight;
    return el;
  };
})();
goog.provide("uno.util.resource");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.events");
goog.require("goog.string");
goog.require("uno.util.dom");
goog.require("uno.util.resource.android");
goog.require("uno.util.resource.generic");
goog.require("uno.util.resource.ios");
goog.require("uno.util.resource.mac");
goog.require("uno.util.resource.win");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.resource");
  var util = uno.util;
  util.resource.counter = 0;
  var client = uno.util.resource.generic;
  util.resource.setClient = function(clientName) {
    client = uno.util.resource[clientName] || client;
  };
  util.resource.all = function(root) {
    return root.querySelectorAll(".en-media");
  };
  util.resource.findResourcesInClientHtml = function(root, editor) {
    return client.findResourcesInClientHtml(root, editor);
  };
  util.resource.findResourcesInClipboardHtml = function(root, editor) {
    return client.findResourcesInClipboardHtml(root, editor);
  };
  util.resource.findByRef = function(ref, node) {
    var selector = '.en-media[data-reference="' + ref + '"]';
    var el = node.querySelector(selector);
    return el;
  };
  util.resource.findByURL = function(url, node) {
    var selector = '.en-media[data-url="' + url + '"]';
    return node.querySelectorAll(selector);
  };
  util.resource.findByHash = function(hash, node) {
    var selector = '.en-media[data-hash="' + hash + '"]';
    return node.querySelectorAll(selector);
  };
  util.resource.createUid = function() {
    return "resource-" + util.resource.counter++;
  };
  util.resource.isResource = function(node) {
    return node && util.dom.matches(node, ".en-media");
  };
  util.resource.isImage = function(elOrMime) {
    var mime = (util.resource.parseMime(elOrMime) || "").toLowerCase();
    var isImage = mime.indexOf("image/") === 0;
    var isPsd = mime === "image/vnd.adobe.photoshop";
    var isTiff = mime === "image/tif" || mime === "image/tiff";
    var isXcf = mime === "image/x-xcf";
    var isInk = mime === "application/vnd.evernote.ink";
    return isInk || isImage && !isPsd && !isTiff && !isXcf;
  };
  util.resource.isPdf = function(elOrMime) {
    var mimes = ["application/pdf", "evernote/x-pdf"];
    var mime = util.resource.parseMime(elOrMime);
    return mime && mimes.indexOf(mime.toLowerCase()) != -1;
  };
  util.resource.isFileUI = function(el) {
    return goog.dom.classes.has(el, "en-media-file");
  };
  util.resource.createMediaFromDict = function(dict) {
    var enmedia = goog.dom.createElement("en-media");
    enmedia.setAttribute("type", dict.mime);
    enmedia.setAttribute("hash", dict.hash);
    if (dict.style) {
      enmedia.setAttribute("style", dict.style);
    }
    if (dict.width) {
      enmedia.setAttribute("width", dict.width);
    }
    if (dict.height) {
      enmedia.setAttribute("height", dict.height);
    }
    return enmedia;
  };
  util.resource.addMetaData = function(el, props) {
    if (props.reference != null) {
      el.setAttribute("data-reference", props.reference);
    }
    if (props.hash != null) {
      el.setAttribute("data-hash", props.hash);
    }
    if (props.type != null) {
      el.setAttribute("data-type", props.type);
    }
    if (props.filename != null) {
      el.setAttribute("data-filename", props.filename);
    }
    if (props.filesize != null) {
      el.setAttribute("data-filesize", props.filesize);
    }
    if (props.thumbnailURL != null) {
      el.setAttribute("data-thumbnail-url", props.thumbnailURL);
    }
    if (props.title != null) {
      el.setAttribute("data-title", props.title);
    }
    if (props.url != null) {
      el.setAttribute("data-url", props.url);
    }
  };
  util.resource.convertClipboardElementToSlug = function(el, context, editor) {
    var enmedia;
    var slug;
    var dict = client.dictFromClipboardElement(el, context);
    if (!dict) {
      log.warning("Could not find resource dictionary for resource");
      goog.dom.removeNode(el);
    } else {
      enmedia = util.resource.createMediaFromDict(dict);
      slug = util.resource.convertMediaToSlug(enmedia, dict, editor);
      goog.dom.replaceNode(slug, el);
    }
    return slug;
  };
  util.resource.convertClientElementToSlug = function(el, editor) {
    var dict = client.dictFromElement(el);
    var props = util.resource.propsFromDict(dict);
    props.reference = props.reference || el.getAttribute("data-reference") || util.resource.createUid();
    var slug = client.convertClientElementToSlug(el, props, editor);
    slug._yjsHook = "en-resource";
    if (util.resource.isImage(dict.mime) && el.getAttribute("height") && el.getAttribute("width") && !editor.hasForeignSource()) {
      el.removeAttribute("height");
    }
    util.resource.addMetaData(slug, props);
    goog.dom.replaceNode(slug, el);
    addCssClasses(slug, props.type);
  };
  util.resource.convertSlugToClientElement = function(slug) {
    var el = client.convertSlugToClientElement(slug);
    el.removeAttribute("class");
    goog.dom.replaceNode(el, slug);
    return el;
  };
  util.resource.convertMediaToSlug = function(enmedia, dict, editor) {
    var props = {};
    var enmlProps = util.resource.propsFromEnml(enmedia);
    Object.keys(enmlProps).forEach(function(key) {
      if (enmlProps[key] == null) {
        delete enmlProps[key];
      }
    });
    goog.object.extend(props, util.resource.propsFromDict(dict), enmlProps);
    props.reference = props.reference || enmedia.getAttribute("data-reference") || util.resource.createUid();
    var slug = client.convertMediaToSlug(enmedia, props, editor);
    slug._yjsHook = "en-resource";
    util.dom.copyAttributes(enmedia, slug, util.styles.rxEvernoteCustomDataAttr);
    util.resource.addMetaData(slug, props);
    if (props.style != null) {
      var style = slug.getAttribute("style") || "";
      slug.setAttribute("style", props.style + style);
    }
    if (props.hidden === true) {
      goog.style.setStyle(slug, "display", "none");
    }
    if (!util.dom.isFollowedByContent(slug)) {
      goog.dom.insertSiblingAfter(document.createElement("br"), slug);
    }
    goog.dom.replaceNode(slug, enmedia);
    addCssClasses(slug, props.type);
    return slug;
  };
  util.resource.convertSlugToMedia = function(slug) {
    var enmedia = goog.dom.createDom("en-media");
    if (!slug.getAttribute("data-hash") || !slug.getAttribute("data-type")) {
      return null;
    }
    enmedia.setAttribute("hash", slug.getAttribute("data-hash"));
    enmedia.setAttribute("type", slug.getAttribute("data-type"));
    if (slug.getAttribute("style") != null) {
      enmedia.setAttribute("style", slug.getAttribute("style"));
    }
    ["width", "height", "align", "alt", "longdesc", "title", "lang", "dir", "border", "hspace", "vspace", "usemap"].forEach(function(name) {
      if (slug.getAttribute(["data", goog.string.toSelectorCase(name)].join("-")) != null) {
        enmedia.setAttribute(name, slug.getAttribute(["data", goog.string.toSelectorCase(name)].join("-")));
      }
    });
    util.dom.copyAttributes(slug, enmedia, util.styles.rxEvernoteCustomDataAttr);
    goog.dom.replaceNode(enmedia, slug);
    return enmedia;
  };
  util.resource.dictFromElement = function(el) {
    if (!el) {
      return {};
    }
    return {filename:el.getAttribute("data-filename"), filesize:el.getAttribute("data-filesize"), hash:el.getAttribute("hash") || el.getAttribute("data-hash"), reference:el.getAttribute("data-reference"), thumbnailURL:el.getAttribute("data-thumbnail-url"), title:el.getAttribute("data-title"), mime:el.getAttribute("type") || el.getAttribute("data-type"), url:el.getAttribute("data-url")};
  };
  util.resource.propsFromEnml = function(enmedia) {
    if (!enmedia) {
      return {};
    }
    return {hash:enmedia.getAttribute("hash"), type:enmedia.getAttribute("type"), width:enmedia.getAttribute("width"), height:enmedia.getAttribute("height"), style:enmedia.getAttribute("style"), align:enmedia.getAttribute("align"), alt:enmedia.getAttribute("alt"), longdesc:enmedia.getAttribute("longdesc"), title:enmedia.getAttribute("title"), lang:enmedia.getAttribute("lang"), dir:enmedia.getAttribute("dir"), border:enmedia.getAttribute("border"), hspace:enmedia.getAttribute("hspace"), vspace:enmedia.getAttribute("vspace"), 
    usemap:enmedia.getAttribute("usemap")};
  };
  util.resource.propsFromDict = function(dict) {
    if (!dict) {
      return {};
    }
    return {attachment:dict.attachment, contextURL:dict.contextURL, defaultActionURL:dict.defaultActionURL, downloaded:dict.downloaded, filename:dict.filename, filesize:dict.filesize, hash:dict.hash, height:dict.height, hidden:dict.hidden === true, elementId:dict.elementId, overlayImageURL:dict.overlayImageURL, overlayColor:dict.overlayColor, overlayOpacity:dict.overlayOpacity, progress:dict.progress, reference:dict.reference, state:dict.state, thumbnailURL:dict.thumbnailURL, title:dict.title, type:dict.mime ? 
    dict.mime.toLowerCase() : "", url:dict.url, width:dict.width};
  };
  util.resource.applyProps = function(target, props) {
    target.setAttribute("hash", props.hash);
    target.setAttribute("type", props.type);
    ["reference", "width", "height", "align", "alt", "longdesc", "title", "lang", "dir", "border", "hspace", "vspace", "usemap"].forEach(function(name) {
      if (props[name]) {
        target.setAttribute(["data", goog.string.toSelectorCase(name)].join("-"), props[name]);
      }
    });
  };
  util.resource.referenceFor = function(el) {
    return el.getAttribute("data-reference");
  };
  util.resource.urlFor = function(el) {
    return el.getAttribute("data-url");
  };
  util.resource.mimeTypeFor = function(el) {
    return el.getAttribute("type") || el.getAttribute("data-type");
  };
  util.resource.parseMime = function(elOrMime) {
    var mime;
    if (elOrMime.getAttribute) {
      mime = util.resource.mimeTypeFor(elOrMime);
    } else {
      if (typeof elOrMime === "string") {
        mime = elOrMime;
      }
    }
    return mime;
  };
  util.resource.hashFor = function(el) {
    return el.getAttribute("hash") || el.getAttribute("data-hash");
  };
  util.resource.isDefaultContextButton = function(el) {
    return goog.dom.classes.has(el, "en-resource-context-default");
  };
  util.resource.isOverflowContextButton = function(el) {
    return goog.dom.classes.has(el, "en-resource-context-overflow");
  };
  util.resource.formatClientHtmlForExport = function(html) {
    return client.formatForExport(html);
  };
  util.resource.toDict = function(el, range) {
    return {hash:el.getAttribute("hash") || el.getAttribute("data-hash"), mime:el.getAttribute("type") || el.getAttribute("data-type"), url:el.getAttribute("data-url"), rect:goog.style.getBounds(el), reference:el.getAttribute("data-reference"), selected:!!(range && !range.isCollapsed() && range.containsNode(el)), filename:el.getAttribute("data-filename") || undefined, filesize:el.getAttribute("data-filesize") || undefined};
  };
  util.resource.toggleObjectsInRange = function(range, clonedObjects) {
    return client.toggleObjectsInRange(range, clonedObjects);
  };
  function addCssClasses(el, type) {
    goog.dom.classlist.add(el, "en-media");
    if (util.resource.isImage(type)) {
      goog.dom.classlist.add(el, "en-media-image");
    } else {
      goog.dom.classlist.add(el, "en-media-file");
      if (util.resource.isPdf(type)) {
        goog.dom.classlist.add(el, "en-media-pdf");
        client.applyPDFStyles(el);
      }
    }
  }
  util.resource.fixSlugInTableDimensions = function(slug) {
    return client.fixSlugInTableDimensions(slug);
  };
})();
goog.provide("uno.util.copy.resources");
goog.require("uno.util.resource");
(function() {
  var util = uno.util;
  util.copy.resources.copy = function(root) {
    return goog.array.map(util.resource.all(root), function(el) {
      return util.resource.toDict(el);
    });
  };
})();
goog.provide("uno.util.copy");
goog.require("goog.dom");
goog.require("uno.util.dom");
goog.require("uno.util.copy.plain");
goog.require("uno.util.copy.table");
goog.require("uno.util.copy.rich");
goog.require("uno.util.copy.resources");
goog.require("uno.util.styles");
(function() {
  var util = uno.util;
  var dom = util.dom;
  var copy = util.copy;
  util.copy.copy = function(editor, options, range) {
    range = range || editor.getRange();
    var pastableHtml = "";
    if (!editor.multirange.isEmpty()) {
      pastableHtml = util.copy.table.getPastableHtml();
    } else {
      if (range && !range.isCollapsed()) {
        pastableHtml = util.copy.getPastableHtml(range);
      } else {
        return {plain:"", html:"", resources:[]};
      }
    }
    if (dom.isTextNode(range.getContainer()) || dom.isUnwrappedTextMarkup(pastableHtml)) {
      var style = util.styles.getCascadedStyle(range.getContainer());
      if (Object.keys(style).length > 0) {
        var styledNode = goog.dom.createDom("span", {style:util.styles.getStyleString(style)});
        styledNode.innerHTML = pastableHtml;
        pastableHtml = styledNode.outerHTML;
      }
    }
    var root = dom.nodeFromHtml("<div>" + pastableHtml + "</div>");
    var resourcesNode = dom.nodeFromHtml(pastableHtml);
    addContext(root.firstChild, range, editor);
    pastableHtml = editor.getClipboardContent(root);
    var richNode = dom.nodeFromHtml(pastableHtml);
    var plainNode = dom.nodeFromHtml(pastableHtml);
    return {resources:options.resources ? copy.resources.copy(resourcesNode) : [], html:options.html ? util.copy.rich.copy(richNode, options) : "", plain:options.plain ? util.copy.plain.copy(plainNode) : ""};
  };
  util.copy.getPastableHtml = function(range) {
    var html = range.getPastableHtml();
    if (html.indexOf("<en-table") !== 0) {
      return html;
    }
    var parts = html.split("</table>");
    if (parts[0].indexOf("colgroup") > -1) {
      return html;
    }
    var colgroup = goog.dom.getAncestor(range.getStartNode(), util.dom.isTable, true).querySelector("colgroup");
    var index = html.indexOf("<tbody>");
    if (index === -1 || !colgroup) {
      return html;
    }
    return html.substr(0, index) + colgroup.outerHTML + html.substr(index);
  };
  util.copy.copyOutside = function(range, formField, options) {
    var richText = "";
    var plainText = "";
    if (formField) {
      var start = formField.selectionStart;
      var end = formField.selectionEnd;
      if (start !== end) {
        plainText = formField.value.substr(Math.min(start, end), Math.max(start, end));
        richText = plainText;
      }
    } else {
      if (!range.isCollapsed()) {
        var html = util.copy.getPastableHtml(range);
        if (options.html) {
          richText = util.copy.rich.copy(dom.nodeFromHtml(html), options);
        }
        if (options.plain) {
          plainText = util.copy.plain.copy(dom.nodeFromHtml(html));
        }
      }
    }
    return {resources:[], html:options.html ? richText : "", plain:options.plain ? plainText : ""};
  };
  function addContext(root, range, editor) {
    if (!editor.multirange.isEmpty()) {
      return;
    }
    var href = getHrefForRange(range);
    var anchor;
    if (href) {
      anchor = goog.dom.createDom("a", {href:href}, root.childNodes);
      root.appendChild(anchor);
    }
    var styledNode = getStyleForRange(range);
    util.styles.mergeAttributes(styledNode, anchor || root);
  }
  function getHrefForRange(range) {
    var matcher = function(node) {
      return node && dom.isA(node) && node.getAttribute("href");
    };
    var startAnchor = goog.dom.getAncestor(range.getStartNode(), matcher, true);
    var endAnchor = goog.dom.getAncestor(range.getEndNode(), matcher, true);
    return startAnchor && endAnchor && startAnchor === endAnchor && startAnchor.getAttribute("href");
  }
  function getStyleForRange(range) {
    var node = range.getContainer();
    var styledNode = goog.dom.createDom("div");
    if (node) {
      while (node && !dom.isEnnote(node) && !dom.isTd(node) && !dom.isLi(node) && !dom.isCodeBlock(node) && !dom.isRevealedCrypt(node) && !dom.isBlockquote(node)) {
        util.styles.mergeAttributes(node, styledNode);
        node = node.parentNode;
      }
    }
    return styledNode;
  }
})();
goog.provide("uno.util.crypto");
goog.require("goog.crypt");
goog.require("goog.crypt.Md5");
goog.require("goog.dom");
goog.require("goog.dom.classlist");
goog.require("goog.string");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.copy");
(function() {
  var util = uno.util;
  var CRYPT_CLASS = uno.defs.crypto.CRYPT_CLASS;
  var CRYPT_HIDDEN_CLASS = uno.defs.crypto.CRYPT_HIDDEN_CLASS;
  var CRYPT_VISIBLE_CLASS = uno.defs.crypto.CRYPT_VISIBLE_CLASS;
  util.crypto.all = function(root) {
    return root.querySelectorAll("." + CRYPT_CLASS);
  };
  util.crypto.for = function(node) {
    return goog.dom.getAncestor(node, util.crypto.isCrypt, true);
  };
  util.crypto.isCrypt = function(node) {
    return node && goog.dom.classlist.contains(node, CRYPT_CLASS);
  };
  util.crypto.isOpen = function(node) {
    return util.crypto.isCrypt(node) && goog.dom.classlist.contains(node, CRYPT_VISIBLE_CLASS);
  };
  util.crypto.createCryptoPlaceholder = function(cryptInfo) {
    var cryptNode = goog.dom.createDom("img", {id:cryptInfo.id, class:CRYPT_CLASS + " " + CRYPT_HIDDEN_CLASS, src:cryptInfo.src || uno.defs.image.TRANSPARENT_IMAGE_DATA_URL, "data-src":cryptInfo.src || "", "data-length":cryptInfo.length || "", "data-cipher":cryptInfo.cipher || "", "data-hint":cryptInfo.hint || "", "data-ciphertext":cryptInfo.cipherText || "", "data-hash":cryptInfo.plainText && util.crypto.hash(cryptInfo.plainText) || ""});
    return cryptNode;
  };
  util.crypto.getCryptInfoFromNode = function(node) {
    if (!node) {
      return null;
    }
    var cryptInfo = {id:node.getAttribute("id"), src:node.getAttribute("data-src"), length:node.getAttribute("data-length"), cipher:node.getAttribute("data-cipher"), hint:node.getAttribute("data-hint") || "", cipherText:node.getAttribute("data-ciphertext"), plainText:node.innerHTML, hash:node.getAttribute("data-hash"), boundingbox:goog.style.getBounds(node)};
    return cryptInfo;
  };
  util.crypto.getNodeFromCryptInfo = function(cryptInfo, options) {
    var selector = "#" + cryptInfo.id.replace(/([^a-z0-9_-])/gi, "\\$1");
    if (options && options.encryptedOnly) {
      selector += ":not(." + CRYPT_VISIBLE_CLASS + ")";
    }
    if (options && options.decryptedOnly) {
      selector += "." + CRYPT_VISIBLE_CLASS;
    }
    return document.querySelector(selector);
  };
  util.crypto.handleClick = function(node, readOnly, dispatchEvent) {
    var cryptNode = node && goog.dom.getAncestor(node, util.crypto.isCrypt, true);
    if (cryptNode && (cryptNode === node || readOnly)) {
      if (!util.crypto.isOpen(cryptNode)) {
        var range = goog.dom.Range.createFromNodeContents(cryptNode);
        if (range) {
          range.select();
        }
      }
      var cryptInfo = util.crypto.getCryptInfoFromNode(cryptNode);
      var hasClass = goog.dom.classlist.contains;
      if (hasClass(cryptNode, CRYPT_HIDDEN_CLASS)) {
        dispatchEvent({type:"decrypt", cryptInfo:cryptInfo});
      } else {
        if (readOnly && hasClass(cryptNode, CRYPT_VISIBLE_CLASS)) {
          dispatchEvent({type:"encrypt", cryptInfo:cryptInfo});
        }
      }
      return true;
    }
    return false;
  };
  util.crypto.isDirty = function(cryptNode) {
    var contentHash = cryptNode.getAttribute("data-hash");
    return util.crypto.isOpen(cryptNode) && contentHash !== util.crypto.hash(cryptNode.innerHTML || "");
  };
  util.crypto.getDirtyCrypto = function(root) {
    var cryptElements = util.crypto.all(root);
    var dirtyCrypto = [];
    goog.iter.forEach(cryptElements, function(cryptNode) {
      if (util.crypto.isDirty(cryptNode)) {
        cryptNode.setAttribute("data-ciphertext", "");
        cryptNode.setAttribute("data-hash", "");
        dirtyCrypto.push(util.crypto.getCryptInfoFromNode(cryptNode));
      }
    });
    return dirtyCrypto;
  };
  util.crypto.updateCryptNodes = function(cryptInfos) {
    cryptInfos.forEach(function(cryptInfo) {
      var cryptNode = util.crypto.getNodeFromCryptInfo(cryptInfo);
      cryptNode.setAttribute("data-ciphertext", cryptInfo.cipherText);
      if (cryptNode.innerHTML) {
        cryptNode.setAttribute("data-hash", util.crypto.hash(cryptNode.innerHTML));
      }
    });
  };
  util.crypto.hash = function(content) {
    var md5 = new goog.crypt.Md5;
    md5.update(content);
    return goog.crypt.byteArrayToHex(md5.digest());
  };
})();
goog.provide("uno.util.structure");
goog.require("goog.asserts");
goog.require("goog.dom");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.structure");
  var util = uno.util;
  var dom = util.dom;
  var structure = util.structure;
  var T = uno.defs.structuretypes;
  var rules = {NOTE:{CODE:1, CRYPTO:1, EMOTICON:1, HR:1, LIST:1, RESOURCE:1, TABLE:1, TEXT:1, TODO:1, CMD_CODE:1, CMD_CRYPTO:1, CMD_HR:1, CMD_INDENT:1, CMD_LIST:1, CMD_TODO:1, TYPE_LIST:1}, CODE:{TEXT:1, CMD_CODE:1}, CRYPTO:{TEXT:1}, TABLE:{CRYPTO:1, EMOTICON:1, LIST:1, RESOURCE:1, TEXT:1, TODO:1, CMD_CRYPTO:1, CMD_INDENT:1, CMD_LIST:1, CMD_TODO:1, TYPE_LIST:1}, LIST:{CRYPTO:1, EMOTICON:1, HR:1, LIST:1, RESOURCE:1, TEXT:1, TODO:1, CMD_CRYPTO:1, CMD_HR:1, CMD_INDENT:1, CMD_LIST:1, CMD_TODO:1}, HR:{CMD_HR:1}, 
  TEXT:{}, TODO:{CMD_INDENT:1, CMD_LIST:1, CMD_TODO:1}, RESOURCE:{}};
  structure.itemAllowed = function(item, container) {
    if (item instanceof HTMLElement) {
      var items = Object.keys(getTypes(item));
      if (items.length) {
        return structure.itemsAllowed(items, container);
      } else {
        item = T.TEXT;
      }
    }
    if (typeof container !== "string") {
      container = getContainerType(container);
    }
    var rule = rules[container];
    if (!rules.NOTE[item]) {
      log.severe("structure.itemAllowed: unknown item type " + item);
    }
    if (!rule) {
      log.severe("structure.itemAllowed: unknown container type " + container);
      return false;
    }
    return !!rule[item];
  };
  structure.itemsAllowed = function(items, container) {
    if (!items) {
      return true;
    }
    return !items.some(function(item) {
      return !structure.itemAllowed(item, container);
    });
  };
  structure.itemAllowedInRange = function(item, range) {
    var nodes = range.isCollapsed() ? [range.getContainer()] : goog.iter.toArray(range);
    var notAllowed = nodes.some(function(node) {
      return !structure.itemAllowed(item, node);
    });
    return !notAllowed;
  };
  structure.itemTypesInRange = function(range) {
    var nodes = goog.iter.toArray(range);
    var types = {};
    nodes.forEach(function(node) {
      var type = getEltType(node);
      if (type) {
        types[type] = 1;
      }
    });
    return Object.keys(types);
  };
  structure.isDroppableTarget = function(target, state) {
    var itemTypes = state.itemTypes;
    if (!itemTypes || !itemTypes.length) {
      return true;
    }
    var notAllowed = itemTypes.some(function(item) {
      return !structure.itemAllowed(item, target);
    });
    return !notAllowed;
  };
  function getEltType(elt) {
    if (dom.isLi(elt) || dom.isOl(elt) || dom.isUl(elt)) {
      return T.LIST;
    }
    if (dom.isTable(elt) || dom.isEntable(elt)) {
      return T.TABLE;
    }
    if (dom.isHr(elt)) {
      return T.HR;
    }
    if (dom.isCodeBlock(elt)) {
      return T.CODE;
    }
    if (dom.isRevealedCrypt(elt) || util.crypto.isCrypt(elt)) {
      return T.CRYPTO;
    }
    if (util.todo.isTodo(elt)) {
      return T.TODO;
    }
    if (util.resource.isResource(elt)) {
      return T.RESOURCE;
    }
    if (dom.isEnnote(elt)) {
      return T.NOTE;
    }
    return null;
  }
  function getTypes(elt) {
    var types = {};
    var type = getEltType(elt);
    if (!type) {
      goog.iter.forEach(elt.childNodes, function(child) {
        var ntypes = getTypes(child);
        Object.keys(ntypes).forEach(function(key) {
          types[key] = 1;
        });
      });
    } else {
      types[type] = 1;
    }
    return types;
  }
  function getContainerType(node) {
    return getEltType(goog.dom.getAncestor(node, getEltType, true)) || T.NOTE;
  }
})();
goog.provide("uno.commands.BasicTextFormatter");
goog.require("goog.debug.Logger");
goog.require("goog.editor.Command");
goog.require("goog.functions");
goog.require("goog.dom");
goog.require("goog.editor.range");
goog.require("uno.BasePlugin");
goog.require("uno.EditorMultiRange");
goog.require("uno.util.crypto");
goog.require("uno.util.dom");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.BasicTextFormatter");
  var WEBKIT_DEFAULT_FONT = "-webkit-standard";
  var util = uno.util;
  var BasicTextFormatter = uno.commands.BasicTextFormatter = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(BasicTextFormatter, uno.BasePlugin);
  BasicTextFormatter.GOOG_COMMAND = {bold:goog.editor.Command.BOLD, fontname:goog.editor.Command.FONT_FACE, insertorderedlist:goog.editor.Command.ORDERED_LIST, insertunorderedlist:goog.editor.Command.UNORDERED_LIST, italic:goog.editor.Command.ITALIC, justifycenter:goog.editor.Command.JUSTIFY_CENTER, justifyfull:goog.editor.Command.JUSTIFY_FULL, justifyleft:goog.editor.Command.JUSTIFY_LEFT, justifyright:goog.editor.Command.JUSTIFY_RIGHT, outdent:goog.editor.Command.OUTDENT, subscript:goog.editor.Command.SUBSCRIPT, 
  superscript:goog.editor.Command.SUPERSCRIPT};
  BasicTextFormatter.COMMANDS = Object.keys(BasicTextFormatter.GOOG_COMMAND);
  BasicTextFormatter.prototype.isSupportedCommand = function(command) {
    return BasicTextFormatter.COMMANDS.indexOf(command) > -1;
  };
  BasicTextFormatter.prototype.activeOnUneditableFields = goog.functions.TRUE;
  goog.editor.plugins.BasicTextFormatter.prototype.isSilentCommand = goog.functions.TRUE;
  BasicTextFormatter.prototype.registerFieldObject = function(fieldObject) {
    uno.BasePlugin.prototype.registerFieldObject.call(this, fieldObject);
    var plugin = fieldObject.plugins_.BTF;
    plugin.activeOnUneditableFields = goog.functions.TRUE;
  };
  BasicTextFormatter.prototype.fixFloatingUnwrappedBR = function() {
    var tags = ["ol", "ul"];
    var range = this.editor.getRange();
    if (range && range.isCollapsed() && range.getStartNode().children) {
      var children = range.getStartNode().children;
      var offset = range.getStartOffset();
      if (offset <= 0 || children.length < 2 || offset >= children.length) {
        return;
      }
      if (tags.indexOf(util.dom.getTagName(children[offset - 1])) > -1 && util.dom.getTagName(children[offset]) === "br") {
        var newdiv = goog.dom.createDom("div");
        newdiv.appendChild(goog.dom.createDom("br"));
        goog.dom.replaceNode(newdiv, children[offset]);
        goog.dom.Range.createFromNodes(newdiv, 0, newdiv, 0).select();
      }
    }
  };
  BasicTextFormatter.prototype.execCommand = function(command, value) {
    var commands = BasicTextFormatter.GOOG_COMMAND;
    var styleOverride = {state:{}, value:{}, enabled:{}};
    var googleCommand = commands[command];
    var swappedObjects;
    var currentStyleStates = Object.assign({}, this.editor.context.style.state, this.editor.context.style.value);
    var currentState = this.editor.context.style.state[command];
    var isOrderedListCommand = !!(command === "insertorderedlist");
    var isUnorderedListCommand = !!(command === "insertunorderedlist");
    var isOutdentCommand = !!(command === "outdent");
    this.editor.dispatchBeforeChange();
    var range = this.editor.getRange();
    if (range && !range.isCollapsed()) {
      this.editor.dispatchBeforeChange();
    }
    if ((isOrderedListCommand || isUnorderedListCommand || isOutdentCommand) && range) {
      swappedObjects = util.resource.toggleObjectsInRange(range, false);
    }
    this.editor.execCommand(googleCommand, value);
    this.fixFloatingUnwrappedBR();
    removeTextSizeAdjust(this.editor);
    var newRange = this.editor.getRange();
    if (range && range.isCollapsed() && !newRange) {
      newRange = range;
      newRange.select();
    }
    if ((isOrderedListCommand || isUnorderedListCommand || isOutdentCommand) && swappedObjects && newRange) {
      util.resource.toggleObjectsInRange(newRange, swappedObjects);
    }
    if (newRange) {
      if (newRange.isCollapsed()) {
        if (["indent", "insertorderedlist", "insertunorderedlist", "justifycenter", "justifyfull", "justifyleft", "justifyright", "outdent"].indexOf(command) > -1) {
          this.editor.dispatchChange();
        }
      } else {
        this.editor.dispatchChange();
      }
    }
    if (command.indexOf("justify") === 0) {
      styleOverride.state.justifyfull = false;
      styleOverride.state.justifycenter = false;
      styleOverride.state.justifyleft = false;
      styleOverride.state.justifyright = false;
      var justifyValue = this.queryCommandValue(command);
      styleOverride.value.justifyfull = justifyValue;
      styleOverride.value.justifycenter = justifyValue;
      styleOverride.value.justifyleft = justifyValue;
      styleOverride.value.justifyright = justifyValue;
    }
    if (command.indexOf("justify") === 0 && currentState) {
      styleOverride.state[command] = true;
    } else {
      if (goog.isDef(currentState)) {
        styleOverride.state[command] = !currentState;
      }
    }
    this.editor.dispatchStyleChange(styleOverride);
    if (command.indexOf("insertorderedlist") === 0 || command.indexOf("insertunorderedlist") === 0) {
      fixStylesAfterListToggle(this.editor, currentStyleStates);
      var afterInsertRange = this.editor.getRange();
      if (range.isCollapsed() && afterInsertRange) {
        afterInsertRange.collapse(true);
      }
    }
    return true;
  };
  BasicTextFormatter.prototype.queryCommandValue = function(command) {
    var result;
    switch(command) {
      case "fontname":
        {
          result = this.editor.queryCommandValue(goog.editor.Command.FONT_FACE);
          if (result === WEBKIT_DEFAULT_FONT) {
            result = this.editor.config.defaults.richTextFont;
          }
          if (result) {
            result = result.replace(/,.*/, "").replace(/['"]/g, "");
          }
          break;
        }
      case "insertorderedlist":
      case "insertunorderedlist":
        {
          if (this.editor.queryCommandValue(goog.editor.Command.UNORDERED_LIST) !== false) {
            result = "ul";
          } else {
            if (this.editor.queryCommandValue(goog.editor.Command.ORDERED_LIST) !== false) {
              result = "ol";
            } else {
              result = "none";
            }
          }
          break;
        }
      case "justifyleft":
      case "justifycenter":
      case "justifyright":
      case "justifyfull":
        {
          if (this.editor.queryCommandValue(goog.editor.Command.JUSTIFY_LEFT) !== false) {
            result = "left";
          } else {
            if (this.editor.queryCommandValue(goog.editor.Command.JUSTIFY_CENTER) !== false) {
              result = "center";
            } else {
              if (this.editor.queryCommandValue(goog.editor.Command.JUSTIFY_RIGHT) !== false) {
                result = "right";
              } else {
                if (this.editor.queryCommandValue(goog.editor.Command.JUSTIFY_FULL) !== false) {
                  result = "justify";
                }
              }
            }
          }
          break;
        }
      default:
        result = this.editor.queryCommandValue(BasicTextFormatter.GOOG_COMMAND[command]);
    }
    return result;
  };
  BasicTextFormatter.prototype.queryCommandEnabled = function(command) {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    if (command === "indent" || command === "outdent") {
      if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CMD_INDENT, range)) {
        return false;
      }
    }
    if (command === "insertorderedlist" || command === "insertunorderedlist") {
      if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CMD_LIST, range)) {
        return false;
      }
    }
    return true;
  };
  function removeTextSizeAdjust(editor) {
    var elements = editor.field.querySelectorAll('*[style*="-webkit-text-size-adjust:"]');
    goog.iter.forEach(elements, function(element) {
      element.style.removeProperty("-webkit-text-size-adjust");
    });
  }
  function fixStylesAfterListToggle(editor, currentStyleStates) {
    var savedRange;
    var range = editor.getRange();
    var node = range.getStartNode();
    var highlighted = currentStyleStates.highlight;
    var subscript = currentStyleStates.subscript;
    var superscript = currentStyleStates.superscript;
    var fontsize = currentStyleStates.fontsize;
    var fontname = currentStyleStates.fontname;
    var forecolor = currentStyleStates.forecolor;
    if (range && range.isCollapsed() && (highlighted || subscript || superscript || fontsize || fontname || forecolor)) {
      savedRange = range.saveUsingDom();
      if (node.parentNode) {
        goog.dom.Range.createFromNodeContents(node.parentNode).select();
      }
    }
    if (highlighted) {
      document.execCommand("backColor", null, uno.defs.highlight.COLOR);
    }
    if (subscript) {
      if (!currentStyleStates.insertorderedlist && !currentStyleStates.insertunorderedlist) {
        editor.execCommand("subscript");
      } else {
        util.dom.removeStyleValue(node.parentNode, "vertical-align");
        util.dom.changeTagName(node.parentNode, "sub");
      }
    }
    if (superscript) {
      if (!currentStyleStates.insertorderedlist && !currentStyleStates.insertunorderedlist) {
        editor.execCommand("superscript");
      } else {
        util.dom.removeStyleValue(node.parentNode, "vertical-align");
        util.dom.changeTagName(node.parentNode, "sup");
      }
    }
    if (currentStyleStates.fontsize) {
      editor.execCommand("fontsize", currentStyleStates.fontsize);
    }
    if (currentStyleStates.fontname) {
      editor.execCommand("fontname", currentStyleStates.fontname);
    }
    if (currentStyleStates.forecolor) {
      editor.execCommand("forecolor", currentStyleStates.forecolor);
    }
    if (savedRange && (highlighted || subscript || superscript)) {
      savedRange.restore().select();
    }
  }
})();
goog.provide("uno.commands.Bounds");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Bounds");
  var Bounds = uno.commands.Bounds = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Bounds, uno.BasePlugin);
  Bounds.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Bounds.prototype.isSupportedCommand = function(command) {
    return command === "bounds";
  };
  Bounds.prototype.execCommand = function() {
    return false;
  };
  Bounds.prototype.queryCommandValue = function() {
    var result = goog.style.getBounds(this.editor.field);
    result.right = result.left + result.width;
    result.bottom = result.top + result.height;
    result.x = result.left;
    result.y = document.body.scrollHeight - result.bottom;
    return result;
  };
})();
goog.provide("uno.commands.Capitalize");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Capitalize");
  var util = uno.util;
  var Capitalize = uno.commands.Capitalize = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(Capitalize, uno.BasePlugin);
  Capitalize.prototype.isSupportedCommand = function(command) {
    return command === "capitalize";
  };
  Capitalize.prototype.execCommandInternal = function() {
    var range = this.editor.getRange();
    var savedRange = range.saveUsingDom();
    util.range.forEachWord(range, function(word, wordRange) {
      var container = wordRange.startContainer;
      var text = container.nodeValue;
      container.nodeValue = text.slice(0, wordRange.startOffset) + word[0].toLocaleUpperCase() + word.slice(1).toLocaleLowerCase() + text.slice(wordRange.endOffset);
    });
    savedRange.restore().select();
  };
})();
goog.provide("uno.commands.CaretLocation");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.CaretLocation");
  var CaretLocation = uno.commands.CaretLocation = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CaretLocation, uno.BasePlugin);
  CaretLocation.prototype.isSupportedCommand = function(command) {
    return command === "caretlocation";
  };
  CaretLocation.prototype.activeOnUneditableFields = goog.functions.TRUE;
  CaretLocation.prototype.execCommand = function(command, coordinate) {
    if (coordinate && typeof document.caretRangeFromPoint === "function") {
      this.editor.multirange.clear();
      var nativeRange = document.caretRangeFromPoint(coordinate.x, coordinate.y);
      if (!nativeRange) {
        return false;
      }
      var range = goog.dom.Range.createFromNodes(nativeRange.startContainer, nativeRange.startOffset, nativeRange.endContainer, nativeRange.endOffset);
      if (range) {
        range.select();
        return true;
      }
    }
    return false;
  };
  CaretLocation.prototype.queryCommandValue = function() {
    return false;
  };
})();
goog.provide("uno.commands.Changes");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Changes");
  var Changes = uno.commands.Changes = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Changes, uno.BasePlugin);
  Changes.prototype.isSupportedCommand = function(command) {
    return command === "changes";
  };
  Changes.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Changes.prototype.execCommand = function() {
    return false;
  };
  Changes.prototype.queryCommandValue = function() {
    return this.editor.dirty || this.editor.isModified();
  };
})();
goog.provide("goog.dom.NodeIterator");
goog.require("goog.dom.TagIterator");
goog.dom.NodeIterator = function(opt_node, opt_reversed, opt_unconstrained, opt_depth) {
  goog.dom.TagIterator.call(this, opt_node, opt_reversed, opt_unconstrained, null, opt_depth);
};
goog.inherits(goog.dom.NodeIterator, goog.dom.TagIterator);
goog.dom.NodeIterator.prototype.next = function() {
  do {
    goog.dom.NodeIterator.superClass_.next.call(this);
  } while (this.isEndTag());
  return this.node;
};
goog.provide("uno.util.paragraph");
goog.require("goog.debug.Logger");
goog.require("goog.editor.node");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("uno.util.dom");
goog.require("uno.util.range");
(function() {
  var STRUCTTYPES = uno.defs.structuretypes;
  var log = goog.debug.Logger.getLogger("uno.util.paragraph");
  var util = uno.util;
  var dom = util.dom;
  util.paragraph.all = function(root) {
    return root.querySelectorAll(["h1", "h2", "h3", "h4", "h5", "h6", 'div:not(.en-code):not([data-en-codeblock]):not([style*="-en-codeblock"])', "p"].join(","));
  };
  util.paragraph.create = function() {
    var div = document.createElement("div");
    div.appendChild(document.createElement("br"));
    return div;
  };
  util.paragraph.remove = function(paragraph) {
    var parent = paragraph.parentNode;
    while (paragraph && dom.isEmpty(paragraph)) {
      goog.dom.removeNode(paragraph);
      paragraph = parent;
      parent = paragraph && paragraph.parentNode;
    }
  };
  util.paragraph.for = function(node) {
    if (!node) {
      return null;
    }
    if (node.tagName && node.tagName.toLowerCase() === "en-note") {
      node = node.firstChild;
    }
    var paraNode = goog.dom.getAncestor(node, function(ancestor) {
      return util.dom.isBlockNode(ancestor);
    }, true);
    if (paraNode) {
      if (paraNode.tagName.toLowerCase() === "en-note") {
        var savedRange;
        var range = goog.dom.Range.createFromWindow();
        if (range && (range.isCollapsed() || range.containsNode(node))) {
          savedRange = range.saveUsingCarets();
        }
        while (node.parentNode !== paraNode) {
          node = node.parentNode;
        }
        var sibs = util.dom.contiguousInlineSiblings(node);
        var blockWrapper = goog.dom.createDom("div");
        goog.dom.replaceNode(blockWrapper, node);
        sibs.forEach(function(sib) {
          blockWrapper.appendChild(sib);
        });
        if (savedRange) {
          savedRange.restore().select();
        }
        return blockWrapper;
      }
    }
    return paraNode;
  };
  util.paragraph.insertAfter = function(paraNode) {
    var newParaNode = util.paragraph.create();
    goog.dom.insertSiblingAfter(newParaNode, paraNode);
    return newParaNode;
  };
  util.paragraph.startsWithTodo = function(paragraph) {
    var node = util.dom.getFirstParagraphItem(paragraph);
    return !!util.todo.isTodo(node);
  };
  util.paragraph.getLeadingTodo = function(paragraph) {
    var firstItem = util.dom.getFirstParagraphItem(paragraph);
    return util.todo.isTodo(firstItem) ? firstItem : null;
  };
  util.paragraph.prevParagraph = function(paraNode) {
    return goog.dom.getPreviousElementSibling(paraNode);
  };
  util.paragraph.nextParagraph = function(paraNode) {
    return goog.dom.getNextElementSibling(paraNode);
  };
  util.paragraph.placeCursorAtStart = function(paraNode) {
    var range = goog.dom.Range.createCaret(paraNode, 0);
    range.select();
    return range;
  };
  util.paragraph.remove = function(paraNode) {
    goog.dom.removeNode(paraNode);
  };
  util.paragraph.hasVisibleContent = function(paraNode, opt) {
    var contentTags = "en-media,embed,img,object";
    var result;
    if (!paraNode) {
      log.warning("hasVisibleContent paraNode is null");
      return false;
    }
    opt = opt || {};
    result = goog.array.some(paraNode.querySelectorAll(contentTags), function(el) {
      return el !== opt.excluding;
    });
    if (!result) {
      result = !goog.string.isEmptyOrWhitespace(paraNode.innerText);
    }
    return result;
  };
  util.paragraph.hasBr = function(paraNode) {
    return paraNode.querySelector("br") != null;
  };
  util.paragraph.appendBr = function(paraNode) {
    paraNode.appendChild(goog.dom.createElement("br"));
  };
  util.paragraph.prepareForDrag = function(state) {
    if (state.dragStartedInNote) {
      var range = state.editor.getRange();
      if (range) {
        state.itemTypes = util.structure.itemTypesInRange(range);
      }
      state.copy = state.editor.queryCommandValue("copy");
    } else {
      var dt = state.event.dataTransfer;
      if (dt.items && dt.items.length && dt.items[0].kind === "file" || dt.files && dt.files.length) {
        state.itemTypes = [STRUCTTYPES.RESOURCE];
      } else {
        state.itemTypes = [STRUCTTYPES.TEXT];
      }
    }
  };
  util.paragraph.isDroppableTarget = function(node) {
    return true;
  };
  util.paragraph.handleDrop = function(event, state, editor) {
    var dataTransfer = event.dataTransfer;
    var htmlContent = dataTransfer && dataTransfer.getData("text/html");
    var textContent = dataTransfer && dataTransfer.getData("text/plain");
    var pasted = state.dataTransferContent.pasted;
    if (state.copy || htmlContent || textContent || pasted) {
      if (event.synthetic) {
      } else {
        event.preventDefault();
        event.stopPropagation();
        var range = util.range.createFromPoints(event.clientX, event.clientY);
        if (state.dragStartedInNote && state.range) {
          state.range.select();
          editor.execCommand("delete");
        }
        if (range) {
          range.select();
        }
      }
      state.dragging = false;
      if (state.copy) {
        editor.execCommand("paste", {value:state.copy.html, type:"html", resources:state.copy.resources});
      } else {
        editor.execCommand("paste", {value:htmlContent || textContent || pasted, type:textContent ? "text" : "html"});
      }
    }
    return null;
  };
})();
goog.provide("uno.util.list");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.util.dom");
(function() {
  var util = uno.util;
  var dom = util.dom;
  util.list.for = function(node) {
    if (node == null) {
      return null;
    }
    if (util.dom.isOl(node) || util.dom.isUl(node)) {
      return node;
    }
    if (!util.dom.isElementNode(node)) {
      node = goog.dom.getParentElement(node);
    }
    var itemNode = util.list.itemFor(node);
    var listNode = itemNode && itemNode.parentNode;
    return listNode;
  };
  util.list.itemFor = function(node) {
    if (!node) {
      return null;
    }
    if (!util.dom.isElementNode(node)) {
      node = goog.dom.getParentElement(node);
    }
    var itemNode = util.dom.compareTagName(node, "li") ? node : goog.dom.getAncestorByTagNameAndClass(node, "li");
    return itemNode;
  };
  util.list.getParagraphs = function(node) {
    var paragraphs = [];
    if (dom.isUl(node) || dom.isOl(node)) {
      var lis = node.querySelectorAll("li");
      goog.array.forEach(lis, function(li) {
        paragraphs = paragraphs.concat(goog.array.toArray(li.childNodes));
      });
    }
    return paragraphs;
  };
  util.list.normalize = function(root) {
    util.list.flattenInvisibleLists(root);
    util.list.flattenInvalidLists(root);
    util.list.moveBlocksOfLis(root);
    util.list.mergeSiblingUls(root);
    util.list.ensureValidLiWrapInUl(root);
  };
  util.list.flattenInvisibleLists = function(root) {
    var invisibleLists = goog.array.filter(root.querySelectorAll("ol, ul"), function(li) {
      return li.style.listStyle === "none";
    });
    goog.array.forEachRight(invisibleLists, function(invisibleList) {
      var isWithinList = goog.dom.getAncestor("ol, ul");
      if (!isWithinList) {
        goog.array.forEachRight(invisibleList.childNodes, function(child) {
          if (dom.isLi(child)) {
            dom.changeTagName(child, "div");
          }
        });
        goog.dom.flattenElement(invisibleList);
      }
    });
  };
  util.list.flattenInvalidLists = function(node) {
    goog.array.forEachRight(node.querySelectorAll("ol,ul"), function(list) {
      if (list.childNodes.length > 0 && !list.querySelector("li")) {
        goog.dom.flattenElement(list);
      }
    });
  };
  util.list.moveBlocksOfLis = function(root) {
    var blocks = root.querySelectorAll('ul, ol, table, [data-en-codeblock], [style*="-en-codeblock"], .en-code');
    goog.array.forEachRight(blocks, function(block) {
      if (dom.isLi(block.parentNode)) {
        var parentNode = block.parentNode;
        var lastNodeMoved = block.parentNode;
        var currentNode = block;
        while (currentNode) {
          var nextSibling = currentNode.nextSibling;
          if (dom.isDiv(currentNode)) {
            currentNode = dom.changeTagName(currentNode, "li");
          }
          goog.dom.insertSiblingAfter(currentNode, lastNodeMoved);
          lastNodeMoved = currentNode;
          currentNode = nextSibling;
        }
        if (!parentNode.firstChild) {
          goog.dom.removeNode(parentNode);
        }
      }
    });
  };
  util.list.mergeSiblingUls = function(node) {
    goog.array.forEachRight(node.querySelectorAll("ul"), function(list) {
      while (util.dom.isUl(list.previousSibling)) {
        var prevList = list.previousSibling;
        while (list.firstChild) {
          prevList.appendChild(list.firstChild);
        }
        list.remove();
        list = prevList;
      }
    });
  };
  util.list.ensureValidLiWrapInUl = function(node) {
    goog.array.forEachRight(node.querySelectorAll("li"), function(li) {
      if (!util.dom.isUl(li.parentNode) && !util.dom.isOl(li.parentNode)) {
        var ul = goog.dom.createDom("ul", null);
        var childNodes = li.parentNode ? goog.array.toArray(li.parentNode.childNodes) : [li];
        goog.dom.replaceNode(ul, li);
        goog.array.forEach(childNodes, function(child) {
          ul.appendChild(child);
        });
      }
    });
  };
  util.list.convertParagraphsToBrs = function(root) {
    var lis = dom.isLi(root) ? [root] : root.querySelectorAll("li");
    goog.array.forEachRight(lis, function(list) {
      goog.array.forEachRight(list.childNodes, function(child) {
        if (util.dom.isBlockNode(child) && !util.dom.isHr(child)) {
          if (child.lastChild && !util.dom.isBr(child.lastChild)) {
            var br = goog.dom.createDom("br");
            child.appendChild(br);
          }
          goog.dom.flattenElement(child);
        }
      });
      var previousSibling = list.lastChild && list.lastChild.previousSibling;
      while (dom.isEncursor(previousSibling)) {
        previousSibling = previousSibling.previousSibling;
      }
      if (list.childNodes.length > 1 && util.dom.isBr(list.lastChild) && !util.dom.isBr(previousSibling)) {
        goog.dom.removeNode(list.lastChild);
      }
    });
  };
})();
goog.provide("uno.commands.CodeBlock");
goog.require("goog.debug.Logger");
goog.require("goog.dom.NodeIterator");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.paragraph");
goog.require("uno.util.table");
goog.require("uno.util.list");
goog.require("uno.util.crypto");
goog.require("uno.defs");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.CodeBlock");
  var util = uno.util;
  var CodeBlock = uno.commands.CodeBlock = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CodeBlock, uno.BasePlugin);
  CodeBlock.prototype.isSupportedCommand = function(command) {
    return command === "codeblock";
  };
  CodeBlock.prototype.execCommandInternal = function() {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    if (this.queryCommandValue("codeblock")) {
      this.findAndRemoveCodeBlock(range);
      return true;
    }
    var copiedText = range.isCollapsed() ? null : this.editor.queryCommandValue("cut");
    var insertParagraphIfRequired = function(editor, updateRange) {
      var result = false;
      var currentRange = editor.getRange();
      if (!util.dom.isEmpty(util.paragraph.for(currentRange.getStartNode())) || editor.field.childNodes && currentRange.getStartNode() === editor.field.childNodes[0]) {
        editor.execCommand("insertparagraph");
        result = true;
      }
      if (updateRange) {
        currentRange.select();
      }
      return result;
    };
    insertParagraphIfRequired(this.editor, true);
    insertParagraphIfRequired(this.editor, false);
    var innerBr = goog.dom.createDom("br");
    var innerDiv = goog.dom.createDom("div", {}, innerBr);
    var codeBlockElement = goog.dom.createDom("div", {class:"en-code"}, innerDiv);
    range = this.editor.getRange();
    var currentNode = range.getStartNode();
    if (util.dom.isEnnote(currentNode)) {
      currentNode = currentNode.childNodes[range.getStartOffset()] || currentNode.lastChild;
    }
    if (currentNode) {
      goog.dom.replaceNode(codeBlockElement, currentNode);
    } else {
      this.editor.field.appendChild(codeBlockElement);
    }
    var newRange = goog.editor.range.placeCursorNextTo(innerBr);
    if (copiedText && copiedText.plain && copiedText.plain.length > 0) {
      goog.editor.range.placeCursorNextTo(innerBr);
      this.editor.execCommand("inserttext", copiedText.plain);
      newRange = goog.editor.range.placeCursorNextTo(codeBlockElement);
    }
    newRange.select();
    return true;
  };
  CodeBlock.prototype.queryCommandValue = function() {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var containerNode = range.getContainerElement();
    return this.isParentNodeCodeBlock(containerNode) || this.isChildNodeCodeBlock([containerNode], range);
  };
  CodeBlock.prototype.isChildNodeCodeBlock = function(nodes, range) {
    return Array.prototype.some.call(nodes, function(node) {
      if (util.dom.isElementNode(node)) {
        if (range.containsNode(node, true) && util.dom.isCodeBlock(node)) {
          return true;
        }
        return this.isChildNodeCodeBlock(node.childNodes, range);
      }
      return false;
    }.bind(this));
  };
  CodeBlock.prototype.isParentNodeCodeBlock = function(node) {
    return goog.dom.getAncestor(node, function(ancestor) {
      return util.dom.isCodeBlock(ancestor);
    }, true);
  };
  CodeBlock.prototype.findAndRemoveCodeBlock = function(range) {
    var containerNode = range.getContainerElement();
    if (util.dom.isCodeBlock(containerNode)) {
      this.unwrapCodeBlock(containerNode);
      return true;
    }
    var block = goog.dom.getAncestor(containerNode, function(ancestor) {
      return util.dom.isCodeBlock(ancestor);
    }, true);
    if (block) {
      this.unwrapCodeBlock(block);
      return true;
    }
    var ci = new goog.dom.NodeIterator(containerNode, true, false);
    var currentChild;
    var foundBlocks = [];
    try {
      while (currentChild = ci.next()) {
        if (range.containsNode(currentChild, true) && util.dom.isCodeBlock(currentChild)) {
          foundBlocks.push(currentChild);
        }
      }
    } catch (err$10) {
      log.fine(err$10.stack || err$10);
    }
    var _this = this;
    foundBlocks.forEach(function(foundBlock) {
      _this.unwrapCodeBlock(foundBlock);
    });
    return true;
  };
  CodeBlock.prototype.unwrapCodeBlock = function(node) {
    var lastChild;
    while (node.firstChild) {
      lastChild = node.firstChild;
      node.parentElement.insertBefore(lastChild, node);
    }
    if (lastChild) {
      var cursorTarget = lastChild.childNodes ? lastChild.childNodes[0] : lastChild;
      goog.editor.range.placeCursorNextTo(cursorTarget);
    }
    node.remove();
    return true;
  };
  CodeBlock.prototype.queryCommandEnabled = function(command) {
    var range = this.editor.getRange();
    if (range) {
      if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CMD_CODE, range)) {
        return false;
      }
    }
    return true;
  };
})();
goog.provide("uno.commands.Content");
goog.require("goog.array");
goog.require("goog.functions");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.crypto");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Content");
  var util = uno.util;
  var Content = uno.commands.Content = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Content, uno.BasePlugin);
  Content.prototype.isSupportedCommand = function(command) {
    return command === "content";
  };
  Content.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Content.prototype.execCommand = function(command, value) {
    var editor = this.editor;
    value = {type:value.type || uno.defs.format.ENML, content:goog.isString(value.content) ? value.content : value, resources:value.resources || {}};
    if (value.type === "html") {
      value.type = uno.defs.format.CLIENT_HTML;
    }
    var content = value.content;
    editor.context.format = value.type;
    if (editor.context.format === uno.defs.format.CLIENT_HTML) {
      if (content && content.indexOf('<div id="en-note">') !== -1) {
        content = content.replace('<div id="en-note">', "").replace(/<\/div>\s*$/, "");
      } else {
        if (content && content.indexOf('<div id="en-note"/>') !== -1) {
          content = editor.config.defaults.html;
        }
      }
    }
    goog.object.extend(editor.context.resources, value.resources);
    editor.setHtml(false, content, true);
    editor.plugins_.UndoRedo.refreshCurrentState(editor);
    this.waitForImages();
    editor.updateEmpty();
    return true;
  };
  Content.prototype.queryCommandValue = function(command, opt) {
    var editor = this.editor;
    var value;
    var initialFormat = editor.context.format;
    opt = opt || {};
    opt.resetChangesState = opt.resetChangesState !== false;
    if (opt.type === "html") {
      editor.context.format = uno.defs.format.CLIENT_HTML;
    } else {
      if (opt.type) {
        editor.context.format = opt.type;
      } else {
        editor.context.format = uno.defs.format.ENML;
      }
    }
    if (opt.cryptInfo) {
      util.crypto.updateCryptNodes(opt.cryptInfo);
    } else {
      var cryptInfo = util.crypto.getDirtyCrypto(editor.field);
      if (cryptInfo.length) {
        return {success:false, cryptInfo:cryptInfo};
      }
    }
    value = editor.getCleanContents();
    if (editor.context.format === uno.defs.format.CLIENT_HTML) {
      value = '<div id="en-note">' + value + "</div>";
    }
    if (opt.resetChangesState) {
      editor.dirty = false;
    }
    editor.context.format = initialFormat;
    return {success:value != null, value:value};
  };
  Content.prototype.waitForImages = function() {
    var me = this;
    var completeImageCount = 0;
    var images = this.editor.field.querySelectorAll("img");
    if (images.length === 0) {
      return setTimeout(function() {
        if (me.editor) {
          me.dispatchContentLoaded();
        }
      }, 0);
    }
    var onImageComplete = function() {
      if (++completeImageCount === images.length) {
        return setTimeout(function() {
          if (me.editor) {
            me.dispatchContentLoaded();
          }
        }, 0);
      }
    };
    goog.array.forEach(images, function waitForImageComplete(img) {
      if (img.getAttribute("src") && !img.naturalWidth && !img.naturalHeight) {
        goog.events.listen(img, "load", onImageComplete);
        goog.events.listen(img, "error", onImageComplete);
      } else {
        onImageComplete();
      }
    });
  };
  Content.prototype.dispatchContentLoaded = function() {
    this.dispatchEvent("contentloaded");
  };
})();
goog.provide("uno.commands.ControlTodos");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.todo");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.ControlTodos");
  var util = uno.util;
  var ControlTodos = uno.commands.ControlTodos = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(ControlTodos, uno.BasePlugin);
  ControlTodos.prototype.isSupportedCommand = function(command) {
    return command === "controltodos";
  };
  ControlTodos.prototype.execCommandInternal = function(command, state) {
    var range = this.editor.getRange();
    var todos = util.todo.all(this.editor.field);
    if (!range.isCollapsed()) {
      todos = goog.array.filter(todos, function(node) {
        return range.containsNode(node, true);
      });
    }
    goog.array.forEach(todos, function(entodo) {
      if (state === "on") {
        util.todo.setChecked(entodo, true);
      } else {
        if (state === "off") {
          util.todo.setChecked(entodo, false);
        } else {
          util.todo.toggle(entodo);
        }
      }
    });
  };
})();
goog.provide("uno.commands.Copy");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.copy");
goog.require("uno.util.objects");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Copy");
  var defs = uno.defs;
  var util = uno.util;
  var Copy = uno.commands.Copy = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Copy, uno.BasePlugin);
  Copy.prototype.isSupportedCommand = function(command) {
    return command === "copy";
  };
  Copy.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Copy.prototype.execCommand = function() {
    return false;
  };
  Copy.prototype.queryCommandValue = function(command, opt) {
    var options = getOptions(opt);
    var range = this.editor.getRange();
    if (range && !goog.dom.getAncestor(range.getContainer(), uno.util.dom.isEnnote, true)) {
      return util.copy.copyOutside(range, this.editor.getFormField(), options);
    }
    this.editor.context.format = defs.format.CLIPBOARD;
    return util.copy.copy(this.editor, options);
  };
  function getOptions(options) {
    return util.objects.mergeOptions(options, {html:true, resources:true, plain:true});
  }
})();
goog.provide("uno.commands.Count");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("goog.string");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Count");
  var Count = uno.commands.Count = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Count, uno.BasePlugin);
  Count.prototype.isSupportedCommand = function(command) {
    return command === "count";
  };
  Count.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Count.prototype.queryCommandValue = function() {
    var text = goog.string.canonicalizeNewlines(this.editor.field.innerText).trim();
    var lines = text.split("\n");
    var words = goog.string.collapseWhitespace(text).split(" ");
    var paragraphs = text.split(/\n{2,}/);
    return {words:words.length, charsWithoutSpaces:words.join("").length, charsWithSpaces:lines.join("").length, paragraphs:paragraphs.length, lines:lines.length};
  };
})();
goog.provide("goog.dom.InputType");
goog.dom.InputType = {BUTTON:"button", CHECKBOX:"checkbox", COLOR:"color", DATE:"date", DATETIME:"datetime", DATETIME_LOCAL:"datetime-local", EMAIL:"email", FILE:"file", HIDDEN:"hidden", IMAGE:"image", MENU:"menu", MONTH:"month", NUMBER:"number", PASSWORD:"password", RADIO:"radio", RANGE:"range", RESET:"reset", SEARCH:"search", SELECT_MULTIPLE:"select-multiple", SELECT_ONE:"select-one", SUBMIT:"submit", TEL:"tel", TEXT:"text", TEXTAREA:"textarea", TIME:"time", URL:"url", WEEK:"week"};
goog.provide("goog.dom.selection");
goog.require("goog.dom.InputType");
goog.require("goog.string");
goog.require("goog.userAgent");
goog.dom.selection.setStart = function(textfield, pos) {
  if (goog.dom.selection.useSelectionProperties_(textfield)) {
    textfield.selectionStart = pos;
  } else {
    if (goog.dom.selection.isLegacyIe_()) {
      var tmp = goog.dom.selection.getRangeIe_(textfield);
      var range = tmp[0];
      var selectionRange = tmp[1];
      if (range.inRange(selectionRange)) {
        pos = goog.dom.selection.canonicalizePositionIe_(textfield, pos);
        range.collapse(true);
        range.move("character", pos);
        range.select();
      }
    }
  }
};
goog.dom.selection.getStart = function(textfield) {
  return goog.dom.selection.getEndPoints_(textfield, true)[0];
};
goog.dom.selection.getEndPointsTextareaIe_ = function(range, selRange, getOnlyStart) {
  var selectionRange = selRange.duplicate();
  var beforeSelectionText = range.text;
  var untrimmedBeforeSelectionText = beforeSelectionText;
  var selectionText = selectionRange.text;
  var untrimmedSelectionText = selectionText;
  var isRangeEndTrimmed = false;
  while (!isRangeEndTrimmed) {
    if (range.compareEndPoints("StartToEnd", range) == 0) {
      isRangeEndTrimmed = true;
    } else {
      range.moveEnd("character", -1);
      if (range.text == beforeSelectionText) {
        untrimmedBeforeSelectionText += "\r\n";
      } else {
        isRangeEndTrimmed = true;
      }
    }
  }
  if (getOnlyStart) {
    return [untrimmedBeforeSelectionText.length, -1];
  }
  var isSelectionRangeEndTrimmed = false;
  while (!isSelectionRangeEndTrimmed) {
    if (selectionRange.compareEndPoints("StartToEnd", selectionRange) == 0) {
      isSelectionRangeEndTrimmed = true;
    } else {
      selectionRange.moveEnd("character", -1);
      if (selectionRange.text == selectionText) {
        untrimmedSelectionText += "\r\n";
      } else {
        isSelectionRangeEndTrimmed = true;
      }
    }
  }
  return [untrimmedBeforeSelectionText.length, untrimmedBeforeSelectionText.length + untrimmedSelectionText.length];
};
goog.dom.selection.getEndPoints = function(textfield) {
  return goog.dom.selection.getEndPoints_(textfield, false);
};
goog.dom.selection.getEndPoints_ = function(textfield, getOnlyStart) {
  textfield = textfield;
  var startPos = 0;
  var endPos = 0;
  if (goog.dom.selection.useSelectionProperties_(textfield)) {
    startPos = textfield.selectionStart;
    endPos = getOnlyStart ? -1 : textfield.selectionEnd;
  } else {
    if (goog.dom.selection.isLegacyIe_()) {
      var tmp = goog.dom.selection.getRangeIe_(textfield);
      var range = tmp[0];
      var selectionRange = tmp[1];
      if (range.inRange(selectionRange)) {
        range.setEndPoint("EndToStart", selectionRange);
        if (textfield.type == goog.dom.InputType.TEXTAREA) {
          return goog.dom.selection.getEndPointsTextareaIe_(range, selectionRange, getOnlyStart);
        }
        startPos = range.text.length;
        if (!getOnlyStart) {
          endPos = range.text.length + selectionRange.text.length;
        } else {
          endPos = -1;
        }
      }
    }
  }
  return [startPos, endPos];
};
goog.dom.selection.setEnd = function(textfield, pos) {
  if (goog.dom.selection.useSelectionProperties_(textfield)) {
    textfield.selectionEnd = pos;
  } else {
    if (goog.dom.selection.isLegacyIe_()) {
      var tmp = goog.dom.selection.getRangeIe_(textfield);
      var range = tmp[0];
      var selectionRange = tmp[1];
      if (range.inRange(selectionRange)) {
        pos = goog.dom.selection.canonicalizePositionIe_(textfield, pos);
        var startCursorPos = goog.dom.selection.canonicalizePositionIe_(textfield, goog.dom.selection.getStart(textfield));
        selectionRange.collapse(true);
        selectionRange.moveEnd("character", pos - startCursorPos);
        selectionRange.select();
      }
    }
  }
};
goog.dom.selection.getEnd = function(textfield) {
  return goog.dom.selection.getEndPoints_(textfield, false)[1];
};
goog.dom.selection.setCursorPosition = function(textfield, pos) {
  if (goog.dom.selection.useSelectionProperties_(textfield)) {
    textfield.selectionStart = pos;
    textfield.selectionEnd = pos;
  } else {
    if (goog.dom.selection.isLegacyIe_()) {
      pos = goog.dom.selection.canonicalizePositionIe_(textfield, pos);
      var sel = textfield.createTextRange();
      sel.collapse(true);
      sel.move("character", pos);
      sel.select();
    }
  }
};
goog.dom.selection.setText = function(textfield, text) {
  textfield = textfield;
  if (goog.dom.selection.useSelectionProperties_(textfield)) {
    var value = textfield.value;
    var oldSelectionStart = textfield.selectionStart;
    var before = value.substr(0, oldSelectionStart);
    var after = value.substr(textfield.selectionEnd);
    textfield.value = before + text + after;
    textfield.selectionStart = oldSelectionStart;
    textfield.selectionEnd = oldSelectionStart + text.length;
  } else {
    if (goog.dom.selection.isLegacyIe_()) {
      var tmp = goog.dom.selection.getRangeIe_(textfield);
      var range = tmp[0];
      var selectionRange = tmp[1];
      if (!range.inRange(selectionRange)) {
        return;
      }
      var range2 = selectionRange.duplicate();
      selectionRange.text = text;
      selectionRange.setEndPoint("StartToStart", range2);
      selectionRange.select();
    } else {
      throw Error("Cannot set the selection end");
    }
  }
};
goog.dom.selection.getText = function(textfield) {
  textfield = textfield;
  if (goog.dom.selection.useSelectionProperties_(textfield)) {
    var s = textfield.value;
    return s.substring(textfield.selectionStart, textfield.selectionEnd);
  }
  if (goog.dom.selection.isLegacyIe_()) {
    var tmp = goog.dom.selection.getRangeIe_(textfield);
    var range = tmp[0];
    var selectionRange = tmp[1];
    if (!range.inRange(selectionRange)) {
      return "";
    } else {
      if (textfield.type == goog.dom.InputType.TEXTAREA) {
        return goog.dom.selection.getSelectionRangeText_(selectionRange);
      }
    }
    return selectionRange.text;
  }
  throw Error("Cannot get the selection text");
};
goog.dom.selection.getSelectionRangeText_ = function(selRange) {
  var selectionRange = selRange.duplicate();
  var selectionText = selectionRange.text;
  var untrimmedSelectionText = selectionText;
  var isSelectionRangeEndTrimmed = false;
  while (!isSelectionRangeEndTrimmed) {
    if (selectionRange.compareEndPoints("StartToEnd", selectionRange) == 0) {
      isSelectionRangeEndTrimmed = true;
    } else {
      selectionRange.moveEnd("character", -1);
      if (selectionRange.text == selectionText) {
        untrimmedSelectionText += "\r\n";
      } else {
        isSelectionRangeEndTrimmed = true;
      }
    }
  }
  return untrimmedSelectionText;
};
goog.dom.selection.getRangeIe_ = function(el) {
  var doc = el.ownerDocument || el.document;
  var selectionRange = doc.selection.createRange();
  var range;
  if (el.type == goog.dom.InputType.TEXTAREA) {
    range = doc.body.createTextRange();
    range.moveToElementText(el);
  } else {
    range = el.createTextRange();
  }
  return [range, selectionRange];
};
goog.dom.selection.canonicalizePositionIe_ = function(textfield, pos) {
  textfield = textfield;
  if (textfield.type == goog.dom.InputType.TEXTAREA) {
    var value = textfield.value.substring(0, pos);
    pos = goog.string.canonicalizeNewlines(value).length;
  }
  return pos;
};
goog.dom.selection.useSelectionProperties_ = function(el) {
  try {
    return typeof el.selectionStart == "number";
  } catch (e) {
    return false;
  }
};
goog.dom.selection.isLegacyIe_ = function() {
  return goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9");
};
goog.provide("uno.util.richlink");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.classlist");
goog.require("goog.dom.selection");
goog.require("goog.string");
goog.require("uno.defs");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.richlink");
  var defs = uno.defs;
  var util = uno.util;
  util.richlink.counter = 0;
  util.richlink.DISPLAY_TYPE = {NONE:"en_rl_none", MINIMAL:"en_rl_minimal", TEXT:"en_rl_text", SMALL:"en_rl_small"};
  util.richlink.isRichLink = function(node) {
    return node && util.dom.matches(node, ".en-richlink");
  };
  util.richlink.componentElementFor = function(el) {
    return goog.dom.getAncestorByTagNameAndClass(el, null, "en-richlink");
  };
  util.richlink.all = function(root) {
    return root.querySelectorAll(".en-richlink");
  };
  util.richlink.allPlain = function(root) {
    return root.querySelectorAll("a:not(.en-richlink)");
  };
  util.richlink.allPending = function(root) {
    return root.querySelectorAll("a.en-richlink-pending");
  };
  util.richlink.allUndecorated = function(root) {
    return Array.prototype.filter.call(util.richlink.allPlain(root), function(link) {
      return link.rev === util.richlink.DISPLAY_TYPE.NONE || link.rev === util.richlink.DISPLAY_TYPE.MINIMAL || link.rev === util.richlink.DISPLAY_TYPE.TEXT || link.rev === util.richlink.DISPLAY_TYPE.SMALL;
    });
  };
  util.richlink.canDecorate = function(el, editor) {
    return !!util.richlink.getProvider(el, editor);
  };
  util.richlink.getProvider = function(el, editor) {
    var provider;
    editor.richlinkProviders.some(function(p) {
      if (p.canDecorate(el.href)) {
        provider = p;
        return true;
      }
    });
    return provider;
  };
  util.richlink.decorate = function(el, editor) {
    if (!editor.config.richlinks.enabled) {
      return;
    }
    if (!el.href || util.richlink.hasNonDecoratableChildren(el)) {
      return;
    }
    if (el.text !== el.href) {
      return;
    }
    var provider = util.richlink.getProvider(el, editor);
    if (provider) {
      el.setAttribute("data-provider", provider.name);
      el.setAttribute("data-title", el.innerText);
      el.setAttribute("data-href", el.href);
      util.richlink.setDisplayType(el, util.richlink.getDisplayType(el));
      provider.decorate(el, editor);
    }
  };
  util.richlink.undecorate = function(el, editor) {
    editor.richlinkProviders.some(function(provider) {
      if (provider.name === el.getAttribute("data-provider")) {
        var anchor = provider.undecorate(el);
        anchor.href = el.getAttribute("data-href");
        anchor.removeAttribute("class");
        anchor.innerText = anchor.getAttribute("data-title");
        Object.keys(anchor.dataset).forEach(function(key) {
          anchor.removeAttribute(["data", goog.string.toSelectorCase(key)].join("-"));
        });
        return true;
      }
    });
  };
  util.richlink.setPending = function(el, pending) {
    if (el) {
      if (pending) {
        goog.dom.classlist.add(el, "en-richlink-pending");
      } else {
        goog.dom.classlist.remove(el, "en-richlink-pending");
      }
    }
  };
  util.richlink.setDisplayType = function(el, displayType) {
    el.setAttribute("rev", displayType || util.richlink.DISPLAY_TYPE.SMALL);
  };
  util.richlink.getDisplayType = function(el) {
    var parent;
    var displayType;
    if (!el) {
      displayType = util.richlink.DISPLAY_TYPE.SMALL;
    } else {
      if (el.hasAttribute("rev")) {
        displayType = el.getAttribute("rev");
      } else {
        if ((parent = util.dom.parent(el, "ul, ol, il, dl, td", null)) !== null) {
          displayType = util.richlink.DISPLAY_TYPE.MINIMAL;
        } else {
          if (util.dom.hasTextNextToIt(el)) {
            displayType = util.richlink.DISPLAY_TYPE.MINIMAL;
          } else {
            if (util.dom.hasTodoNextToIt(el)) {
              displayType = util.richlink.DISPLAY_TYPE.MINIMAL;
            } else {
              displayType = util.richlink.DISPLAY_TYPE.SMALL;
            }
          }
        }
      }
    }
    return displayType;
  };
  util.richlink.hasNonDecoratableChildren = function(node) {
    if (!node || !node.childNodes || node.childNodes.length == 0) {
      return false;
    }
    for (var index = 0; index < node.children.length; index++) {
      if (node.children[index].nodeName && (node.children[index].nodeName.toLowerCase() == "img" || uno.defs.blockElements[node.children[index].nodeName.toLowerCase()] && node.children[index].nodeName.toLowerCase() != "p")) {
        return true;
      }
      if (util.richlink.hasNonDecoratableChildren(node.children[index])) {
        return true;
      }
    }
    return false;
  };
  util.richlink.handleClick = function(el, target, editor) {
    var result = false;
    editor.richlinkProviders.some(function(provider) {
      if (provider.name === el.getAttribute("data-provider")) {
        result = provider.handleClick(el, target, editor);
      }
    });
    return result;
  };
  util.richlink.handleMouseMove = function(el, target, editor) {
    var result = false;
    editor.richlinkProviders.some(function(provider) {
      if (provider.name === el.getAttribute("data-provider")) {
        result = provider.handleMouseMove(el, target, editor);
      }
    });
    return result;
  };
  util.richlink.handleMouseOut = function(el, target, editor) {
    var result = false;
    editor.richlinkProviders.some(function(provider) {
      if (provider.name === el.getAttribute("data-provider")) {
        result = provider.handleMouseOut(el, target, editor);
      }
    });
    return result;
  };
})();
goog.provide("uno.commands.CreateLink");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.editor.plugins.BasicTextFormatter");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.richlink");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.CreateLink");
  var util = uno.util;
  var CreateLink = uno.commands.CreateLink = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CreateLink, uno.BasePlugin);
  CreateLink.prototype.isSupportedCommand = function(command) {
    return command === "createlink";
  };
  CreateLink.prototype.activeOnUneditableFields = goog.functions.TRUE;
  CreateLink.prototype.execCommandInternal = function(command, value) {
    var container;
    var editor = this.editor;
    var url = goog.isObject(value) ? value.url : value;
    var title = goog.isObject(value) ? value.title || value.url : value;
    var range = editor.getRange();
    var dom = goog.dom;
    var node;
    if (range == null) {
      return;
    }
    if (url == null) {
      return;
    }
    if (range.isCollapsed()) {
      node = dom.createTextNode(title);
      range.replaceContentsWithNode(node);
      range = goog.dom.Range.createFromNodes(node, 0, node, title.length);
      range.select();
    }
    editor.execCommand(goog.editor.plugins.BasicTextFormatter.COMMAND.CREATE_LINK, range, url);
    range = editor.getRange();
    container = range.getContainerElement();
    if (util.dom.compareTagName(container, "a")) {
      container.setAttribute("href", url);
      util.richlink.decorate(container, editor);
    }
    goog.array.forEachRight(container.querySelectorAll("a"), function(a) {
      if (editor.getRange() && editor.getRange().containsNode(a)) {
        a.setAttribute("href", url);
        util.richlink.decorate(a, editor);
      }
    });
    if (range.isCollapsed()) {
      goog.editor.range.placeCursorNextTo(editor.getRange().getStartNode());
    }
    editor.updateEmpty();
  };
  CreateLink.prototype.queryCommandValue = function() {
    var anchor;
    var range = this.editor.getRange();
    if (range && (range.isCollapsed() || range.getContainer() === range.getStartNode())) {
      anchor = goog.dom.getAncestorByTagNameAndClass(range.getStartNode(), "a");
      if (anchor && anchor.hasAttribute("href")) {
        return anchor.getAttribute("href");
      }
    }
    return null;
  };
  CreateLink.prototype.queryCommandEnabled = function(command) {
    return !!this.editor.getRange();
  };
})();
goog.provide("uno.commands.Crypt");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.classlist");
goog.require("goog.editor.range");
goog.require("goog.functions");
goog.require("goog.object");
goog.require("goog.string");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.crypto");
goog.require("uno.util.dom");
goog.require("uno.util.list");
goog.require("uno.util.copy");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Crypt");
  var util = uno.util;
  var Crypt = uno.commands.Crypt = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Crypt, uno.BasePlugin);
  var CRYPT_CLASS = uno.defs.crypto.CRYPT_CLASS;
  var CRYPT_HIDDEN_CLASS = uno.defs.crypto.CRYPT_HIDDEN_CLASS;
  var CRYPT_VISIBLE_CLASS = uno.defs.crypto.CRYPT_VISIBLE_CLASS;
  Crypt.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Crypt.prototype.isSupportedCommand = function(command) {
    return command === "crypt";
  };
  Crypt.prototype.queryCommandEnabled = function(command, value) {
    if (value) {
      var action = value.open || value.close || value.revert;
      if (action && (action.id == null || this.editor.field.querySelector("#" + action.id))) {
        return true;
      }
      if (value.decrypt && this.editor.field.querySelector("#" + value.decrypt.cryptInfo.id)) {
        return true;
      }
    }
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CMD_CRYPTO, range)) {
      return false;
    }
    var selection = getSelectedContents(this.editor);
    return !!(range && !range.isCollapsed() && !getCryptNodeFromRange(range) && selection && isValidHtml(selection.html));
  };
  Crypt.prototype.queryCommandValue = function(command, value) {
    var range = this.editor.getRange();
    if (range) {
      var cryptNode = getCryptNodeFromRange(range);
      var hasClass = goog.dom.classlist.contains;
      if (cryptNode) {
        if (value === "open") {
          return hasClass(cryptNode, CRYPT_VISIBLE_CLASS);
        } else {
          if (value === "closed") {
            return hasClass(cryptNode, CRYPT_HIDDEN_CLASS) || !hasClass(cryptNode, CRYPT_VISIBLE_CLASS);
          } else {
            if (value === "selected") {
              var cryptInfo = util.crypto.getCryptInfoFromNode(cryptNode);
              cryptInfo.open = !!hasClass(cryptNode, CRYPT_VISIBLE_CLASS);
              return cryptInfo;
            }
          }
        }
        return true;
      }
    }
    return false;
  };
  Crypt.prototype.execCommand = function(command, options) {
    var editor = this.editor;
    var range = editor.getRange();
    var result;
    if (!options) {
      result = requestEncryption(null, editor);
    } else {
      if (options.encrypt) {
        result = encrypt(options.encrypt, range, editor);
      } else {
        if (options.decrypt) {
          result = decrypt(options.decrypt, range, editor);
        } else {
          if (options.revert) {
            result = revert(options.revert, range, editor);
          } else {
            if (options.open) {
              result = open(options.open, range, editor);
            } else {
              if (options.close) {
                result = close(options.close, range, editor);
              } else {
                result = false;
              }
            }
          }
        }
      }
    }
    return result;
  };
  function isValidHtml(html) {
    var frag = util.dom.fragFromString(html);
    return frag.querySelectorAll("img,object,embed,table,tr,td,th,tbody,thead,ul,ol,hr").length === 0;
  }
  function getSelectedContents(editor) {
    return util.copy.copy(editor, {html:true, addMarker:false});
  }
  function requestEncryption(options, editor) {
    var selection = getSelectedContents(editor);
    if (!selection.html) {
      return false;
    }
    var cryptInfo = {id:"crypt-" + editor.context.crypt.incrementUniqueId(), length:"", cipher:"", hint:"", cipherText:"", plainText:selection.html, src:options && options.src || ""};
    editor.dispatchEvent({type:"encrypt", cryptInfo:cryptInfo});
    return cryptInfo;
  }
  function hide(options, range, editor) {
    if (!range || range.isCollapsed()) {
      return false;
    }
    var selection = getSelectedContents(editor);
    if (!selection.html) {
      return false;
    }
    var encryptedNode = util.crypto.createCryptoPlaceholder({id:options.cryptInfo.id, src:options.cryptInfo.src, plainText:options.cryptInfo.plainText});
    editor.execCommand("delete");
    editor.getRange().insertNode(encryptedNode, true);
    return encryptedNode;
  }
  function encrypt(options, range, editor) {
    if (!options) {
      return false;
    }
    if (!options.cryptInfo) {
      return options.src ? requestEncryption(options, editor) : false;
    }
    if (!options.cipherText) {
      return false;
    }
    var cryptNode = hide(options, range, editor);
    if (cryptNode) {
      cryptNode.setAttribute("data-ciphertext", options.cipherText);
      cryptNode.setAttribute("data-cipher", options.cipher);
      cryptNode.setAttribute("data-length", options.length);
      cryptNode.setAttribute("data-hint", options.hint);
      editor.dispatchChange();
      return true;
    }
    return false;
  }
  function decrypt(options, range, editor) {
    var cryptInfo = options && options.cryptInfo;
    var encryptedOnly = cryptInfo.revert ? {} : {encryptedOnly:true};
    var cryptNode = util.crypto.getNodeFromCryptInfo(cryptInfo, encryptedOnly);
    if (!cryptNode || !options.plainText) {
      return false;
    }
    var result = openCrypt(cryptNode, options.plainText, cryptInfo.revert, editor);
    return result;
  }
  function revert(options, range, editor) {
    var cryptInfo = {};
    var cryptNode = getCryptNode(options, range);
    if (cryptNode) {
      if (util.crypto.isOpen(cryptNode)) {
        openCrypt(cryptNode, cryptNode.innerHTML, true, editor);
      } else {
        goog.object.extend(cryptInfo, options, util.crypto.getCryptInfoFromNode(cryptNode), {revert:true});
        if (options.plainText) {
          cryptInfo.plainText = options.plainText;
        }
        editor.dispatchEvent({type:"decrypt", cryptInfo:cryptInfo});
      }
      return true;
    }
    return false;
  }
  function open(options, range, editor) {
    var cryptInfo = {};
    var cryptNode = getCryptNode(options, range);
    if (cryptNode) {
      goog.object.extend(cryptInfo, options, util.crypto.getCryptInfoFromNode(cryptNode));
      editor.dispatchEvent({type:"decrypt", cryptInfo:cryptInfo});
      return true;
    }
    return false;
  }
  function getCryptNode(options, range) {
    var cryptNode;
    if (options.id) {
      cryptNode = util.crypto.getNodeFromCryptInfo(options);
    } else {
      if (range) {
        var container = range.getContainerElement();
        cryptNode = util.crypto.isCrypt(container) ? container : container.querySelector("." + CRYPT_CLASS);
        if (cryptNode) {
          options.id = cryptNode.id;
        }
      }
    }
    return cryptNode;
  }
  function close(options, range, editor) {
    if (options.all) {
      var cryptNodes = editor.field.querySelectorAll("." + CRYPT_VISIBLE_CLASS);
      if (!cryptNodes.length) {
        return false;
      }
      goog.array.forEach(cryptNodes, function(cryptNode) {
        closeCrypt(cryptNode, options, editor);
      });
      return true;
    }
    if (options.id) {
      var cryptNode = util.crypto.getNodeFromCryptInfo(options, {decryptedOnly:true});
      if (cryptNode) {
        return closeCrypt(cryptNode, options, editor);
      }
    }
    return false;
  }
  function openCrypt(cryptNode, plainText, openPermanently, editor) {
    var placeholder = null;
    var cryptInfo = util.crypto.getCryptInfoFromNode(cryptNode);
    if (!plainText) {
      return false;
    }
    if (openPermanently) {
      placeholder = document.createElement("span");
      placeholder.innerHTML = plainText;
      editor.dispatchChange();
    } else {
      var attrs = {class:CRYPT_CLASS + " " + CRYPT_VISIBLE_CLASS, id:cryptInfo.id, "data-src":cryptInfo.src || "", "data-length":cryptInfo.length, "data-cipher":cryptInfo.cipher, "data-hint":cryptInfo.hint, "data-ciphertext":cryptInfo.cipherText};
      placeholder = goog.dom.createDom("blockquote", attrs);
      placeholder.innerHTML = plainText;
      placeholder.setAttribute("data-hash", util.crypto.hash(placeholder.innerHTML));
      placeholder.setAttribute("contentEditable", !editor.config.crypt.readOnly);
    }
    return !!replaceNodeAndKeepSelection(cryptNode, placeholder, openPermanently);
  }
  function closeCrypt(cryptNode, options, editor) {
    var cryptInfo = {};
    goog.object.extend(cryptInfo, options, util.crypto.getCryptInfoFromNode(cryptNode));
    if (util.crypto.isDirty(cryptNode)) {
      goog.object.extend(cryptInfo, {plainText:cryptNode.innerHTML});
      editor.dispatchEvent({type:"encrypt", cryptInfo:cryptInfo});
      return true;
    }
    var placeholder = util.crypto.createCryptoPlaceholder(cryptInfo);
    return !!replaceNodeAndKeepSelection(cryptNode, placeholder);
  }
  function getCryptNodeFromRange(range) {
    if (!range) {
      return null;
    }
    var container = document.createElement("div");
    container.innerHTML = range.getValidHtml();
    return container.querySelector("." + CRYPT_CLASS);
  }
  function replaceNodeAndKeepSelection(oldNode, newNode, flatten) {
    goog.dom.replaceNode(newNode, oldNode);
    var range = goog.editor.range.placeCursorNextTo(newNode);
    range.select();
    if (flatten) {
      goog.dom.flattenElement(newNode);
    }
    return range;
  }
})();
goog.provide("uno.commands.Cut");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Cut");
  var Cut = uno.commands.Cut = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Cut, uno.BasePlugin);
  Cut.prototype.isSupportedCommand = function(command) {
    return command === "cut";
  };
  Cut.prototype.execCommandInternal = function(command, opt) {
    return !!this.queryCommandValue(command, opt);
  };
  Cut.prototype.queryCommandValue = function() {
    var result = this.editor.queryCommandValue("copy");
    this.editor.execCommand("delete", "selection", undefined, true);
    return result;
  };
})();
goog.provide("uno.commands.Delete");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.iter");
goog.require("uno.BasePlugin");
goog.require("uno.EditorMultiRange");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.table");
(function() {
  var util = uno.util;
  var log = goog.debug.Logger.getLogger("uno.commands.Delete");
  var ZERO_WIDTH_SPACE = uno.defs.unicode.ZERO_WIDTH_SPACE;
  var Delete = uno.commands.Delete = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(Delete, uno.BasePlugin);
  Delete.WORD = "word";
  Delete.SELECTION = "selection";
  Delete.prototype.isSupportedCommand = function(command) {
    return command === "delete";
  };
  Delete.prototype.queryCommandValue = function(command) {
    return document.queryCommandValue(command);
  };
  Delete.prototype.execCommand = function(command, value, options) {
    if (options && options.smart === false) {
      clearBaseAndExtent();
    }
    var forward = options ? options.forward : false;
    var native = options ? options.native : false;
    var formField = this.editor.getFormField();
    if (formField) {
      return deleteSelection(forward);
    }
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var focusNode = range.getFocusNode();
    var focusOffset = range.getFocusOffset();
    if (value === Delete.SELECTION && range.isCollapsed()) {
      return false;
    }
    if (value === Delete.WORD) {
      var wordRange = getWordRange(range, focusOffset, forward);
      selectRange(wordRange);
      range = this.editor.getRange();
      value = 1;
    }
    this.editor.dispatchBeforeChange();
    var result;
    var count = parseInt(value, 10);
    count = isNaN(count) ? 1 : count;
    for (var i = 0; i < count; i++) {
      var currentNode = focusNode.childNodes && focusNode.childNodes[focusOffset - 1];
      if (isCursorAfterCodeBlock(focusNode, focusOffset) && range.isCollapsed()) {
        result = moveCursorToEndOfCodeBlock(focusNode, this.editor);
      } else {
        if (isCursorAtBeginningOfCodeBlock(focusNode, focusOffset) && range.isCollapsed()) {
          result = moveFirstLineOutOfCodeBlock(focusNode, this.editor);
        } else {
          if (this.editor.multirange.isInvoking()) {
            result = emptyCell(focusNode);
          } else {
            if (shouldEmptyCell(range, forward)) {
              result = emptyCell(focusNode, true);
            } else {
              if (!forward && isTableSelectedBeforeCursor(range) || forward && isTableSelectedAfterCursor(range)) {
                result = true;
              } else {
                if (assistedTableDelete(range, forward)) {
                  result = true;
                } else {
                  if (isLastIndentation(focusNode, focusOffset) && range.isCollapsed() && !forward) {
                    result = deleteIndentation(focusNode);
                  } else {
                    if (isAfterResource(focusNode, focusOffset, forward)) {
                      result = removeResource(focusNode, range.isCollapsed());
                    } else {
                      if (isEditorDefaultEmpty(this.editor)) {
                        result = true;
                      } else {
                        if (range.isCollapsed() && isEmptyParagraph(focusNode) && !isAtBeginningOfNote(focusNode, focusOffset, this.editor)) {
                          result = removeParagraph(focusNode);
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
      if (typeof result !== "undefined") {
        if (result === true) {
          this.editor.dispatchChange();
        }
        return result;
      } else {
        if (native) {
          return false;
        }
      }
      deleteSelection(forward);
    }
    this.editor.dispatchChange();
    return true;
  };
  function isEditorDefaultEmpty(editor) {
    return editor.field.innerHTML === editor.config.defaults.html;
  }
  function isAtBeginningOfNote(node, offset, editor) {
    if (offset === 0 && editor.field && util.dom.isBeginningOfLineChild(node, editor.field)) {
      return true;
    }
    return false;
  }
  function removeParagraph(paragraph) {
    var blockquote = goog.dom.getAncestor(paragraph, util.dom.isBlockquote, true, 2);
    var previousParagraph;
    var lastWord;
    if (blockquote) {
      previousParagraph = blockquote.previousSibling;
      var newNode = goog.dom.createDom("div", {}, goog.dom.createDom("br"));
      if (util.dom.isEmpty(blockquote)) {
        goog.dom.replaceNode(newNode, blockquote);
        lastWord = util.dom.endContent(blockquote.previousSibling);
      } else {
        lastWord = util.dom.endContent(paragraph.previousSibling);
        util.paragraph.remove(paragraph);
      }
      if (lastWord) {
        goog.editor.range.placeCursorNextTo(lastWord);
      }
    } else {
      lastWord = util.dom.endContent(paragraph.previousSibling);
      util.paragraph.remove(paragraph);
      if (lastWord) {
        goog.editor.range.placeCursorNextTo(lastWord);
      }
    }
    return true;
  }
  function clearBaseAndExtent() {
    var sel = window.getSelection();
    if (!sel || sel.setBaseAndExtent === undefined || sel.baseNode === undefined) {
      return;
    }
    var clear = sel.type === "Range" && (sel.anchorNode !== sel.baseNode || sel.anchorOffset !== sel.baseOffset || sel.extentNode !== sel.focusNode || sel.extentOffset !== sel.focusOffset);
    if (clear) {
      sel.setBaseAndExtent(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);
    }
  }
  function deleteSelection(forward) {
    var commandName = forward ? "forwarddelete" : "delete";
    return document.execCommand(commandName);
  }
  function selectRange(range) {
    var currentSelection = window.getSelection();
    currentSelection.removeAllRanges();
    currentSelection.addRange(range.getBrowserRangeObject());
  }
  function getWordRange(currentRange, offset, forward) {
    var wordRange = currentRange;
    var wordNode = currentRange.getContainer();
    if (offset && wordNode && wordNode.nodeType === Node.TEXT_NODE) {
      var found = false;
      var index = 0;
      wordNode.nodeValue.split(" ").forEach(function(word, i, arr) {
        var oldIndex = index;
        index += word.length;
        if (i < arr.length - 1) {
          index++;
        }
        if (!found) {
          if (forward && (offset === oldIndex || offset === oldIndex - 1)) {
            found = true;
          } else {
            if (!forward && (offset === index || offset === index - 1)) {
              found = true;
            } else {
              if (offset > oldIndex && offset < index) {
                found = true;
              }
            }
          }
          if (found) {
            wordRange = goog.dom.Range.createFromNodes(wordNode, oldIndex, wordNode, index);
          }
        }
      });
    }
    return wordRange;
  }
  function isTableSelectedBeforeCursor(range) {
    if (!range.isCollapsed() || range.getFocusOffset() > 0 || isCursorAtBeginningOfLI(range)) {
      return false;
    }
    var beforeNode = getParagraphBeforeNode(range.getFocusNode());
    if (!beforeNode) {
      return false;
    }
    var enTable = util.dom.isEntable(beforeNode) ? beforeNode : beforeNode.querySelector("en-table");
    if (enTable) {
      goog.dom.Range.createFromNodes(enTable, 0, enTable, enTable.childNodes.length).select();
      enTable.classList.add("selected");
      return true;
    }
    return false;
  }
  function isTableSelectedAfterCursor(range) {
    if (!range.isCollapsed()) {
      return false;
    }
    var node = util.dom.getLastParagraphItem(range.getFocusNode());
    if (!node || util.dom.isTextNode(node) && node.length > range.getFocusOffset()) {
      return false;
    }
    var nextNode = util.dom.nextNode(node);
    if (!nextNode) {
      return false;
    }
    var enTable = util.dom.isEntable(nextNode) ? nextNode : nextNode.querySelector("en-table");
    if (enTable) {
      goog.dom.Range.createFromNodes(enTable, 0, enTable, enTable.childNodes.length).select();
      enTable.classList.add("selected");
      return true;
    }
    return false;
  }
  function assistedTableDelete(range, forward) {
    if (range.isCollapsed()) {
      return false;
    }
    var startAncestor = goog.dom.getAncestor(range.getStartNode(), util.dom.isEntable, true);
    var endAncestor = goog.dom.getAncestor(range.getEndNode(), util.dom.isEntable, true);
    var tableParent = null;
    var tableIndex = 0;
    var deleted = false;
    if (endAncestor && endAncestor !== startAncestor && endAncestor.classList.contains("selected")) {
      tableIndex = util.dom.index(endAncestor);
      tableParent = endAncestor.parentElement;
      endAncestor.remove();
      deleted = true;
    }
    if (startAncestor && startAncestor.classList.contains("selected")) {
      tableIndex = util.dom.index(startAncestor);
      tableParent = startAncestor.parentElement;
      startAncestor.remove();
      deleted = true;
    }
    if (deleted && !range.isCollapsed()) {
      deleteSelection(forward);
    }
    return deleted;
  }
  function shouldEmptyCell(range, forward) {
    var startNode = range.getStartNode();
    var endNode = range.getEndNode();
    var cell = goog.dom.getAncestor(startNode, util.dom.isTd, true);
    var endAncestor = goog.dom.getAncestor(endNode, util.dom.isTd, true);
    if (!cell || cell !== endAncestor) {
      return false;
    }
    if (util.dom.isEmptyContent(cell)) {
      return true;
    }
    var startOffset = range.getStartOffset();
    var endOffset = range.getEndOffset();
    var leaves = goog.array.filter(util.dom.getNodeLeaves(cell), function(node) {
      return !util.dom.isBr(node);
    });
    if (range.isCollapsed() && leaves.length === 1) {
      if (util.dom.isTextNode(leaves[0]) && leaves[0] === startNode && startNode.length === 1 && (startOffset === 1 && !forward || startOffset === 0 && forward)) {
        return true;
      }
      if (leaves[0].parentNode === startNode && (startOffset === 1 && !forward || startOffset === 0 && forward)) {
        return true;
      }
    }
    if (!range.isCollapsed() && goog.array.every(leaves, range.containsNode, range)) {
      return true;
    }
    return false;
  }
  function isEmptyParagraph(node) {
    return node === util.paragraph.for(node) && util.dom.isEmpty(node);
  }
  function isLastIndentation(node, offset) {
    if (offset) {
      return false;
    }
    if (util.dom.isElementNode(node) && (util.dom.isLi(node) || util.dom.isBlockquote(node))) {
      return true;
    } else {
      if (util.dom.isTextNode(node) && (util.dom.isLi(node.parentNode) || util.dom.isBlockquote(node.parentNode))) {
        return true;
      }
    }
    return false;
  }
  function getParagraphBeforeNode(node) {
    var previousParagraph = null;
    var currentParagraph = util.paragraph.for(node);
    if (!currentParagraph) {
      return false;
    }
    while (!previousParagraph) {
      previousParagraph = util.paragraph.prevParagraph(currentParagraph);
      if (previousParagraph && !util.dom.isEnnote(previousParagraph)) {
        break;
      } else {
        if (util.dom.isEnnote(previousParagraph)) {
          break;
        } else {
          currentParagraph = currentParagraph.parentNode;
        }
      }
    }
    return previousParagraph;
  }
  function isCursorAtBeginningOfLI(range) {
    if (!range.isCollapsed() || range.getFocusOffset() > 0) {
      return false;
    }
    var node = range.getFocusNode();
    while (node && !util.dom.isEnnote(node)) {
      if (!node.previousSibling && util.dom.isLi(node)) {
        return true;
      }
      node = node.parentNode;
    }
    return false;
  }
  function isCursorAtBeginningOfCodeBlock(node, offset) {
    var block = goog.dom.getAncestor(node, function(ancestor) {
      return util.dom.isCodeBlock(ancestor);
    }, true);
    if (block && util.dom.isEmpty(block)) {
      return true;
    }
    if (offset === 0 && block && block.childNodes && block.childNodes[0] === util.paragraph.for(node)) {
      return true;
    }
    return false;
  }
  function moveFirstLineOutOfCodeBlock(node) {
    var block = goog.dom.getAncestor(node, function(ancestor) {
      return util.dom.isCodeBlock(ancestor);
    }, true);
    var textLine = block.childNodes[0].textContent;
    if (textLine.length === 0) {
      textLine = goog.dom.createDom("br");
    }
    block.childNodes[0].remove();
    var newLine = goog.dom.createDom("div", {}, textLine);
    block.parentElement.insertBefore(newLine, block);
    goog.editor.range.selectNodeStart(newLine);
    if (!block.childNodes || block.childNodes.length === 0) {
      block.remove();
    }
    return true;
  }
  function getCodeBlockBeforeNode(node) {
    var previousParagraph = getParagraphBeforeNode(node);
    if (previousParagraph && util.dom.isCodeBlock(previousParagraph)) {
      var block = previousParagraph;
      while (block.childNodes && block.childNodes.length > 0) {
        block = block.childNodes[block.childNodes.length - 1];
      }
      return block;
    }
    return false;
  }
  function moveCursorToEndOfCodeBlock(node, editor) {
    var newText = node.textContent;
    var block = getCodeBlockBeforeNode(node);
    if (block) {
      goog.editor.range.placeCursorNextTo(block);
      var range = editor.getRange();
      range.insertNode(goog.dom.createTextNode(newText));
      node.remove();
      return true;
    }
    return false;
  }
  function isCursorAfterCodeBlock(node, offset) {
    if (offset > 0) {
      return false;
    }
    return getCodeBlockBeforeNode(node);
  }
  function isAfterResource(node, offset, forward) {
    if (node.nodeType === Node.TEXT_NODE) {
      if (forward && (node.length === offset || node.textContent === ZERO_WIDTH_SPACE)) {
        node = node.nextSibling;
      } else {
        if (offset === 0 || node.textContent === ZERO_WIDTH_SPACE) {
          node = node.previousSibling;
        }
      }
    }
    if (util.dom.isEnmedia(node)) {
      return true;
    }
    return false;
  }
  function emptyCell(focusNode, placeCursor) {
    var cell = goog.dom.getAncestor(focusNode, util.dom.isTd, true);
    if (cell) {
      cell.innerHTML = "<div><br></div>";
      if (placeCursor) {
        goog.editor.range.placeCursorNextTo(cell.firstChild);
      }
      return true;
    }
    return false;
  }
  function removeResource(node, isCursorCollapsed, forward) {
    var enMedia = node;
    if (node.nodeType === Node.TEXT_NODE) {
      var sibling = forward ? node.nextSibling : node.previousSibling;
      if (sibling && sibling.tagName && sibling.tagName.toLowerCase() === "en-media") {
        enMedia = sibling;
      }
    }
    var previousSibling = enMedia.previousSibling;
    var nextSibling = enMedia.nextSibling;
    var startNode = enMedia.parentNode;
    var startOffset = util.dom.index(enMedia);
    if (previousSibling && previousSibling.textContent === ZERO_WIDTH_SPACE) {
      startNode = previousSibling;
      startOffset = 0;
    }
    var endNode = enMedia.parentNode;
    var endOffset = util.dom.index(enMedia) + 1;
    if (nextSibling && nextSibling.textContent === ZERO_WIDTH_SPACE) {
      endNode = nextSibling;
      endOffset = 1;
    }
    var range = goog.dom.Range.createFromNodes(startNode, startOffset, endNode, endOffset);
    if (isCursorCollapsed) {
      range.select();
    } else {
      deleteSelection(forward);
    }
    return true;
  }
  function deleteIndentation(element, forward) {
    var node = element.nodeType === Node.TEXT_NODE ? element.parentNode : element;
    var parent = node.parentNode;
    if (util.dom.isBlockquote(parent) || util.dom.isUl(parent) || util.dom.isOl(parent)) {
      var tagName = node.tagName.toLowerCase();
      var lis = parent.querySelectorAll(tagName);
      if (lis.length && lis[0] === node) {
        var grandParent = parent.parentNode;
        var line;
        var isParentAList = tagName === "li" && util.dom.isUl(grandParent) || util.dom.isOl(grandParent);
        var isParentABlockquote = tagName === "blockquote" && util.dom.isBlockquote(grandParent);
        if (grandParent && isParentAList || isParentABlockquote) {
          line = node;
        } else {
          line = document.createElement("div");
          line.innerHTML = node.innerHTML || "<br>";
        }
        if (lis.length === 0) {
          goog.dom.replaceNode(line, parent);
        } else {
          goog.dom.removeNode(node);
          grandParent.insertBefore(line, parent);
        }
        var range = goog.dom.Range.createFromNodes(line, 0, line, 0);
        range.select();
        return true;
      }
    }
    return deleteSelection(forward);
  }
})();
goog.provide("uno.commands.DeleteTable");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.editor.plugins.TableEditor");
goog.require("uno.BasePlugin");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.DeleteTable");
  var util = uno.util;
  var DeleteTable = uno.commands.DeleteTable = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(DeleteTable, uno.BasePlugin);
  DeleteTable.prototype.isSupportedCommand = function(command) {
    return command === "deletetable";
  };
  DeleteTable.prototype.execCommandInternal = function() {
    var table = goog.dom.getAncestor(this.editor.getRange().getStartNode(), util.dom.isTable);
    return util.table.delete(goog.dom.getAncestor(table, util.dom.isEntable) || table);
  };
  DeleteTable.prototype.queryCommandEnabled = function() {
    return !!util.table.cellForStructureChange(this.editor.getRange());
  };
})();
goog.provide("uno.commands.DeleteTableCol");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.DeleteTableCol");
  var util = uno.util;
  var DeleteTableCol = uno.commands.DeleteTableCol = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(DeleteTableCol, uno.BasePlugin);
  DeleteTableCol.prototype.isSupportedCommand = function(command) {
    return command === "deletetablecol";
  };
  DeleteTableCol.prototype.execCommandInternal = function() {
    var indexes = [];
    var enTable = util.table.getActive();
    var table = null;
    if (util.table.selection.isActive(enTable)) {
      indexes = util.table.selection.getColumnIndexes();
      util.table.selection.clear();
    } else {
      if (enTable) {
        var info = util.table.infoForCell(util.table.getActiveCell());
        if (info) {
          for (var c = info.startColIndex; c <= info.endColIndex; c++) {
            indexes.push(c);
          }
        }
      } else {
        var cell = util.table.cellForStructureChange(this.editor.getRange());
        var info = util.table.infoForCell(cell);
        if (info) {
          table = goog.dom.getAncestor(cell, util.dom.isTable);
          indexes.push(info.startColIndex);
        }
      }
    }
    return util.table.deleteColumns(enTable || table, indexes);
  };
  DeleteTableCol.prototype.queryCommandEnabled = function() {
    return !!util.table.cellForStructureChange(this.editor.getRange());
  };
})();
goog.provide("uno.commands.DeleteTableRow");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.DeleteTableRow");
  var util = uno.util;
  var DeleteTableRow = uno.commands.DeleteTableRow = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(DeleteTableRow, uno.BasePlugin);
  DeleteTableRow.prototype.isSupportedCommand = function(command) {
    return command === "deletetablerow";
  };
  DeleteTableRow.prototype.execCommandInternal = function() {
    var indexes = [];
    var enTable = util.table.getActive();
    var table = null;
    if (util.table.selection.isActive(enTable)) {
      indexes = util.table.selection.getRowIndexes();
      util.table.selection.clear();
    } else {
      if (enTable) {
        var info = util.table.infoForCell(util.table.getActiveCell());
        if (info) {
          for (var r = info.startRowIndex; r <= info.endRowIndex; r++) {
            indexes.push(r);
          }
        }
      } else {
        var cell = util.table.cellForStructureChange(this.editor.getRange());
        var info = util.table.infoForCell(cell);
        if (info) {
          table = goog.dom.getAncestor(cell, util.dom.isTable);
          indexes.push(info.startRowIndex);
        }
      }
    }
    return util.table.deleteRows(enTable || table, indexes);
  };
  DeleteTableRow.prototype.queryCommandEnabled = function() {
    return !!util.table.cellForStructureChange(this.editor.getRange());
  };
})();
goog.provide("uno.commands.Editable");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Editable");
  var Editable = uno.commands.Editable = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Editable, uno.BasePlugin);
  Editable.prototype.isSupportedCommand = function(command) {
    return command === "editable";
  };
  Editable.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Editable.prototype.execCommand = function(command, makeEditable) {
    if (makeEditable === "true") {
      makeEditable = true;
    } else {
      if (makeEditable === "false") {
        makeEditable = false;
      }
    }
    if (this.editor.readOnly && makeEditable) {
      return false;
    }
    if (makeEditable === this.editor.inEditMode()) {
      return true;
    }
    if (makeEditable) {
      this.editor.showVirtualKeyboardOnFocus = false;
      this.editor.enterEditMode(this.editor.saveRange());
      this.editor.showVirtualKeyboardOnFocus = true;
    } else {
      this.editor.leaveEditMode();
    }
    return true;
  };
  Editable.prototype.queryCommandValue = function() {
    return this.editor.inEditMode();
  };
})();
goog.provide("uno.commands.searchapi");
(function() {
  var searchapi = uno.commands.searchapi;
  var DIACRITIC_CHARS = {a:"a\u24d0\uff41\u1e9a\u00e0\u00e1\u00e2\u1ea7\u1ea5\u1eab\u1ea9\u00e3\u0101\u0103\u1eb1\u1eaf\u1eb5\u1eb3\u0227\u01e1\u00e4\u01df\u1ea3\u00e5\u01fb\u01ce\u0201\u0203\u1ea1\u1ead\u1eb7\u1e01\u0105\u2c65\u0250", b:"b\u24d1\uff42\u1e03\u1e05\u1e07\u0180\u0183\u0253", c:"c\u24d2\uff43\u0107\u0109\u010b\u010d\u00e7\u1e09\u0188\u023c\ua73f\u2184", d:"d\u24d3\uff44\u1e0b\u010f\u1e0d\u1e11\u1e13\u1e0f\u0111\u018c\u0256\u0257\ua77a", e:"e\u24d4\uff45\u00e8\u00e9\u00ea\u1ec1\u1ebf\u1ec5\u1ec3\u1ebd\u0113\u1e15\u1e17\u0115\u0117\u00eb\u1ebb\u011b\u0205\u0207\u1eb9\u1ec7\u0229\u1e1d\u0119\u1e19\u1e1b\u0247\u025b\u01dd", 
  f:"f\u24d5\uff46\u1e1f\u0192\ua77c", g:"g\u24d6\uff47\u01f5\u011d\u1e21\u011f\u0121\u01e7\u0123\u01e5\u0260\ua7a1\u1d79\ua77f", h:"h\u24d7\uff48\u0125\u1e23\u1e27\u021f\u1e25\u1e29\u1e2b\u1e96\u0127\u2c68\u2c76\u0265", i:"i\u24d8\uff49\u00ec\u00ed\u00ee\u0129\u012b\u012d\u00ef\u1e2f\u1ec9\u01d0\u0209\u020b\u1ecb\u012f\u1e2d\u0268\u0131", j:"j\u24d9\uff4a\u0135\u01f0\u0249", k:"k\u24da\uff4b\u1e31\u01e9\u1e33\u0137\u1e35\u0199\u2c6a\ua741\ua743\ua745\ua7a3", l:"l\u24db\uff4c\u0140\u013a\u013e\u1e37\u1e39\u013c\u1e3d\u1e3b\u017f\u0142\u019a\u026b\u2c61\ua749\ua781\ua747", 
  m:"m\u24dc\uff4d\u1e3f\u1e41\u1e43\u0271\u026f", n:"n\u24dd\uff4e\u01f9\u0144\u00f1\u1e45\u0148\u1e47\u0146\u1e4b\u1e49\u019e\u0272\u0149\ua791\ua7a5", o:"o\u24de\uff4f\u00f2\u00f3\u00f4\u1ed3\u1ed1\u1ed7\u1ed5\u00f5\u1e4d\u022d\u1e4f\u014d\u1e51\u1e53\u014f\u022f\u0231\u00f6\u022b\u1ecf\u0151\u01d2\u020d\u020f\u01a1\u1edd\u1edb\u1ee1\u1edf\u1ee3\u1ecd\u1ed9\u01eb\u01ed\u00f8\u01ff\u0254\ua74b\ua74d\u0275", p:"p\u24df\uff50\u1e55\u1e57\u01a5\u1d7d\ua751\ua753\ua755", q:"q\u24e0\uff51\u024b\ua757\ua759", 
  r:"r\u24e1\uff52\u0155\u1e59\u0159\u0211\u0213\u1e5b\u1e5d\u0157\u1e5f\u024d\u027d\ua75b\ua7a7\ua783", s:"s\u24e2\uff53\u00df\u015b\u1e65\u015d\u1e61\u0161\u1e67\u1e63\u1e69\u0219\u015f\u023f\ua7a9\ua785\u1e9b", t:"t\u24e3\uff54\u1e6b\u1e97\u0165\u1e6d\u021b\u0163\u1e71\u1e6f\u0167\u01ad\u0288\u2c66\ua787", u:"u\u24e4\uff55\u00f9\u00fa\u00fb\u0169\u1e79\u016b\u1e7b\u016d\u00fc\u01dc\u01d8\u01d6\u01da\u1ee7\u016f\u0171\u01d4\u0215\u0217\u01b0\u1eeb\u1ee9\u1eef\u1eed\u1ef1\u1ee5\u1e73\u0173\u1e77\u1e75\u0289", 
  v:"v\u24e5\uff56\u1e7d\u1e7f\u028b\ua75f\u028c", w:"w\u24e6\uff57\u1e81\u1e83\u0175\u1e87\u1e85\u1e98\u1e89\u2c73", x:"x\u24e7\uff58\u1e8b\u1e8d", y:"y\u24e8\uff59\u1ef3\u00fd\u0177\u1ef9\u0233\u1e8f\u00ff\u1ef7\u1e99\u1ef5\u01b4\u024f\u1eff", z:"z\u24e9\uff5a\u017a\u1e91\u017c\u017e\u1e93\u1e95\u01b6\u0225\u0240\u2c6c\ua763"};
  var DIACRITICMAP = {};
  for (var s in DIACRITIC_CHARS) {
    if (DIACRITIC_CHARS.hasOwnProperty(s)) {
      var characters = DIACRITIC_CHARS[s];
      DIACRITICMAP[s] = "[" + s + characters + "]";
      for (var i = 0; i < characters.length; i++) {
        var letter = characters[i];
        if (!DIACRITICMAP[letter]) {
          DIACRITICMAP[letter] = DIACRITICMAP[s];
        }
      }
    }
  }
  var UNICODE_CJK_RANGES = "\u1100-\u11ff\u2e80-\u312f\u3130-\u31bf\u31f0-\u9fff\ua960-\ua97f\uac00-\ud7ff\uf900-\ufaff\ufe30-\ufe4f\uff61-\uffdc";
  var UNICODE_LETTER_CATEGORY_RANGES = "A-Za-z\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16f1-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2183\u2184\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005\u3006\u3031-\u3035\u303b\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6e5\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ad\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
  var UNICODE_MARK_CATEGORY_RANGES = "\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f\u109a-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u192b\u1930-\u193b\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f\u1ab0-\u1abe\u1b00-\u1b04\u1b34-\u1b44\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1be6-\u1bf3\u1c24-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfc-\u1dff\u20d0-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9e5\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f";
  var UNICODE_DECIMAL_DIGIT_CATEGORY_RANGES = "0-9\u0660-\u0669\u06f0-\u06f9\u07c0-\u07c9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0de6-\u0def\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u1090-\u1099\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\u1a80-\u1a89\u1a90-\u1a99\u1b50-\u1b59\u1bb0-\u1bb9\u1c40-\u1c49\u1c50-\u1c59\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua9d0-\ua9d9\ua9f0-\ua9f9\uaa50-\uaa59\uabf0-\uabf9\uff10-\uff19";
  var UNICODE_ALPHANUM_RANGES = UNICODE_LETTER_CATEGORY_RANGES + UNICODE_MARK_CATEGORY_RANGES + UNICODE_DECIMAL_DIGIT_CATEGORY_RANGES;
  var UNDERSCORE_RANGES = "_\uff3f";
  var EN_CJK_ALPHANUM_CHARSET = "(?=[" + UNICODE_LETTER_CATEGORY_RANGES + UNICODE_MARK_CATEGORY_RANGES + UNICODE_DECIMAL_DIGIT_CATEGORY_RANGES + "])[" + UNICODE_CJK_RANGES + "]";
  var EN_CJK_ALPHANUM_REGEX = RegExp(EN_CJK_ALPHANUM_CHARSET);
  var EN_WORD_BOUNDARY_CHARSET = "(?:[^" + UNICODE_LETTER_CATEGORY_RANGES + UNICODE_MARK_CATEGORY_RANGES + UNICODE_DECIMAL_DIGIT_CATEGORY_RANGES + "]|[" + UNICODE_CJK_RANGES + "])";
  var STARTSWITH_EN_WORD_BOUNDARY_REGEX = RegExp("^" + EN_WORD_BOUNDARY_CHARSET);
  var ENDSWITH_EN_WORD_BOUNDARY_REGEX = RegExp(EN_WORD_BOUNDARY_CHARSET + "$");
  var EN_WORD_DELIMITER_CHARSET = "[^" + UNICODE_ALPHANUM_RANGES + UNDERSCORE_RANGES + "]";
  var EN_WORD_DELIMITER_REGEX = RegExp(EN_WORD_DELIMITER_CHARSET);
  var ONE_OR_MORE_EN_WORD_DELIMITER_PATTERN = EN_WORD_DELIMITER_CHARSET + "+";
  var ZERO_OR_MORE_EN_WORD_DELIMITER_PATTERN = EN_WORD_DELIMITER_CHARSET + "*";
  var EN_STOPWORDS = ["a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
  var EN_STOPWORDS_REGEX = RegExp("^(" + EN_STOPWORDS.join("|") + ")$", "i");
  searchapi.getNoteSearchRegex = function(rawSearchTerm, caseSensitive) {
    var searchTerm = rawSearchTerm.trim();
    var prefixMatch = /\*$/.test(searchTerm);
    searchTerm = prefixMatch ? searchTerm.substring(0, searchTerm.length - 1) : searchTerm;
    if (searchTerm.length <= 0) {
      return null;
    }
    if (EN_STOPWORDS_REGEX.test(searchTerm)) {
      return null;
    }
    var pattern = searchTerm;
    var newValue = [];
    var prevCharDelimeter = false;
    var prevCharCJK = false;
    for (var s = 0; s < pattern.length; s++) {
      var character = pattern[s];
      if (isCharCJKAlphanum(character)) {
        if (prevCharCJK) {
          newValue.push(ZERO_OR_MORE_EN_WORD_DELIMITER_PATTERN);
        }
        newValue.push(character);
        prevCharDelimeter = false;
        prevCharCJK = true;
      } else {
        if (isCharWordDelimiter(character)) {
          if (!prevCharDelimeter) {
            newValue.push(ONE_OR_MORE_EN_WORD_DELIMITER_PATTERN);
          }
          prevCharDelimeter = true;
          prevCharCJK = false;
        } else {
          if (prevCharCJK) {
            newValue.push(ZERO_OR_MORE_EN_WORD_DELIMITER_PATTERN);
          }
          var item = DIACRITICMAP[character.toLowerCase()];
          if (item) {
            newValue.push(item);
          } else {
            newValue.push(character);
          }
          prevCharDelimeter = false;
          prevCharCJK = false;
        }
      }
    }
    pattern = newValue.join("");
    pattern = pattern.replace(/\s/g, "\\s");
    pattern = "(" + pattern + ")";
    var groupIdxForHighlight = 1;
    if (!startsWithWordBoundary(searchTerm)) {
      pattern = "(^|" + EN_WORD_BOUNDARY_CHARSET + ")" + pattern;
      groupIdxForHighlight++;
    }
    if (!prefixMatch && !endsWithWordBoundary(searchTerm)) {
      pattern = pattern + "(?:" + EN_WORD_BOUNDARY_CHARSET + "|$)";
    }
    return {regex:new RegExp(pattern, caseSensitive ? "g" : "gi"), getTextRange:function(m) {
      var startIdx = m.index;
      var endIdx = startIdx;
      for (var idx = 1; idx <= groupIdxForHighlight; idx++) {
        startIdx = endIdx;
        endIdx = startIdx + m[idx].length;
      }
      return {start:startIdx, end:endIdx};
    }};
  };
  searchapi.getFindInNoteRegex = function(searchTerm, caseSensitive) {
    var pattern = [searchTerm].map(function(word) {
      if (word instanceof RegExp) {
        return word.source;
      }
      return word.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&").replace(/\s/g, "\\s");
    });
    return {regex:new RegExp(pattern, caseSensitive ? "g" : "gi"), getTextRange:function(m, regex) {
      return {start:m.index, end:regex.lastIndex};
    }};
  };
  var isCharCJKAlphanum = function(character) {
    return EN_CJK_ALPHANUM_REGEX.test(character);
  };
  var isCharWordDelimiter = function(character) {
    return EN_WORD_DELIMITER_REGEX.test(character);
  };
  var startsWithWordBoundary = function(sentence) {
    return STARTSWITH_EN_WORD_BOUNDARY_REGEX.test(sentence);
  };
  var endsWithWordBoundary = function(sentence) {
    return ENDSWITH_EN_WORD_BOUNDARY_REGEX.test(sentence);
  };
})();
goog.provide("uno.commands.Find");
goog.require("uno.commands.searchapi");
goog.require("goog.functions");
goog.require("goog.object");
goog.require("goog.debug.Logger");
goog.require("goog.iter");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.range");
goog.require("uno.util.zoomscale");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Find");
  var util = uno.util;
  var Find = uno.commands.Find = function() {
    uno.BasePlugin.call(this, log.getName());
    this.current = {hasMore:false, matches:[], index:-1, term:null, regex:null};
  };
  goog.inherits(Find, uno.BasePlugin);
  Find.NEXT = "next";
  Find.PREV = "prev";
  Find.FIRST = "first";
  Find.LAST = "last";
  Find.ALL = "all";
  Find.CLEAR = "clear";
  Find.prototype.isSupportedCommand = function(command) {
    return command === "find";
  };
  Find.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Find.prototype.queryCommandValue = function(command, rawOptions) {
    this.options = Object.assign({caseSensitive:false}, mergeOptions(this.editor.config.find, rawOptions || this.options));
    var options = this.options;
    var current = this.current;
    var result = {limit:options.limit, hasMore:current.hasMore, count:current.matches.length, items:current.matches, index:current.index};
    if (options.value) {
      if (typeof options.value === "string" && options.value.length && options.limit) {
        var getNoteSearchRegex = uno.commands.searchapi.getNoteSearchRegex;
        var getFindInNoteRegex = uno.commands.searchapi.getFindInNoteRegex;
        var searchApi = options.noteSearchMatching ? getNoteSearchRegex(options.value, options.caseSensitive) : getFindInNoteRegex(options.value, options.caseSensitive);
        var searchElements = document.querySelectorAll(options.selector);
        var matches = [];
        var regexResult;
        Array.prototype.forEach.call(searchElements, function(searchElement) {
          var searchRange = goog.dom.Range.createFromNodeContents(searchElement);
          var textNodes = textNodesFor(searchRange);
          var rawText = searchRange.getText();
          var offset = 0;
          var boundingBoxes;
          while ((regexResult = searchApi.regex.exec(rawText)) && regexResult && matches.length < options.limit) {
            var textRange = searchApi.getTextRange(regexResult, searchApi.regex);
            searchApi.regex.lastIndex = textRange.end;
            var boundingNodes = getBoundingNodes(textNodes, textRange.start, textRange.end, offset);
            boundingBoxes = getBoundingBoxesFromRange(boundingNodes, options.includeRangeInfo);
            offset = boundingNodes.offset;
            if (boundingBoxes) {
              var scrollTop = util.dom.scrollTop(document.body);
              if (util.dom.isBoundingBoxOnScreen(boundingBoxes[0].top - scrollTop, boundingBoxes[0].bottom - scrollTop)) {
                current.index = matches.length;
              }
              matches.push(boundingBoxes);
            }
          }
        });
        current.hasMore = !!regexResult;
        current.matches = matches;
        current.term = options.value;
        current.regex = searchApi.regex;
        current.index = current.index > -1 ? current.index : 0;
      }
      result = {limit:options.limit, hasMore:current.hasMore, count:current.matches.length, items:current.matches, index:current.index};
    }
    if (options.excludeMatches) {
      delete result.items;
    }
    return result;
  };
  function mergeOptions(configOptions, options) {
    var parsedOptions = {};
    var defaultOptions = {limit:100, excludeMatches:false, selector:"en-note", noteSearchMatching:false, includeRangeInfo:false};
    goog.object.extend(parsedOptions, defaultOptions || {});
    goog.object.extend(parsedOptions, configOptions || {});
    goog.object.extend(parsedOptions, options || {});
    parsedOptions.limit = isNaN(parsedOptions.limit) || parsedOptions.limit < 0 ? 100 : parseInt(parsedOptions.limit, 10);
    parsedOptions.selector = parsedOptions.selector && typeof parsedOptions.selector === "string" ? parsedOptions.selector : "en-note";
    return parsedOptions;
  }
  function textNodesFor(range) {
    var textNodesArray = [];
    var startIndex = 0;
    goog.iter.forEach(range, function(node, notUsed, element) {
      if (node.nodeType === Node.TEXT_NODE) {
        var text = node.nodeValue;
        var endIndex = startIndex + text.length;
        textNodesArray[startIndex] = {wordOffsetInTextNode:0, node:node, text:text, startIndex:startIndex, endIndex:endIndex};
        startIndex = endIndex;
      }
    });
    return textNodesArray;
  }
  function getBoundingNodes(textNodes, start, end, offset) {
    if (!textNodes) {
      return {offset:0};
    }
    offset = offset || 0;
    var nodes = textNodes.slice(offset);
    var startNode = null;
    var endNode = null;
    for (var i in nodes) {
      var node = nodes[parseInt(i)];
      if (node.startIndex <= start) {
        startNode = node;
      }
      if (node.endIndex >= end) {
        endNode = node;
      }
      if (startNode && endNode) {
        break;
      }
    }
    if (startNode && endNode) {
      return {offset:startNode.startIndex, startNode:startNode.node, startIndex:startNode.startIndex, startOffset:start - startNode.startIndex, endNode:endNode.node, endIndex:endNode.endIndex, endOffset:end - endNode.startIndex, string:[startNode.text, endNode.text].join(" "), length:end - start};
    }
  }
  function getBoundingBoxesFromRange(boundingNodes, includeRangeInfo) {
    if (!boundingNodes || !boundingNodes.startNode || !boundingNodes.endNode) {
      return;
    }
    var elementRange = goog.dom.Range.createFromNodes(boundingNodes.startNode, boundingNodes.startOffset, boundingNodes.endNode, boundingNodes.endOffset);
    var boundingBoxes = util.range.getBoundingBoxesFromRange(elementRange.getBrowserRangeObject());
    if (boundingBoxes && boundingBoxes.length) {
      var adjustedScroll = util.dom.scrollTop(document.body);
      boundingBoxes = boundingBoxes.map(function(boundingBox) {
        if (boundingBox) {
          boundingBox = util.zoomscale.normalizeRect(boundingBox);
          boundingBox.top = adjustedScroll + boundingBox.top;
          boundingBox.string = boundingNodes.string;
          boundingBox.length = boundingNodes.length;
          boundingBox.from = boundingNodes.startIndex;
          boundingBox.to = boundingNodes.endIndex;
        }
        if (includeRangeInfo) {
          boundingBox.rangeInfo = boundingNodes;
        }
        return boundingBox;
      });
    }
    return boundingBoxes;
  }
})();
goog.provide("uno.commands.Focus");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Focus");
  var util = uno.util;
  var Focus = uno.commands.Focus = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Focus, uno.BasePlugin);
  Focus.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Focus.prototype.isSupportedCommand = function(command) {
    return command === "focus";
  };
  Focus.prototype.execCommand = function(command, value) {
    if (this.editor.readOnly) {
      return false;
    }
    var opt = {force:false, pos:"top", scroll:false};
    goog.object.extend(opt, value || {});
    this.editor.enterEditMode(true);
    this.editor.focus();
    if (opt.force) {
      if (opt.pos === "top") {
        this.editor.placeCursorAtStart();
      } else {
        if (opt.pos === "bottom") {
          this.editor.placeCursorAtEnd();
        }
      }
    }
    if (opt.scroll) {
      util.range.scrollSelectionIntoView(this.editor);
    }
    return true;
  };
  Focus.prototype.queryCommandValue = function() {
    return this.editor.isFocused();
  };
})();
goog.provide("uno.commands.FontSize");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.editor.Command");
goog.require("goog.functions");
goog.require("goog.style");
goog.require("uno.BasePlugin");
goog.require("uno.util.font");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.FontSize");
  var util = uno.util;
  var ZERO_WIDTH_SPACE = uno.defs.unicode.ZERO_WIDTH_SPACE;
  var FontSize = uno.commands.FontSize = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(FontSize, uno.BasePlugin);
  FontSize.prototype.isSupportedCommand = function(command) {
    return command === "fontsize";
  };
  FontSize.prototype.activeOnUneditableFields = goog.functions.TRUE;
  FontSize.prototype.execCommand = function(command, size) {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var sizeValue = util.font.prepareSize(size);
    if (range.isCollapsed()) {
      this.setFontSizeCollapsed(sizeValue, range);
    } else {
      this.editor.dispatchBeforeChange();
      this.setFontSizeExpanded(sizeValue, range);
      this.editor.dispatchChange();
      this.editor.dispatchStyleChange();
    }
    return true;
  };
  FontSize.prototype.queryCommandValue = function() {
    var range = this.editor.getRange();
    if (!range) {
      return "";
    }
    var startNode = range.getStartNode();
    var startEl = startNode.nodeType === goog.dom.NodeType.TEXT ? goog.dom.getParentElement(startNode) : startNode;
    var size = util.font.getSize(startEl);
    return size.toString();
  };
  FontSize.prototype.setFontSizeCollapsed = function(size, range) {
    var node = range.getStartNode();
    var container = range.getContainerElement();
    var fontEl;
    var lineEmpty = util.dom.isEmpty(range.getStartNode());
    if (container.tagName === "FONT" && node.textContent.split(ZERO_WIDTH_SPACE).join("").length === 0) {
      fontEl = container;
    } else {
      this.editor.execCommand(goog.editor.Command.FONT_SIZE, 1);
      document.execCommand("inserttext", false, ZERO_WIDTH_SPACE);
      range = this.editor.getRange();
      if (lineEmpty) {
        var br = goog.dom.createDom("br");
        range.insertNode(br);
        range = this.editor.getRange();
      }
      fontEl = range.getContainerElement();
    }
    util.font.normalize(fontEl, size);
  };
  FontSize.prototype.setFontSizeExpanded = function(size, range) {
    var fontEls;
    this.editor.execCommand(goog.editor.Command.FONT_SIZE, 1);
    range = this.editor.getRange();
    fontEls = document.querySelectorAll("font[size]");
    goog.array.forEach(fontEls, function(fontEl) {
      if (range.containsNode(fontEl, true)) {
        util.font.normalizeFontSize(fontEl, size);
      }
    });
  };
})();
goog.provide("uno.commands.ForeColor");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.EditorMultiRange");
goog.require("uno.util.font");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.ForeColor");
  var util = uno.util;
  var ForeColor = uno.commands.ForeColor = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(ForeColor, uno.BasePlugin);
  ForeColor.prototype.activeOnUneditableFields = goog.functions.TRUE;
  ForeColor.prototype.isSupportedCommand = function(command) {
    return command === "forecolor";
  };
  ForeColor.prototype.execCommand = function(command, color) {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var isCollapsed = range.isCollapsed();
    if (!isCollapsed) {
      this.editor.dispatchBeforeChange();
    }
    this.editor.execCommand(goog.editor.Command.FONT_COLOR, color);
    var container = range.getContainerElement();
    var fontAnchors = container.querySelectorAll("font a");
    for (var i = 0; i < fontAnchors.length; i++) {
      goog.style.setStyle(fontAnchors[i], "color", color);
    }
    if (!isCollapsed) {
      this.editor.dispatchChange();
    }
    this.editor.dispatchStyleChange();
    return true;
  };
  ForeColor.prototype.queryCommandValue = function() {
    var range = this.editor.getRange();
    if (!range) {
      return "";
    }
    var startNode = range.getStartNode();
    var startEl = startNode.nodeType === goog.dom.NodeType.TEXT ? goog.dom.getParentElement(startNode) : startNode;
    var color = util.font.getColor(startEl) || "rgb(0, 0, 0)";
    return color.toString();
  };
})();
goog.provide("uno.commands.ForwardDelete");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.ForwardDelete");
  var ForwardDelete = uno.commands.ForwardDelete = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ForwardDelete, uno.BasePlugin);
  ForwardDelete.prototype.isSupportedCommand = function(command) {
    return command === "forwarddelete";
  };
  ForwardDelete.prototype.queryCommandValue = function(command) {
    return document.queryCommandValue(command);
  };
  ForwardDelete.prototype.execCommand = function(command, value) {
    this.editor.execCommand("delete", value, {forward:true}, true);
  };
})();
goog.provide("uno.commands.Highlight");
goog.require("goog.debug.Logger");
goog.require("goog.editor.Command");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
(function() {
  var util = uno.util;
  var log = goog.debug.Logger.getLogger("uno.commands.Highlight");
  var highlightBackgroundColor = uno.defs.highlight.COLOR;
  var highlightPlaceholder = "rgb(255, 255, 255)";
  var Highlight = uno.commands.Highlight = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(Highlight, uno.BasePlugin);
  Highlight.prototype.isSupportedCommand = function(command) {
    return command === "highlight";
  };
  Highlight.prototype.execCommand = function() {
    var multirange = this.editor.multirange;
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var highlighted = this.editor.context.style.state.highlight;
    this.editor.dispatchBeforeChange();
    document.execCommand("backColor", null, highlighted ? highlightPlaceholder : highlightBackgroundColor);
    cleanupHighlight([range.getContainerElement()], range);
    if (!multirange.isInvoking() || multirange.isLastInvokedRange()) {
      this.editor.dispatchStyleChange({state:{highlight:!highlighted}, value:{}, enabled:{}});
    }
    this.editor.dispatchChange();
    return true;
  };
  Highlight.prototype.queryCommandValue = function() {
    var range = this.editor.getRange();
    var state = document.queryCommandValue("backColor");
    if (!range) {
      return false;
    }
    var startNode = range.getStartNode();
    var endNode = range.getEndNode();
    if (range && range.isCollapsed()) {
      if (startNode.nodeType === Node.TEXT_NODE) {
        return highlightBackgroundColor === state;
      }
    }
    if (highlightBackgroundColor === state) {
      return true;
    }
    var container = range.getContainerElement();
    var nodes = [];
    if (container === startNode && container === endNode) {
      nodes.push(container);
    } else {
      Array.prototype.forEach.call(container.childNodes || [], function(node) {
        if (range.containsNode(node, true) || node.contains(startNode) || node.contains(endNode)) {
          nodes.push(node);
        }
      });
    }
    return isHighlighted(range, nodes);
  };
  Highlight.prototype.queryCommandEnabled = goog.functions.TRUE;
  function cleanupHighlight(nodes, range) {
    Array.prototype.forEach.call(nodes || [], function(node) {
      if (range.containsNode(node, true)) {
        if (util.dom.isElementNode(node)) {
          if (node.style.backgroundColor === highlightPlaceholder) {
            node.style.backgroundColor = "";
          }
          if (node.childNodes) {
            cleanupHighlight(node.childNodes, range);
          }
        }
      }
    });
  }
  function isHighlighted(range, nodes) {
    if (!nodes) {
      return false;
    }
    var filteredNodes = Array.prototype.filter.call(nodes, function(node) {
      return range.containsNode(node, true);
    });
    if (filteredNodes.length === 0) {
      return false;
    }
    return Array.prototype.every.call(filteredNodes, function(node) {
      if (util.dom.isElementNode(node)) {
        var style = window.getComputedStyle(node);
        if (style.backgroundColor === highlightBackgroundColor) {
          return true;
        }
        if (["rgba(0, 0, 0, 0)", "rgb(255, 255, 255)"].indexOf(style.backgroundColor) > -1) {
          return isHighlighted(range, node.childNodes);
        }
      }
      return false;
    });
  }
})();
goog.provide("uno.commands.InsertHorizontalRule");
goog.require("goog.debug.Logger");
goog.require("goog.editor.Command");
goog.require("uno.util.dom");
goog.require("uno.util.table");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertHorizontalRule");
  var util = uno.util;
  var InsertHorizontalRule = uno.commands.InsertHorizontalRule = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(InsertHorizontalRule, uno.BasePlugin);
  InsertHorizontalRule.prototype.isSupportedCommand = function(command) {
    return command === "inserthorizontalrule";
  };
  InsertHorizontalRule.prototype.activeOnUneditableFields = goog.functions.TRUE;
  InsertHorizontalRule.prototype.execCommandInternal = function() {
    this.editor.execCommand(goog.editor.Command.HORIZONTAL_RULE);
    return true;
  };
  InsertHorizontalRule.prototype.queryCommandValue = function() {
    return this.editor.queryCommandValue(goog.editor.Command.HORIZONTAL_RULE);
  };
  InsertHorizontalRule.prototype.queryCommandEnabled = function() {
    var range = this.editor.getRange();
    if (range) {
      if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CMD_HR, range)) {
        return false;
      }
    }
    return true;
  };
})();
goog.provide("uno.commands.InsertHtml");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertHtml");
  var InsertHtml = uno.commands.InsertHtml = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(InsertHtml, uno.BasePlugin);
  InsertHtml.prototype.isSupportedCommand = function(command) {
    return command === "inserthtml";
  };
  InsertHtml.prototype.execCommandInternal = function(command, html) {
    return this.editor.execCommand("paste", {type:"html", value:html});
  };
})();
goog.provide("uno.commands.InsertText");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertText");
  var InsertText = uno.commands.InsertText = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(InsertText, uno.BasePlugin);
  InsertText.prototype.isSupportedCommand = function(command) {
    return command === "inserttext";
  };
  InsertText.prototype.execCommandInternal = function(command, plainText) {
    return this.editor.execCommand("paste", {type:"plain", value:plainText});
  };
})();
goog.provide("uno.commands.InsertParagraph");
goog.require("goog.debug.Logger");
goog.require("goog.object");
goog.require("uno.BasePlugin");
goog.require("uno.util.todo");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertParagraph");
  var util = uno.util;
  var InsertParagraph = uno.commands.InsertParagraph = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(InsertParagraph, uno.BasePlugin);
  InsertParagraph.prototype.isSupportedCommand = function(command) {
    return command === "insertparagraph";
  };
  InsertParagraph.prototype.execCommandInternal = function(command, options) {
    options = options || {};
    var editor = this.editor;
    var range = editor.getRange();
    if (!range) {
      return false;
    }
    if (!range.isCollapsed()) {
      editor.execCommand("delete");
    }
    range = this.editor.getRange();
    var p = util.paragraph.for(range.getStartNode());
    range = this.editor.getRange();
    var node = range.getStartNode();
    var offset = range.getStartOffset();
    var isTextNode = util.dom.isTextNode(node);
    if (isTextNode && offset > 0 && offset < node.length) {
      node.splitText(offset);
    }
    util.styles.createPendingStyles(editor);
    var savedRange = range.saveUsingCarets();
    if (!goog.dom.contains(p, savedRange.getCaret(true))) {
      savedRange.removeCarets();
      return false;
    }
    var newp = goog.editor.node.splitDomTreeAt(savedRange.getCaret(true), savedRange.getCaret(true), p);
    if (!p.childNodes.length || !util.dom.isBr(goog.dom.getLastElementChild(p))) {
      p.appendChild(document.createElement("br"));
    }
    goog.dom.insertSiblingAfter(newp, p);
    newp.normalize();
    if (!newp.childNodes.length || !util.dom.isBr(goog.dom.getLastElementChild(newp))) {
      newp.appendChild(document.createElement("br"));
    }
    savedRange.restore().select();
    var hasPrevTodoItem = util.todo.all(p).length > 0;
    if (hasPrevTodoItem) {
      goog.array.forEach(newp.children, function(child) {
        if (util.dom.isEmpty(child)) {
          child.remove();
        }
      });
      if (node.parentElement && util.dom.isA(node.parentElement)) {
        editor.context.style.pendingStyles.state.underline = false;
        editor.context.style.pendingStyles.value.forecolor = editor.config.defaults.foreColor;
      }
    }
    if (!util.dom.isEmpty(newp) && !hasPrevTodoItem) {
      util.styles.clearPendingStyles(this.editor);
    }
    if (options.cursorPosition === "new" && newp.children.length > 0) {
      goog.dom.Range.createCaret(newp, 0).select();
    } else {
      if (options.cursorPosition === "original" && node) {
        goog.dom.Range.createCaret(node, isTextNode ? node.length : node.children.length).select();
      }
    }
    return true;
  };
})();
goog.provide("uno.commands.InsertTable");
goog.require("goog.debug.Logger");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.editor.range");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.table");
goog.require("uno.util.list");
goog.require("uno.util.paragraph");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertTable");
  var util = uno.util;
  var InsertTable = uno.commands.InsertTable = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(InsertTable, uno.BasePlugin);
  InsertTable.prototype.isSupportedCommand = function(command) {
    return command === "inserttable";
  };
  InsertTable.prototype.activeOnUneditableFields = goog.functions.TRUE;
  InsertTable.prototype.execCommandInternal = function(command, options) {
    var enTable = util.table.create(options);
    var range = this.editor.getRange();
    if (!range.isCollapsed()) {
      this.editor.execCommand("delete");
      range = this.editor.getRange();
    }
    if (!util.dom.isEmpty(util.paragraph.for(range.getStartNode()))) {
      this.editor.execCommand("insertparagraph", {cursorPosition:"original"});
      range = this.editor.getRange();
      if (!util.dom.isEmpty(util.paragraph.for(range.getStartNode()))) {
        this.editor.execCommand("insertparagraph", {cursorPosition:"new"});
      }
    }
    range = this.editor.getRange();
    range.insertNode(enTable);
    util.table.normalizeDOMPlacement(enTable);
    var targetBr = enTable.querySelector("td br");
    goog.editor.range.placeCursorNextTo(targetBr, true);
    return true;
  };
  InsertTable.prototype.queryCommandEnabled = function() {
    var range = this.editor.getRange();
    if (range == null) {
      return false;
    }
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.TABLE, range)) {
      return false;
    }
    return true;
  };
})();
goog.provide("uno.commands.InsertTableCol");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.table");
goog.require("uno.util.table.selection");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertTableCol");
  var util = uno.util;
  var InsertTableCol = uno.commands.InsertTableCol = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(InsertTableCol, uno.BasePlugin);
  InsertTableCol.prototype.isSupportedCommand = function(command) {
    return command === "inserttablecol";
  };
  InsertTableCol.prototype.execCommandInternal = function(command, value) {
    var enTable = util.table.getActive();
    var cell = util.table.getActiveCell();
    var retVal = false;
    var index = -1;
    if (enTable && cell) {
      index = util.table.colIndex(cell, value === "after");
      retVal = util.table.insertColumns(enTable, index);
      if (retVal && util.table.selection.isActive(enTable)) {
        util.table.selection.create(enTable, this.editor.multirange);
      }
    } else {
      cell = util.table.cellForStructureChange(this.editor.getRange());
      if (cell) {
        var table = goog.dom.getAncestor(this.editor.getRange().getStartNode(), util.dom.isTable);
        index = util.table.colIndex(cell, value === "after");
        retVal = util.table.insertColumns(table, index);
      }
    }
    return retVal;
  };
  InsertTableCol.prototype.queryCommandEnabled = function() {
    return !!util.table.cellForStructureChange(this.editor.getRange());
  };
})();
goog.provide("uno.commands.InsertTableRow");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.table");
goog.require("uno.util.table.selection");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertTableRow");
  var util = uno.util;
  var InsertTableRow = uno.commands.InsertTableRow = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(InsertTableRow, uno.BasePlugin);
  InsertTableRow.prototype.isSupportedCommand = function(command) {
    return command === "inserttablerow";
  };
  InsertTableRow.prototype.execCommandInternal = function(command, value) {
    var enTable = util.table.getActive();
    var cell = util.table.getActiveCell();
    var retVal = false;
    var index = -1;
    if (enTable && cell) {
      index = util.table.rowIndex(cell, value === "after");
      retVal = util.table.insertRows(enTable, index);
      if (retVal && util.table.selection.isActive(enTable)) {
        util.table.selection.create(enTable, this.editor.multirange);
      }
    } else {
      cell = util.table.cellForStructureChange(this.editor.getRange());
      if (cell) {
        var table = goog.dom.getAncestor(this.editor.getRange().getStartNode(), util.dom.isTable);
        index = util.table.rowIndex(cell, value === "after");
        retVal = util.table.insertRows(table, index);
      }
    }
    return retVal;
  };
  InsertTableRow.prototype.queryCommandEnabled = function() {
    return !!util.table.cellForStructureChange(this.editor.getRange());
  };
})();
goog.provide("uno.util.fullsize");
goog.require("uno.util.img");
(function() {
  var util = uno.util;
  util.fullsize.preserve = function(editor, bounds) {
    document.body.classList.add("fullsize");
    editor.execCommand("active", false);
    var field = editor.field;
    field.style.position = "fixed";
    field.style.overflow = "hidden";
    field.style.top = bounds.top + "px";
    field.style.left = bounds.left + "px";
    field.style.width = bounds.width + "px";
    field.style.height = bounds.height + "px";
    util.img.layoutResizer();
    field.scrollTop = editor.context.fullsize.scrollY;
  };
  util.fullsize.restore = function(editor) {
    var field = editor.field;
    field.style.position = "";
    field.style.overflow = "";
    field.style.top = "";
    field.style.left = "";
    field.style.width = "";
    field.style.height = "";
    document.scrollingElement.scrollTop = editor.context.fullsize.scrollY;
    util.img.layoutResizer();
    setTimeout(function() {
      document.body.classList.remove("fullsize");
      editor.execCommand("active", true);
      editor.execCommand("focus", true);
    }, 10);
  };
})();
goog.provide("uno.components.Preview");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.events");
goog.require("goog.events.KeyCodes");
goog.require("uno.util.dom");
goog.require("uno.util.zoomscale");
(function() {
  var Preview = uno.components.Preview = function(opt) {
    this.items = [];
    this.index_ = -1;
    this.state_ = 0;
    this.resizeTimer_ = null;
    this.lblFilename_ = goog.dom.createDom("span", {class:"lbl-filename"});
    this.btnClose_ = goog.dom.createDom("button", {class:"btn-close"});
    this.btnPrev_ = goog.dom.createDom("button", {class:"btn-prev"});
    this.btnNext_ = goog.dom.createDom("button", {class:"btn-next"});
    this.container_ = goog.dom.createDom("div", {class:"container"});
    var toolbar = goog.dom.createDom("div", {class:"toolbar"}, this.lblFilename_);
    var children = [toolbar, this.btnPrev_, this.btnNext_, this.btnClose_, this.container_];
    this.element = goog.dom.createDom("div", {class:"en-preview"}, children);
    opt = opt || {};
    this.onClose = typeof opt.onClose === "function" ? opt.onClose : null;
    this.onChange = typeof opt.onChange === "function" ? opt.onChange : null;
    this.animated = opt.animated === false ? false : true;
    this.translucent = opt.translucent === false ? false : true;
    goog.events.listen(this.element, "click", handleClick.bind(this));
    goog.events.listen(document.body, "keydown", handleKey.bind(this));
    goog.events.listen(window, "resize", handleResize.bind(this));
  };
  Preview.Transition = {PRESENT:1, DISMISS:2};
  Preview.State = {ACTIVE:1 << 0, ZOOMABLE:1 << 1, FULLSIZE:1 << 2, RESIZED:1 << 3};
  Object.defineProperty(Preview.prototype, "state", {get:function() {
    return this.state_;
  }});
  Preview.prototype.present = function(items, initialItem) {
    this.items = items;
    this.state_ = 0;
    if (initialItem && items.indexOf(initialItem) > -1) {
      this.index_ = items.indexOf(initialItem);
    } else {
      if (items.length > 0) {
        this.index_ = 0;
      } else {
        this.index_ = -1;
      }
    }
    this.element.classList.toggle("nonav", items.length <= 1);
    var self = this;
    this.renderItem_(this.items[this.index_], true).then(function(img) {
      return self.transitionTo_(Preview.Transition.PRESENT, img, initialItem);
    }).then(function() {
      self.state_ |= Preview.State.ACTIVE;
      self.updateZoomIndicator_();
    });
  };
  Preview.prototype.dismiss = function() {
    this.state_ &= ~Preview.State.ACTIVE;
    var img = this.container_.children[0];
    var src = img.getAttribute("src");
    var reference = img.getAttribute("data-reference");
    var origin = goog.array.find(this.items, function(node) {
      return node.getAttribute("src") === src && node.getAttribute("data-reference") === reference;
    });
    if (origin && !(this.state_ & Preview.State.RESIZED)) {
      this.transitionTo_(Preview.Transition.DISMISS, img, origin).then(this.onClose);
    } else {
      this.onClose();
    }
  };
  Preview.prototype.cleanup = function() {
    this.container_.innerHTML = "";
    this.element.remove();
    this.element.classList.remove("animated");
    this.element.classList.remove("presented");
    this.element.classList.remove("nonav");
    this.element.classList.remove("fullsize");
    this.element.classList.remove("zoomable");
    this.element.classList.remove("opaque");
  };
  Preview.prototype.go = function(index) {
    if (!this.items.length || index === this.index_) {
      return;
    }
    this.index_ = Math.max(Math.min(this.items.length - 1, index), 0);
    var item = this.items[this.index_];
    var self = this;
    this.renderItem_(item).then(function() {
      self.updateZoomIndicator_();
      self.onChange(item);
    });
  };
  Preview.prototype.next = function() {
    this.go(this.index_ + 1 >= this.items.length ? 0 : this.index_ + 1);
  };
  Preview.prototype.previous = function() {
    this.go(this.index_ === 0 ? this.items.length - 1 : this.index_ - 1);
  };
  Preview.prototype.zoomIn = function() {
    this.state_ |= Preview.State.FULLSIZE;
    this.element.classList.add("fullsize");
  };
  Preview.prototype.zoomOut = function() {
    this.state_ &= ~Preview.State.FULLSIZE;
    this.element.classList.remove("fullsize");
  };
  Preview.prototype.transitionTo_ = function(direction, item, origin) {
    var ib = item.getBoundingClientRect();
    var ob = origin.getBoundingClientRect();
    var presenting = direction === Preview.Transition.PRESENT;
    var zoom = uno.util.zoomscale.getZoom();
    var translate = uno.util.dom.isVisibleInView(origin);
    var self = this;
    var x = ob.left * zoom - ib.left;
    var y = ob.top * zoom - ib.top;
    var sx = ob.width * zoom / ib.width;
    var sy = ob.height * zoom / ib.height;
    var itemOpacity = 1;
    var itemTransform = "translate3d(0, 0, 0) scale(1, 1)";
    var originOpacity = 0;
    var originTransform = itemTransform;
    if (translate) {
      originOpacity = 1;
      originTransform = ["translate3d(" + x + "px, " + y + "px, 0)", "scale(" + sx + ", " + sy + ")"].join(" ");
    }
    item.style.transform = presenting ? originTransform : itemTransform;
    item.style.opacity = presenting ? originOpacity : itemOpacity;
    item.style.visibility = "";
    return new Promise(function(resolve) {
      var safetyTimer = null;
      var timerDuration = 350;
      var resolveHandler = function() {
        clearTimeout(safetyTimer);
        if (!presenting) {
          self.element.classList.remove("animated");
        }
        resolve();
      };
      setTimeout(function() {
        if (self.animated) {
          safetyTimer = setTimeout(function() {
            goog.events.unlisten(item, "transitionend", resolveHandler);
            resolveHandler();
          }, timerDuration);
          goog.events.listenOnce(item, "transitionend", resolveHandler);
        } else {
          resolve();
        }
        if (presenting) {
          if (self.animated) {
            self.element.classList.add("animated");
          }
          if (!self.translucent) {
            self.element.classList.add("opaque");
          }
          self.element.classList.add("presented");
          item.style.transform = itemTransform;
          item.style.opacity = itemOpacity;
        } else {
          self.element.classList.remove("presented");
          item.style.transform = originTransform;
          item.style.opacity = originOpacity;
        }
      }, 10);
    });
  };
  Preview.prototype.updateZoomIndicator_ = function() {
    var img = this.container_.children[0];
    if (!img || img.naturalWidth <= window.innerWidth && img.naturalHeight <= window.innerHeight) {
      this.state_ &= ~Preview.State.ZOOMABLE;
      this.element.classList.remove("zoomable");
    } else {
      this.state_ |= Preview.State.ZOOMABLE;
      this.element.classList.add("zoomable");
    }
  };
  Preview.prototype.renderItem_ = function(node, hiddenOnRender) {
    var self = this;
    var img = goog.dom.createDom("img", {src:node.getAttribute("src"), "data-reference":node.getAttribute("data-reference")});
    var title = createFilename(node);
    if (hiddenOnRender === true) {
      img.style.visibility = "hidden";
    }
    return new Promise(function(resolve) {
      var fn = function() {
        resolve(img);
      };
      goog.events.listenOnce(img, "load", fn);
      goog.events.listenOnce(img, "error", fn);
      self.lblFilename_.textContent = title;
      self.container_.innerHTML = "";
      self.container_.appendChild(img);
      self.element.classList.remove("zoomable");
    });
  };
  function createFilename(node) {
    var title = node.getAttribute("data-title") || node.getAttribute("data-filename") || null;
    if (title) {
      return title;
    }
    var ext;
    switch(node.getAttribute("data-type")) {
      case "image/jpeg":
      case "image/jpg":
        ext = ".jpg";
        break;
      case "image/png":
        ext = ".png";
        break;
      case "image/tiff":
        ext = ".tiff";
        break;
      case "image/bmp":
        ext = ".bmp";
        break;
      case "image/gif":
        ext = ".gif";
        break;
      default:
        ext = "";
    }
    return "Untitled" + ext;
  }
  function handleResize() {
    if (!(this.state_ & Preview.State.ACTIVE)) {
      return;
    }
    clearTimeout(this.resizeTimer_);
    this.resizeTimer_ = setTimeout(this.updateZoomIndicator_.bind(this), 250);
    if (this.state_ & Preview.State.RESIZED) {
      return;
    }
    this.state_ |= Preview.State.RESIZED;
    this.element.classList.add("opaque");
  }
  function handleClick(evt) {
    if (!(this.state_ & Preview.State.ACTIVE)) {
      return;
    }
    evt.preventDefault();
    var target = evt.target;
    var isFullsize = this.state_ & Preview.State.FULLSIZE;
    var isZoomable = this.state_ & Preview.State.ZOOMABLE;
    if (isFullsize && this.btnClose_ === target || !isFullsize && [this.btnClose_, this.container_, this.element].indexOf(target) > -1) {
      this.dismiss();
    } else {
      if (!isFullsize && this.btnNext_ === target) {
        this.next();
      } else {
        if (!isFullsize && this.btnPrev_ === target) {
          this.previous();
        } else {
          if (isFullsize && this.btnClose_ !== target) {
            this.zoomOut();
          } else {
            if (isZoomable && this.container_.children[0] === target) {
              this.zoomIn();
            }
          }
        }
      }
    }
  }
  function handleKey(evt) {
    if (!(this.state_ & Preview.State.ACTIVE)) {
      return;
    }
    var KeyCodes = goog.events.KeyCodes;
    var code = evt.keyCode;
    var isFullsize = this.state_ & Preview.State.FULLSIZE;
    if (code === KeyCodes.ESC) {
      this.dismiss();
      evt.preventDefault();
    } else {
      if (!isFullsize && [KeyCodes.RIGHT, KeyCodes.DOWN].indexOf(code) > -1) {
        this.next();
        evt.preventDefault();
      } else {
        if (!isFullsize && [KeyCodes.LEFT, KeyCodes.UP].indexOf(code) > -1) {
          this.previous();
          evt.preventDefault();
        }
      }
    }
  }
})();
goog.provide("uno.util.preview.generic");
(function() {
  var generic = uno.util.preview.generic;
  generic.getOptions = function() {
    return {};
  };
})();
goog.provide("uno.util.preview.win");
(function() {
  var win = uno.util.preview.win;
  win.getOptions = function() {
    return {animated:false, translucent:false};
  };
})();
goog.provide("uno.util.preview");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("uno.components.Preview");
goog.require("uno.util.dom");
goog.require("uno.util.img");
goog.require("uno.util.preview.generic");
goog.require("uno.util.preview.win");
goog.require("uno.util.table");
goog.require("uno.util.tools");
(function() {
  var util = uno.util;
  var client = uno.util.preview.generic;
  var preview = null;
  var clickNode = null;
  util.preview.setClient = function(clientName) {
    client = util.preview[clientName] || client;
  };
  util.preview.fullsizeOpened = function(editor, opt) {
    var field = editor.field;
    var items = getItems(field);
    var node = clickNode || findImageByHash(opt.hash, field);
    if (!editor || !node || !items.length) {
      return false;
    }
    if (!preview) {
      preview = new uno.components.Preview(Object.assign({onClose:function() {
        editor.closeFullSize("preview");
      }, onChange:function(img) {
        handleOnChange(img, editor);
      }}, client.getOptions()));
    }
    if (!preview.element.parentNode) {
      util.tools.append(preview.element);
    }
    setTimeout(function() {
      preview.present(items, node);
    }, 0);
    return true;
  };
  util.preview.fullsizeClosed = function(editor) {
    if (!isVisible()) {
      return;
    }
    preview.cleanup();
  };
  util.preview.requestOpen = function(editor, node) {
    if (!node) {
      return;
    }
    clickNode = node;
    editor.openFullSize("preview");
  };
  function getItems(root) {
    var items = [].slice.call(root.querySelectorAll("img.en-media-image"));
    var diversity = true;
    if (items.length > 1) {
      var src = items[0].getAttribute("src");
      diversity = !goog.array.every(items, function(node) {
        return node.getAttribute("src") === src;
      });
    }
    return diversity ? items : [items[0]];
  }
  function isVisible() {
    return preview ? !!preview.element.parentNode : false;
  }
  function handleOnChange(img, editor) {
    util.img.setSelected(img);
    var field = editor.field;
    var scrollY = editor.context.fullsize.scrollY;
    var ib = img.getBoundingClientRect();
    var nb = field.getBoundingClientRect();
    var offset = 10;
    ib = {top:ib.top - offset, bottom:ib.bottom + offset, height:ib.height + offset * 2};
    var direction = null;
    var isTaller = ib.height > nb.height;
    if (ib.top < nb.top && ib.bottom < nb.bottom) {
      direction = "top";
    } else {
      if (ib.top > nb.top && ib.bottom > nb.bottom) {
        direction = "bottom";
      }
    }
    if (direction === "top" && !isTaller || direction === "bottom" && isTaller) {
      scrollY = field.scrollTop - (nb.top - ib.top);
      field.scrollTop = scrollY;
    } else {
      if (direction === "bottom" && !isTaller || direction === "top" && isTaller) {
        scrollY = field.scrollTop - (nb.bottom - ib.bottom);
        field.scrollTop = scrollY;
      }
    }
    util.table.scrollCellIntoView(goog.dom.getAncestor(img, util.dom.isTd));
  }
  function findImageByHash(hash, root) {
    if (!hash) {
      return null;
    }
    var nodes = util.resource.findByHash(hash, root);
    if (nodes.length > 0 && util.resource.isImage(nodes[0])) {
      return nodes[0];
    }
    return null;
  }
})();
goog.provide("uno.commands.FullSize");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.fullsize");
goog.require("uno.util.preview");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.FullSize");
  var util = uno.util;
  var FullSize = uno.commands.FullSize = function() {
    uno.BasePlugin.call(this, log.getName());
    this.utilOwners = {preview:util.preview, archive:uno.realtime.util.commenting};
  };
  goog.inherits(FullSize, uno.BasePlugin);
  FullSize.prototype.activeOnUneditableFields = goog.functions.TRUE;
  FullSize.prototype.isSupportedCommand = function(command) {
    return command === "fullsize";
  };
  FullSize.prototype.execCommand = function(command, value) {
    var state = this.editor.context.fullsize || {};
    var options = value || {};
    var action = options.action;
    var utilOwner = this.utilOwners[state.owner];
    if (!utilOwner) {
      log.warning("Fullsize is missing request owner.");
    } else {
      if (action === "open" && state.enabled) {
        log.warning("Fullsize is already opened, blocking redundat command.");
      } else {
        if (action === "close" && !state.enabled) {
          log.warning("Fullsize should be closed, blocking wrong command.");
        } else {
          if (action === "open") {
            util.fullsize.preserve(this.editor, options.bounds);
            if (utilOwner.fullsizeOpened(this.editor, options)) {
              this.editor.context.fullsize.pending = false;
              this.editor.context.fullsize.enabled = true;
              return true;
            }
            util.fullsize.restore(this.editor);
            this.editor.context.fullsize = {enabled:false};
          } else {
            if (action === "close") {
              utilOwner.fullsizeClosed(this.editor);
              util.fullsize.restore(this.editor);
              this.editor.context.fullsize = {enabled:false};
              return true;
            }
          }
        }
      }
    }
    return false;
  };
  FullSize.prototype.queryCommandEnabled = function(command, value) {
    var options = value || {};
    var state = this.editor.context.fullsize || {};
    var action = options.action;
    return action === "open" && !state.enabled && options.bounds && state.pending && this.utilOwners[state.owner] || action === "close" && state.enabled && state.pending;
  };
  FullSize.prototype.queryCommandValue = function() {
    return !!(this.editor.context.fullsize || {}).enabled;
  };
})();
goog.provide("uno.commands.MergeCells");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.table");
goog.require("uno.util.table.selection");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.MergeCells");
  var util = uno.util;
  var MergeCells = uno.commands.MergeCells = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(MergeCells, uno.BasePlugin);
  MergeCells.prototype.isSupportedCommand = function(command) {
    return command === "mergecells";
  };
  MergeCells.prototype.execCommandInternal = function(command, value) {
    var cell = util.table.getActiveCell();
    var cells = !util.table.selection.isActive() && cell ? [cell] : util.table.selection.getCells();
    var selected = util.table.selection.isActive();
    var enTable = util.table.getActive();
    var mergedCell, splitCells;
    if ((value === true || value === undefined) && util.table.mergeable(cells)) {
      util.table.selection.clear();
      mergedCell = util.table.mergeCells(cells);
      util.table.selection.create(enTable, this.editor.multirange, mergedCell);
    } else {
      if (!value && util.table.unmergeable(cells)) {
        util.table.selection.clear();
        splitCells = util.table.splitCells(cells);
        if (selected) {
          util.table.selection.create(enTable, this.editor.multirange, splitCells[0], splitCells[splitCells.length - 1]);
        }
      }
    }
    if (mergedCell || splitCells) {
      this.editor.dispatchStyleChange();
      return true;
    }
    return false;
  };
  MergeCells.prototype.queryCommandEnabled = function() {
    var selected = util.table.selection.isActive() || util.table.selection.isPending();
    var cell = util.table.getActiveCell();
    var cells = !selected && cell ? [cell] : util.table.selection.getCells();
    return util.table.unmergeable(cells) || util.table.mergeable(cells);
  };
  MergeCells.prototype.queryCommandValue = function() {
    var selected = util.table.selection.isActive() || util.table.selection.isPending();
    var cell = util.table.getActiveCell();
    var cells = !selected && cell ? [cell] : util.table.selection.getCells();
    return util.table.unmergeable(cells) && !util.table.mergeable(cells);
  };
})();
goog.provide("uno.commands.MigrateTable");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.MigrateTable");
  var util = uno.util;
  var MigrateTable = uno.commands.MigrateTable = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(MigrateTable, uno.BasePlugin);
  MigrateTable.prototype.isSupportedCommand = function(command) {
    return command === "migratetable";
  };
  MigrateTable.prototype.execCommandInternal = function(command, value) {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var table = null;
    var node = range.getStartNode();
    while (node && node.parentNode) {
      if (util.dom.isTable(node)) {
        table = node;
      }
      node = node.parentNode;
    }
    if (!table) {
      return false;
    }
    if (!range.isCollapsed()) {
      var startTd = goog.dom.getAncestor(range.getStartNode(), util.dom.isTd);
      var endTd = goog.dom.getAncestor(range.getEndNode(), util.dom.isTd);
      if (startTd !== endTd) {
        range.collapse(true);
      }
    }
    var savedRange = range.saveUsingCarets();
    if (!util.table.migrateToEnTable(table)) {
      return false;
    }
    savedRange.restore();
    return true;
  };
  MigrateTable.prototype.queryCommandEnabled = function() {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var table = null;
    var td = null;
    var enTable = goog.dom.getAncestor(range.getStartNode(), function(node) {
      if (util.dom.isTable(node)) {
        table = node;
      }
      if (util.dom.isTd(node)) {
        td = node;
      }
      return util.dom.isEntable(node);
    }, true);
    return !enTable && table && td;
  };
})();
goog.provide("uno.commands.Shutdown");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.util.dom");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Shutdown");
  var util = uno.util;
  var Shutdown = uno.commands.Shutdown = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Shutdown, uno.BasePlugin);
  Shutdown.prototype.isSupportedCommand = function(command) {
    return command === "shutdown";
  };
  Shutdown.prototype.execCommand = function() {
    log.info("Beginning non-realtime shutdown! NOTE LOCKED");
    this.editor.execCommand("active", false);
    this.editor.dispatchEvent({type:"shutdownComplete", code:"success"});
    return true;
  };
  Shutdown.prototype.queryCommandEnabled = goog.functions.TRUE;
})();
goog.provide("uno.commands.TableAlign");
goog.require("goog.debug.Logger");
goog.require("goog.style");
goog.require("uno.BasePlugin");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.TableAlign");
  var util = uno.util;
  var TableAlign = uno.commands.TableAlign = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TableAlign, uno.BasePlugin);
  TableAlign.prototype.isSupportedCommand = function(command) {
    return command === "tablealign";
  };
  TableAlign.prototype.execCommand = function(command, direction) {
    if (["left", "center", "right"].indexOf(direction) < 0) {
      log.warning("Saw unexpected alignment value", direction);
      direction = "left";
    }
    var table = util.table.getActive();
    if (!table) {
      return false;
    }
    this.editor.dispatchBeforeChange();
    util.table.setAlignment(table, direction);
    this.editor.dispatchChange();
    return true;
  };
  TableAlign.prototype.queryCommandValue = function() {
    var table = util.table.getActive();
    if (!table) {
      return "";
    }
    return util.table.getAlignment(table);
  };
  TableAlign.prototype.queryCommandEnabled = function() {
    return !!util.table.getActive();
  };
})();
goog.provide("uno.commands.TableBorderColor");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.style");
goog.require("uno.BasePlugin");
goog.require("uno.EditorMultiRange");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.TableBorderColor");
  var util = uno.util;
  var TableBorderColor = uno.commands.TableBorderColor = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(TableBorderColor, uno.BasePlugin);
  TableBorderColor.prototype.isSupportedCommand = function(command) {
    return command === "tablebordercolor";
  };
  TableBorderColor.prototype.execCommand = function(command, color) {
    color = color || "";
    var enTable = util.table.getActive();
    if (!enTable) {
      return false;
    }
    this.editor.dispatchBeforeChange();
    enTable.style.borderColor = color;
    goog.array.forEach(enTable.querySelectorAll("td"), function(cell) {
      cell.style.borderColor = color;
    });
    this.editor.dispatchChange();
    return true;
  };
  TableBorderColor.prototype.queryCommandValue = function() {
    var enTable = util.table.getActive();
    if (enTable) {
      var td = enTable.querySelector("td");
      return td ? goog.style.getComputedStyle(td, "borderColor") : "";
    }
    return "";
  };
  TableBorderColor.prototype.queryCommandEnabled = function() {
    return !!util.table.getActive();
  };
})();
goog.provide("uno.commands.TableBorderWidth");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.style");
goog.require("uno.BasePlugin");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.TableBorderWidth");
  var util = uno.util;
  var TableBorderWidth = uno.commands.TableBorderWidth = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TableBorderWidth, uno.BasePlugin);
  TableBorderWidth.prototype.isSupportedCommand = function(command) {
    return command === "tableborderwidth";
  };
  TableBorderWidth.prototype.execCommand = function(command, value) {
    var borderWidth = parseInt(value, 10);
    if (isNaN(borderWidth) || borderWidth < 0) {
      log.warning("Invalid value given to tableborderwidth: " + value);
      return false;
    }
    var enTable = util.table.getActive();
    if (!enTable) {
      return false;
    }
    this.editor.dispatchBeforeChange();
    var val = borderWidth + "px";
    enTable.style.borderWidth = val;
    goog.array.forEach(enTable.querySelectorAll("td"), function(cell) {
      cell.style.borderWidth = val;
    });
    this.editor.dispatchChange();
    return true;
  };
  TableBorderWidth.prototype.queryCommandValue = function() {
    var enTable = util.table.getActive();
    if (enTable) {
      var td = enTable.querySelector("td");
      var val = parseInt(td ? goog.style.getComputedStyle(td, "borderWidth") : "", 10);
      if (!isNaN(val)) {
        return "" + val;
      }
    }
    return "0";
  };
  TableBorderWidth.prototype.queryCommandEnabled = function() {
    return !!util.table.getActive();
  };
})();
goog.provide("uno.commands.TableCellColor");
goog.require("goog.color");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.EditorMultiRange");
goog.require("uno.defs");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.TableCellColor");
  var util = uno.util;
  var TableCellColor = uno.commands.TableCellColor = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(TableCellColor, uno.BasePlugin);
  TableCellColor.prototype.isSupportedCommand = function(command) {
    return command === "tablecellcolor";
  };
  TableCellColor.prototype.execCommandInternal = function(command, value) {
    var hexValue = goog.color.parse(value).hex;
    var isTransparent = hexValue === "#ffffff";
    var range = this.editor.getRange();
    var cells = util.table.cellsForRange(range);
    var colorPalette = ["#ffffff", "#eaeaea", "#d4d4d4", "#ddd1f3", "#f0d1f6", "#fbcfd6", "#fedec1", "#ffe697", "#cdedd8", "#cdeef0", "#cde6f9", "#ccd7ea", "#3f3f3f", "#737373", "#979797", "#8b65e0", "#c064d1", "#fc5356", "#fd7b39", "#ffc200", "#57b779", "#57bfc4", "#54a9e6", "#426bb3"];
    cells.forEach(function(cell) {
      var textColor = colorPalette.indexOf(hexValue) >= 12 ? "white" : "black";
      goog.dom.Range.createFromNodeContents(cell).select();
      this.editor.execCommand("forecolor", textColor);
      range.select();
      cell.style.background = "";
      if (isTransparent) {
        cell.style.backgroundColor = "";
        cell.style.borderColor = uno.defs.table.BORDER_COLOR;
      } else {
        cell.style.borderColor = util.table.darkenBorderColor(hexValue);
        cell.style.backgroundColor = hexValue;
      }
      this.editor.dispatchChange();
    }, this);
    return true;
  };
  TableCellColor.prototype.queryCommandValue = function() {
    var cells = util.table.cellsForRange(this.editor.getRange());
    if (!cells.length) {
      return "";
    }
    var style = cells[0].style;
    var color;
    if (style.backgroundColor) {
      try {
        color = goog.color.hexToRgbStyle(goog.color.parse(style.backgroundColor).hex);
      } catch (ex) {
        color = null;
        log.fine(ex.stack || ex);
      }
      return color != null ? color : "";
    }
    return "";
  };
  TableCellColor.prototype.queryCommandEnabled = function() {
    return !this.editor.multirange.isEmpty() || util.table.cellsForRange(this.editor.getRange()).length > 0;
  };
})();
goog.provide("uno.commands.TableEqualCol");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.TableEqualCol");
  var util = uno.util;
  var TableEqualCol = uno.commands.TableEqualCol = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TableEqualCol, uno.BasePlugin);
  TableEqualCol.prototype.isSupportedCommand = function(command) {
    return command === "tableequalcol";
  };
  TableEqualCol.prototype.execCommandInternal = function(command) {
    var indexes = util.table.selection.getColumnIndexes();
    if (indexes.length < 2) {
      return false;
    }
    util.table.equalizeColumns(util.table.getActive(), indexes);
    return true;
  };
  TableEqualCol.prototype.queryCommandEnabled = function() {
    return !this.editor.multirange.isEmpty() || util.table.selection.getColumnIndexes() > 1;
  };
})();
goog.provide("uno.commands.TableFitNote");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.TableFitNote");
  var util = uno.util;
  var TableFitNote = uno.commands.TableFitNote = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TableFitNote, uno.BasePlugin);
  TableFitNote.prototype.isSupportedCommand = function(command) {
    return command === "tablefitnote";
  };
  TableFitNote.prototype.execCommandInternal = function(command) {
    return util.table.fitNote(util.table.getActive());
  };
  TableFitNote.prototype.queryCommandEnabled = function() {
    return !!util.table.getActive();
  };
})();
goog.provide("uno.commands.TableVerticalAlign");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.EditorMultiRange");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.TableVerticalAlign");
  var util = uno.util;
  var TableVerticalAlign = uno.commands.TableVerticalAlign = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(TableVerticalAlign, uno.BasePlugin);
  TableVerticalAlign.prototype.isSupportedCommand = function(command) {
    return command === "tableverticalalign";
  };
  TableVerticalAlign.prototype.execCommandInternal = function(command, align) {
    if (["", "middle", "top", "bottom"].indexOf(align) < 0) {
      log.warning("Saw unexpected vertical-align value", align);
      align = "";
    }
    if (align === "top") {
      align = "";
    }
    util.table.cellsForRange(this.editor.getRange()).forEach(function(cell) {
      cell.style.verticalAlign = align;
    });
    return true;
  };
  TableVerticalAlign.prototype.queryCommandEnabled = function() {
    return !this.editor.multirange.isEmpty() || util.table.cellsForRange(this.editor.getRange()).length > 0;
  };
})();
goog.provide("uno.util.codeblock");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.paragraph");
(function() {
  var util = uno.util;
  util.codeblock.create = function(paragraphs) {
    if (paragraphs == null) {
      paragraphs = [];
    }
    if (paragraphs.length === 0) {
      paragraphs.push(util.paragraph.create());
    }
    var codeblock = goog.dom.createDom("div", {class:"en-code"}, paragraphs);
    return codeblock;
  };
  util.codeblock.all = function(root) {
    return root.querySelectorAll(".en-code");
  };
  util.codeblock.for = function(node) {
    return goog.dom.getAncestor(node, util.dom.isCodeBlock, true);
  };
  util.codeblock.updateEmpty = function(node) {
    if (!node) {
      return false;
    }
    var block = goog.dom.getAncestor(node, function(ancestor) {
      return util.dom.isCodeBlock(ancestor);
    }, true);
    if (block && block.childNodes.length && !util.dom.isDiv(block.childNodes[0]) && !util.list.for(block.childNodes[0])) {
      var innerContent = block.childNodes[0].cloneNode(true);
      var innerDiv = goog.dom.createDom("div", {}, innerContent);
      for (var i = 1; i < block.childNodes.length; i++) {
        innerDiv.appendChild(block.childNodes[i].cloneNode(true));
        block.childNodes[i].remove();
      }
      goog.dom.replaceNode(innerDiv, block.childNodes[0]);
      goog.editor.range.placeCursorNextTo(innerContent);
      return true;
    }
    return false;
  };
  util.codeblock.updateTopSpace = function(editor) {
    var firstChild = editor.field.childNodes[0];
    if (util.dom.isCodeBlock(firstChild)) {
      var innerDiv = goog.dom.createDom("div", {}, goog.dom.createDom("br"));
      editor.field.insertBefore(innerDiv, firstChild);
    }
  };
})();
goog.provide("uno.commands.Indent");
goog.require("goog.debug.Logger");
goog.require("goog.editor.Command");
goog.require("uno.util.dom");
goog.require("uno.util.codeblock");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Indent");
  var util = uno.util;
  var Indent = uno.commands.Indent = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Indent, uno.BasePlugin);
  Indent.prototype.isSupportedCommand = function(command) {
    return command === "indent";
  };
  Indent.prototype.execCommandInternal = function() {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    var swappedObjects;
    var parentLi = util.dom.parent(range.getContainerElement(), "li");
    if (parentLi) {
      var lineFeedNode = goog.editor.range.getDeepEndPoint(range, true).node;
      var isAfterLineFeed = parentLi.querySelectorAll("br").length && parentLi.childNodes.length > 1 && !util.todo.isTodo(parentLi.firstChild) && (util.dom.isBr(lineFeedNode) || isAfterLinefeed(lineFeedNode, range));
      if (isAfterLineFeed) {
        var tab = goog.dom.createDom(goog.dom.TagName.SPAN, null, uno.defs.tab.CHARACTER_SEQUENCE);
        if (util.dom.isBr(lineFeedNode)) {
          goog.dom.replaceNode(tab, lineFeedNode);
        } else {
          range.insertNode(tab);
        }
        this.editor.dispatchChange();
        range = goog.editor.range.placeCursorNextTo(tab);
        return true;
      }
    }
    swappedObjects = util.resource.toggleObjectsInRange(range, false);
    this.editor.execCommand(goog.editor.Command.INDENT);
    var newRange = this.editor.getRange();
    util.resource.toggleObjectsInRange(newRange, swappedObjects);
    return true;
  };
  Indent.prototype.queryCommandValue = function() {
    return this.editor.queryCommandValue(goog.editor.Command.INDENT);
  };
  Indent.prototype.queryCommandEnabled = function() {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CMD_INDENT, range)) {
      return false;
    }
    return true;
  };
  function isAfterLinefeed(node, range) {
    if (!range.isCollapsed()) {
      return false;
    }
    while (node && !util.dom.isLi(node)) {
      if (util.dom.isLi(node.parentNode)) {
        break;
      }
      node = node.parentNode;
    }
    var prevSiblings = util.dom.getPreviousSiblings(node);
    var siblingBr = goog.array.find(prevSiblings, function(sibling) {
      return sibling.nodeName === "BR";
    });
    return !!siblingBr;
  }
})();
goog.provide("uno.commands.InsertTodo");
goog.require("goog.debug.Logger");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("uno.BasePlugin");
goog.require("goog.string");
goog.require("uno.util.dom");
goog.require("uno.util.todo");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertTodo");
  var util = uno.util;
  var ZERO_WIDTH_SPACE = uno.defs.unicode.ZERO_WIDTH_SPACE;
  var InsertTodo = uno.commands.InsertTodo = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(InsertTodo, uno.BasePlugin);
  InsertTodo.prototype.isSupportedCommand = function(command) {
    return command === "inserttodo";
  };
  InsertTodo.prototype.execCommandInternal = function(command, value) {
    var editor = this.editor;
    var toggle = value === "toggle";
    var range = editor.getRange();
    var startNode = range.getStartNode();
    var node;
    if (toggle) {
      node = startNode;
      while (node = goog.dom.getPreviousElementSibling(node)) {
        if (util.todo.isTodo(node)) {
          util.todo.toggle(node);
          return true;
        }
      }
    } else {
      if (range.isCollapsed()) {
        var todo = util.todo.create();
        if (editor.context.style.hasPendingStyles) {
          node = util.styles.setInlineStyles(todo, editor.context.style.pendingStyles, editor.config.defaults);
        } else {
          node = todo;
        }
        range.insertNode(node);
        if (util.dom.isBr(node.nextSibling)) {
          goog.dom.removeNode(node.nextSibling);
        }
        if (node.previousSibling && node.previousSibling.textContent === ZERO_WIDTH_SPACE) {
          goog.dom.removeNode(node.previousSibling);
        }
        if (node.parentNode) {
          node.parentNode.normalize();
        }
        goog.editor.range.placeCursorNextTo(todo);
        util.styles.clearPendingStyles(editor);
      } else {
        var container = range.getContainer();
        if (container === range.getAnchorNode()) {
          container = null;
        }
        var existing = goog.array.toArray(util.todo.all(editor.field)).filter(function(n) {
          return range.containsNode(n, true);
        });
        if (existing.length > 0) {
          existing.forEach(util.todo.remove);
        } else {
          var nodes = goog.array.toArray(editor.field.querySelectorAll("div,li"));
          nodes = nodes.filter(function(node) {
            return range.containsNode(node, true) && (!container || container.contains(node)) && goog.array.every(node.childNodes, util.dom.isInlineNode) && (!goog.string.isEmpty(node.textContent) || !!node.querySelector("img"));
          });
          if (nodes.length > 0) {
            nodes.forEach(function(node) {
              var entodo = util.todo.create();
              if (node.childNodes.length === 0) {
                node.appendChild(entodo);
              } else {
                var leftMostLeaf = goog.editor.node.getLeftMostLeaf(node);
                goog.dom.insertSiblingBefore(entodo, leftMostLeaf);
              }
            });
            goog.dom.Range.createFromNodes(nodes[0], 0, range.getEndNode(), range.getEndOffset()).select();
          }
        }
      }
    }
  };
  InsertTodo.prototype.queryCommandEnabled = function() {
    var range = this.editor.getRange();
    if (!range) {
      return false;
    }
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CMD_TODO, range)) {
      return false;
    }
    return true;
  };
})();
goog.provide("uno.commands.InsertDrawing");
goog.require("goog.debug.Logger");
goog.require("goog.editor.node");
goog.require("goog.editor.range");
goog.require("uno.BasePlugin");
goog.require("goog.string");
goog.require("uno.util.dom");
goog.require("uno.util.todo");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.InsertDrawing");
  var util = uno.util;
  var ZERO_WIDTH_SPACE = uno.defs.unicode.ZERO_WIDTH_SPACE;
  var InsertDrawing = uno.commands.InsertDrawing = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(InsertDrawing, uno.BasePlugin);
  InsertDrawing.prototype.isSupportedCommand = function(command) {
    return command === "insertdrawing";
  };
  InsertDrawing.prototype.execCommandInternal = function(command, value) {
    var enDrawing = document.createElement("magic-drawing");
    enDrawing._yjsHook = "magic-drawing";
    var range = this.editor.getRange();
    if (!range.isCollapsed()) {
      this.editor.execCommand("delete");
      range = this.editor.getRange();
    }
    if (!util.dom.isEmpty(util.paragraph.for(range.getStartNode()))) {
      this.editor.execCommand("insertparagraph", {cursorPosition:"original"});
      range = this.editor.getRange();
      if (!util.dom.isEmpty(util.paragraph.for(range.getStartNode()))) {
        this.editor.execCommand("insertparagraph", {cursorPosition:"new"});
      }
    }
    range = this.editor.getRange();
    range.insertNode(enDrawing);
    util.table.normalizeDOMPlacement(enDrawing);
    return true;
  };
  InsertDrawing.prototype.queryCommandEnabled = function() {
    var range = this.editor.getRange();
    if (range == null) {
      return false;
    }
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.TABLE, range)) {
      return false;
    }
    return true;
  };
})();
goog.provide("uno.commands.Lowercase");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Lowercase");
  var util = uno.util;
  var Lowercase = uno.commands.Lowercase = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(Lowercase, uno.BasePlugin);
  Lowercase.prototype.isSupportedCommand = function(command) {
    return command === "lowercase";
  };
  Lowercase.prototype.execCommandInternal = function() {
    var range = this.editor.getRange();
    var savedRange = range.saveUsingDom();
    util.range.forEachWord(range, function(word, wordRange) {
      var container = wordRange.startContainer;
      var text = container.nodeValue;
      container.nodeValue = text.slice(0, wordRange.startOffset) + word.toLocaleLowerCase() + text.slice(wordRange.endOffset);
    });
    savedRange.restore().select();
    return true;
  };
})();
goog.provide("uno.commands.Margin");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Margin");
  var Margin = uno.commands.Margin = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Margin, uno.BasePlugin);
  Margin.prototype.isSupportedCommand = function(command) {
    return command === "margin";
  };
  Margin.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Margin.prototype.execCommand = function(command, value) {
    if (value == null) {
      return false;
    }
    if (this.editor == null || this.editor.field == null) {
      return false;
    }
    var field = this.editor.field;
    var note = value.note;
    if (note) {
      field.style.paddingTop = toCssValue(note.top, "px");
      field.style.paddingBottom = toCssValue(note.bottom, "px");
      field.style.paddingLeft = toCssValue(note.left, "px");
      field.style.paddingRight = toCssValue(note.right, "px");
    }
    if (value.scroll) {
      this.editor.config.margin.scroll = {top:value.scroll.top || 0, left:value.scroll.left || 0, bottom:value.scroll.bottom || 0, right:value.scroll.right || 0};
    }
    if (value.offset) {
      this.editor.config.margin.offset = {height:value.offset.height || 0, width:value.offset.width || 0};
    }
    return true;
  };
  function toCssValue(value, unit) {
    var result;
    switch(typeof value) {
      case "number":
        result = value + unit;
        break;
      case "string":
        if (value.indexOf(unit) > -1) {
          result = value;
        } else {
          result = value + unit;
        }
        break;
      case "undefined":
        result = null;
        break;
      default:
        result = value;
    }
    return result;
  }
})();
goog.provide("uno.util.normalize");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.list");
goog.require("uno.util.table");
goog.require("uno.util.paragraph");
goog.require("uno.util.richlink");
goog.require("uno.util.styles");
goog.require("goog.array");
goog.require("goog.dom");
(function() {
  var util = uno.util;
  var dom = util.dom;
  util.normalize.normalizeNode = function(node, options) {
    options = options || {};
    if (dom.isTextNode(node)) {
      node = node.parentNode;
    }
    var savedCursor = null;
    var endCursor = null;
    if (options.range) {
      savedCursor = util.range.saveCursor(options.range);
    }
    node.innerHTML = util.normalize.normalizeHtml(node.innerHTML);
    util.normalize.normalizeDom(node, options);
    if (savedCursor) {
      endCursor = node.querySelector("#" + savedCursor.endCaretId_);
      if (options.range.isCollapsed() && endCursor && !dom.isBr(endCursor.nextSibling) && endCursor.parentNode.childNodes === 2) {
        goog.dom.insertSiblingAfter(document.createElement("br"), endCursor);
      }
      savedCursor.restore();
    }
    return node;
  };
  util.normalize.normalizeHtml = function(html, options) {
    var nonVoidTag = /<(?!area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)([\w-]+)([^>]*)\/>/g;
    var invalidCharacters = /[\u0000\u0001-\u0008\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\u000B\uFFFE\uFFFF]|[\x01-\x10][\uFFFE-\uFFFF]/g;
    var zwsRegex = new RegExp(uno.defs.unicode.ZERO_WIDTH_SPACE, "g");
    options = options || {};
    html = html.replace(zwsRegex, "").replace(invalidCharacters, "").replace(/(<pre(?:>|\s[^>]*>))([\u0000-\uffff]*?)<\/pre>/g, function(m, g1, g2) {
      return "<div" + g1.substr(4) + g2.replace(/\r?\n/g, "<br>").replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;") + "</div>";
    }).replace(/^<div><span>(.*)<\/span>\n<\/div>$/, "<div>$1</div>").replace(/\n\n\/\*\*\/\n\x3c!--[\s\w{:}#;-]+>\n\/\*\*\/\n/g, "").replace(nonVoidTag, "<$1$2></$1>").replace(/<!\[CDATA\[([^]*?)\]\]>/g, function(match, raw) {
      var s = "";
      for (var i = 0, l = raw.length; i < l; i++) {
        s += "&#" + raw.charCodeAt(i) + ";";
      }
      return s;
    });
    if (options.simplifyFormat) {
      html = html.replace(/([^ ])&nbsp;([^ ])/g, "$1 $2");
    }
    html = util.normalize.removeExcessiveEmptyLinesInHtml(html);
    return html;
  };
  util.normalize.normalizeDom = function(root, options) {
    options = options || {};
    root.normalize();
    if (dom.isTextNode(root)) {
      return;
    }
    util.normalize.removeUnsupportedNodes(root);
    util.normalize.removeUnsupportedTags(root);
    util.normalize.normalizeRenderingBox(root);
    util.normalize.replaceBrsByParagraphs(root.querySelectorAll("br"));
    util.normalize.removeEmptyNodes(root);
    util.list.normalize(root);
    util.table.normalize(root, options.ignoreTableStyles);
    util.normalize.ensureValidParagraph(root.childNodes);
    util.normalize.flattenRedundantNodes(root);
    if (!options.ignoreInlineNodes) {
      util.normalize.inlineNodes(root, options);
    }
    util.list.convertParagraphsToBrs(root);
    if (options.removeFormat) {
      util.normalize.removeRichLinkFormat(root);
    }
  };
  util.normalize.removeUnsupportedTags = function(frag) {
    goog.array.forEachRight(frag.querySelectorAll("en-note, script, meta, style, input, option, select, button"), goog.dom.removeNode);
    goog.array.forEachRight(frag.querySelectorAll('a[x-apple-data-detectors="true"]'), goog.dom.flattenElement);
  };
  util.normalize.normalizeRenderingBox = function(frag) {
    var nodes = frag.querySelectorAll('[style*="display"]');
    goog.array.forEachRight(nodes, function(node) {
      if (dom.inlineObjects.indexOf(node.tagName && node.tagName.toLowerCase()) > -1) {
        return;
      }
      if (dom.isBlockNode(node) && node.style && ["inline", "inline-block"].indexOf(node.style.display) > -1) {
        node = dom.changeTagName(node, "span");
      }
      if (dom.isInlineNode(node) && node.style && ["block"].indexOf(node.style.display) > -1) {
        node = dom.changeTagName(node, "div");
      }
      node.style.display = "";
    });
  };
  util.normalize.replaceBrsByParagraphs = function(brs) {
    var getCloneTagName = function(node) {
      return isInvalidParent(node) || dom.isNoteSection(node) || dom.isP(node) || dom.isPre(node) ? "div" : node.tagName;
    };
    goog.array.forEach(brs, function(br) {
      var clone;
      var sibling;
      var parent;
      var nodes = [];
      var node = br;
      var hasSiblings = false;
      if (dom.isBlockNode(br.parentNode) && br.parentNode.childNodes.length === 1) {
        return;
      }
      while (dom.isInlineNode(node)) {
        var siblings = [];
        sibling = node.previousSibling;
        parent = node.parentNode;
        while (sibling && dom.isInlineNode(sibling)) {
          siblings.push(sibling);
          sibling = sibling.previousSibling;
        }
        if (siblings.length) {
          hasSiblings = true;
        }
        node = node.parentNode;
        var newClone = dom.isInlineNode(node) ? node.cloneNode() : goog.dom.createDom(getCloneTagName(node));
        if (clone) {
          newClone.appendChild(clone);
        }
        clone = newClone;
        goog.array.forEach(siblings, function(child) {
          goog.dom.insertChildAt(clone, child, 0);
        });
      }
      if (hasSiblings) {
        goog.dom.removeNode(br);
        if (dom.isEmpty(clone)) {
          return;
        }
      } else {
        clone = goog.dom.createDom(getCloneTagName(node));
        clone.appendChild(br);
      }
      if (sibling) {
        goog.dom.insertSiblingAfter(clone, sibling);
      } else {
        if (parent) {
          goog.dom.insertChildAt(parent, clone, 0);
        }
      }
      if (dom.isInlineNode(clone.nextSibling) && !dom.isBr(clone.nextSibling) && dom.isEmptyContent(clone.nextSibling) && !clone.nextSibling.querySelector("br")) {
        goog.dom.removeNode(clone.nextSibling);
      }
    });
  };
  util.normalize.removeEmptyNodes = function(root) {
    var deepestNodes = dom.getNodeLeaves(root, dom.inlineObjects, true);
    goog.array.forEachRight(deepestNodes, function(node) {
      var parent = node.parentNode;
      while (node && util.normalize.isEmptyNode(node)) {
        goog.dom.removeNode(node);
        node = parent;
        parent = node && node.parentNode;
      }
    });
  };
  util.normalize.isEmptyNode = function(node) {
    return [].concat(dom.inlineObjects, dom.tableObjects).indexOf(dom.getTagName(node)) === -1 && dom.isEmpty(node);
  };
  util.normalize.ensureValidParagraph = function(siblings) {
    var paragraphNodes = [];
    goog.array.forEachRight(siblings, function(node) {
      var parentNode = node.parentNode;
      var previousSibling = node.previousSibling;
      var nextSibling = node.nextSibling;
      var paragraph = node;
      if (dom.isInlineNode(node) && (dom.isBlockNode(previousSibling) || dom.isBlockNode(nextSibling) || dom.isNoteSection(parentNode))) {
        var tagName = dom.isBlockNode(parentNode) && !dom.isNoteSection(parentNode) ? parentNode.tagName : "div";
        if (dom.isBlockNode(nextSibling) || !nextSibling) {
          paragraphNodes.push(node);
          while (dom.isInlineNode(node.previousSibling)) {
            paragraphNodes.unshift(node.previousSibling);
            node = node.previousSibling;
          }
          paragraph = goog.dom.createDom(tagName, null, paragraphNodes);
          if (nextSibling) {
            goog.dom.insertSiblingBefore(paragraph, nextSibling);
          } else {
            parentNode.appendChild(paragraph);
          }
        } else {
          if (dom.isBlockNode(previousSibling)) {
            paragraphNodes.push(node);
            while (dom.isInlineNode(node.nextSibling)) {
              paragraphNodes.push(node.nextSibling);
              node = node.nextSibling;
            }
            paragraph = goog.dom.createDom(tagName, null, paragraphNodes);
            goog.dom.insertSiblingAfter(paragraph, previousSibling);
          }
        }
        paragraphNodes = [];
      }
      if (paragraph && paragraph.childNodes.length) {
        util.normalize.ensureValidParagraph(paragraph.childNodes);
      }
    });
  };
  var isInvalidParent = function(parentNode) {
    return !parentNode || !parentNode.parentNode || dom.isEnnote(parentNode) || dom.isFragment(parentNode);
  };
  util.normalize.flattenRedundantNodes = function(root) {
    var deepestNodes = dom.getNodeLeaves(root, dom.inlineObjects);
    var dumbParentNode = goog.dom.createDom("div");
    deepestNodes.forEach(function(node) {
      while (!isInvalidParent(node.parentNode)) {
        var parentNode = node.parentNode;
        if (dom.isUl(parentNode) || dom.isOl(parentNode) || dom.isLi(parentNode) || dom.isTd(parentNode) || dom.isTd(node) || dom.isTr(node) || dom.isColgroup(parentNode) || dom.isCodeBlock(parentNode) || dom.isRevealedCrypt(parentNode) || dom.isBlockquote(parentNode) || dom.isTextNode(node)) {
          if (dom.isTd(parentNode) || dom.isTr(node) || dom.isColgroup(parentNode)) {
            node = goog.dom.getAncestor(node, dom.isEntable) || goog.dom.getAncestor(node, dom.isTable) || parentNode;
          } else {
            node = parentNode;
          }
        } else {
          if (dom.isBlockNode(node)) {
            if (dom.isBlockNode(parentNode)) {
              if (parentNode.getAttribute("style")) {
                node = parentNode;
              } else {
                goog.array.forEachRight(parentNode.childNodes, function(child) {
                  util.styles.mergeAttributes(parentNode, child, true);
                  goog.dom.insertSiblingAfter(child, parentNode);
                });
                if (!parentNode.childNodes.length) {
                  goog.dom.removeNode(parentNode);
                } else {
                  goog.dom.flattenElement(parentNode);
                }
              }
            } else {
              goog.array.forEachRight(parentNode.childNodes, function(child) {
                var paragraphs = [child];
                if (dom.isTable(child)) {
                  paragraphs = util.table.getParagraphs(child);
                } else {
                  if (dom.isUl(child) || dom.isOl(child)) {
                    paragraphs = util.list.getParagraphs(child);
                  }
                }
                goog.array.forEach(paragraphs, function(paragraph) {
                  if (dom.isTextNode(paragraph)) {
                    paragraph = goog.dom.createDom("div", null, paragraph);
                  }
                  var newNode = parentNode.cloneNode();
                  dom.moveChildren(paragraph, newNode);
                  paragraph.appendChild(newNode);
                });
              });
              var previousSiblings = dom.getPreviousSiblings(parentNode);
              if (previousSiblings.length) {
                var leftParagraph = goog.dom.createDom("div", null, previousSiblings);
                goog.dom.insertSiblingBefore(leftParagraph, parentNode);
              }
              var nextSiblings = dom.getNextSiblings(parentNode);
              if (nextSiblings.length) {
                var rightParagraph = goog.dom.createDom("div", null, nextSiblings);
                goog.dom.insertSiblingAfter(rightParagraph, parentNode);
              }
              if (!parentNode.childNodes.length) {
                goog.dom.removeNode(parentNode);
              } else {
                goog.dom.flattenElement(parentNode);
              }
            }
          } else {
            node = parentNode;
          }
        }
      }
      util.styles.mergeAttributes(dumbParentNode, node, true);
    });
  };
  util.normalize.normalizeParagraphStructure = function(paragraph) {
    if (dom.isP(paragraph)) {
      paragraph = dom.changeTagName(paragraph, "div");
      if (paragraph.style.marginBottom.length === 0 && paragraph.style.marginTop.length === 0) {
        util.styles.setMetadata(paragraph, "-en-paragraph", true);
        paragraph.style.marginTop = "1em";
        paragraph.style.marginBottom = "1em";
      }
    }
    return paragraph;
  };
  util.normalize.inlineNodes = function(root, options) {
    var paragraphs = util.paragraph.all(root);
    var dumbNode = goog.dom.createDom("div");
    if (!paragraphs.length && dom.isElementNode(root)) {
      paragraphs = [root];
    }
    goog.array.forEach(paragraphs, function(paragraph) {
      paragraph = util.normalize.normalizeParagraphStructure(paragraph);
      if (dom.isBlockNode(paragraph.firstChild)) {
        return;
      }
      var deepestNodes = util.dom.getNodeLeaves(paragraph, dom.inlineObjects);
      var nodes = [];
      deepestNodes.forEach(function(node) {
        var link = false;
        var element = node;
        while (element !== paragraph) {
          if (element.attributes && element.getAttribute("href")) {
            link = element;
            break;
          }
          element = element.parentNode;
        }
        if (dom.isTextNode(node)) {
          var currentNode = node;
          node = goog.dom.createDom("span", null, node.textContent);
          if (!options.removeFormat) {
            while (dom.isInlineNode(currentNode) && currentNode.parentNode) {
              util.styles.mergeAttributes(currentNode.parentNode, node, false, {disallowedStyles:"align.*|animation.*|flex.*|float|grid.*|justify.*|left|list.*|margin.*|padding.*|shape.*|text-align|transition.*", allowedAttrs:"data-.*|title|class"});
              currentNode = currentNode.parentNode;
            }
          }
          if (!node.hasAttributes()) {
            node = node.firstChild;
          }
        }
        if (link) {
          var href = link.getAttribute("href");
          if (dom.isSpan(node) || dom.isTextNode(node)) {
            var anchor = goog.dom.createDom("a", {href:href}, node.textContent);
            goog.array.forEach(node.attributes || [], function(attr) {
              anchor.setAttribute(attr.name, attr.value);
            });
            if (link.getAttribute("rev")) {
              anchor.setAttribute("rev", link.getAttribute("rev"));
            }
            node = anchor;
          } else {
            if (dom.isImg(node) || util.resource.isImage(node)) {
              node = goog.dom.createDom("a", {href:href}, node);
            }
          }
        }
        nodes.push(node);
      });
      if (nodes.length) {
        while (paragraph.firstChild) {
          paragraph.removeChild(paragraph.firstChild);
        }
        var mergeOptions = {allowedStyles:".*", disallowedStyles:options.removeFormat ? ".*" : "", disallowedAttrs:options.externalContent ? "name|id|data-.*|bgcolor|class" : "bgcolor"};
        util.styles.mergeAttributes(dumbNode, paragraph, false, mergeOptions);
        nodes.forEach(function(node) {
          paragraph.appendChild(node);
          if (dom.isInlineNode(paragraph) && !paragraph.hasAttributes()) {
            goog.dom.flattenElement(paragraph);
          }
        });
      }
    });
  };
  util.normalize.removeUnsupportedNodes = function(frag) {
    var iterator = frag.ownerDocument.createNodeIterator(frag, 8 | 128, null, false);
    var element;
    var nodeList = [];
    while (element = iterator.nextNode()) {
      nodeList.push(element);
    }
    for (var i = nodeList.length - 1; i >= 0; i--) {
      var node = nodeList[i];
      var nodeType = node.nodeType;
      if (nodeType === Node.COMMENT_NODE) {
        if (node.data.indexOf("[CDATA[") === 0) {
          var nextSibling = node.nextSibling;
          var textNode = document.createTextNode(node.data.substr(7));
          goog.dom.replaceNode(textNode, node);
          node = textNode;
          if (node.data.lastIndexOf("]]") !== node.data.length - 2 && nextSibling && nextSibling.nodeType === Node.TEXT_NODE) {
            nextSibling.data = nextSibling.data.replace(/^(.*?)\]\]\>(.*?)$/gi, "$1$2");
            node.data += ">";
          } else {
            node.data = node.data.replace(/^(.*?)\]\](.*?)$/gi, "$1$2");
          }
        } else {
          node.parentNode.removeChild(node);
        }
      } else {
        goog.dom.replaceNode(document.createTextNode(node.data), node);
      }
    }
  };
  util.normalize.removeExcessiveEmptyLinesInHtml = function(html) {
    return html.replace(/(<li[^>]*>(?:(?!<\/li).)*?)(?:<div><br\s?\/><\/div>){6,}/g, "$1<div><br /></div>");
  };
  util.normalize.removeRichLinkFormat = function(frag) {
    goog.array.forEach(util.richlink.all(frag), function(link) {
      var parent = link.parentNode;
      if (util.dom.isA(parent)) {
        parent.innerHTML = parent.href;
      }
    });
  };
})();
goog.provide("uno.util.n3");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.list");
goog.require("uno.util.table");
goog.require("uno.util.paragraph");
goog.require("uno.util.styles");
goog.require("uno.util.normalize");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.functions");
(function() {
  var util = uno.util;
  var dom = util.dom;
  util.n3.normalizeNode = function(node, options) {
    start("util.normalize.normalizeNode");
    options = options || {};
    if (dom.isTextNode(node)) {
      node = node.parentNode;
    }
    var savedCursor = null;
    var endCursor = null;
    if (options.range) {
      savedCursor = util.range.saveCursor(options.range);
    }
    node.innerHTML = util.normalize.normalizeHtml(node.innerHTML, options);
    util.n3.normalizeDom(node, options);
    if (savedCursor) {
      endCursor = node.querySelector("#" + savedCursor.endCaretId_);
      if (options.range.isCollapsed() && endCursor && !dom.isBr(endCursor.nextSibling) && endCursor.parentNode.childNodes === 2) {
        goog.dom.insertSiblingAfter(document.createElement("br"), endCursor);
      }
      savedCursor.restore();
    }
    stop("util.normalize.normalizeNode");
    return node;
  };
  util.n3.normalizeDom = function(root, options) {
    start("util.n3.normalizeDom");
    options = options || {};
    root.normalize();
    if (dom.isTextNode(root)) {
      stop("util.n3.normalizeDom");
      return;
    }
    util.normalize.removeUnsupportedNodes(root);
    util.normalize.removeUnsupportedTags(root);
    if (options.simplifyFormat) {
      removeTags(root, ["blockquote", 'div[style*="-en-codeblock:"]', "[data-en-codeblock]"]);
    }
    util.normalize.removeEmptyNodes(root);
    util.list.normalize(root);
    util.table.normalize(root, options.ignoreTableStyles);
    normalizeInlineNodes(root, options);
    util.normalize.replaceBrsByParagraphs(root.querySelectorAll("br"));
    util.list.convertParagraphsToBrs(root);
    stop("util.n3.normalizeDom");
  };
  function normalizeInlineNodes(root, options) {
    start("util.normalize.normalizeDom normalizeInlineNodes");
    options = options || {};
    var parents = [root];
    var walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {acceptNode:function(node) {
      if (node.firstChild == null || isOpaqueElement(node)) {
        return NodeFilter.FILTER_REJECT;
      } else {
        parents.push(node);
        return NodeFilter.FILTER_ACCEPT;
      }
    }});
    while (walker.nextNode()) {
    }
    goog.array.forEachRight(parents, function(parent, index) {
      if (parent.tagName === "SPAN" && !parent.getAttribute("style") && !util.styles.hasMetadata(parent)) {
        goog.dom.flattenElement(parent);
      } else {
        parent = replacePtagWithDiv(parent);
        parent = matchTagNameToDisplayProperty(parent);
        ensureChildrenAreAllBlocksOrAllInline(parent);
      }
    });
    var elementsAndStyles = findContentParentsAndStyles(root, options);
    var elements = elementsAndStyles.nodes;
    var styles = elementsAndStyles.styles;
    normalizeFormatting(elements, styles, options);
    stop("util.normalize.normalizeDom normalizeInlineNodes");
  }
  function replacePtagWithDiv(el) {
    if (el.tagName === "P") {
      el = dom.changeTagName(el, "div");
      if (el.style.marginBottom.length === 0 && el.style.marginTop.length === 0) {
        util.styles.setMetadata(el, "-en-paragraph", true);
        el.style.marginTop = "1em";
        el.style.marginBottom = "1em";
      }
    }
    return el;
  }
  function matchTagNameToDisplayProperty(node) {
    if (dom.isBlockNode(node) && node.style && node.style.display === "inline") {
      node = dom.changeTagName(node, "span");
      node.style.display = "";
    } else {
      if (!dom.isBlockNode(node) && node.style && node.style.display === "block") {
        node = dom.changeTagName(node, "div");
        node.style.display = "";
      }
    }
    return node;
  }
  function ensureChildrenAreAllBlocksOrAllInline(parent) {
    if (parent.childNodes.length < 2) {
      return;
    }
    if (isOpaqueElement(parent)) {
      return;
    }
    var curCluster = {nodes:[], hasBlock:null};
    var clusters = [curCluster];
    var childrenShouldBeBlocks = false;
    goog.array.forEach(parent.childNodes, function(child) {
      var hasBlock = isBlockLayout(child);
      childrenShouldBeBlocks = childrenShouldBeBlocks || hasBlock;
      if (curCluster.hasBlock == null || hasBlock === curCluster.hasBlock) {
        curCluster.nodes.push(child);
        curCluster.hasBlock = hasBlock;
      } else {
        curCluster = {nodes:[child], hasBlock:hasBlock};
        clusters.push(curCluster);
      }
    });
    if (clusters.length > 1 && childrenShouldBeBlocks) {
      goog.array.forEach(clusters, function(cluster) {
        if (!cluster.hasBlock) {
          var container = document.createElement("div");
          goog.dom.replaceNode(container, cluster.nodes[0]);
          goog.array.forEach(cluster.nodes, function(child) {
            container.appendChild(child);
          });
        }
      });
    }
  }
  function findContentParentsAndStyles(root, options) {
    var parents = [];
    var parent;
    var parentStyles = [];
    var parentStyle;
    var children = [];
    var child;
    var childStyles = [];
    var resultNodes = [];
    var resultStyles = [];
    var redundantNodes = [];
    var i;
    var hasContentChild;
    var isRedundantDiv;
    var isRedundantInline;
    var temp1, temp2;
    parents.push(root);
    if (root.tagName && root.tagName === "EN-NOTE") {
      parentStyles.push({});
    } else {
      parentStyles.push(combinedStyle(root, {}, options));
    }
    while (parents.length > 0) {
      parent = parents.pop();
      parentStyle = parentStyles.pop();
      if (!isOpaqueElement(parent)) {
        hasContentChild = false;
        isRedundantDiv = parent.tagName === "DIV" && !util.styles.hasLayoutStyle(parent) && !util.styles.hasMetadata(parent);
        isRedundantInline = !dom.isBlockNode(parent) && !util.styles.hasLayoutStyle(parent) && !util.styles.hasMetadata(parent);
        for (i = parent.childNodes.length - 1; i > -1; i--) {
          child = parent.childNodes[i];
          if (child.firstChild != null && !dom.isCodeBlock(child)) {
            children.push(child);
            childStyles.push(combinedStyle(child, parentStyle, options));
          }
          if (isRedundantDiv && child.tagName !== "DIV") {
            isRedundantDiv = false;
          }
          if (!hasContentChild && (child.nodeType === Node.TEXT_NODE || child.tagName === "IMG" || util.resource.isImage(child))) {
            hasContentChild = true;
          }
        }
        if (hasContentChild && Object.keys(parentStyle).length > 0) {
          resultNodes.push(parent);
          resultStyles.push(parentStyle);
        } else {
          if (isRedundantDiv || isRedundantInline) {
            redundantNodes.push(parent);
          }
        }
      }
      if (parents.length === 0) {
        temp1 = parents;
        temp2 = parentStyles;
        parents = children;
        parentStyles = childStyles;
        children = temp1;
        childStyles = temp2;
      }
    }
    goog.array.forEach(redundantNodes, dom.flattenElement);
    return {nodes:resultNodes, styles:resultStyles};
  }
  function normalizeFormatting(contentParents, styles, options) {
    options = options || {};
    goog.array.forEachRight(contentParents, function(parent, index) {
      var style = styles[index];
      var wrappers;
      var clusters = [];
      var cluster;
      goog.array.forEach(parent.childNodes, function(child) {
        if (child.nodeType === Node.TEXT_NODE || child.tagName === "IMG" || child.tagName === "BR" || util.resource.isResource(child)) {
          if (cluster == null) {
            cluster = [];
            clusters.push(cluster);
          }
          cluster.push(child);
        } else {
          cluster = null;
        }
      });
      if (style.href != null) {
        if (parent.tagName !== "A") {
          wrappers = clusters.map(function() {
            return document.createElement("a");
          });
        }
      } else {
        if (parent.tagName !== "SPAN" || clusters.length > 1) {
          wrappers = clusters.map(function() {
            return document.createElement("span");
          });
        }
      }
      if (wrappers) {
        wrappers.forEach(function(wrapper, idx) {
          goog.dom.replaceNode(wrapper, clusters[idx][0]);
          clusters[idx].forEach(function(node) {
            wrapper.appendChild(node);
          });
          if (!dom.isBlockNode(parent)) {
            Object.keys(parent.style).forEach(function(key) {
              if (isNaN(key) && parent.style[key] != null && parent.style[key] !== "" && style[key] == null && key !== "cssText") {
                style[key] = parent.style[key];
              }
            });
            dom.flattenElement(parent);
          }
        });
      } else {
        wrappers = [parent];
      }
      wrappers.forEach(function(wrapper) {
        applyStyle(style, wrapper, options.simplifyFormat);
      });
    });
  }
  var TAGS_TO_STYLES = {B:{name:"fontWeight", value:"bold"}, EM:{name:"fontStyle", value:"italic"}, I:{name:"fontStyle", value:"italic"}, STRIKE:{name:"textDecoration", value:"line-through"}, S:{name:"textDecoration", value:"line-through"}, STRONG:{name:"fontWeight", value:"bold"}, SUB:{name:"verticalAlign", value:"sub"}, SUP:{name:"verticalAlign", value:"super"}, U:{name:"textDecoration", value:"underline"}};
  var COMPOUND_STYLES = ["textDecoration"];
  function isBlockLayout(node) {
    return dom.isBlockNode(node) && node.style.float !== "left" && node.style.float !== "right" && node.style.display !== "inline" && node.style.display !== "inline-block";
  }
  function combinedStyle(node, parentStyle, options) {
    options = options || {};
    if (options.removeFormat) {
      return parentStyle;
    }
    var fontSize;
    var style = {};
    var declaration = node.style;
    if (declaration == null) {
      return style;
    }
    goog.object.extend(style, parentStyle);
    var styleFromTag = TAGS_TO_STYLES[node.tagName];
    if (styleFromTag) {
      if (COMPOUND_STYLES.indexOf(styleFromTag.name) !== -1 && style[styleFromTag.name] != null) {
        style[styleFromTag.name] += " " + styleFromTag.value;
      } else {
        style[styleFromTag.name] = styleFromTag.value;
      }
    } else {
      if (node.tagName === "FONT" && !options.simplifyFormat) {
        if (node.getAttribute("color")) {
          style.color = node.getAttribute("color");
        }
        if (node.getAttribute("face")) {
          style.fontFamily = node.getAttribute("face");
        }
        if (node.getAttribute("size") && declaration.fontSize === "") {
          if (isRelativeValue(node.getAttribute("size")) && isRelativeValue(style.fontSize)) {
            style.fontSize = combineRelativeValues(node.getAttribute("size"), style.fontSize);
          } else {
            style.fontSize = node.getAttribute("size");
          }
        }
      } else {
        if (node.tagName === "A") {
          if (style.color) {
            delete style.color;
          }
          if (node.getAttribute("href")) {
            style.href = node.getAttribute("href");
          }
        }
      }
    }
    var styleNames = options.simplifyFormat ? SIMPLIFY_FORMAT_STYLES : util.styles.inlineStyles;
    styleNames.forEach(function(name) {
      var value = declaration[name];
      if (name === "backgroundColor" && dom.isBlockNode(node)) {
        return;
      }
      if (value != null && value !== "" && value !== "inherit") {
        style[name] = value;
      }
    });
    if (options.simplifyFormat) {
      node.removeAttribute("style");
    } else {
      styleNames.forEach(function(name) {
        if (name !== "backgroundColor" && name !== "fontSize") {
          declaration[name] = null;
        }
      });
    }
    if (style.backgroundColor && !declaration.backgroundColor && dom.isBlockNode(node)) {
      declaration.backgroundColor = null;
    }
    if (node.getAttribute("style") === "") {
      node.removeAttribute("style");
    }
    return style;
  }
  function stripStyles(node, styleNames) {
    var declaration = node.style;
    styleNames.forEach(function(name) {
      if (declaration[name] !== "") {
        declaration[name] = "";
      }
    });
  }
  function applyStyle(style, el, simplifyFormat) {
    if (simplifyFormat) {
      el.removeAttribute("style");
    }
    Object.keys(style).filter(function(key) {
      return key === "href" ? !el.href : el.style[key] === "";
    }).forEach(function(key) {
      if (key === "href") {
        el.href = style.href;
      } else {
        el.style[key] = style[key];
      }
    });
  }
  function isRelativeValue(value) {
    return false;
  }
  function combineRelativeValues(v1, v2) {
    return v1;
  }
  function removeTags(root, tagNames) {
    if (!tagNames) {
      return;
    }
    if (typeof tagNames === "string") {
      tagNames = [tagNames];
    }
    var selector = tagNames.join(",");
    goog.array.forEach(root.querySelectorAll(selector), dom.flattenElement);
  }
  var SIMPLIFY_FORMAT_STYLES = ["fontStyle", "fontWeight", "textDecoration"];
  function wrapTopLevelChunksInParagraphs(origins) {
    goog.array.forEach(origins, function(origin) {
      var inlineNodes = [];
      var p;
      goog.array.forEachRight(origin.childNodes, function(child) {
        if (!util.dom.isBlockNode(child)) {
          inlineNodes.push(child);
        } else {
          if (inlineNodes.length > 0) {
            p = goog.dom.createDom("div", null, inlineNodes.reverse());
            goog.dom.insertSiblingAfter(p, child);
            inlineNodes = [];
          }
        }
      });
      if (inlineNodes.length > 0) {
        p = goog.dom.createDom("div", null, inlineNodes.reverse());
        goog.dom.insertChildAt(origin, p, 0);
      }
    });
  }
  function convertBlockquoteToParagraphMargin(frag) {
    var blockquotes = frag.querySelectorAll("blockquote");
    var hierarchy = [];
    var marginIncrement = 40;
    goog.array.forEach(blockquotes, function(blockquote) {
      var paragraphs = blockquote.querySelectorAll("div");
      goog.array.forEach(paragraphs, function(p) {
        var left = parseInt(p.style.marginLeft, 10) || 0;
        left += marginIncrement;
        p.style.marginLeft = left + "px";
      });
      goog.dom.flattenElement(blockquote);
    });
  }
  var opaqueTagNames = ["EN-CRYPT", "EN-MEDIA", "EMBED", "OBJECT"];
  function isOpaqueElement(el) {
    return el != null && opaqueTagNames.indexOf(el.tagName) !== -1;
  }
})();
goog.provide("uno.util.paste.plain");
(function() {
  var util = uno.util;
  util.paste.plain.getContent = function(content) {
    return content.split("\n").map(function(line) {
      var value = goog.string.htmlEscape(line).replace(/\r/, "").replace(/\t/gi, uno.defs.tab.CHARACTER_SEQUENCE).replace(/[ \t]{2,}/gi, function(match) {
        var nbsp = String.fromCharCode(160);
        var result = "";
        for (var i = 0; i < match.length; i++) {
          result += nbsp;
        }
        return result;
      });
      if (!value) {
        value = "<br>";
      }
      return "<div>" + value + "</div>";
    }).join("");
  };
})();
goog.provide("uno.util.paste");
goog.require("goog.editor.range");
goog.require("goog.editor.node");
goog.require("goog.dom.Range");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("uno.util.paragraph");
goog.require("uno.util.dom");
goog.require("uno.util.font");
goog.require("uno.util.range");
goog.require("uno.util.table");
goog.require("uno.util.n3");
goog.require("uno.util.copy.plain");
goog.require("uno.util.paste.plain");
(function() {
  var util = uno.util;
  var dom = util.dom;
  var copy = util.copy;
  var paste = util.paste;
  var MIME = util.paste.MIME = {TEXT_HTML:"text/html", TEXT_PLAIN:"text/plain", TEXT_XML:"text/xml", TEXT_RICHTEXT:"text/richtext"};
  util.paste.paste = function(clipboardContent, range, options) {
    options = options || {};
    var pasteTarget = util.paste.getTarget(range);
    if (!pasteTarget) {
      return false;
    } else {
      if (dom.parent(pasteTarget, "en-search")) {
        pasteTarget.querySelector("input[type=text]").value = clipboardContent.textContent ? clipboardContent.textContent : clipboardContent || "";
        return false;
      }
    }
    var paragraphs = [];
    var pastingInLi = goog.dom.getAncestor(pasteTarget, dom.isLi, true);
    var pastingInTable = goog.dom.getAncestor(pasteTarget, dom.isTable, true);
    var pastingInCodeBlock = goog.dom.getAncestor(pasteTarget, dom.isCodeBlock, true);
    var pastingInCrypt = goog.dom.getAncestor(pasteTarget, dom.isRevealedCrypt, true);
    var pastingInTodo = util.paragraph.startsWithTodo(pasteTarget);
    options.cursorPosition = getCursorPosition(range);
    options.alignment = pasteTarget.style.textAlign;
    setStyles(clipboardContent, options);
    if (pastingInTable && (clipboardContent.childNodes.length > 1 || !dom.isEntable(clipboardContent.firstChild))) {
      var tables = clipboardContent.querySelectorAll("en-table");
      goog.array.forEach(tables, plainifyTable);
    }
    var nodeArray = Array.prototype.slice.call(clipboardContent.childNodes);
    goog.array.forEach(nodeArray, function(child, index) {
      if (pastingInLi && (dom.isUl(child) || dom.isOl(child))) {
        goog.array.forEach(child.childNodes, function(li) {
          paragraphs.push(li);
        });
      } else {
        if ((pastingInCodeBlock || pastingInCrypt) && dom.isCodeBlock(child)) {
          paragraphs = paragraphs.concat(plainifyCodeBlock(child));
        } else {
          if (dom.isRevealedCrypt(child)) {
            paragraphs = paragraphs.concat(plainifyCrypt(child));
          } else {
            if (options.alignment) {
              child.style.textAlign = options.alignment;
            }
            if (pastingInTodo) {
              if (options.cursorPosition.beginningOfLine && util.paragraph.startsWithTodo(child)) {
                pasteTarget.parentNode.insertBefore(child, pasteTarget);
              } else {
                if (index === 0) {
                  var todo = util.paragraph.getLeadingTodo(child);
                  if (todo) {
                    goog.dom.removeNode(todo);
                  }
                } else {
                  if (!util.paragraph.startsWithTodo(child)) {
                    util.todo.addTodoToParagraph(child);
                  }
                }
                paragraphs.push(child);
              }
            } else {
              paragraphs.push(child);
            }
          }
        }
      }
    });
    if (pastingInTodo && !paragraphs.length) {
      return goog.editor.range.placeCursorNextTo(pasteTarget.previousSibling);
    }
    if (pastingInTable && paragraphs.length === 1 && dom.isEntable(paragraphs[0])) {
      var table = paragraphs[0].querySelector("table");
      return mergeTables(pasteTarget, table, range);
    }
    if (!util.structure.itemsAllowed(paragraphs, pasteTarget)) {
      var empty = true;
      paragraphs = paragraphs.map(function(p) {
        if (!util.structure.itemAllowed(p, pasteTarget)) {
          var div = goog.dom.createDom("div");
          goog.iter.forEach(p.attributes, function(attr) {
            div.setAttribute(attr.name, attr.value);
          });
          var text = copy.plain.copy(p);
          empty &= text.trim() === "";
          div.innerHTML = paste.plain.getContent(text);
          return div;
        } else {
          empty &= dom.isEmpty(p);
        }
        return p;
      });
      if (empty) {
        return false;
      }
    }
    return mergeContent(pasteTarget, paragraphs, range, options);
  };
  util.paste.getTarget = function(range) {
    if (!range) {
      return false;
    }
    var node = util.range.boundary(range.getStartNode(), range.getStartOffset()) || range.getStartNode();
    if (dom.isEnnote(node)) {
      return false;
    }
    var paragraph = goog.dom.getAncestor(node, dom.isBlockNode, true);
    if (dom.isEnnote(paragraph) || dom.isHr(paragraph)) {
      var siblings = dom.contiguousInlineSiblings(node);
      paragraph = goog.dom.createDom("div");
      goog.dom.insertSiblingBefore(paragraph, node);
      siblings.forEach(function(sibling) {
        paragraph.appendChild(sibling);
      });
    }
    return paragraph;
  };
  util.paste.normalizeOptions = function(input, context) {
    var opt = {values:[], matchStyle:input.matchStyle || false, select:false, enclipboard:false, pasteValue:"", resources:[]};
    var strInput = !!(typeof input === "string" && input);
    var oldInput = !!(typeof input === "object" && input.value);
    var newInput = !!(typeof input === "object" && input.values instanceof Array && input.values.find(function(payload) {
      return !!payload.value && (payload.type === MIME.TEXT_HTML || payload.type === MIME.TEXT_PLAIN);
    }));
    if (!strInput && !oldInput && !newInput) {
      return opt;
    }
    if (strInput) {
      opt.values.push({type:MIME.TEXT_HTML, value:input});
      opt.pasteValue = input;
    } else {
      if (newInput) {
        for (var i = input.values.length - 1; i >= 0; i--) {
          var obj = input.values[i];
          if (obj.type && obj.value) {
            opt.values.push(obj);
            if (obj.type === MIME.TEXT_HTML) {
              opt.pasteValue = obj.value;
            }
          }
        }
        if (input.resources instanceof Array) {
          opt.resources = input.resources;
        }
        if (!opt.pasteValue) {
          var plainValue = util.paste.getValueType(opt, MIME.TEXT_PLAIN);
          if (plainValue) {
            opt.pasteValue = util.paste.plain.getContent(plainValue);
          }
        }
      } else {
        if (oldInput) {
          opt.values.push({type:input.type === "plain" ? MIME.TEXT_PLAIN : MIME.TEXT_HTML, value:input.value});
          if (input.resources instanceof Array) {
            opt.resources = input.resources;
          }
          opt.pasteValue = input.type === "plain" ? util.paste.plain.getContent(input.value) : input.value;
        }
      }
    }
    var clipboardRegex = /-en-clipboard:\s*true;/g;
    var enclipboard = clipboardRegex.test(opt.pasteValue);
    opt.pasteValue = "<div>" + opt.pasteValue.replace(clipboardRegex, "") + "</div>";
    context.format = uno.defs.format.CLIPBOARD;
    context.copyPaste.externalContent = !enclipboard;
    (input.resources || []).forEach(function(res) {
      context.resources[res.id] = res;
    });
    return opt;
  };
  util.paste.getValueType = function(options, type) {
    var obj = options.values.find(function(payload) {
      return payload.type === type;
    });
    return obj ? obj.value : "";
  };
  util.paste.pasteOutside = function(formField, options) {
    if (formField) {
      var value = util.paste.getValueType(options, MIME.TEXT_PLAIN);
      if (!value) {
        var htmlValue = util.paste.getValueType(options, MIME.TEXT_HTML);
        if (htmlValue) {
          value = htmlValue.replace(/<br\/?>/gi, "\n");
        }
      }
      if (value) {
        value = value.replace(/<[^>]*>/g, "").replace(/\u00a0/g, " ").replace(/&nbsp;/g, "");
        return document.execCommand("insertText", null, value);
      }
    }
    return false;
  };
  function plainifyCodeBlock(node) {
    return goog.array.toArray(node.childNodes);
  }
  function plainifyCrypt(node) {
    return goog.array.toArray(node.childNodes);
  }
  function plainifyTable(table) {
    if (!table) {
      return;
    }
    var trs = goog.array.toArray(table.querySelectorAll("tr"));
    var content = goog.dom.createDom("div");
    goog.array.forEach(trs, function(tr) {
      var tds = tr.querySelectorAll("td");
      goog.array.forEach(tds, function(td) {
        goog.array.forEach(td.childNodes, function(paragraph) {
          if (paragraph.innerHTML === "<br>") {
            return;
          }
          content.appendChild(paragraph);
        });
      });
      var blankLine = goog.dom.createDom("div");
      blankLine.innerHTML = "<br>";
      content.appendChild(blankLine);
    });
    goog.dom.replaceNode(content, table);
    goog.dom.flattenElement(content);
  }
  function getCursorPosition(range) {
    var node = range.getStartNode();
    var offset = range.getStartOffset();
    var position = {beginningOfLine:false};
    if (dom.isTextNode(node)) {
      if (!node.parentNode.previousSibling && offset === 0) {
        position.beginningOfLine = true;
      }
    } else {
      if (offset === 0) {
        position.beginningOfLine = true;
      }
    }
    return position;
  }
  function isObject(node) {
    return dom.isEntable(node) || dom.isHeader(node) || dom.isTable(node) || dom.isCodeBlock(node) || dom.isBlockquote(node) || dom.isRevealedCrypt(node) || dom.isUl(node) || dom.isOl(node);
  }
  function stripStyles(clipboardContent) {
    goog.array.forEach(clipboardContent.querySelectorAll("*"), function(node) {
      if (node.removeAttribute) {
        node.removeAttribute("style");
      }
      if (node.tagName.match(/h[1-9]{1}/i)) {
        dom.changeTagName(node, "div");
      }
    });
  }
  function setStyles(clipboardContent, options) {
    if (options.matchStyle) {
      stripStyles(clipboardContent);
    }
    var currentStyles = util.styles.toStyleObject(options.currentStyles, options.defaultStyles);
    var paragraphs = util.paragraph.all(clipboardContent);
    goog.array.forEach(paragraphs, function(paragraph) {
      goog.array.forEach(paragraph.childNodes, function(child) {
        if (util.table.for(child)) {
          return;
        }
        var sourceStyle = {};
        if (!options.matchStyle) {
          sourceStyle = util.styles.getNodeStyle(child);
        }
        if (!options.enclipboard) {
        }
        Object.keys(currentStyles).forEach(function(key) {
          var value = currentStyles[key];
          if (value && (options.matchStyle || !options.enclipboard && !sourceStyle[key])) {
            sourceStyle[key] = value;
          }
        });
        var styles = util.styles.getStyleString(sourceStyle);
        if (styles) {
          if (dom.isTextNode(child)) {
            var node = goog.dom.createDom("span", null, child.textContent);
            child.parentNode.replaceChild(node, child);
            child = node;
          }
          child.setAttribute("style", styles);
        } else {
          if (!dom.isTextNode(child)) {
            child.removeAttribute("style");
          }
        }
      });
    });
  }
  function mergeContent(pasteTarget, paragraphs, range, options) {
    if (!paragraphs.length) {
      return false;
    }
    var shouldSplit = !!(paragraphs.length > 1 || isObject(paragraphs[0]));
    var pastingInList = goog.dom.getAncestor(pasteTarget, dom.isLi, true);
    var firstParagraph = paragraphs.shift();
    var lastParagraph = paragraphs.length ? paragraphs.pop() : null;
    var lastPara = lastParagraph || firstParagraph;
    var lastWord = dom.getLastParagraphItem(lastPara) || lastPara && lastPara.lastChild;
    var placeholder = goog.dom.createTextNode("");
    if (dom.isEmpty(pasteTarget)) {
      pasteTarget.innerHTML = "";
      pasteTarget.appendChild(placeholder);
    } else {
      var targetLastWord = dom.getLastParagraphItem(pasteTarget);
      if (dom.isBr(targetLastWord)) {
        goog.dom.removeNode(targetLastWord);
      }
      range.insertNode(placeholder);
      if (!goog.dom.contains(pasteTarget, placeholder)) {
        if (options.cursorPosition.beginningOfLine) {
          goog.dom.insertChildAt(pasteTarget, placeholder, 0);
        } else {
          pasteTarget.appendChild(placeholder);
        }
      }
    }
    if (shouldSplit) {
      var restOfParagraph = goog.editor.node.splitDomTreeAt(placeholder, null, pasteTarget);
      var lastItemInserted = pasteTarget;
      if (isObject(firstParagraph)) {
        goog.dom.insertSiblingAfter(firstParagraph, pasteTarget);
        goog.dom.removeNode(placeholder);
        lastItemInserted = firstParagraph;
        if (dom.isEmpty(pasteTarget)) {
          goog.dom.removeNode(pasteTarget);
        }
      } else {
        goog.dom.insertSiblingAfter(firstParagraph, placeholder);
        goog.dom.flattenElement(firstParagraph);
        goog.dom.removeNode(placeholder);
      }
      if (lastParagraph) {
        if (isObject(lastParagraph)) {
          goog.dom.insertSiblingAfter(lastParagraph, lastItemInserted);
          if (!dom.isEmpty(restOfParagraph)) {
            goog.dom.insertSiblingAfter(restOfParagraph, lastParagraph);
          }
        } else {
          goog.dom.insertSiblingAfter(restOfParagraph, lastItemInserted);
          if (dom.isEmpty(restOfParagraph)) {
            restOfParagraph.appendChild(lastParagraph);
          } else {
            goog.dom.insertSiblingBefore(lastParagraph, restOfParagraph.firstChild);
          }
          goog.dom.flattenElement(lastParagraph);
        }
      } else {
        if (!dom.isEmpty(restOfParagraph)) {
          goog.dom.insertSiblingAfter(restOfParagraph, lastItemInserted);
        }
      }
      while (paragraphs.length) {
        var node = paragraphs.shift();
        if (pastingInList && dom.isDiv(node)) {
          node = dom.changeTagName(node, "li");
        }
        goog.dom.insertSiblingAfter(node, lastItemInserted);
        lastItemInserted = node;
      }
      if (lastWord && lastWord.parentNode) {
        goog.editor.range.placeCursorNextTo(lastWord);
      }
    } else {
      goog.dom.replaceNode(firstParagraph, placeholder);
      goog.dom.flattenElement(firstParagraph);
    }
    if (lastWord && lastWord.parentNode) {
      return goog.editor.range.placeCursorNextTo(lastWord);
    }
    return false;
  }
  function mergeTables(pasteTarget, clipboardTable) {
    var td = goog.dom.getAncestor(pasteTarget, dom.isTd, true);
    var table = goog.dom.getAncestor(td, dom.isTable);
    var enTable = goog.dom.getAncestor(table, dom.isEntable);
    if (!enTable || !td) {
      return null;
    }
    var clipMatrix = util.table.matrix(clipboardTable);
    var matrix = util.table.matrix(table);
    var startRowIndex = util.table.rowIndex(td, false, matrix);
    var startColIndex = util.table.colIndex(td, false, matrix);
    var endRowIndex = startRowIndex + clipMatrix.length - 1;
    var endColIndex = startColIndex + clipMatrix[0].length - 1;
    var rowAddCount = Math.max(0, endRowIndex - (matrix.length - 1));
    var colAddCount = Math.max(0, endColIndex - (matrix[0].length - 1));
    var unmerged = false;
    var needfill = false;
    if (rowAddCount || colAddCount) {
      if (rowAddCount) {
        util.table.insertRows(enTable, matrix.length, rowAddCount);
      }
      if (colAddCount) {
        util.table.insertColumns(enTable, matrix[0].length, colAddCount);
      }
      matrix = util.table.matrix(table);
    }
    for (var r = endRowIndex; r >= startRowIndex; r--) {
      for (var c = endColIndex; c >= startColIndex; c--) {
        var info = matrix[r][c].info;
        var node = info.node;
        if (info.startRowIndex === r && info.startColIndex === c) {
          util.table.splitCell(node, matrix);
          unmerged = true;
          continue;
        }
        if (info.startRowIndex !== r && r === startRowIndex) {
          util.table.setRowSpan(node, r - info.startRowIndex);
          unmerged = true;
          needfill = true;
        }
        if (info.startColIndex !== c && c === startColIndex) {
          util.table.setColSpan(node, c - info.startColIndex);
          unmerged = true;
          needfill = true;
        }
      }
    }
    if (needfill) {
      matrix = util.table.matrix(table);
      matrix.forEach(function(row, rowIndex) {
        for (var colIndex = 0; colIndex < matrix[0].length; colIndex++) {
          if (row[colIndex] === undefined) {
            util.table.insertTd(util.table.createEmptyTd(), rowIndex, colIndex, table, matrix);
          }
        }
      });
    }
    if (unmerged) {
      matrix = util.table.matrix(table);
    }
    goog.array.forEachRight(clipMatrix, function(row, rowIndex) {
      goog.array.forEachRight(row, function(obj, colIndex) {
        var info = obj.info;
        if (info.startRowIndex !== rowIndex || info.startColIndex !== colIndex) {
          return;
        }
        var relativeRowIndex = rowIndex + startRowIndex;
        var relativeColIndex = colIndex + startColIndex;
        var targetTd;
        if (info.state & util.table.State.MERGED) {
          var rowOffset = info.endRowIndex - info.startRowIndex;
          var colOffset = info.endColIndex - info.startColIndex;
          var nodes = [];
          for (var r = relativeRowIndex; r <= relativeRowIndex + rowOffset; r++) {
            for (var c = relativeColIndex; c <= relativeColIndex + colOffset; c++) {
              nodes.push(matrix[r][c].info.node);
            }
          }
          targetTd = util.table.mergeCells(nodes);
        } else {
          targetTd = matrix[rowIndex + startRowIndex][colIndex + startColIndex].info.node;
        }
        targetTd.innerHTML = info.node.innerHTML;
        targetTd.style.backgroundColor = info.node.style.backgroundColor;
      });
    });
    var lastCellNode = matrix[endRowIndex][endColIndex].info.node;
    var leaf = dom.getLastParagraphItem(lastCellNode) || lastCellNode && lastCellNode.lastChild;
    if (leaf) {
      goog.editor.range.placeCursorNextTo(leaf);
    }
    return goog.dom.Range.createFromNodes(enTable, 0, enTable, enTable.childNodes.length);
  }
})();
goog.provide("uno.commands.Paste");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.editor.range");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.copy.plain");
goog.require("uno.util.dom");
goog.require("uno.util.img");
goog.require("uno.util.paste");
goog.require("uno.util.paste.plain");
goog.require("uno.util.table.selection");
goog.require("uno.util.normalize");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Paste");
  var util = uno.util;
  var dom = util.dom;
  var Paste = uno.commands.Paste = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Paste, uno.BasePlugin);
  Paste.prototype.isSupportedCommand = function(command) {
    return command === "paste" || command === "pasteplain";
  };
  Paste.prototype.queryCommandValue = function() {
    return true;
  };
  Paste.prototype.execCommand = function(command, value) {
    var editor = this.editor;
    var range = editor.getRange();
    var formField = editor.getFormField();
    var opt = util.paste.normalizeOptions(value, editor.context);
    if (!opt.pasteValue) {
      return false;
    }
    if (range && !goog.dom.getAncestor(range.getContainer(), uno.util.dom.isEnnote, true)) {
      return util.paste.pasteOutside(formField, opt);
    }
    if (!editor.multirange.isEmpty()) {
      var pasteCell = util.table.selection.getPasteCell();
      if (!pasteCell) {
        return false;
      }
      util.table.selection.clear();
      pasteCell.innerHTML = uno.defs.table.CELL_HTML;
      goog.editor.range.selectNodeStart(pasteCell);
    } else {
      if (!range) {
        editor.placeCursorAtEnd();
        range = editor.getRange();
        if (!range) {
          return false;
        }
      } else {
        if (!range.isCollapsed()) {
          editor.execCommand("delete", "selection", {smart:false});
          range = editor.getRange();
        }
      }
    }
    editor.dispatchBeforeChange();
    var cleanedContent = editor.prepareContentsHtml.call(editor, opt.pasteValue, {});
    if (opt.matchStyle) {
      cleanedContent = util.paste.plain.getContent(util.copy.plain.copy(dom.nodeFromHtml(cleanedContent)));
    }
    var currentStyles = {};
    goog.object.extend(currentStyles, editor.context.style.state, editor.context.style.value);
    var startRange = editor.getRange();
    var pasteRange = util.paste.paste(dom.nodeFromHtml(cleanedContent), editor.getRange(), {editor:editor, enclipboard:opt.enclipboard, matchStyle:opt.matchStyle, currentStyles:currentStyles, defaultStyles:{richTextFont:editor.config.defaults.richTextFont, fontName:editor.config.defaults.fontFamily, fontSize:editor.config.defaults.fontSize, fontColor:editor.config.defaults.foreColor}});
    uno.util.drop.handlePaste(!!pasteRange, editor.context.dragState, editor);
    if (!pasteRange) {
      return false;
    }
    var savedRange = editor.saveRange();
    editor.field.normalize();
    editor.dispatchChange();
    editor.restoreRange(savedRange);
    util.range.scrollSelectionIntoView(editor);
    if (opt.select) {
      pasteRange.moveToNodes(startRange.getStartNode(), startRange.getStartOffset(), pasteRange.getEndNode(), pasteRange.getEndOffset());
      pasteRange.select();
    }
    if (pasteRange) {
      this.dispatchEvent({type:uno.Editor.EventType.DOM_UPDATE, range:pasteRange, paste:true});
    }
    return true;
  };
})();
goog.provide("uno.commands.PlainText");
goog.require("goog.debug.Logger");
goog.require("goog.editor.Command");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.PlainText");
  var PlainText = uno.commands.PlainText = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(PlainText, uno.BasePlugin);
  PlainText.prototype.isSupportedCommand = function(command) {
    return command === "plaintext";
  };
  PlainText.prototype.activeOnUneditableFields = goog.functions.TRUE;
  PlainText.prototype.execCommandInternal = function() {
    this.editor.enterEditMode(true);
    this.editor.execCommand("selectall");
    var copyResults = this.editor.queryCommandValue("copy");
    this.editor.field.innerHTML = "";
    var plainText = goog.string.htmlEscape(copyResults.plain).replace(/  /g, " &nbsp;").split("\n").map(function(line) {
      return "<div>" + (line.trim() ? line : "<br>") + "</div>";
    }).join("\n");
    this.editor.setHtml(false, plainText);
    this.editor.execCommand("selectall");
    this.editor.execCommand("fontname", this.editor.config.defaults.plainTextFont);
    this.editor.placeCursorAtEnd();
    return true;
  };
})();
goog.provide("uno.commands.PrintPreview");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.classlist");
goog.require("goog.functions");
goog.require("goog.object");
goog.require("goog.array");
goog.require("goog.style");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.todo");
(function() {
  var util = uno.util;
  var log = goog.debug.Logger.getLogger("uno.commands.PrintPreview");
  var previousPreviewContainer;
  var PrintPreview = uno.commands.PrintPreview = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(PrintPreview, uno.BasePlugin);
  PrintPreview.CONTAINER_ID = "print-container";
  PrintPreview.HEADER_TITLE_ID = "header-title";
  PrintPreview.HEADER_TABLE_ID = "header-table";
  PrintPreview.HEADER_LABEL_CLASS = "header-table-label";
  PrintPreview.HEADER_TEXT_CLASS = "header-table-text";
  PrintPreview.PRINT_INSERT_CLASS = "en-print";
  PrintPreview.CHECKBOX_CLASS = "checkbox";
  PrintPreview.CHECKED_CLASS = "checked";
  PrintPreview.PDF_CLASS = "pdf";
  PrintPreview.AUDIO_CLASS = "audio";
  PrintPreview.GENERIC_ATTACHMENT_CLASS = "generic-attachment";
  PrintPreview.HTML_PRINT_CLASS = "printing";
  PrintPreview.prototype.isSupportedCommand = function(command) {
    return command === "printpreview";
  };
  PrintPreview.prototype.activeOnUneditableFields = goog.functions.TRUE;
  PrintPreview.prototype.execCommand = function(command, localization, options) {
    var field = this.editor.field;
    var parsedLocalization = parseLocalization(localization);
    var parsedOptions = parseOptions(options);
    if (parsedOptions.disable) {
      this.disable();
      return true;
    }
    var previewContainer = goog.dom.createDom("div", {id:PrintPreview.CONTAINER_ID, class:PrintPreview.PRINT_INSERT_CLASS});
    var addMetadata = !!parsedOptions && Object.keys(parsedOptions).some(function(key) {
      return key !== "title" && parsedOptions[key] != null;
    });
    if (addMetadata) {
      var metaDataHeader = generateMetadataHeader(parsedOptions, parsedLocalization);
      previewContainer.appendChild(metaDataHeader);
      var hr = goog.dom.createDom("hr");
      previewContainer.appendChild(hr);
      previewContainer.appendChild(createGap());
    }
    var titleText = parsedOptions && parsedOptions.title;
    if (titleText) {
      var title = createTitle(titleText);
      previewContainer.appendChild(title);
      previewContainer.appendChild(createGap());
    }
    var note = copyNote(field);
    replaceEmbeds(note, parsedLocalization);
    replaceTodos(note);
    previewContainer.innerHTML = previewContainer.innerHTML + note.innerHTML;
    field.style.display = "none";
    if (previousPreviewContainer) {
      goog.dom.replaceNode(previewContainer, previousPreviewContainer);
    } else {
      goog.dom.append(field.parentElement, previewContainer);
    }
    previousPreviewContainer = previewContainer;
    if (!this.editor.config.disableBackgroundPrint) {
      goog.dom.classlist.add(document.querySelector("html"), PrintPreview.HTML_PRINT_CLASS);
    }
    this.editor.dispatchEvent("printReady");
    return true;
  };
  PrintPreview.prototype.queryCommandValue = function() {
    return util.dom.isVisibleInView(document.getElementById("print-container"));
  };
  PrintPreview.prototype.disposeInternal = function() {
    this.disable();
  };
  PrintPreview.prototype.disable = function() {
    var field = this.editor && this.editor.field;
    if (field) {
      field.style.display = "";
    }
    if (previousPreviewContainer) {
      goog.dom.removeNode(previousPreviewContainer);
    }
    previousPreviewContainer = null;
    goog.dom.classlist.remove(document.querySelector("html"), PrintPreview.HTML_PRINT_CLASS);
  };
  function generateMetadataHeader(options, localization) {
    var table, tr, td, row, col, toInsert, tds, span1, span2;
    table = goog.dom.createDom("table", {id:PrintPreview.HEADER_TABLE_ID, class:PrintPreview.PRINT_INSERT_CLASS});
    for (row = 0; row < 4; row++) {
      tr = goog.dom.createDom("tr");
      table.appendChild(tr);
      for (col = 0; col < 2; col++) {
        td = goog.dom.createDom("td");
        tr.appendChild(td);
      }
    }
    toInsert = [[localization.author, "author"], [localization.notebook, "notebook"], [localization.created, "created"], [localization.tags, "tags"], [localization.updated, "updated"], [localization.url, "url"], [localization.deleted, "deleted"], [localization.location, "location"]];
    tds = table.querySelectorAll("td");
    toInsert.forEach(function(data, i) {
      if (options[data[1]] === null) {
        return;
      }
      tds[i].innerHTML = "";
      span1 = goog.dom.createDom("span", {class:PrintPreview.HEADER_LABEL_CLASS});
      span1.textContent = data[0];
      span2 = goog.dom.createDom("span", {class:PrintPreview.HEADER_TEXT_CLASS});
      span2.textContent = " " + options[data[1]];
      tds[i].appendChild(span1);
      tds[i].appendChild(span2);
    });
    return table;
  }
  function parseOptions(options) {
    var defaultOptions = {title:null, notebook:null, created:null, updated:null, deleted:null, author:null, location:null, tags:null, url:null};
    if (typeof options === "string") {
      try {
        options = JSON.parse(options);
      } catch (e) {
        return defaultOptions;
      }
    }
    var parsedOptions = goog.object.clone(options || {});
    goog.object.extend(defaultOptions, parsedOptions);
    return defaultOptions;
  }
  function parseLocalization(localization) {
    var defaultLocalization = {notebook:"Notebook:", created:"Created:", updated:"Updated:", deleted:"Deleted:", author:"Author:", location:"Location:", tags:"Tags:", url:"Source:", pdf_file:"PDF File", audio_file:"Audio File", generic_file:"Generic File"};
    var parsedLocalization = goog.object.clone(localization || {});
    goog.object.extend(defaultLocalization, parsedLocalization);
    return defaultLocalization;
  }
  function createGap() {
    return goog.dom.createDom("br", {class:PrintPreview.PRINT_INSERT_CLASS});
  }
  function createTitle(title) {
    var header = goog.dom.createDom("div", {id:PrintPreview.HEADER_TITLE_ID, class:PrintPreview.PRINT_INSERT_CLASS});
    header.textContent = title;
    return header;
  }
  function copyNote(noteElement) {
    if (!noteElement) {
      log.warning("Could not find note!");
      return document.createElement("div");
    }
    var clonedNote = noteElement.cloneNode(true);
    goog.array.forEach(clonedNote.childNodes, function(node) {
      if (node.nodeType !== Node.TEXT_NODE) {
        goog.dom.classlist.add(node, PrintPreview.PRINT_INSERT_CLASS);
      }
    });
    return clonedNote;
  }
  function replaceEmbeds(note, localization) {
    goog.array.forEach(note.querySelectorAll("embed"), function(embed) {
      var replacement = goog.dom.createDom("div", {class:PrintPreview.PRINT_INSERT_CLASS});
      switch(embed.getAttribute("type")) {
        case "evernote/x-pdf":
          goog.dom.classlist.add(replacement, PrintPreview.PDF_CLASS);
          replacement.textContent = localization.pdf_file;
          break;
        case "evernote/x-attachment":
          var id = embed.getAttribute("id");
          if (id && id.match(/.*en-media:audio.*/)) {
            goog.dom.classlist.add(replacement, PrintPreview.AUDIO_CLASS);
            replacement.textContent = localization.audio_file;
          } else {
            goog.dom.classlist.add(replacement, PrintPreview.GENERIC_ATTACHMENT_CLASS);
            replacement.textContent = localization.generic_file;
          }
          break;
        default:
          log.warning("Found <embed> with unknown type! " + embed);
          goog.dom.classlist.add(replacement, PrintPreview.GENERIC_ATTACHMENT_CLASS);
          replacement.textContent = localization.generic_file;
      }
      goog.dom.replaceNode(replacement, embed);
    });
  }
  function replaceTodos(note) {
    goog.array.forEach(util.todo.all(note), function(todo) {
      var replacement = goog.dom.createDom("div", {class:PrintPreview.PRINT_INSERT_CLASS + " " + PrintPreview.CHECKBOX_CLASS});
      if (util.todo.isChecked(todo)) {
        goog.dom.classlist.add(replacement, PrintPreview.CHECKED_CLASS);
      }
      goog.dom.replaceNode(replacement, todo);
    });
  }
})();
goog.provide("uno.commands.Redo");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Redo");
  var Redo = uno.commands.Redo = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Redo, uno.BasePlugin);
  Redo.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Redo.prototype.isSupportedCommand = function(command) {
    return command === "redo";
  };
  Redo.prototype.execCommand = function() {
    var formField = this.editor.getFormField();
    var result = false;
    if (formField) {
    } else {
      result = this.editor.execCommand(goog.editor.Command.REDO);
    }
    return result;
  };
  Redo.prototype.queryCommandValue = function() {
    return !!this.editor.queryCommandValue(goog.editor.Command.REDO);
  };
})();
goog.provide("uno.commands.RemoveFormat");
goog.require("goog.debug.Logger");
goog.require("goog.editor.Command");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.normalize");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.RemoveFormat");
  var util = uno.util;
  var RemoveFormat = uno.commands.RemoveFormat = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(RemoveFormat, uno.BasePlugin);
  RemoveFormat.prototype.isSupportedCommand = function(command) {
    return command === "removeformat";
  };
  RemoveFormat.prototype.activeOnUneditableFields = goog.functions.TRUE;
  RemoveFormat.prototype.execCommandInternal = function() {
    var editor = this.editor;
    var range = editor.getRange();
    var container = (!range || range.isCollapsed()) && editor.multirange.isEmpty() ? editor.field : range.getContainer();
    if (util.dom.isTextNode(container)) {
      container = container.parentNode;
    }
    if (range && !range.isCollapsed() && container === editor.field) {
      goog.array.forEachRight(container.childNodes, function(child) {
        if (range.containsNode(child, true)) {
          if (util.dom.isTextNode(child)) {
            child = child.parentNode;
          }
          util.normalize.normalizeNode(child, {editor:editor, removeFormat:true});
        }
      });
    } else {
      util.normalize.normalizeNode(container, {editor:editor, removeFormat:true});
    }
    return true;
  };
})();
goog.provide("uno.commands.Resources");
goog.require("goog.debug.Logger");
goog.require("goog.editor.range");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.img");
goog.require("uno.util.resource");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Resources");
  var util = uno.util;
  var Resources = uno.commands.Resources = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Resources, uno.BasePlugin);
  Resources.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Resources.prototype.isSupportedCommand = function(command) {
    return command === "resources";
  };
  Resources.prototype.execCommand = function(command, value) {
    var me = this;
    var editor = this.editor;
    var startedInEditMode = editor.inEditMode();
    var hasChanges = false;
    var hasInserts = false;
    if (!goog.isArray(value)) {
      value = [value];
    }
    hasChanges = value.some(function(dict) {
      if (dict.action === "insert" || dict.action === "delete") {
        return true;
      } else {
        if (dict.action === "update") {
          return goog.array.some(me.findElementsForDict(dict), function(el) {
            var existing = util.resource.dictFromElement(el);
            return dict.filename != null && dict.filename !== existing.filename || dict.filesize != null && dict.filesize !== existing.filesize || dict.hash != null && dict.hash !== existing.hash || dict.mime != null && dict.mime !== existing.mime || dict.url != null && dict.url !== existing.url;
          });
        }
      }
      return false;
    });
    hasInserts = value.some(function(dict) {
      return dict.action === "insert";
    });
    if (hasChanges) {
      editor.dispatchBeforeChange();
    }
    if (!startedInEditMode && hasInserts) {
      editor.enterEditMode(true);
    }
    var resourcesToAdd = [];
    value.forEach(function(dict) {
      if (dict.action === "insert") {
        if (dict.pos === "bottom") {
          editor.placeCursorAtEnd();
        }
        resourcesToAdd.push(me.add(dict));
      } else {
        if (dict.action === "update") {
          me.update(dict);
        } else {
          if (dict.action === "delete") {
            me.remove(dict);
          }
        }
      }
    });
    if (resourcesToAdd.length > 0) {
      var scrollTarget = resourcesToAdd[resourcesToAdd.length - 1];
      var scrollAfterLoad = util.resource.isImage(scrollTarget);
      var imagesToAdd = resourcesToAdd.filter(util.resource.isImage);
      var addResourcesPromise = imagesToAdd.map(util.img.ratioResizeIfNeeded);
      Promise.all(addResourcesPromise).then(function(resizes) {
        var shouldDispatchChange = resizes.some(function(img) {
          return !!img;
        });
        if (shouldDispatchChange) {
          editor.dispatchChange();
        }
        if (scrollAfterLoad) {
          scrollTarget.scrollIntoView();
        }
      });
      if (!scrollAfterLoad) {
        goog.editor.range.placeCursorNextTo(scrollTarget);
        scrollTarget.scrollIntoView();
      }
    }
    if (!startedInEditMode && hasInserts) {
      editor.blur();
    }
    if (hasChanges) {
      editor.dispatchChange();
    }
    return hasChanges;
  };
  Resources.prototype.add = function(dict) {
    var editor = this.editor;
    var enmedia = util.resource.createMediaFromDict(dict);
    var range = editor.getRange();
    var slug = util.resource.convertMediaToSlug(enmedia, dict, editor);
    var ref = dict.beforeRef || dict.afterRef;
    var refNode = dict.beforeRef || dict.afterRef ? util.resource.findByRef(ref, editor.field) : null;
    if (refNode) {
      if (dict.beforeRef) {
        goog.dom.insertSiblingBefore(slug, refNode);
      } else {
        goog.dom.insertSiblingAfter(slug, refNode);
      }
    } else {
      if (range && !util.dom.isEmpty(util.paragraph.for(range.getStartNode()))) {
        editor.execCommand("insertparagraph");
      }
      switch(dict.justify) {
        case "left":
        case "center":
        case "right":
          editor.execCommand("justify" + dict.justify);
          break;
        default:
      }
      editor.getRange().insertNode(slug);
      goog.editor.range.placeCursorNextTo(slug);
    }
    return slug;
  };
  Resources.prototype.update = function(dict) {
    var elements;
    var enmedia;
    var slug;
    var editor = this.editor;
    elements = this.findElementsForDict(dict);
    goog.array.forEach(elements, function(el) {
      var combodict = {};
      goog.object.extend(combodict, util.resource.dictFromElement(el), dict);
      enmedia = util.resource.createMediaFromDict(combodict);
      slug = util.resource.convertMediaToSlug(enmedia, combodict, editor);
      if (el._yxml != null) {
        slug._yxml = el._yxml;
        slug._yxml._dom = slug;
        slug._yjsHook = el._yjsHook;
        slug.dataset.yjsHook = "en-resource";
        el._yxml = null;
      }
      goog.dom.replaceNode(slug, el);
    });
  };
  Resources.prototype.remove = function(dict) {
    var elements = this.findElementsForDict(dict);
    goog.array.forEach(elements, function(el) {
      var par = util.paragraph.for(el);
      goog.dom.removeNode(el);
      if (util.dom.isEmpty(par)) {
        par.innerHTML = "<br>";
      }
    });
  };
  Resources.prototype.findElementsForDict = function(dict) {
    var elements;
    var el;
    if (dict.reference) {
      el = util.resource.findByRef(dict.reference, this.editor.field);
      elements = [];
      if (el) {
        elements.push(el);
      }
    } else {
      if (dict.originalURL) {
        elements = util.resource.findByURL(dict.originalURL, this.editor.field);
      } else {
        elements = util.resource.findByHash(dict.hash, this.editor.field);
      }
    }
    return elements;
  };
  Resources.prototype.queryCommandValue = function(command, opt) {
    var editor = this.editor;
    var range = editor.getRange();
    var sibling;
    var list = goog.array.map(util.resource.all(editor.field), function(el) {
      var dict = util.resource.toDict(el, range);
      if (opt === "neighbors") {
        sibling = el.previousElementSibling;
        if (util.resource.isResource(sibling)) {
          dict.prevNeighbour = util.resource.toDict(sibling, range);
        }
        sibling = el.nextElementSibling;
        if (util.resource.isResource(sibling)) {
          dict.nextNeighbour = util.resource.toDict(sibling, range);
        }
      }
      return dict;
    });
    return list;
  };
  Resources.prototype.queryCommandEnabled = function(command, value) {
    if (!goog.isArray(value)) {
      value = [value];
    }
    var hasInsert = value.some(function(dict) {
      return dict.action === "insert";
    });
    if (hasInsert) {
      var range = this.editor.getRange();
      return range && util.structure.itemAllowedInRange(uno.defs.structuretypes.RESOURCE, range);
    }
    return true;
  };
})();
goog.provide("uno.commands.RichlinksConvert");
goog.require("uno.BasePlugin");
goog.require("uno.util.richlink");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.RichlinksConvert");
  var RichlinksConvert = uno.commands.RichlinksConvert = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(RichlinksConvert, uno.BasePlugin);
  RichlinksConvert.prototype.isSupportedCommand = function(command) {
    return command === "richlinks.convert";
  };
  RichlinksConvert.prototype.execCommandInternal = function() {
    uno.util.dom.queryReverse(uno.defs.richlink.ANCHOR_ELEMENT_SELECTOR, document.body).forEach(function(node) {
      uno.util.richlink.handleLink(node, true);
      RichlinksConvert.editor.dispatchEvent({type:uno.Editor.EventType.DELAYEDCHANGE});
    });
  };
})();
goog.provide("uno.commands.RichlinksRefresh");
goog.require("uno.BasePlugin");
goog.require("uno.util.richlink");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.RichlinksRefresh");
  var RichlinksRefresh = uno.commands.RichlinksRefresh = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(RichlinksRefresh, uno.BasePlugin);
  RichlinksRefresh.prototype.isSupportedCommand = function(command) {
    return command === "richlinks.refresh";
  };
  RichlinksRefresh.prototype.execCommandInternal = function() {
  };
})();
goog.provide("uno.commands.Search");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.Range");
goog.require("goog.events.KeyCodes");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.loc");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Search");
  var util = uno.util;
  var KeyCodes = goog.events.KeyCodes;
  var ENTER = KeyCodes.ENTER;
  var TAB = KeyCodes.TAB;
  var ESC = KeyCodes.ESC;
  var Search = uno.commands.Search = function() {
    uno.BasePlugin.call(this, log.getName());
    this.panel = null;
    this.timer = null;
    this.index = 0;
    this.items = [];
  };
  goog.inherits(Search, uno.BasePlugin);
  Search.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Search.prototype.isSupportedCommand = function(command) {
    return command === "search";
  };
  Search.prototype.execCommand = function(command, show) {
    if (!this.panel) {
      this.createPanel();
    }
    if (show === false) {
      this.hide();
    } else {
      this.show();
    }
  };
  Search.prototype.queryCommandValue = function() {
    return this.find(this.getFindTerm());
  };
  Search.prototype.queryCommandEnabled = function() {
    return true;
  };
  Search.prototype.disposeInternal = function() {
    this.hide();
  };
  Search.prototype.onSearchFocus = function(event) {
    this.index = 0;
    this.find(this.getFindTerm());
  };
  Search.prototype.onCloseClick = function(event) {
    this.clearHighlights();
    this.hide();
  };
  Search.prototype.onFindNextClick = function(event) {
    if (this.items.length > 0) {
      this.index = this.index === this.items.length - 1 ? 0 : this.index + 1;
      this.highlight();
    }
  };
  Search.prototype.onFindPrevClick = function(event) {
    if (this.items.length > 0) {
      this.index = this.index === 0 ? this.items.length - 1 : this.index - 1;
      this.highlight();
    }
  };
  Search.prototype.onReplaceClick = function(event) {
    this.replace();
  };
  Search.prototype.onReplaceAllClick = function(event) {
    this.replace(true);
  };
  Search.prototype.onFindInput = function(event) {
    clearTimeout(this.timer);
    this.timer = setTimeout(this.find.bind(this, event.target.value), event.target.value ? 200 : 0);
  };
  Search.prototype.onFindKeyDown = function(event) {
    if (event.keyCode === ENTER || event.keyCode === TAB) {
      this.find(event.target.value);
    }
    this.onPanelKeyDown(event);
  };
  Search.prototype.onPanelKeyDown = function(event) {
    if (event.keyCode === ESC) {
      this.onCloseClick(event);
    } else {
      if (event.keyCode === ENTER && event.shiftKey) {
        this.onReplaceAllClick(event);
      }
    }
  };
  Search.prototype.onFindCaseCheckboxChanged = function(event) {
    this.index = 0;
    this.find(this.getFindTerm());
  };
  Search.prototype.show = function() {
    document.body.appendChild(this.panel);
    this.panel.querySelector(".en-find-input").focus();
  };
  Search.prototype.hide = function() {
    if (this.timer) {
      clearTimeout(this.timer);
    }
    this.index = 0;
    this.items = [];
    if (this.panel) {
      this.panel.querySelector(".en-find-input").value = null;
      this.panel.querySelector(".en-replace-input").value = null;
      this.panel.querySelector(".en-status-row").innerHTML = "";
      goog.dom.removeNode(this.panel);
    }
  };
  Search.prototype.find = function(term) {
    var result = term ? this.editor.queryCommandValue("find", {value:term, caseSensitive:this.getCaseSensitive(), includeRangeInfo:true}) : null;
    if (result && result.items) {
      this.items = result.items;
    } else {
      this.items = [];
      this.index = 0;
    }
    this.highlight();
    return result;
  };
  Search.prototype.replace = function(all) {
    var editor = this.editor;
    var term = this.getReplaceTerm();
    var items = all ? this.items : [this.items[this.index]];
    var replaced = false;
    goog.array.forEachRight(items, function(matches) {
      goog.array.forEachRight(matches, function(item) {
        var info = item.rangeInfo;
        if (util.dom.isTextNode(info.startNode) && info.startNode === info.endNode) {
          info.startNode.replaceData(info.startOffset, info.endOffset - info.startOffset, term);
          replaced = true;
        } else {
          var range = document.createRange();
          range.setStart(info.startNode, info.startOffset);
          range.setEnd(info.endNode, info.endOffset);
          var selection = window.getSelection();
          if (selection.rangeCount > 0) {
            selection.removeAllRanges();
          }
          selection.addRange(range);
          editor.execCommand("paste", {type:"plain", value:term});
        }
      });
    });
    if (replaced) {
      this.editor.dispatchChange();
    }
    if (this.index === this.items.length - 1) {
      this.index = 0;
    }
    this.find(this.getFindTerm());
  };
  Search.prototype.highlight = function() {
    this.editor.execCommand("accentuate", {clearFirst:true, boxes:this.items, selectedBoxIndex:this.index});
    this.updateStatus();
  };
  Search.prototype.clearHighlights = function() {
    this.editor.execCommand("accentuate", {clearFirst:true});
    this.updateStatus();
  };
  Search.prototype.getCaseSensitive = function() {
    if (this.panel) {
      return !!this.panel.querySelector(".en-find-case-checkbox").checked;
    } else {
      return false;
    }
  };
  Search.prototype.getFindTerm = function() {
    if (this.panel) {
      return this.panel.querySelector(".en-find-input").value;
    }
  };
  Search.prototype.getReplaceTerm = function() {
    if (this.panel) {
      return this.panel.querySelector(".en-replace-input").value || "";
    }
  };
  Search.prototype.updateStatus = function() {
    var status = this.panel && this.panel.querySelector(".en-status-row");
    var term = this.getFindTerm();
    if (status) {
      if (term) {
        if (this.items.length > 0) {
          status.innerHTML = [util.loc.t("Match"), this.index + 1, util.loc.t("of"), this.items.length].join(" ");
        } else {
          status.innerHTML = util.loc.t("No matches found");
        }
      } else {
        status.innerHTML = "";
      }
    }
  };
  Search.prototype.createPanel = function() {
    this.panel = goog.dom.createDom("en-search", null, [goog.dom.createDom("div", ["en-search-controls"], [goog.dom.createDom("div", ["en-search-row", "en-find-row"], [goog.dom.createDom("button", "en-search-close-btn"), goog.dom.createDom("input", {type:"text", placeholder:util.loc.t("Find text in note"), class:"en-search-input en-find-input", tabIndex:"10001"}), goog.dom.createDom("button", "en-find-next-btn", util.loc.t("Next")), goog.dom.createDom("button", "en-find-prev-btn", util.loc.t("Previous")), 
    goog.dom.createDom("input", {type:"checkbox", className:"en-find-case-checkbox"}), goog.dom.createDom("span", "en-find-match-case-text", util.loc.t("Match case"))]), goog.dom.createDom("div", ["en-search-row", "en-replace-row"], [goog.dom.createDom("input", {type:"text", placeholder:util.loc.t("Replace with"), class:"en-search-input en-replace-input", tabIndex:"10002"}), goog.dom.createDom("button", "en-replace-btn", util.loc.t("Replace")), goog.dom.createDom("button", "en-replace-all-btn", util.loc.t("Replace All"))])]), 
    goog.dom.createDom("div", ["en-search-row", "en-status-row"])]);
    this.editor.eventRegister.listenWithScope(this.panel, "focus", this.onSearchFocus, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-find-input"), "input", this.onFindInput, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-find-input"), "paste", this.onFindInput, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-find-input"), "keydown", this.onFindKeyDown, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-search-close-btn"), "click", this.onCloseClick, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-find-next-btn"), "click", this.onFindNextClick, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-find-prev-btn"), "click", this.onFindPrevClick, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-find-case-checkbox"), "change", this.onFindCaseCheckboxChanged, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-replace-btn"), "click", this.onReplaceClick, false, this);
    this.editor.eventRegister.listenWithScope(this.panel.querySelector(".en-replace-all-btn"), "click", this.onReplaceAllClick, false, this);
    this.editor.eventRegister.listenWithScope(this.panel, "focusout", this.clearHighlights, false, this);
    this.editor.eventRegister.listenWithScope(this.panel, "keydown", this.onPanelKeyDown, false, this);
  };
})();
goog.provide("uno.commands.SelectAll");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.Range");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.SelectAll");
  var dom = uno.util.dom;
  var SelectAll = uno.commands.SelectAll = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(SelectAll, uno.BasePlugin);
  SelectAll.SELECTOR = "en-note";
  SelectAll.prototype.isSupportedCommand = function(command) {
    return command === "selectall";
  };
  SelectAll.prototype.activeOnUneditableFields = goog.functions.TRUE;
  SelectAll.prototype.execCommand = function() {
    var currentRange = this.editor.getRange();
    if (dom.parent(currentRange.getContainerElement(), "en-search")) {
      currentRange.getContainerElement().querySelector("input[type=text]").select();
      return false;
    }
    var contentElement = goog.dom.getElement(SelectAll.SELECTOR);
    var range = goog.dom.Range.createFromNodeContents(contentElement);
    range.select();
    return true;
  };
  SelectAll.prototype.queryCommandValue = function() {
  };
})();
goog.provide("uno.commands.Selection");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Selection");
  var util = uno.util;
  var Selection = uno.commands.Selection = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Selection, uno.BasePlugin);
  Selection.prototype.isSupportedCommand = function(command) {
    return command === "selection";
  };
  Selection.prototype.execCommand = function(command, selectionPath) {
    try {
      var path = selectionPath;
      var startNode = getNodeFromPath(this.editor.field, path.startNode);
      var endNode = getNodeFromPath(this.editor.field, path.endNode);
      var range = goog.dom.Range.createFromNodes(startNode, path.startOffset, endNode, path.endOffset);
      this.editor.restoreRange(range);
      return true;
    } catch (err$11) {
      log.warning("could not restore the range");
      log.fine(err$11.stack || err$11);
      return false;
    }
  };
  Selection.prototype.queryCommandValue = function() {
    var range = this.editor.getRange();
    if (range) {
      var path = {startNode:getNodePath(range.getStartNode()), endNode:getNodePath(range.getEndNode()), startOffset:range.getStartOffset(), endOffset:range.getEndOffset(), collapsed:range.isCollapsed()};
      return path;
    }
    return "";
  };
  function getNodePath(node) {
    var path = [];
    goog.dom.getAncestor(node, function(element) {
      if (util.dom.isEnnote(element)) {
        return true;
      }
      path.unshift(util.dom.index(element));
      return false;
    }, true);
    return path;
  }
  function getNodeFromPath(root, path) {
    var node = root;
    path.forEach(function(index) {
      if (node.childNodes) {
        node = node.childNodes[index];
      }
    });
    return node;
  }
})();
goog.provide("uno.commands.SimpleText");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.functions");
goog.require("goog.editor.range");
goog.require("goog.style");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.n3");
goog.require("uno.util.range");
goog.require("uno.util.table.selection");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.SimpleText");
  var util = uno.util;
  var SimpleText = uno.commands.SimpleText = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(SimpleText, uno.BasePlugin);
  SimpleText.prototype.isSupportedCommand = function(command) {
    return command === "simpletext";
  };
  SimpleText.prototype.activeOnUneditableFields = goog.functions.TRUE;
  SimpleText.prototype.execCommandInternal = function() {
    var editor = this.editor;
    var range = editor.getRange();
    var container = (!range || range.isCollapsed()) && editor.multirange.isEmpty() ? editor.field : range.getContainer();
    if (util.dom.isTextNode(container)) {
      container = container.parentNode;
    }
    uno.util.table.selection.clear();
    if (range && !range.isCollapsed() && container === editor.field) {
      goog.array.forEachRight(container.childNodes, function(child) {
        if (range.containsNode(child, true)) {
          if (util.dom.isTextNode(child)) {
            child = child.parentNode;
          }
          util.n3.normalizeNode(child, {editor:editor, simplifyFormat:true});
        }
      });
    } else {
      util.n3.normalizeNode(container, {editor:editor, simplifyFormat:true});
    }
    return true;
  };
})();
goog.provide("uno.util.link");
goog.require("goog.debug.Logger");
(function() {
  var util = uno.util;
  util.link.all = function(root) {
    return root.querySelectorAll("a[href]");
  };
})();
goog.provide("uno.commands.Stats");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.link");
goog.require("uno.util.todo");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Stats");
  var util = uno.util;
  var Stats = uno.commands.Stats = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Stats, uno.BasePlugin);
  Stats.prototype.isSupportedCommand = function(command) {
    return command === "stats";
  };
  Stats.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Stats.prototype.queryCommandEnabled = goog.functions.TRUE;
  Stats.prototype.queryCommandValue = function() {
    var stats = {};
    stats.isEmpty = util.dom.isEmpty(this.editor.field);
    stats.isDirty = this.editor.queryCommandValue("changes");
    stats.isReadOnly = this.editor.readOnly;
    stats.isEditable = this.editor.inEditMode();
    stats.hasFocus = this.editor.isFocused();
    stats.todo = util.todo.all(this.editor.field).length;
    stats.link = util.link.all(this.editor.field).length;
    stats.firstLine = this.editor.field.innerText.trim().split("\n").shift();
    stats.selection = this.editor.queryCommandValue("selection");
    stats.lastSelection = null;
    return stats;
  };
})();
goog.provide("uno.commands.Strikethrough");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Strikethrough");
  var Strikethrough = uno.commands.Strikethrough = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(Strikethrough, uno.BasePlugin);
  Strikethrough.prototype.isSupportedCommand = function(command) {
    return command === "strikethrough";
  };
  Strikethrough.prototype.execCommand = function() {
    var range = this.editor.getRange();
    var underlined = this.editor.context.style.state.underline;
    if (!range.isCollapsed()) {
      var result = this.editor.execCommand(goog.editor.Command.STRIKE_THROUGH);
      this.editor.dispatchChange();
      this.editor.dispatchStyleChange();
      return result;
    }
    if (underlined) {
      document.execCommand("insertText", null, uno.defs.unicode.ZERO_WIDTH_SPACE);
      var updatedRange = this.editor.getRange();
      var node = updatedRange.getStartNode();
      var startOffset = updatedRange.getStartOffset();
      var newRange = goog.dom.Range.createFromNodes(node, startOffset - 1, node, startOffset);
      newRange.select();
      this.editor.execCommand(goog.editor.Command.STRIKE_THROUGH);
      newRange.collapse();
      newRange.select();
    } else {
      var currentState = this.editor.context.style.state.strikethrough;
      this.editor.execCommand(goog.editor.Command.STRIKE_THROUGH);
      this.editor.dispatchStyleChange({state:{strikethrough:!currentState, underline:underlined}, value:{}, enabled:{}});
    }
    return true;
  };
  Strikethrough.prototype.queryCommandValue = function() {
    return this.editor.queryCommandValue(goog.editor.Command.STRIKE_THROUGH);
  };
})();
goog.provide("uno.commands.Tab");
goog.require("goog.debug.Logger");
goog.require("goog.events.BrowserEvent");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Tab");
  var Tab = uno.commands.Tab = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Tab, uno.BasePlugin);
  Tab.prototype.isSupportedCommand = function(command) {
    return command === "tab";
  };
  Tab.prototype.execCommandInternal = function(command, options) {
    var event = document.createEvent("Event");
    var browserEvent = new goog.events.BrowserEvent(event);
    browserEvent.shiftKey = options === true;
    browserEvent.keyCode = goog.events.KeyCodes.TAB;
    this.editor.handleKeyDown_(browserEvent);
  };
  Tab.prototype.queryCommandValue = function() {
    return null;
  };
  Tab.prototype.queryCommandEnabled = function() {
    return true;
  };
})();
goog.provide("uno.commands.Underline");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.EditorMultiRange");
goog.require("uno.util.range");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Underline");
  var Underline = uno.commands.Underline = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(Underline, uno.BasePlugin);
  Underline.prototype.isSupportedCommand = function(command) {
    return command === "underline";
  };
  Underline.prototype.execCommand = function() {
    var range = this.editor.getRange();
    var strikethrough = this.editor.context.style.state.strikethrough;
    if (!range.isCollapsed()) {
      var result = this.editor.execCommand(goog.editor.Command.UNDERLINE);
      this.editor.dispatchChange();
      this.editor.dispatchStyleChange();
      return result;
    }
    if (strikethrough) {
      document.execCommand("insertText", null, uno.defs.unicode.ZERO_WIDTH_SPACE);
      var updatedRange = this.editor.getRange();
      var node = updatedRange.getStartNode();
      var startOffset = updatedRange.getStartOffset();
      var newRange = goog.dom.Range.createFromNodes(node, startOffset - 1, node, startOffset);
      newRange.select();
      this.editor.execCommand(goog.editor.Command.UNDERLINE);
      newRange.collapse();
      newRange.select();
    } else {
      var currentState = this.editor.context.style.state.underline;
      this.editor.execCommand(goog.editor.Command.UNDERLINE);
      this.editor.dispatchStyleChange({state:{underline:!currentState, strikethrough:strikethrough}, value:{}, enabled:{}});
    }
    return true;
  };
  Underline.prototype.queryCommandValue = function() {
    return this.editor.queryCommandValue(goog.editor.Command.UNDERLINE);
  };
})();
goog.provide("uno.commands.Undo");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Undo");
  var Undo = uno.commands.Undo = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Undo, uno.BasePlugin);
  Undo.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Undo.prototype.isSupportedCommand = function(command) {
    return command === "undo";
  };
  Undo.prototype.execCommand = function() {
    var formField = this.editor.getFormField();
    var result = false;
    if (formField) {
    } else {
      result = this.editor.execCommand(goog.editor.Command.UNDO);
    }
    return result;
  };
  Undo.prototype.queryCommandValue = function() {
    return !!this.editor.queryCommandValue(goog.editor.Command.UNDO);
  };
})();
goog.provide("goog.editor.plugins.UndoRedoState");
goog.require("goog.events.EventTarget");
goog.editor.plugins.UndoRedoState = function(asynchronous) {
  goog.editor.plugins.UndoRedoState.base(this, "constructor");
  this.asynchronous_ = asynchronous;
};
goog.inherits(goog.editor.plugins.UndoRedoState, goog.events.EventTarget);
goog.editor.plugins.UndoRedoState.ACTION_COMPLETED = "action_completed";
goog.editor.plugins.UndoRedoState.prototype.isAsynchronous = function() {
  return this.asynchronous_;
};
goog.editor.plugins.UndoRedoState.prototype.undo = goog.abstractMethod;
goog.editor.plugins.UndoRedoState.prototype.redo = goog.abstractMethod;
goog.editor.plugins.UndoRedoState.prototype.equals = goog.abstractMethod;
goog.provide("goog.editor.plugins.UndoRedoManager");
goog.provide("goog.editor.plugins.UndoRedoManager.EventType");
goog.require("goog.editor.plugins.UndoRedoState");
goog.require("goog.events");
goog.require("goog.events.EventTarget");
goog.editor.plugins.UndoRedoManager = function() {
  goog.events.EventTarget.call(this);
  this.maxUndoDepth_ = 100;
  this.undoStack_ = [];
  this.redoStack_ = [];
  this.pendingActions_ = [];
};
goog.inherits(goog.editor.plugins.UndoRedoManager, goog.events.EventTarget);
goog.editor.plugins.UndoRedoManager.EventType = {STATE_CHANGE:"state_change", STATE_ADDED:"state_added", BEFORE_UNDO:"before_undo", BEFORE_REDO:"before_redo"};
goog.editor.plugins.UndoRedoManager.prototype.inProgressActionKey_ = null;
goog.editor.plugins.UndoRedoManager.prototype.setMaxUndoDepth = function(depth) {
  this.maxUndoDepth_ = depth;
};
goog.editor.plugins.UndoRedoManager.prototype.addState = function(state) {
  if (this.undoStack_.length == 0 || !state.equals(this.undoStack_[this.undoStack_.length - 1])) {
    this.undoStack_.push(state);
    if (this.undoStack_.length > this.maxUndoDepth_) {
      this.undoStack_.shift();
    }
    var redoLength = this.redoStack_.length;
    this.redoStack_.length = 0;
    this.dispatchEvent({type:goog.editor.plugins.UndoRedoManager.EventType.STATE_ADDED, state:state});
    if (this.undoStack_.length == 1 || redoLength) {
      this.dispatchStateChange_();
    }
  }
};
goog.editor.plugins.UndoRedoManager.prototype.dispatchStateChange_ = function() {
  this.dispatchEvent(goog.editor.plugins.UndoRedoManager.EventType.STATE_CHANGE);
};
goog.editor.plugins.UndoRedoManager.prototype.undo = function() {
  this.shiftState_(this.undoStack_, this.redoStack_);
};
goog.editor.plugins.UndoRedoManager.prototype.redo = function() {
  this.shiftState_(this.redoStack_, this.undoStack_);
};
goog.editor.plugins.UndoRedoManager.prototype.hasUndoState = function() {
  return this.undoStack_.length > 0;
};
goog.editor.plugins.UndoRedoManager.prototype.hasRedoState = function() {
  return this.redoStack_.length > 0;
};
goog.editor.plugins.UndoRedoManager.prototype.shiftState_ = function(fromStack, toStack) {
  if (fromStack.length) {
    var state = fromStack.pop();
    toStack.push(state);
    this.addAction_({type:fromStack == this.undoStack_ ? goog.editor.plugins.UndoRedoManager.EventType.BEFORE_UNDO : goog.editor.plugins.UndoRedoManager.EventType.BEFORE_REDO, func:fromStack == this.undoStack_ ? state.undo : state.redo, state:state});
    if (fromStack.length == 0 || toStack.length == 1) {
      this.dispatchStateChange_();
    }
  }
};
goog.editor.plugins.UndoRedoManager.prototype.addAction_ = function(action) {
  this.pendingActions_.push(action);
  if (this.pendingActions_.length == 1) {
    this.doAction_();
  }
};
goog.editor.plugins.UndoRedoManager.prototype.doAction_ = function() {
  if (this.inProgressActionKey_ || this.pendingActions_.length == 0) {
    return;
  }
  var action = this.pendingActions_.shift();
  var e = {type:action.type, state:action.state};
  if (this.dispatchEvent(e)) {
    if (action.state.isAsynchronous()) {
      this.inProgressActionKey_ = goog.events.listen(action.state, goog.editor.plugins.UndoRedoState.ACTION_COMPLETED, this.finishAction_, false, this);
      action.func.call(action.state);
    } else {
      action.func.call(action.state);
      this.doAction_();
    }
  }
};
goog.editor.plugins.UndoRedoManager.prototype.finishAction_ = function() {
  goog.events.unlistenByKey(this.inProgressActionKey_);
  this.inProgressActionKey_ = null;
  this.doAction_();
};
goog.editor.plugins.UndoRedoManager.prototype.clearHistory = function() {
  if (this.undoStack_.length > 0 || this.redoStack_.length > 0) {
    this.undoStack_.length = 0;
    this.redoStack_.length = 0;
    this.dispatchStateChange_();
  }
};
goog.editor.plugins.UndoRedoManager.prototype.undoPeek = function() {
  return this.undoStack_[this.undoStack_.length - 1];
};
goog.editor.plugins.UndoRedoManager.prototype.redoPeek = function() {
  return this.redoStack_[this.redoStack_.length - 1];
};
goog.provide("goog.editor.plugins.UndoRedo");
goog.require("goog.dom");
goog.require("goog.dom.NodeOffset");
goog.require("goog.dom.Range");
goog.require("goog.editor.BrowserFeature");
goog.require("goog.editor.Command");
goog.require("goog.editor.Field");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.node");
goog.require("goog.editor.plugins.UndoRedoManager");
goog.require("goog.editor.plugins.UndoRedoState");
goog.require("goog.events");
goog.require("goog.events.EventHandler");
goog.require("goog.log");
goog.require("goog.object");
goog.editor.plugins.UndoRedo = function(opt_manager) {
  goog.editor.Plugin.call(this);
  this.setUndoRedoManager(opt_manager || new goog.editor.plugins.UndoRedoManager);
  this.eventHandlers_ = {};
  this.currentStates_ = {};
  this.initialFieldChange_ = null;
  this.boundRestoreState_ = goog.bind(this.restoreState, this);
};
goog.inherits(goog.editor.plugins.UndoRedo, goog.editor.Plugin);
goog.editor.plugins.UndoRedo.prototype.logger = goog.log.getLogger("goog.editor.plugins.UndoRedo");
goog.editor.plugins.UndoRedo.prototype.inProgressUndo_ = null;
goog.editor.plugins.UndoRedo.prototype.undoManager_;
goog.editor.plugins.UndoRedo.prototype.managerStateChangeKey_;
goog.editor.plugins.UndoRedo.COMMAND = {UNDO:"+undo", REDO:"+redo"};
goog.editor.plugins.UndoRedo.SUPPORTED_COMMANDS_ = goog.object.transpose(goog.editor.plugins.UndoRedo.COMMAND);
goog.editor.plugins.UndoRedo.prototype.setMaxUndoDepth = function(depth) {
  this.undoManager_.setMaxUndoDepth(depth);
};
goog.editor.plugins.UndoRedo.prototype.setUndoRedoManager = function(manager) {
  if (this.managerStateChangeKey_) {
    goog.events.unlistenByKey(this.managerStateChangeKey_);
  }
  this.undoManager_ = manager;
  this.managerStateChangeKey_ = goog.events.listen(this.undoManager_, goog.editor.plugins.UndoRedoManager.EventType.STATE_CHANGE, this.dispatchCommandValueChange_, false, this);
};
goog.editor.plugins.UndoRedo.prototype.isSupportedCommand = function(command) {
  return command in goog.editor.plugins.UndoRedo.SUPPORTED_COMMANDS_;
};
goog.editor.plugins.UndoRedo.prototype.unregisterFieldObject = function(fieldObject) {
  this.disable(fieldObject);
  this.setFieldObject(null);
};
goog.editor.plugins.UndoRedo.prototype.getCurrentFieldObject = function() {
  return this.getFieldObject();
};
goog.editor.plugins.UndoRedo.prototype.getFieldObjectForHash = function(fieldHashCode) {
  return this.getFieldObject();
};
goog.editor.plugins.UndoRedo.prototype.getCurrentEventTarget = function() {
  return this.getFieldObject();
};
goog.editor.plugins.UndoRedo.prototype.enable = function(fieldObject) {
  if (this.isEnabled(fieldObject)) {
    return;
  }
  fieldObject.clearDelayedChange();
  var eventHandler = new goog.events.EventHandler(this);
  if (!goog.editor.BrowserFeature.USE_MUTATION_EVENTS) {
    eventHandler.listen(fieldObject, goog.editor.Field.EventType.BEFORECHANGE, this.handleBeforeChange_);
  }
  eventHandler.listen(fieldObject, goog.editor.Field.EventType.DELAYEDCHANGE, this.handleDelayedChange_);
  eventHandler.listen(fieldObject, goog.editor.Field.EventType.BLUR, this.handleBlur_);
  this.eventHandlers_[fieldObject.getHashCode()] = eventHandler;
  this.updateCurrentState_(fieldObject);
};
goog.editor.plugins.UndoRedo.prototype.disable = function(fieldObject) {
  fieldObject.clearDelayedChange();
  var eventHandler = this.eventHandlers_[fieldObject.getHashCode()];
  if (eventHandler) {
    eventHandler.dispose();
    delete this.eventHandlers_[fieldObject.getHashCode()];
  }
  if (this.currentStates_[fieldObject.getHashCode()]) {
    delete this.currentStates_[fieldObject.getHashCode()];
  }
};
goog.editor.plugins.UndoRedo.prototype.isEnabled = function(fieldObject) {
  return !!this.eventHandlers_[fieldObject.getHashCode()];
};
goog.editor.plugins.UndoRedo.prototype.disposeInternal = function() {
  goog.editor.plugins.UndoRedo.superClass_.disposeInternal.call(this);
  for (var hashcode in this.eventHandlers_) {
    this.eventHandlers_[hashcode].dispose();
    delete this.eventHandlers_[hashcode];
  }
  this.setFieldObject(null);
  if (this.undoManager_) {
    this.undoManager_.dispose();
    delete this.undoManager_;
  }
};
goog.editor.plugins.UndoRedo.prototype.getTrogClassId = function() {
  return "UndoRedo";
};
goog.editor.plugins.UndoRedo.prototype.execCommand = function(command, var_args) {
  if (command == goog.editor.plugins.UndoRedo.COMMAND.UNDO) {
    this.undoManager_.undo();
  } else {
    if (command == goog.editor.plugins.UndoRedo.COMMAND.REDO) {
      this.undoManager_.redo();
    }
  }
};
goog.editor.plugins.UndoRedo.prototype.queryCommandValue = function(command) {
  var state = null;
  if (command == goog.editor.plugins.UndoRedo.COMMAND.UNDO) {
    state = this.undoManager_.hasUndoState();
  } else {
    if (command == goog.editor.plugins.UndoRedo.COMMAND.REDO) {
      state = this.undoManager_.hasRedoState();
    }
  }
  return state;
};
goog.editor.plugins.UndoRedo.prototype.dispatchCommandValueChange_ = function() {
  var eventTarget = this.getCurrentEventTarget();
  eventTarget.dispatchEvent({type:goog.editor.Field.EventType.COMMAND_VALUE_CHANGE, commands:[goog.editor.plugins.UndoRedo.COMMAND.REDO, goog.editor.plugins.UndoRedo.COMMAND.UNDO]});
};
goog.editor.plugins.UndoRedo.prototype.restoreState = function(state, content, cursorPosition) {
  var fieldObj = this.getFieldObjectForHash(state.fieldHashCode);
  if (!fieldObj) {
    return;
  }
  fieldObj.stopChangeEvents(true, true);
  try {
    fieldObj.dispatchBeforeChange();
    fieldObj.execCommand(goog.editor.Command.CLEAR_LOREM, true);
    goog.editor.node.replaceInnerHtml(fieldObj.getElement(), content);
    if (cursorPosition) {
      cursorPosition.select();
    }
    var previousFieldObject = this.getCurrentFieldObject();
    fieldObj.focus();
    if (previousFieldObject && previousFieldObject.getHashCode() != state.fieldHashCode) {
      previousFieldObject.execCommand(goog.editor.Command.UPDATE_LOREM);
    }
    this.currentStates_[state.fieldHashCode].setUndoState(content, cursorPosition);
  } catch (e) {
    goog.log.error(this.logger, "Error while restoring undo state", e);
  } finally {
    this.inProgressUndo_ = state;
    fieldObj.dispatchChange();
    fieldObj.dispatchSelectionChangeEvent();
  }
};
goog.editor.plugins.UndoRedo.prototype.handleKeyboardShortcut = function(e, key, isModifierPressed) {
  if (isModifierPressed) {
    var command;
    if (key == "z") {
      command = e.shiftKey ? goog.editor.plugins.UndoRedo.COMMAND.REDO : goog.editor.plugins.UndoRedo.COMMAND.UNDO;
    } else {
      if (key == "y") {
        command = goog.editor.plugins.UndoRedo.COMMAND.REDO;
      }
    }
    if (command) {
      var state = command == goog.editor.plugins.UndoRedo.COMMAND.UNDO ? this.undoManager_.undoPeek() : this.undoManager_.redoPeek();
      if (state && state.fieldHashCode) {
        this.getCurrentFieldObject().execCommand(command);
      } else {
        this.execCommand(command);
      }
      return true;
    }
  }
  return false;
};
goog.editor.plugins.UndoRedo.prototype.clearHistory = function() {
  this.getFieldObject().stopChangeEvents(true, true);
  this.undoManager_.clearHistory();
  this.getFieldObject().startChangeEvents();
};
goog.editor.plugins.UndoRedo.prototype.refreshCurrentState = function(fieldObject) {
  if (this.isEnabled(fieldObject)) {
    if (this.currentStates_[fieldObject.getHashCode()]) {
      delete this.currentStates_[fieldObject.getHashCode()];
    }
    this.updateCurrentState_(fieldObject);
  }
};
goog.editor.plugins.UndoRedo.prototype.handleBeforeChange_ = function(e) {
  if (this.inProgressUndo_) {
    return;
  }
  var fieldObj = e.target;
  var fieldHashCode = fieldObj.getHashCode();
  if (this.initialFieldChange_ != fieldHashCode) {
    this.initialFieldChange_ = fieldHashCode;
    this.updateCurrentState_(fieldObj);
  }
};
goog.editor.plugins.UndoRedo.prototype.handleDelayedChange_ = function(e) {
  if (this.inProgressUndo_) {
    var state = this.inProgressUndo_;
    this.inProgressUndo_ = null;
    state.dispatchEvent(goog.editor.plugins.UndoRedoState.ACTION_COMPLETED);
    return;
  }
  this.updateCurrentState_(e.target);
};
goog.editor.plugins.UndoRedo.prototype.handleBlur_ = function(e) {
  var fieldObj = e.target;
  if (fieldObj) {
    fieldObj.clearDelayedChange();
  }
};
goog.editor.plugins.UndoRedo.prototype.getCursorPosition_ = function(fieldObj) {
  var cursorPos = new goog.editor.plugins.UndoRedo.CursorPosition_(fieldObj);
  if (!cursorPos.isValid()) {
    return null;
  }
  return cursorPos;
};
goog.editor.plugins.UndoRedo.prototype.updateCurrentState_ = function(fieldObj) {
  var fieldHashCode = fieldObj.getHashCode();
  var content, cursorPos;
  if (fieldObj.queryCommandValue(goog.editor.Command.USING_LOREM)) {
    content = "";
    cursorPos = null;
  } else {
    content = fieldObj.getElement().innerHTML;
    cursorPos = this.getCursorPosition_(fieldObj);
  }
  var currentState = this.currentStates_[fieldHashCode];
  if (currentState) {
    if (currentState.undoContent_ == content) {
      return;
    } else {
      if (content == "" || currentState.undoContent_ == "") {
        var emptyContents = fieldObj.getInjectableContents("", {});
        if (content == emptyContents && currentState.undoContent_ == "" || currentState.undoContent_ == emptyContents && content == "") {
          return;
        }
      }
    }
    currentState.setRedoState(content, cursorPos);
    this.undoManager_.addState(currentState);
  }
  this.currentStates_[fieldHashCode] = new goog.editor.plugins.UndoRedo.UndoState_(fieldHashCode, content, cursorPos, this.boundRestoreState_);
};
goog.editor.plugins.UndoRedo.UndoState_ = function(fieldHashCode, content, cursorPosition, restore) {
  goog.editor.plugins.UndoRedoState.call(this, true);
  this.fieldHashCode = fieldHashCode;
  this.restore_ = restore;
  this.setUndoState(content, cursorPosition);
};
goog.inherits(goog.editor.plugins.UndoRedo.UndoState_, goog.editor.plugins.UndoRedoState);
goog.editor.plugins.UndoRedo.UndoState_.prototype.undoContent_;
goog.editor.plugins.UndoRedo.UndoState_.prototype.undoCursorPosition_;
goog.editor.plugins.UndoRedo.UndoState_.prototype.redoContent_;
goog.editor.plugins.UndoRedo.UndoState_.prototype.redoCursorPosition_;
goog.editor.plugins.UndoRedo.UndoState_.prototype.undo = function() {
  this.restore_(this, this.undoContent_, this.undoCursorPosition_);
};
goog.editor.plugins.UndoRedo.UndoState_.prototype.redo = function() {
  this.restore_(this, this.redoContent_, this.redoCursorPosition_);
};
goog.editor.plugins.UndoRedo.UndoState_.prototype.setUndoState = function(content, cursorPosition) {
  this.undoContent_ = content;
  this.undoCursorPosition_ = cursorPosition;
};
goog.editor.plugins.UndoRedo.UndoState_.prototype.setRedoState = function(content, cursorPosition) {
  this.redoContent_ = content;
  this.redoCursorPosition_ = cursorPosition;
};
goog.editor.plugins.UndoRedo.UndoState_.prototype.equals = function(rhs) {
  return this.fieldHashCode == rhs.fieldHashCode && this.undoContent_ == rhs.undoContent_ && this.redoContent_ == rhs.redoContent_;
};
goog.editor.plugins.UndoRedo.CursorPosition_ = function(field) {
  this.field_ = field;
  var win = field.getEditableDomHelper().getWindow();
  var range = field.getRange();
  var isValidRange = !!range && range.isRangeInDocument() && range.getWindow() == win;
  range = isValidRange ? range : null;
  if (goog.editor.BrowserFeature.HAS_W3C_RANGES) {
    this.initW3C_(range);
  } else {
    if (goog.editor.BrowserFeature.HAS_IE_RANGES) {
      this.initIE_(range);
    }
  }
};
goog.editor.plugins.UndoRedo.CursorPosition_.prototype.initW3C_ = function(range) {
  this.isValid_ = false;
  if (!range) {
    return;
  }
  var anchorNode = range.getAnchorNode();
  var focusNode = range.getFocusNode();
  if (!anchorNode || !focusNode) {
    return;
  }
  var anchorOffset = range.getAnchorOffset();
  var anchor = new goog.dom.NodeOffset(anchorNode, this.field_.getElement());
  var focusOffset = range.getFocusOffset();
  var focus = new goog.dom.NodeOffset(focusNode, this.field_.getElement());
  if (range.isReversed()) {
    this.startOffset_ = focus;
    this.startChildOffset_ = focusOffset;
    this.endOffset_ = anchor;
    this.endChildOffset_ = anchorOffset;
  } else {
    this.startOffset_ = anchor;
    this.startChildOffset_ = anchorOffset;
    this.endOffset_ = focus;
    this.endChildOffset_ = focusOffset;
  }
  this.isValid_ = true;
};
goog.editor.plugins.UndoRedo.CursorPosition_.prototype.initIE_ = function(range) {
  this.isValid_ = false;
  if (!range) {
    return;
  }
  var ieRange = range.getTextRange(0).getBrowserRangeObject();
  if (!goog.dom.contains(this.field_.getElement(), ieRange.parentElement())) {
    return;
  }
  var contentEditableRange = this.field_.getEditableDomHelper().getDocument().body.createTextRange();
  contentEditableRange.moveToElementText(this.field_.getElement());
  var startMarker = ieRange.duplicate();
  startMarker.collapse(true);
  startMarker.setEndPoint("StartToStart", contentEditableRange);
  this.startOffset_ = goog.editor.plugins.UndoRedo.CursorPosition_.computeEndOffsetIE_(startMarker);
  var endMarker = ieRange.duplicate();
  endMarker.setEndPoint("StartToStart", contentEditableRange);
  this.endOffset_ = goog.editor.plugins.UndoRedo.CursorPosition_.computeEndOffsetIE_(endMarker);
  this.isValid_ = true;
};
goog.editor.plugins.UndoRedo.CursorPosition_.prototype.isValid = function() {
  return this.isValid_;
};
goog.editor.plugins.UndoRedo.CursorPosition_.prototype.toString = function() {
  if (goog.editor.BrowserFeature.HAS_W3C_RANGES) {
    return "W3C:" + this.startOffset_.toString() + "\n" + this.startChildOffset_ + ":" + this.endOffset_.toString() + "\n" + this.endChildOffset_;
  }
  return "IE:" + this.startOffset_ + "," + this.endOffset_;
};
goog.editor.plugins.UndoRedo.CursorPosition_.prototype.select = function() {
  var range = this.getRange_(this.field_.getElement());
  if (range) {
    if (goog.editor.BrowserFeature.HAS_IE_RANGES) {
      this.field_.getElement().focus();
    }
    goog.dom.Range.createFromBrowserRange(range).select();
  }
};
goog.editor.plugins.UndoRedo.CursorPosition_.prototype.getRange_ = function(baseNode) {
  if (goog.editor.BrowserFeature.HAS_W3C_RANGES) {
    var startNode = this.startOffset_.findTargetNode(baseNode);
    var endNode = this.endOffset_.findTargetNode(baseNode);
    if (!startNode || !endNode) {
      return null;
    }
    return goog.dom.Range.createFromNodes(startNode, this.startChildOffset_, endNode, this.endChildOffset_).getBrowserRangeObject();
  }
  var sel = baseNode.ownerDocument.body.createTextRange();
  sel.moveToElementText(baseNode);
  sel.collapse(true);
  sel.moveEnd("character", this.endOffset_);
  sel.moveStart("character", this.startOffset_);
  return sel;
};
goog.editor.plugins.UndoRedo.CursorPosition_.computeEndOffsetIE_ = function(range) {
  var testRange = range.duplicate();
  var text = range.text;
  var guess = text.length;
  testRange.collapse(true);
  testRange.moveEnd("character", guess);
  var diff;
  var numTries = 10;
  while (diff = testRange.compareEndPoints("EndToEnd", range)) {
    guess -= diff;
    testRange.moveEnd("character", -diff);
    --numTries;
    if (0 == numTries) {
      break;
    }
  }
  var offset = 0;
  var pos = text.indexOf("\n\r");
  while (pos != -1) {
    ++offset;
    pos = text.indexOf("\n\r", pos + 1);
  }
  return guess + offset;
};
goog.provide("uno.commands.UndoRedo");
goog.require("goog.editor.plugins.UndoRedo");
goog.require("goog.functions");
(function() {
  var UndoRedo = uno.commands.UndoRedo = function(optManager) {
    goog.editor.plugins.UndoRedo.call(this, optManager);
  };
  goog.inherits(UndoRedo, goog.editor.plugins.UndoRedo);
  UndoRedo.prototype.activeOnUneditableFields = goog.functions.TRUE;
})();
goog.provide("uno.commands.Unlink");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Unlink");
  var util = uno.util;
  var Unlink = uno.commands.Unlink = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(Unlink, uno.BasePlugin);
  Unlink.prototype.isSupportedCommand = function(command) {
    return command === "unlink";
  };
  Unlink.prototype.activeOnUneditableFields = goog.functions.TRUE;
  function getLinks(range) {
    if (!range) {
      return [];
    }
    var container = range.getContainer();
    var links = [];
    var link = container && goog.dom.getAncestor(container, util.dom.isA, true);
    if (link) {
      links.push(link);
    }
    if (util.dom.isElementNode(container)) {
      links = links.concat(Array.prototype.slice.call(container.querySelectorAll("a")));
    }
    return links;
  }
  Unlink.prototype.execCommand = function() {
    var links = getLinks(this.editor.getRange());
    if (!links.length) {
      return false;
    }
    this.editor.dispatchBeforeChange();
    goog.array.forEach(links, goog.dom.flattenElement);
    this.editor.dispatchChange();
    return true;
  };
  Unlink.prototype.queryCommandEnabled = function() {
    var links = getLinks(this.editor.getRange());
    return links.length;
  };
  Unlink.prototype.queryCommandValue = function(command) {
    return this.queryCommandEnabled(command);
  };
})();
goog.provide("uno.commands.Uppercase");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.Uppercase");
  var util = uno.util;
  var Uppercase = uno.commands.Uppercase = function() {
    uno.BasePlugin.call(this, log.getName());
    this.multiRangeMode = uno.EditorMultiRange.Mode.ALL;
  };
  goog.inherits(Uppercase, uno.BasePlugin);
  Uppercase.prototype.isSupportedCommand = function(command) {
    return command === "uppercase";
  };
  Uppercase.prototype.execCommandInternal = function() {
    var range = this.editor.getRange();
    var savedRange = range.saveUsingDom();
    util.range.forEachWord(range, function(word, wordRange) {
      var container = wordRange.startContainer;
      var text = container.nodeValue;
      container.nodeValue = text.slice(0, wordRange.startOffset) + word.toLocaleUpperCase() + text.slice(wordRange.endOffset);
    });
    savedRange.restore().select();
    return true;
  };
})();
goog.provide("uno.commands.ZoomScale");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.img");
goog.require("uno.util.preview");
goog.require("uno.util.zoomscale");
(function() {
  var log = goog.debug.Logger.getLogger("uno.commands.ZoomScale");
  var util = uno.util;
  var MIN_ZOOM_SCALE = 0.75;
  var MAX_ZOOM_SCALE = 2.0;
  function boundedZoomScale(zoomScale) {
    return Math.min(Math.max(zoomScale, MIN_ZOOM_SCALE), MAX_ZOOM_SCALE);
  }
  function zoomInFrom(fromZoomScale) {
    var toZoomScale = 1.0;
    if (Math.abs(fromZoomScale - 0.5) < 0.01 || fromZoomScale < 0.5) {
      toZoomScale = 0.67;
    } else {
      if (Math.abs(fromZoomScale - 0.67) < 0.01 || fromZoomScale < 0.67) {
        toZoomScale = 0.75;
      } else {
        if (Math.abs(fromZoomScale - 0.75) < 0.01 || fromZoomScale < 0.75) {
          toZoomScale = 0.9;
        } else {
          if (Math.abs(fromZoomScale - 0.9) < 0.01 || fromZoomScale < 0.9) {
            toZoomScale = 1.0;
          } else {
            if (Math.abs(fromZoomScale - 1.0) < 0.01 || fromZoomScale < 1.0) {
              toZoomScale = 1.1;
            } else {
              if (Math.abs(fromZoomScale - 1.1) < 0.01 || fromZoomScale < 1.1) {
                toZoomScale = 1.25;
              } else {
                if (Math.abs(fromZoomScale - 1.25) < 0.01 || fromZoomScale < 1.25) {
                  toZoomScale = 1.5;
                } else {
                  if (Math.abs(fromZoomScale - 1.5) < 0.01 || fromZoomScale < 1.5) {
                    toZoomScale = 1.75;
                  } else {
                    if (Math.abs(fromZoomScale - 1.75) < 0.01 || fromZoomScale < 1.75) {
                      toZoomScale = 2.0;
                    } else {
                      if (Math.abs(fromZoomScale - 2.0) < 0.01 || fromZoomScale < 2.0) {
                        toZoomScale = 2.5;
                      } else {
                        if (Math.abs(fromZoomScale - 2.5) < 0.01 || fromZoomScale < 2.5) {
                          toZoomScale = 3.0;
                        } else {
                          toZoomScale = 3.0;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    return boundedZoomScale(toZoomScale);
  }
  function zoomOutFrom(fromZoomScale) {
    var toZoomScale = 1.0;
    if (Math.abs(fromZoomScale - 0.5) < 0.01 || fromZoomScale < 0.5) {
      toZoomScale = 0.5;
    } else {
      if (Math.abs(fromZoomScale - 0.67) < 0.01 || fromZoomScale < 0.67) {
        toZoomScale = 0.5;
      } else {
        if (Math.abs(fromZoomScale - 0.75) < 0.01 || fromZoomScale < 0.75) {
          toZoomScale = 0.67;
        } else {
          if (Math.abs(fromZoomScale - 0.9) < 0.01 || fromZoomScale < 0.9) {
            toZoomScale = 0.75;
          } else {
            if (Math.abs(fromZoomScale - 1.0) < 0.01 || fromZoomScale < 1.0) {
              toZoomScale = 0.9;
            } else {
              if (Math.abs(fromZoomScale - 1.1) < 0.01 || fromZoomScale < 1.1) {
                toZoomScale = 1.0;
              } else {
                if (Math.abs(fromZoomScale - 1.25) < 0.01 || fromZoomScale < 1.25) {
                  toZoomScale = 1.1;
                } else {
                  if (Math.abs(fromZoomScale - 1.5) < 0.01 || fromZoomScale < 1.5) {
                    toZoomScale = 1.25;
                  } else {
                    if (Math.abs(fromZoomScale - 1.75) < 0.01 || fromZoomScale < 1.75) {
                      toZoomScale = 1.5;
                    } else {
                      if (Math.abs(fromZoomScale - 2.0) < 0.01 || fromZoomScale < 2.0) {
                        toZoomScale = 1.75;
                      } else {
                        if (Math.abs(fromZoomScale - 2.5) < 0.01 || fromZoomScale < 2.5) {
                          toZoomScale = 2.0;
                        } else {
                          if (Math.abs(fromZoomScale - 3.0) < 0.01 || fromZoomScale < 3.0) {
                            toZoomScale = 2.5;
                          } else {
                            toZoomScale = 3.0;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    return boundedZoomScale(toZoomScale);
  }
  var ZoomScale = uno.commands.ZoomScale = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ZoomScale, uno.BasePlugin);
  ZoomScale.prototype.isSupportedCommand = function(command) {
    return command === "zoomscale";
  };
  ZoomScale.prototype.activeOnUneditableFields = goog.functions.TRUE;
  ZoomScale.prototype.execCommand = function(command, value) {
    var fullsize = this.editor.context.fullsize || {};
    if (fullsize.enabled || fullsize.pending) {
      return false;
    }
    var zoomScale = 0;
    if (value === "+") {
      zoomScale = zoomInFrom(uno.util.zoomscale.getZoom());
    } else {
      if (value === "-") {
        zoomScale = zoomOutFrom(uno.util.zoomscale.getZoom());
      } else {
        zoomScale = parseFloat(value);
      }
    }
    if (zoomScale > 0 && zoomScale < 10.0) {
      var editorBody = this.editor.field;
      if (editorBody) {
        editorBody.style.zoom = zoomScale;
        util.img.layoutResizer();
        util.img.layoutToolbar();
      }
      return true;
    }
    return false;
  };
  ZoomScale.prototype.queryCommandValue = function() {
    return uno.util.zoomscale.getZoom();
  };
})();
goog.provide("uno.PluginManager");
goog.require("goog.debug.Logger");
goog.require("goog.array");
(function() {
  var log = goog.debug.Logger.getLogger("uno.PluginManager");
  var PluginManager = uno.PluginManager = function() {
    this.elements = [];
  };
  PluginManager.prototype.add = function(obj) {
    this.elements.push(obj);
  };
  PluginManager.prototype.filterRemove = function(filterFunc) {
    this.elements = goog.array.filter(this.elements, filterFunc);
  };
  PluginManager.prototype.clear = function() {
    this.elements = [];
  };
  PluginManager.prototype.forEach = function(callback) {
    if (callback == null) {
      return;
    }
    for (var i = 0; i < this.elements.length; i++) {
      callback(this.elements[i], i, this.elements);
    }
  };
  PluginManager.prototype.forEachRight = function(callback) {
    if (callback == null) {
      return;
    }
    for (var i = this.elements.length - 1; i >= 0; i--) {
      callback(this.elements[i], i, this.elements);
    }
  };
  PluginManager.prototype.firstToReturnTrue = function(funcName, funcArgs) {
    for (var i = 0; i < this.elements.length; i++) {
      if (this.tryToRun(this.elements[i], funcName, funcArgs) === true) {
        return this.elements[i];
      }
    }
    return null;
  };
  PluginManager.prototype.firstSupportedCommand = function(command) {
    return this.firstToReturnTrue("isSupportedCommand", [command]);
  };
  PluginManager.prototype.isSupportedCommand = function(command) {
    return !!this.firstToReturnTrue("isSupportedCommand", [command]);
  };
  PluginManager.prototype.execCommand = function() {
    var args = Array.prototype.slice.call(arguments);
    var command = args.length > 0 ? args[0] : null;
    var plugin = this.firstSupportedCommand(command);
    if (plugin == null) {
      return false;
    }
    var result = null;
    if (goog.isFunction(plugin.execCommandInternal)) {
      result = this.tryToRun(plugin, "execCommandInternal", args);
    }
    if (result == null) {
      result = this.tryToRun(plugin, "execCommand", args);
    }
    return !!result;
  };
  PluginManager.prototype.queryCommandEnabled = function() {
    var args = Array.prototype.slice.call(arguments);
    var command = args.length > 0 ? args[0] : null;
    var plugin = this.firstSupportedCommand(command);
    return !!this.tryToRun(plugin, "queryCommandEnabled", args);
  };
  PluginManager.prototype.queryCommandValue = function() {
    var args = Array.prototype.slice.call(arguments);
    var command = args.length > 0 ? args[0] : null;
    var plugin = this.firstSupportedCommand(command);
    var result = this.tryToRun(plugin, "queryCommandValue", args);
    if (result == null) {
      result = "";
    }
    if (!goog.isString(result)) {
      result = JSON.stringify(result);
    }
    return result;
  };
  PluginManager.prototype.tryToRun = function(element, funcName, funcArgs) {
    if (element == null) {
      log.warning("No plugin element supplied to tryToRun: \n" + JSON.stringify(funcName) + "\n---\n" + JSON.stringify(funcArgs));
      return null;
    }
    if (goog.isFunction(element[funcName])) {
      try {
        return element[funcName].apply(element, funcArgs);
      } catch (ex) {
        log.severe("Error running " + funcName + " with " + JSON.stringify(funcArgs) + ". \nDetails: " + ex + "\n" + ex.stack);
      }
    }
    return null;
  };
})();
goog.provide("uno.filters.CodeBlockFilter");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.util.codeblock");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.CodeBlockFilter");
  var util = uno.util;
  var CodeBlockFilter = uno.filters.CodeBlockFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CodeBlockFilter, uno.BasePlugin);
  CodeBlockFilter.prototype.prepareContentsDom = function(frag) {
    var codeblocks = frag.querySelectorAll("[data-en-codeblock]");
    goog.array.forEachRight(codeblocks, function(enmlCodeblock) {
      var codeblock = util.codeblock.create(enmlCodeblock.childNodes);
      goog.dom.replaceNode(codeblock, enmlCodeblock);
    });
  };
  CodeBlockFilter.prototype.cleanContentsDom = function(frag) {
    var codeblocks = util.codeblock.all(frag);
    goog.array.forEachRight(codeblocks, function(codeblock) {
      var enmlCodeblock = goog.dom.createDom("div", {style:uno.defs.codeblock.style}, codeblock.childNodes);
      util.styles.setMetadata(enmlCodeblock, "-en-codeblock", "true");
      goog.dom.replaceNode(enmlCodeblock, codeblock);
    });
  };
})();
goog.provide("uno.filters.cryptfilter.win");
goog.require("goog.dom.classlist");
goog.require("uno.defs");
goog.require("uno.util.crypto");
(function() {
  var win = uno.filters.cryptfilter.win;
  var util = uno.util;
  var CRYPT_CLASS = uno.defs.crypto.CRYPT_CLASS;
  win.importHTML = function(fragment, context) {
    var cryptElements = fragment.querySelectorAll('img[src^="en-resource://database/pprotect:"]');
    Array.prototype.forEach.call(cryptElements, function(node) {
      node.setAttribute("id", "crypt-" + context.crypt.incrementUniqueId());
      node.setAttribute("data-src", node.src);
      goog.dom.classlist.add(node, CRYPT_CLASS);
    });
    return fragment;
  };
  win.exportHTML = function(fragment) {
    var cryptElements = util.crypto.all(fragment);
    Array.prototype.forEach.call(cryptElements, function(node) {
      if (util.crypto.isOpen(node)) {
        var newNode = document.createElement("img");
        newNode.setAttribute("id", node.getAttribute("id"));
        newNode.setAttribute("class", node.getAttribute("class"));
        newNode.setAttribute("src", node.getAttribute("data-src"));
        newNode.setAttribute("data-length", node.getAttribute("data-length"));
        newNode.setAttribute("data-cipher", node.getAttribute("data-cipher"));
        newNode.setAttribute("data-hint", node.getAttribute("data-hint"));
        newNode.setAttribute("data-ciphertext", node.getAttribute("data-ciphertext"));
        node.parentNode.replaceChild(newNode, node);
      } else {
        node.setAttribute("src", node.getAttribute("data-src"));
        node.removeAttribute("data-src");
      }
    });
  };
})();
goog.provide("uno.filters.CryptFilter");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.filters.cryptfilter.win");
goog.require("uno.util.crypto");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.CryptFilter");
  var util = uno.util;
  var CryptFilter = uno.filters.CryptFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CryptFilter, uno.BasePlugin);
  CryptFilter.prototype.prepareContentsDom = function(fragment) {
    var context = this.editor.context;
    if (context.format === uno.defs.format.ENML) {
      if (this.client.importENML) {
        this.client.importENML(fragment, context);
      } else {
        Array.prototype.forEach.call(fragment.querySelectorAll("en-crypt"), function(node) {
          var newId = context.crypt.incrementUniqueId();
          var cryptInfo = {id:"crypt-" + newId};
          cryptInfo.cipherText = node.textContent;
          cryptInfo.length = node.getAttribute("length");
          cryptInfo.cipher = node.getAttribute("cipher");
          cryptInfo.hint = node.getAttribute("hint");
          var newNode = util.crypto.createCryptoPlaceholder(cryptInfo);
          goog.dom.replaceNode(newNode, node);
        });
      }
    } else {
      if (context.format === uno.defs.format.CLIENT_HTML) {
        if (this.client.importHTML) {
          this.client.importHTML(fragment, context);
        }
      } else {
        if (context.format === uno.defs.format.CLIPBOARD) {
          if (this.client.importHTML) {
            this.client.importHTML(fragment, context);
          }
        }
      }
    }
  };
  CryptFilter.prototype.cleanContentsDom = function(fragment) {
    var context = this.editor.context;
    if (context.format === uno.defs.format.ENML) {
      if (this.client.exportENML) {
        this.client.exportENML(fragment);
      } else {
        Array.prototype.forEach.call(util.crypto.all(fragment), function(node) {
          var newNode = goog.dom.createDom("en-crypt");
          newNode.setAttribute("cipher", node.getAttribute("data-cipher") || "AES");
          newNode.setAttribute("length", node.getAttribute("data-length") || "128");
          newNode.setAttribute("hint", node.getAttribute("data-hint") || "");
          newNode.innerHTML = node.getAttribute("data-ciphertext") || "";
          goog.dom.replaceNode(newNode, node);
        });
      }
    } else {
      if (context.format === uno.defs.format.CLIENT_HTML) {
        if (this.client.exportHTML) {
          this.client.exportHTML(fragment);
        }
      } else {
        if (context.format === uno.defs.format.CLIPBOARD) {
          Array.prototype.forEach.call(util.crypto.all(fragment), function(node) {
            var newId = "crypt-" + context.crypt.incrementUniqueId();
            node.id = newId;
          });
        }
      }
    }
  };
})();
goog.provide("uno.filters.CommentFilter");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.CommentFilter");
  var defs = uno.defs;
  var util = uno.util;
  var CommentFilter = uno.filters.CommentFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CommentFilter, uno.BasePlugin);
  CommentFilter.prototype.prepareContentsDom = function(frag) {
    goog.array.forEach(frag.querySelectorAll("span[data-en-comment]"), function(node) {
      util.dom.changeTagName(node, "en-comment");
    });
  };
  CommentFilter.prototype.cleanContentsDom = function(frag) {
    var isClipboard = this.editor.context.format === defs.format.CLIPBOARD;
    goog.array.forEach(frag.querySelectorAll("en-comment"), function(node) {
      if (isClipboard) {
        goog.dom.removeNode(node);
      } else {
        util.dom.changeTagName(node, "span");
      }
    });
  };
})();
goog.provide("uno.filters.EnmlFilter");
goog.require("goog.debug.Logger");
goog.require("goog.string");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.EnmlFilter");
  var util = uno.util;
  var rxDocType = /^<!DOCTYPE[^>]*>\n?/g;
  var rxXhtmlNs = / +xmlns="(http:\/\/www.w3.org\/1999\/xhtml)?"/g;
  var rxInvalidHtmlChars = new RegExp(uno.defs.regex.INVALID_HTML_CHARS, "g");
  var rxEnNoteOpening = /<\s*en-note[^>]*>/;
  var rxEnNoteClosing = /<\/\s*en-note\s*>/;
  var rxEnNoteVoid = /<\s*en-note\s*\/\s*>/;
  var rxEnTodoNonVoid = /<en-todo([^>]*?)>.*?<\/en-todo>/g;
  var rxEnMediaNonVoid = /<en-media([^>]*?)>.*?<\/en-media>/g;
  var EnmlFilter = uno.filters.EnmlFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(EnmlFilter, uno.BasePlugin);
  EnmlFilter.prototype.prepareContentsHtml = function(html) {
    var openingMatch;
    var closingMatch;
    if (!html) {
      return html;
    }
    openingMatch = html.match(rxEnNoteOpening);
    closingMatch = html.match(rxEnNoteClosing);
    var voidMatch = html.match(rxEnNoteVoid);
    if (voidMatch) {
      html = "";
    } else {
      if (openingMatch && closingMatch) {
        html = html.substring(openingMatch.index + openingMatch[0].length, closingMatch.index);
      } else {
        if (this.editor.context.format === uno.defs.format.ENML) {
          log.info("html:");
          log.info(html);
          log.severe("Cannot find en-note node in ENML");
        }
      }
    }
    html = html.trim();
    return html;
  };
  EnmlFilter.prototype.prepareContentsDom = function(frag) {
    var node = frag && frag.firstChild;
    if (frag.childNodes.length === 1 && node.tagName === "SPAN" && node.attributes.length === 0 && node.firstChild) {
      while (node.firstChild) {
        frag.appendChild(node.firstChild);
      }
      frag.removeChild(node);
    }
  };
  EnmlFilter.prototype.cleanContentsHtml = function(html) {
    if (this.editor.context.format !== uno.defs.format.ENML) {
      return html;
    }
    var liveRoot = this.editor.field;
    var enmlDTD = document.implementation.createDocumentType("en-note", "", "http://xml.evernote.com/pub/enml2.dtd");
    var enmlDocument = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "en-note", enmlDTD);
    var enmlNode = enmlDocument.documentElement;
    var legalNoteAttributes = ["style", "bgcolor", "title", "lang", "dir", "text"];
    var zwsRegex = new RegExp(uno.defs.unicode.ZERO_WIDTH_SPACE, "g");
    html = html.replace(zwsRegex, "");
    var frag = util.dom.fragFromString(html);
    if (liveRoot && liveRoot.hasAttributes()) {
      goog.array.forEach(liveRoot.attributes, function(a) {
        if (goog.array.contains(legalNoteAttributes, a.name)) {
          enmlNode.setAttribute(a.name.toLowerCase(), a.value);
        }
      });
    }
    var treeWalker = document.createTreeWalker(frag, NodeFilter.SHOW_ELEMENT);
    while (treeWalker.nextNode()) {
      var currentNode = treeWalker.currentNode;
      if (currentNode.tagName === "EN-CURSOR") {
        currentNode.remove();
        continue;
      }
      currentNode.removeAttribute("id");
      currentNode.removeAttribute("class");
      currentNode.removeAttribute("x-apple-data-detectors");
      currentNode.removeAttribute("x-apple-data-detectors-type");
      currentNode.removeAttribute("x-apple-data-detectors-result");
      for (var key in currentNode.dataset) {
        currentNode.removeAttribute(["data", goog.string.toSelectorCase(key)].join("-"));
      }
    }
    goog.array.forEachRight(frag.querySelectorAll('*[style*="-en-clipboard"]'), function(el) {
      util.styles.removeStyle(el, "-en-clipboard");
    });
    var clonedNode = enmlDocument.importNode(frag, true);
    var ennote = enmlDocument.querySelector("en-note");
    util.styles.removeStyle(ennote, "display");
    util.styles.removeStyle(ennote, "margin");
    util.styles.removeStyle(ennote, "padding");
    ennote.appendChild(clonedNode);
    var xmlString = (new XMLSerializer).serializeToString(enmlDocument);
    xmlString = xmlString.replace(rxInvalidHtmlChars, "").replace(rxDocType, '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">').replace(rxXhtmlNs, "").replace(rxEnTodoNonVoid, "<en-todo$1 />").replace(rxEnMediaNonVoid, "<en-media$1 />");
    return xmlString;
  };
})();
goog.provide("uno.filters.FontSizeFilter");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.FontSizeFilter");
  var FontSizeFilter = uno.filters.FontSizeFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(FontSizeFilter, uno.BasePlugin);
  FontSizeFilter.prototype.cleanContentsHtml = function(html) {
    return html.replace(uno.defs.unicode.ZERO_WIDTH_SPACE, "");
  };
})();
goog.provide("uno.filters.MetadataFilter");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.MetadataFilter");
  var util = uno.util;
  var MetadataFilter = uno.filters.MetadataFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(MetadataFilter, uno.BasePlugin);
  MetadataFilter.prototype.prepareContentsDom = function(frag) {
    util.styles.metadataImportSelectors.forEach(function(selector) {
      goog.array.forEachRight(frag.querySelectorAll(selector), function(el) {
        util.styles.convertStylesToDataAttributes(el);
      });
    });
  };
  MetadataFilter.prototype.cleanContentsDom = function(frag) {
    util.styles.metadataExportSelectors.forEach(function(selector) {
      goog.array.forEachRight(frag.querySelectorAll(selector), function(el) {
        util.styles.convertDataAttributesToStyles(el);
      });
    });
  };
})();
goog.provide("uno.filters.NormalizeFilter");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.normalize");
goog.require("uno.util.n3");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.NormalizeFilter");
  var util = uno.util;
  var NormalizeFilter = uno.filters.NormalizeFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(NormalizeFilter, uno.BasePlugin);
  NormalizeFilter.prototype.prepareContentsHtml = function(html) {
    return util.normalize.normalizeHtml(html);
  };
  NormalizeFilter.prototype.prepareContentsDom = function(frag) {
    var context = this.editor.context;
    var HTML = uno.defs.format.CLIENT_HTML;
    var ENML = uno.defs.format.ENML;
    if ((context.format === ENML || context.format === HTML) && !this.editor.config.noNormalize) {
      util.n3.normalizeDom(frag, {editor:this.editor});
    } else {
      if (context.format === uno.defs.format.CLIPBOARD) {
        util.normalize.normalizeDom(frag, {editor:this.editor, externalContent:context.copyPaste.externalContent});
      }
    }
  };
})();
goog.provide("uno.filters.PasteFilter");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.array");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.PasteFilter");
  var util = uno.util;
  var PasteFilter = uno.filters.PasteFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(PasteFilter, uno.BasePlugin);
  PasteFilter.prototype.prepareContentsDom = function(frag) {
    var context = this.editor.context;
    if (context.format === uno.defs.format.CLIPBOARD) {
      transformURLs(frag);
    }
  };
  function transformURLs(frag) {
    var urlRe = new RegExp(uno.defs.regex.SIMPLE_URL, "gi");
    var emailRe = new RegExp(uno.defs.regex.SIMPLE_EMAIL, "gi");
    goog.array.forEachRight(util.dom.getNodeLeaves(frag), function(node) {
      var isTextNode = util.dom.isTextNode(node);
      var isLinked = !!goog.dom.getAncestor(node, function(ancestor) {
        return !!ancestor.hasAttribute && ancestor.hasAttribute("href");
      });
      if (isTextNode && !isLinked) {
        var text = node.textContent;
        var hasMatch = urlRe.test(text) || emailRe.test(text);
        if (hasMatch) {
          var c = 0;
          var matches = [];
          var replacers = [];
          var html;
          html = text.replace(emailRe, function(match) {
            matches.push(match);
            replacers.push(replaceEmail);
            return placeholder(c++);
          }).replace(urlRe, function(match) {
            matches.push(match);
            replacers.push(replaceUrl);
            return placeholder(c++);
          });
          html = goog.string.htmlEscape(html);
          matches.forEach(function(match, i) {
            html = html.replace(placeholder(i), replacers[i](match));
          });
          node.parentNode.replaceChild(util.dom.fragFromString(html), node);
        }
      }
    });
  }
  function replaceEmail(email) {
    return '<a href="mailto:' + email + '">' + email + "</a>";
  }
  function replaceUrl(url) {
    var href = /[a-z]+:\/\//i.test(url) ? url : "http://" + url;
    return '<a href="' + href + '">' + url + "</a>";
  }
  function placeholder(index) {
    return "{{__" + index + "__}}";
  }
})();
goog.provide("uno.filters.PrePasteFilter");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.array");
goog.require("uno.BasePlugin");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.PrePasteFilter");
  var util = uno.util;
  var PrePasteFilter = uno.filters.PrePasteFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(PrePasteFilter, uno.BasePlugin);
  PrePasteFilter.prototype.prepareContentsDom = function(frag) {
    var context = this.editor.context;
    if (context.format === uno.defs.format.CLIPBOARD) {
      transformMicrosoftWordListsWithMap(frag);
    }
  };
  function transformMicrosoftWordListsWithMap(frag) {
    var queue = [];
    goog.array.forEach(frag.querySelectorAll("p"), function(node) {
      if (util.dom.getNodeLength(node) === 1 && util.dom.getTagName(node.firstChild) === "o:p") {
        goog.dom.removeNode(node.firstChild);
        node.appendChild(goog.dom.createDom("br"));
        util.dom.changeTagName(node, "div");
      }
    });
    goog.array.forEach(frag.querySelectorAll('div[style*="mso-line-break-override"]'), function(node) {
      var level = 1 + ((parseFloat(node.style.marginLeft) + parseFloat(node.style.textIndent)) / 0.5 || 0);
      var results = node.querySelectorAll('span[style*="mso-special-format"]');
      if (results.length > 0) {
        var isItem;
        var listType = "ul";
        if (util.styles.getStyle(results[0], "mso-special-format").toLowerCase() !== "bullet") {
          listType = "ol";
        }
        if (util.dom.getNodeLength(results[0].parentNode) === 1) {
          isItem = true;
          goog.dom.removeNode(results[0].parentNode);
        } else {
          goog.dom.removeNode(results[0]);
        }
        appendListItem(node, queue, level, listType, isItem);
      }
    });
    var rxLevel = /level([0-9]+)/;
    var rxMsoIgnore = /ignore/i;
    goog.array.forEach(frag.querySelectorAll("div[style*=mso], p[style*=mso]"), function(node) {
      var listMso = (util.styles.getStyle(node, "mso-list") || "").toLowerCase().match(rxLevel);
      if (listMso) {
        var level = parseInt(listMso.pop(), 10);
        var levelKey = listMso.pop();
        if (!isNaN(level)) {
          var listType = "ul";
          var spanMso = node.querySelectorAll('span[style*="mso-list:"]');
          if (spanMso) {
            goog.array.forEach(spanMso, function() {
              var span = spanMso[0];
              var spanMsoType = util.styles.getStyle(span, "mso-list").toLowerCase().match(rxMsoIgnore);
              if (spanMsoType) {
                if (span.textContent.match(/[0-9a-z]+.*/g)) {
                  listType = "ol";
                }
                if (util.dom.matches(span.parentNode, "span") && util.dom.getNodeLength(span.parentNode) === 1) {
                  goog.dom.removeNode(span.parentNode);
                } else {
                  goog.dom.removeNode(span);
                }
              }
            });
          }
          appendListItem(node, queue, level, listType);
        }
      } else {
        appendListItem(node, queue);
      }
    });
  }
  function getList(node, queue, level, listType) {
    if (level === undefined) {
      return queue.slice(-1).pop();
    }
    var list = null;
    var parent;
    while (!list && queue.length) {
      list = queue.pop();
      if (list.level === level) {
        if (util.dom.matches(list, listType)) {
          queue.push(list);
        } else {
          parent = list.parentNode;
          list = goog.dom.createDom(listType);
          list.level = level;
          queue.push(list);
          parent.appendChild(list);
        }
      } else {
        if (list.level < level) {
          queue.push(list);
          parent = list;
          list = goog.dom.createDom(listType);
          list.level = level;
          queue.push(list);
          parent.appendChild(list);
        } else {
          list = null;
        }
      }
    }
    if (!list) {
      list = goog.dom.createDom(listType);
      list.level = level;
      queue.push(list);
      node.parentNode.insertBefore(list, node);
    }
    return list;
  }
  function appendListItem(node, queue, level, listType, isItem) {
    var list = getList(node, queue, level, listType);
    goog.array.forEach(node.getElementsByTagName("o:p"), function(elem) {
      goog.dom.removeNode(elem);
    });
    if (!list || !node.getAttribute("style")) {
      node.removeAttribute("style");
      return;
    }
    util.dom.detachNode(node);
    var listItem = node;
    if (isItem || util.styles.getStyle(node, "mso-list")) {
      node = util.dom.changeTagName(node, "div");
      listItem = goog.dom.createDom("li");
      listItem.appendChild(node);
    } else {
      var lastItem = list.lastElementChild;
      if (lastItem) {
        list = lastItem;
      }
    }
    node.removeAttribute("style");
    list.appendChild(listItem);
  }
})();
goog.provide("uno.filters.ResourceFilter");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.resource");
goog.require("uno.util.img");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.ResourceFilter");
  var defs = uno.defs;
  var util = uno.util;
  var ResourceFilter = uno.filters.ResourceFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ResourceFilter, uno.BasePlugin);
  ResourceFilter.prototype.prepareContentsDom = function(frag) {
    var editor = this.editor;
    var context = this.editor.context;
    var dict;
    if (context.format === defs.format.ENML) {
      goog.array.forEach(frag.querySelectorAll("en-media"), function(enmedia) {
        var hash = enmedia.getAttribute("hash");
        if (hash) {
          hash = hash.toLowerCase();
          enmedia.setAttribute("hash", hash);
        }
        dict = context.resources[hash];
        util.resource.convertMediaToSlug(enmedia, dict, editor);
      });
    } else {
      if (context.format === defs.format.CLIENT_HTML) {
        goog.array.forEach(util.resource.findResourcesInClientHtml(frag, editor), function(el) {
          if (util.dom.compareTagName(el, "en-media")) {
            dict = context.resources[el.getAttribute("hash")];
            util.resource.convertMediaToSlug(el, dict, editor);
          } else {
            util.resource.convertClientElementToSlug(el, editor);
          }
        });
      } else {
        if (context.format === defs.format.CLIPBOARD) {
          goog.array.forEach(util.resource.findResourcesInClipboardHtml(frag, editor), function(el) {
            util.resource.convertClipboardElementToSlug(el, context, editor);
          });
        }
      }
    }
  };
  ResourceFilter.prototype.cleanContentsDom = function(frag) {
    var context = this.editor.context;
    if (context.format === defs.format.ENML) {
      goog.array.forEachRight(util.resource.all(frag), function(el) {
        util.resource.convertSlugToMedia(el);
      });
    } else {
      if (context.format === defs.format.CLIENT_HTML) {
        goog.array.forEachRight(util.resource.all(frag), function(el) {
          util.resource.convertSlugToClientElement(el);
        });
      } else {
        if (context.format === defs.format.CLIPBOARD) {
          goog.array.forEachRight(util.resource.all(frag), function(el) {
            util.resource.convertSlugToClientElement(el);
          });
        }
      }
    }
  };
  ResourceFilter.prototype.cleanContentsHtml = function(html) {
    if (this.editor.context.format === defs.format.CLIENT_HTML) {
      html = util.resource.formatClientHtmlForExport(html);
      html = html.replace(uno.defs.unicode.ZERO_WIDTH_SPACE, "");
    }
    return html;
  };
  ResourceFilter.prototype.handleDomUpdate = function(event) {
    if (event.paste) {
      var images = [];
      var editor = this.editor;
      goog.iter.forEach(event.range, function(node, _, iter) {
        if (iter.isStartTag() && util.dom.isImg(node)) {
          images.push(node);
        }
      });
      Promise.all(goog.array.map(images, util.img.ratioResizeIfNeeded)).then(function(resizes) {
        if (resizes.indexOf(true) > -1) {
          editor.dispatchChange();
        }
      });
    }
  };
})();
goog.provide("uno.filters.RichlinkFilter");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.richlink");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.RichlinkFilter");
  var util = uno.util;
  var RICHLINK_CONVERT_DELAY = 400;
  var RichlinkFilter = uno.filters.RichlinkFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(RichlinkFilter, uno.BasePlugin);
  RichlinkFilter.prototype.prepareContentsDom = function(frag, styles) {
    var editor = this.editor;
    var links;
    var fromClipboard = editor.context.format === uno.defs.format.CLIPBOARD;
    if (!editor.config.richlinks.enabled) {
      return;
    }
    if (fromClipboard) {
      links = util.richlink.allPlain(frag);
    } else {
      links = util.richlink.allUndecorated(frag);
    }
    if (links.length > 0) {
      goog.array.forEach(links, function(link) {
        if (util.richlink.canDecorate(link, editor)) {
          util.richlink.setPending(link, true);
        }
      });
      setTimeout(function() {
        var pendingLinks = util.richlink.allPending(editor.field);
        goog.array.forEach(pendingLinks, function(link) {
          if (util.richlink.canDecorate(link, editor)) {
            util.richlink.setPending(link, false);
            if (fromClipboard) {
              editor.plugins_.UndoRedo.updateCurrentState_(editor);
            }
            util.richlink.decorate(link, editor);
          }
        });
      }, fromClipboard ? RICHLINK_CONVERT_DELAY : 0);
    }
  };
  RichlinkFilter.prototype.cleanContentsDom = function(frag) {
    var editor = this.editor;
    if (editor.config.richlinks.enabled) {
      goog.array.forEach(util.richlink.all(frag), function(link) {
        util.richlink.undecorate(link, editor);
      });
    }
  };
})();
goog.provide("uno.filters.SectionBreakFilter");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.SectionBreakFilter");
  var util = uno.util;
  var SectionBreakFilter = uno.filters.SectionBreakFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(SectionBreakFilter, uno.BasePlugin);
  SectionBreakFilter.prototype.cleanContentsDom = function(frag) {
    var sectionbreaks = frag.querySelectorAll('[style*="-evernote-encp-section-break"]');
    goog.array.forEach(sectionbreaks, function(sectionbreak) {
      sectionbreak.style.display = "none";
      util.styles.setMetadata(sectionbreak, "-evernote-encp-section-break", true);
    });
  };
})();
goog.provide("uno.filters.TableFilter");
goog.require("goog.debug.Logger");
goog.require("goog.array");
goog.require("goog.iter");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.TableFilter");
  var defs = uno.defs;
  var util = uno.util;
  var TableFilter = uno.filters.TableFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TableFilter, uno.BasePlugin);
  TableFilter.prototype.prepareContentsDom = function(frag) {
    var isClipboard = this.editor.context.format === defs.format.CLIPBOARD;
    goog.array.forEach(frag.querySelectorAll("table"), function(table) {
      var enTable = util.table.attachAdornments(table);
      if (!isClipboard && enTable) {
        util.table.normalizeDOMPlacement(enTable);
      }
    });
  };
  TableFilter.prototype.cleanContentsDom = function(frag) {
    var isClipboard = this.editor.context.format === defs.format.CLIPBOARD;
    goog.array.forEach(frag.querySelectorAll("en-table"), function(enTable) {
      util.table.clearAdornments(enTable, !isClipboard);
    });
  };
  TableFilter.prototype.handleDomUpdate = function(event) {
    start("TableFilter.prototype.handleDomUpdate");
    var range = event.range;
    var enTable = goog.dom.getAncestor(range.getStartNode(), util.dom.isEntable, true);
    if (enTable) {
      start("table.layout");
      util.table.layout(enTable);
      stop("table.layout");
    } else {
      goog.iter.forEach(range, function(node, _, iter) {
        if (iter.isStartTag() && util.dom.isEntable(node)) {
          util.table.layout(node);
        }
      });
    }
    stop("TableFilter.prototype.handleDomUpdate");
  };
})();
goog.provide("uno.filters.TodoFilter");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.util.todo");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.TodoFilter");
  var defs = uno.defs;
  var util = uno.util;
  var TodoFilter = uno.filters.TodoFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TodoFilter, uno.BasePlugin);
  TodoFilter.prototype.prepareContentsDom = function(frag) {
    var context = this.editor.context;
    if (context.format === defs.format.ENML) {
      goog.array.forEach(util.todo.allEnmlTodos(frag), function(entodo) {
        util.todo.decorate(entodo);
      });
    } else {
      if (context.format === defs.format.CLIPBOARD) {
        var todos = util.todo.all(frag);
        Array.prototype.forEach.call(todos, function(todo) {
          var newTodo = util.todo.convertTodoInClipboard(todo);
          if (newTodo) {
            goog.dom.replaceNode(newTodo, todo);
          }
        });
      } else {
        goog.array.forEach(util.todo.findTodosInClientHtml(frag), function(el) {
          util.todo.convertClientElementToTodo(el);
        });
      }
    }
  };
  TodoFilter.prototype.cleanContentsDom = function(frag) {
    var context = this.editor.context;
    if (context.format === defs.format.ENML) {
      goog.array.forEach(util.todo.all(frag), function(entodo) {
        util.todo.undecorate(entodo);
      });
    } else {
      if (context.format === defs.format.CLIPBOARD) {
        var todos = util.todo.all(frag);
        Array.prototype.forEach.call(todos, function(todo) {
          var newTodo = util.todo.convertTodoToClipboardElement(todo);
          if (newTodo) {
            goog.dom.replaceNode(newTodo, todo);
          }
        });
      } else {
        goog.array.forEachRight(util.todo.all(frag), function(entodo) {
          util.todo.convertTodoToClientElement(entodo);
        });
      }
    }
  };
})();
goog.provide("uno.filters.BasicTextFormatterFilter");
goog.require("goog.debug.Logger");
goog.require("goog.array");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.BasicTextFormatterFilter");
  var highlightBackgroundColor = uno.defs.highlight.COLOR;
  var util = uno.util;
  var CLIENT_HTML = uno.defs.format.CLIENT_HTML;
  var ENML = uno.defs.format.ENML;
  var BasicTextFormatterFilter = uno.filters.BasicTextFormatterFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(BasicTextFormatterFilter, uno.BasePlugin);
  BasicTextFormatterFilter.prototype.prepareContentsDom = function(frag) {
    var context = this.editor.context;
    if ([ENML, CLIENT_HTML].indexOf(context.format) > -1) {
      var nodes = frag.querySelectorAll('[style*="background-color"],[data' + uno.defs.highlight.STYLE + "]");
      Array.prototype.forEach.call(nodes, function(node) {
        var bgColor = node.style.backgroundColor.toString();
        if (!bgColor || uno.defs.highlight.regex.test(bgColor)) {
          node.style.backgroundColor = highlightBackgroundColor;
          node.removeAttribute("data" + uno.defs.highlight.STYLE);
        }
      });
    }
  };
  BasicTextFormatterFilter.prototype.cleanContentsDom = function(frag) {
    var context = this.editor.context;
    if ([ENML, CLIENT_HTML].indexOf(context.format) > -1 && frag.querySelectorAll != null) {
      var nodes = frag.querySelectorAll('[style*="background-color"]');
      goog.array.forEach(nodes, function(node) {
        if (node.attributes.style) {
          var bgColor = node.style.backgroundColor.toString();
          if (uno.defs.highlight.regex.test(bgColor)) {
            util.styles.setMetadata(node, uno.defs.highlight.STYLE, "true");
          }
        }
      });
    }
  };
})();
goog.provide("uno.filters.ZoomScaleFilter");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.ZoomScaleFilter");
  var ZoomScaleFilter = uno.filters.ZoomScaleFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ZoomScaleFilter, uno.BasePlugin);
  ZoomScaleFilter.prototype.cleanContentsDom = function(frag) {
    frag.firstElementChild && frag.firstElementChild.style.removeProperty("zoom");
  };
})();
goog.provide("uno.filters.CopyFilter");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.filters.CopyFilter");
  var util = uno.util;
  var CopyFilter = uno.filters.CopyFilter = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CopyFilter, uno.BasePlugin);
  CopyFilter.prototype.cleanContentsHtml = function(html) {
    return html;
  };
})();
goog.provide("uno.filters.All");
goog.require("uno.PluginManager");
goog.require("uno.filters.CodeBlockFilter");
goog.require("uno.filters.CryptFilter");
goog.require("uno.filters.CommentFilter");
goog.require("uno.filters.EnmlFilter");
goog.require("uno.filters.FontSizeFilter");
goog.require("uno.filters.MetadataFilter");
goog.require("uno.filters.NormalizeFilter");
goog.require("uno.filters.PasteFilter");
goog.require("uno.filters.PrePasteFilter");
goog.require("uno.filters.ResourceFilter");
goog.require("uno.filters.RichlinkFilter");
goog.require("uno.filters.SectionBreakFilter");
goog.require("uno.filters.TableFilter");
goog.require("uno.filters.TodoFilter");
goog.require("uno.filters.BasicTextFormatterFilter");
goog.require("uno.filters.ZoomScaleFilter");
goog.require("uno.filters.CopyFilter");
(function() {
  uno.filters.All = function() {
    var PM = new uno.PluginManager;
    PM.add(new uno.filters.EnmlFilter);
    PM.add(new uno.filters.PrePasteFilter);
    PM.add(new uno.filters.MetadataFilter);
    PM.add(new uno.filters.CommentFilter);
    PM.add(new uno.filters.TodoFilter);
    PM.add(new uno.filters.NormalizeFilter);
    PM.add(new uno.filters.PasteFilter);
    PM.add(new uno.filters.CryptFilter);
    PM.add(new uno.filters.ResourceFilter);
    PM.add(new uno.filters.RichlinkFilter);
    PM.add(new uno.filters.SectionBreakFilter);
    PM.add(new uno.filters.TableFilter);
    PM.add(new uno.filters.BasicTextFormatterFilter);
    PM.add(new uno.filters.CodeBlockFilter);
    PM.add(new uno.filters.FontSizeFilter);
    PM.add(new uno.filters.ZoomScaleFilter);
    PM.add(new uno.filters.CopyFilter);
    return PM;
  };
})();
goog.provide("uno.listeners.AccentuateListener");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.img");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.AccentuateListener");
  var util = uno.util;
  var AccentuateListener = uno.listeners.AccentuateListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(AccentuateListener, uno.BasePlugin);
  AccentuateListener.CONTAINER_CLASSNAME = ".accentuate-container";
  AccentuateListener.BOX_CLASSNAME = ".en-find-result";
  AccentuateListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  AccentuateListener.prototype.handleSelectionChange = function(event) {
    var config = this.editor.config.accentuate;
    if (config.clearOnClickSelector) {
      var range = this.editor.getRange();
      if (range) {
        var focusNode = range.getFocusNode();
        var selector = document.querySelector(config.clearOnClickSelector);
        var editor = this.editor;
        if (event && goog.dom.contains(selector, focusNode)) {
          editor.execCommand("accentuate", {clearFirst:true});
        }
        goog.array.forEach(util.img.all(this.editor.field), util.img.removeOverlay);
      }
    }
  };
})();
goog.provide("uno.listeners.AttachmentListener");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.resource");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.AttachmentListener");
  var util = uno.util;
  var AttachmentListener = uno.listeners.AttachmentListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(AttachmentListener, uno.BasePlugin);
  AttachmentListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  AttachmentListener.prototype.handleClick = function(e) {
    if (!util.resource.isFileUI(e.target) || !this.editor.config.resourceConfig.openLinkNotifications) {
      return false;
    }
    var target = e.target;
    var evt = {type:"linkclick", target:target, data:{action:undefined, eventType:"tap", hash:util.resource.hashFor(target), href:util.resource.urlFor(target), mime:util.resource.mimeTypeFor(target), module:"resource", reference:util.resource.referenceFor(target)}};
    if (util.resource.isDefaultContextButton(target)) {
      evt.data.action = "generic-default";
    } else {
      if (util.resource.isOverflowContextButton(target)) {
        evt.data.action = "generic-context";
      } else {
        evt.data.action = "open";
      }
    }
    this.editor.dispatchEvent(evt);
    return true;
  };
  AttachmentListener.prototype.handleMouseDown = function(e) {
    if (util.resource.isPdf(e.target)) {
      this.editor.field.blur();
    }
  };
  AttachmentListener.prototype.handleDoubleClick = function(e) {
    if (util.resource.isFileUI(e.target)) {
      this.editor.dispatchEvent({type:uno.Editor.EventType.RESOURCE_DOUBLECLICK, src:e.target.src});
      return true;
    }
    return false;
  };
})();
goog.provide("uno.listeners.AutoCorrectListener");
goog.require("goog.debug.Logger");
goog.require("goog.editor.range");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.AutoCorrectListener");
  var wordCharacterRegexp = new RegExp(uno.defs.regex.WORD_CHARACTER, "g");
  var lastCharacterIsAlphanum;
  var spellcheckOn = true;
  var AutoCorrectListener = uno.listeners.AutoCorrectListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(AutoCorrectListener, uno.BasePlugin);
  AutoCorrectListener.prototype.handleKeyPress = function(event) {
    wordCharacterRegexp.lastIndex = 0;
    var data = String.fromCharCode(event.keyCode);
    if (!wordCharacterRegexp.test(data)) {
      if (lastCharacterIsAlphanum) {
        var undoPlugin = this.editor.plugins_.UndoRedo;
        undoPlugin.updateCurrentState_(this.editor);
        lastCharacterIsAlphanum = false;
      }
    } else {
      lastCharacterIsAlphanum = true;
      if (!spellcheckOn) {
        this.editor.field.setAttribute("autocorrect", "on");
        this.editor.field.setAttribute("spellcheck", "true");
        spellcheckOn = true;
      }
    }
  };
  AutoCorrectListener.prototype.handleAfterExecCommand = function(event) {
    if (event.command === "undo") {
      if (spellcheckOn) {
        this.editor.field.setAttribute("autocorrect", "off");
        this.editor.field.setAttribute("spellcheck", "false");
        spellcheckOn = false;
      }
    }
  };
})();
goog.provide("uno.listeners.ChangeListener");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.img");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.ChangeListener");
  var ChangeListener = uno.listeners.ChangeListener = function() {
    uno.BasePlugin.call(this, log.getName());
    goog.editor.Field.isSpecialGeneratingKey_ = goog.functions.FALSE;
    goog.editor.Field.isGeneratingKey_ = goog.functions.FALSE;
  };
  goog.inherits(ChangeListener, uno.BasePlugin);
  ChangeListener.prototype.handleKeyPress = function() {
    this.editor.gotGeneratingKey_ = false;
    return false;
  };
})();
goog.provide("uno.listeners.ClipboardListener");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.ClipboardListener");
  var ClipboardListener = uno.listeners.ClipboardListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ClipboardListener, uno.BasePlugin);
  ClipboardListener.prototype.handleCopy = function(event) {
    if (this.editor.config.clipboard.intercept) {
      copyToClipboard(JSON.parse(EN.queryCommandValue("copy", null)), event);
    }
  };
  ClipboardListener.prototype.handleCut = function(event) {
    if (this.editor.config.clipboard.intercept) {
      copyToClipboard(JSON.parse(EN.queryCommandValue("cut")), event);
    }
  };
  var REGEX = /(<a(?=\s)[^>]*?\s+href=\")\s*?(evernote:\/\/.*?)\s*?(\".*?>)/gi;
  function stripInternalEvernoteLinks(string) {
    return string.replace(REGEX, function(_, a_start, uri, a_end) {
      return a_start + EN.convertEvernoteLinkToPublicLink(uri) + a_end;
    });
  }
  function copyToClipboard(copiedData, event) {
    copiedData.plain = copiedData.plain || "";
    copiedData.html = stripInternalEvernoteLinks(copiedData.html || "");
    event.event_.clipboardData.setData("text/plain", copiedData.plain);
    event.event_.clipboardData.setData("text/html", copiedData.html);
    event.preventDefault();
  }
  ClipboardListener.prototype.handlePaste = function(event) {
    if (this.editor.config.clipboard.intercept) {
      var enforcedPlain = event.shiftKey && (event.metaKey || event.ctrlKey);
      EN.notification("pasteRequested", {plain:!!enforcedPlain});
    }
    event.preventDefault();
    return true;
  };
})();
goog.provide("uno.listeners.CodeBlockListener");
goog.require("uno.BasePlugin");
goog.require("uno.util.codeblock");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.CodeBlockListener");
  var util = uno.util;
  var CodeBlockListener = uno.listeners.CodeBlockListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CodeBlockListener, uno.BasePlugin);
  CodeBlockListener.prototype.handleAfterExecCommand = function() {
    var range = this.editor.getRange();
    if (range) {
      util.codeblock.updateEmpty(range.getStartNode());
    }
  };
})();
goog.provide("uno.listeners.CryptListener");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.defs");
goog.require("uno.BasePlugin");
goog.require("uno.util.crypto");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.CryptListener");
  var util = uno.util;
  var CryptListener = uno.listeners.CryptListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(CryptListener, uno.BasePlugin);
  CryptListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  CryptListener.prototype.handleClick = function(e) {
    var dispatchEvent = this.editor.dispatchEvent.bind(this);
    var readOnly = this.editor.config.crypt.readOnly;
    return util.crypto.handleClick(e.target, readOnly, dispatchEvent);
  };
  CryptListener.prototype.handleDoubleClick = function(e) {
    var el = event.target;
    if (util.crypto.isCrypt(el) && !util.crypto.isOpen(el)) {
      goog.editor.range.placeCursorNextTo(el);
      this.editor.dispatchEvent({type:"cryptdoubleclick", id:el.getAttribute("id"), src:el.getAttribute("src")});
      return true;
    }
  };
})();
goog.provide("uno.listeners.deletelistener.mac");
(function() {
  var mac = uno.listeners.deletelistener.mac;
  mac.handleAfterExecCommand = function(event, editor) {
    if (event.command === "delete") {
      setTimeout(function fixCaret() {
        var range = editor.getRange();
        if (range && range.getStartNode() === editor.field) {
          var first = editor.field.firstChild;
          if (first.tagName !== "DIV") {
            setTimeout(fixCaret);
            return;
          }
          var tmp = document.createElement("input");
          tmp.setAttribute("style", "width:1px;height:1px;border:none;margin:0;padding:0;top:0;left:0;position:absolute");
          tmp.setAttribute("tabIndex", "-1");
          document.body.appendChild(tmp);
          tmp.setSelectionRange(0, 0);
          var newRange = goog.dom.Range.createFromNodes(first, 0, first, 0);
          newRange.select();
          tmp.remove();
        }
      });
    }
  };
})();
goog.provide("uno.listeners.DeleteListener");
goog.require("goog.debug.Logger");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
goog.require("uno.util.codeblock");
goog.require("uno.listeners.deletelistener.mac");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.DeleteListener");
  var util = uno.util;
  var BACKSPACE = goog.events.KeyCodes.BACKSPACE;
  var kKey = goog.events.KeyCodes.K;
  var DeleteListener = uno.listeners.DeleteListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(DeleteListener, uno.BasePlugin);
  DeleteListener.prototype.handleKeyDown = function(event) {
    if (event.ctrlKey && event.keyCode === kKey) {
      this.editor.dispatchChange();
    }
    if (event.keyCode === BACKSPACE) {
      if (this.editor.execCommand("delete", null, {native:true}, true)) {
        event.preventDefault();
        return true;
      } else {
        setTimeout(this.editor.dispatchChange.bind(this.editor));
      }
    }
  };
  DeleteListener.prototype.handleAfterExecCommand = function(event) {
    if (event.command === "delete") {
      var range = this.editor.getRange();
      util.codeblock.updateTopSpace(this.editor);
      if (range) {
        util.codeblock.updateEmpty(range.getStartNode());
      }
    }
    if (this.client.handleAfterExecCommand) {
      return this.client.handleAfterExecCommand(event, this.editor);
    }
  };
})();
goog.provide("uno.util.drag");
goog.require("goog.debug.Logger");
goog.require("uno.defs");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.drag");
  var util = uno.util;
  var dom = util.dom;
  var DRAGTYPES = uno.defs.dragtypes;
  var STRUCTTYPES = uno.defs.structuretypes;
  util.drag.start = function(target, state, options) {
    options = options || {};
    state.dragging = true;
    state.dragStartedInNote = options.dragStartedInNote;
    state.nativeDrag = !!options.nativeDrag;
    state.target = target;
    state.editor = options.editor;
    state.range = options.editor.getRange();
    state.handleOutsideDrop = options.handleOutsideDrop;
    state.event = options.event;
    if (util.img.isDraggable(state.target)) {
      state.dragType = DRAGTYPES.IMAGE;
    } else {
      if (util.attachment.isDraggable(state.target)) {
        state.dragType = DRAGTYPES.ATTACHMENT;
      } else {
        state.dragType = DRAGTYPES.NATIVE;
      }
    }
    options.event.dataTransfer.effectAllowed = "all";
    util.drag.prepareForDrag(state, options);
    state.draggedItems = util.drag.getDraggedItems(state) || [];
    if (options.setDataTransfer) {
      options.setDataTransfer(state.event, state);
    }
  };
  util.drag.prepareForDrag = function(state, options) {
    switch(state.dragType) {
      case DRAGTYPES.NATIVE:
        util.paragraph.prepareForDrag(state, options);
        break;
      case DRAGTYPES.IMAGE:
        util.img.prepareForDrag(state, options);
        break;
      case DRAGTYPES.ATTACHMENT:
        util.attachment.prepareForDrag(state, options);
        break;
      default:
    }
  };
  util.drag.getDraggedItems = function(state) {
    if (Array.isArray(state.draggedItems) && state.draggedItems.length) {
      return state.draggedItems;
    }
    switch(state.dragType) {
      case DRAGTYPES.IMAGE:
        return util.img.getDraggedItems(state.target);
      case DRAGTYPES.ATTACHMENT:
        return util.attachment.getDraggedItems(state.target);
      default:
        return [];
    }
  };
  util.drag.clear = function(state) {
    state.dragging = false;
    state.mousedown = false;
    state.mousedownTarget = null;
    state.target = null;
    state.itemTypes = null;
    state.copy = null;
    state.handleOutsideDrop = null;
    state.draggedItems = [];
  };
})();
goog.provide("uno.util.drop");
goog.require("goog.debug.Logger");
goog.require("uno.util.structure");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.drop");
  var util = uno.util;
  var dom = util.dom;
  var DRAGTYPES = uno.defs.dragtypes;
  util.drop.isDroppableTarget = function(dropTarget, state) {
    switch(state.dragType) {
      case DRAGTYPES.NATIVE:
        return util.paragraph.isDroppableTarget(dropTarget, state);
      case DRAGTYPES.IMAGE:
        return util.img.isDroppableTarget(dropTarget, state);
      case DRAGTYPES.ATTACHMENT:
        return util.attachment.isDroppableTarget(dropTarget, state);
      default:
        return false;
    }
  };
  util.drop.shouldUpdateDroppableTarget = function(target, newState, state) {
    var shouldUpdate = newState.hoveredItem !== state.hoveredItem;
    state.hoveredItem = newState.hoveredItem;
    state.hoveredArea = newState.hoveredArea;
    return shouldUpdate;
  };
  util.drop.updateDroppableTarget = function(target, newState, state) {
    state.dropEffect = util.structure.itemsAllowed(state.itemTypes, target) ? "move" : "none";
  };
  util.drop.dropItems = function(event, state, editor) {
    var dropRange = util.range.createFromPoints(event.clientX, event.clientY);
    if (!dropRange || editor.readOnly) {
      return false;
    }
    var target = dropRange.getContainer();
    if (!util.structure.isDroppableTarget(target, state)) {
      return false;
    }
    var outsideDropHandled = !state.dragStartedInNote && state.handleOutsideDrop && state.handleOutsideDrop(event, state, editor);
    state.dropRange = dropRange;
    if (!outsideDropHandled) {
      switch(state.dragType) {
        case DRAGTYPES.NATIVE:
          util.paragraph.handleDrop(event, state, editor);
          break;
        case DRAGTYPES.IMAGE:
          util.img.handleDrop(event, state, editor);
          break;
        case DRAGTYPES.ATTACHMENT:
          util.attachment.handleDrop(event, state, editor);
          break;
        default:
          break;
      }
      editor.dispatchChange();
    }
    return true;
  };
  util.drop.clear = function(state, field) {
    state.hoveredItem = null;
    state.hoveredArea = "";
    state.dropContainer = null;
    state.dragStartedInNote = false;
    state.nativeDrag = false;
    state.dataTransferContent = {};
    state.range = null;
    state.dropRange = null;
    state.dragType = "";
    state.scrollId = 0;
    state.target = null;
    util.drag.clear(state, field);
  };
  util.drop.handlePaste = function(goodPaste, state, editor) {
    if (!state.dragging) {
      return;
    }
    if (!goodPaste) {
      if (editor.lastCommand === "delete") {
        editor.dispatchChange(true);
        editor.execCommand("undo");
      }
    }
    setTimeout(function() {
      util.drop.clear(state, editor.field);
    });
  };
})();
goog.provide("uno.listeners.dragdroplistener.win");
goog.require("uno.util.resource");
(function() {
  var win = uno.listeners.dragdroplistener.win;
  var util = uno.util;
  var dragFromNote = false;
  var codeblocksEditable = true;
  function getFiles(event) {
    var dt = event.dataTransfer;
    var files = [];
    if (dt.items) {
      for (var i = 0; i < dt.items.length; i++) {
        if (dt.items[i].kind === "file") {
          files.push(dt.items[i].getAsFile());
        }
      }
    } else {
      for (var j = 0; j < dt.files.length; j++) {
        files.push(dt.files[j]);
      }
    }
    return files;
  }
  win.setDataTransfer = function(event, state) {
    if (event.target && (util.resource.isFileUI(event.target) || util.resource.isImage(event.target) || util.img.isResource(event.target))) {
      var dataurl = event.target.src.replace("database", "raw");
      var filename = event.target.getAttribute("data-filename") || "";
      var data = {type:"DownloadURL", value:"application/octet-stream:" + filename.replace(/:/g, "-") + ":" + dataurl};
      state.dataTransferContent[data.type] = data.value;
      event.dataTransfer.setData(data.type, data.value);
    }
  };
  win.handleOutsideDrop = function(event, state) {
    var files = getFiles(event);
    if (files.length) {
      event.preventDefault();
      files.forEach(function(file, i) {
        var filereader = new FileReader;
        var xhr = new XMLHttpRequest;
        xhr.open("POST", "http://loadhtml/dragdata");
        xhr.setRequestHeader("Content-Type", "application/octet-stream");
        xhr.setRequestHeader("X-Content-Filename", encodeURIComponent(file.name));
        xhr.setRequestHeader("X-File-Sequence", i + 1 + " of " + files.length);
        if (i === files.length - 1) {
          xhr.setRequestHeader("X-File-Final", true);
        }
        filereader.addEventListener("loadend", function(e) {
          var buffer = filereader.result;
          var dataview = new Uint8Array(buffer);
          xhr.send(dataview);
        });
        filereader.readAsArrayBuffer(file);
      });
      return true;
    }
    return false;
  };
})();
goog.provide("uno.listeners.DragDropListener");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.drag");
goog.require("uno.util.drop");
goog.require("uno.listeners.dragdroplistener.win");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.DragDropListener");
  var KeyCodes = goog.events.KeyCodes;
  var util = uno.util;
  var drag = util.drag;
  var drop = util.drop;
  var DragDropListener = uno.listeners.DragDropListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(DragDropListener, uno.BasePlugin);
  DragDropListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  function getEvent(event) {
    event = event.event_ || event;
    if (event.touches && event.touches.length) {
      return event.touches[0];
    }
    return event;
  }
  function handleDragStart(event, state, options) {
    var target = event.target;
    if (!state.dragging) {
      drag.start(target, state, {nativeDrag:options.nativeDrag, field:options.editor.field, event:event, editor:options.editor, dragStartedInNote:options.dragStartedInNote, setDataTransfer:options.setDataTransfer, handleOutsideDrop:options.handleOutsideDrop});
    }
  }
  function handleDragMove(event, state, editor) {
    if (state.dragging) {
      var target = event.target;
      if (drop.isDroppableTarget(target, state)) {
        var hoveredItem = target;
        var hoveredArea = null;
        var newState = {hoveredArea:hoveredArea, hoveredItem:hoveredItem};
        if (drop.shouldUpdateDroppableTarget(target, newState, state)) {
          drop.updateDroppableTarget(target, newState, state);
          if (state.dropEffect && event.dataTransfer) {
            event.dataTransfer.dropEffect = state.dropEffect;
            state.dropEffect = null;
          }
        }
      }
    }
  }
  function handleDrop(event, state, editor) {
    if (state.dragging) {
      event.preventDefault();
      drop.dropItems(event, state, editor);
    }
    drop.clear(state, editor.field);
  }
  DragDropListener.prototype.handleDragStart = function(event) {
    var dragState = this.editor.context.dragState;
    handleDragStart(getEvent(event), dragState, {editor:this.editor, nativeDrag:true, dragStartedInNote:true, setDataTransfer:this.client.setDataTransfer});
  };
  DragDropListener.prototype.handleMouseDown = function(event) {
    this.editor.context.dragState.mousedown = true;
    this.editor.context.dragState.mousedownTarget = event.target;
  };
  DragDropListener.prototype.handleDragOver = function(event) {
    var dragState = this.editor.context.dragState;
    if (dragState.dragging) {
      handleDragMove(getEvent(event), this.editor.context.dragState, this.editor);
    } else {
      handleDragStart({target:dragState.mousedownTarget, dataTransfer:getEvent(event).dataTransfer}, dragState, {editor:this.editor, nativeDrag:true, dragStartedInNote:!!dragState.mousedownTarget, setDataTransfer:this.client.setDataTransfer, handleOutsideDrop:this.client.handleOutsideDrop});
    }
  };
  DragDropListener.prototype.handleDragEnter = function(event) {
    event.preventDefault();
    var dragState = this.editor.context.dragState;
    if (dragState.dragging) {
      handleDragMove(getEvent(event), this.editor.context.dragState, this.editor);
    }
  };
  DragDropListener.prototype.handleMouseMove = function(event) {
    var dragState = this.editor.context.dragState;
    if (dragState.mousedown) {
      if (dragState.dragging) {
        return handleDragMove(getEvent(event), dragState, this.editor);
      }
    }
    return false;
  };
  DragDropListener.prototype.handleMouseUp = function(event) {
    var dragState = this.editor.context.dragState;
    if (dragState.dragging) {
      handleDrop(getEvent(event), dragState, this.editor);
    }
    dragState.mousedown = false;
    dragState.mousedownTarget = null;
  };
  DragDropListener.prototype.handleDrop = function(event) {
    handleDrop(getEvent(event), this.editor.context.dragState, this.editor);
  };
  DragDropListener.prototype.handleDragEnd = function(event) {
    if (this.editor.context.dragState.dragging) {
      drop.clear(this.editor.context.dragState, this.editor.field);
    }
  };
  DragDropListener.prototype.handleDragLeave = function(event) {
    var e = event.event_;
    if (util.dom.isEnnote(event.target) && (e.pageX < 25 || document.body.offsetWidth - e.pageX < 25)) {
      drop.clear(this.editor.context.dragState, this.editor.field);
    }
  };
  DragDropListener.prototype.handleWindowMouseUp = function(event) {
    if (this.editor.context.dragState.dragging) {
      drop.clear(this.editor.context.dragState, this.editor.field);
    }
  };
  DragDropListener.prototype.handleKeyUp = function(event) {
    if (event.keyCode === KeyCodes.ESC) {
      drop.clear(this.editor.context.dragState, this.editor.field);
    }
  };
  DragDropListener.prototype.handleMouseOut = function(event) {
    if (!event.toElement && !event.relatedTarget && this.editor.context.dragState.dragging) {
      drop.clear(this.editor.context.dragState, this.editor.field);
    }
  };
  DragDropListener.prototype.handleSelectStart = function(event) {
    if (this.editor.context.dragState.dragging) {
      event.preventDefault();
      event.stopPropagation();
    }
  };
})();
goog.provide("uno.listeners.EnterListener");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
goog.require("uno.util.paragraph");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.EnterListener");
  var util = uno.util;
  var dom = util.dom;
  var ENTER = goog.events.KeyCodes.ENTER;
  var EnterListener = uno.listeners.EnterListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(EnterListener, uno.BasePlugin);
  EnterListener.prototype.handleKeyDown = function(event) {
    if (event.keyCode === ENTER) {
      var range = this.editor.getRange();
      var table = range.getStartNode();
      if (table === range.getEndNode() && dom.isEntable(table)) {
        var paragraph = util.paragraph.create();
        goog.dom.replaceNode(paragraph, table);
        this.editor.selectContent(paragraph, true);
        this.editor.dispatchChange();
        return true;
      }
    }
    return false;
  };
})();
goog.provide("uno.listeners.NoteListener");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
goog.require("uno.util.paragraph");
goog.require("uno.util.todo");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.NoteListener");
  var util = uno.util;
  var selectingLines = false;
  var DOWN = goog.events.KeyCodes.DOWN;
  var UP = goog.events.KeyCodes.UP;
  var LEFT = goog.events.KeyCodes.LEFT;
  var RIGHT = goog.events.KeyCodes.RIGHT;
  var NoteListener = uno.listeners.NoteListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(NoteListener, uno.BasePlugin);
  NoteListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  NoteListener.prototype.handleKeyDown = function(e) {
    if ([DOWN, UP, LEFT, RIGHT].indexOf(e.keyCode) > -1 && e.shiftKey && !selectingLines) {
      selectingLines = true;
    } else {
      selectingLines = false;
    }
  };
  NoteListener.prototype.handleNativeSelectionChange = function() {
    var range = this.editor.getRange();
    if (range && !range.isCollapsed() && !selectingLines) {
      var rx = "^(<br( ?\\/)?>\\s*)?" + "(<\\/[^>]+>\\s*)+" + "(<[^\\/>]+>\\s*)+" + "(<br( ?\\/)?>\\s*)?$";
      rx = new RegExp(rx, "i");
      if (rx.test(range.getHtmlFragment())) {
        range.collapse(true);
        range.select();
      }
    }
    selectingLines = false;
  };
  NoteListener.prototype.handleClick = function(e) {
    if (!this.editor.readOnly) {
      var isOutsideNote = !goog.dom.getAncestor(e.target, util.dom.isEnnote, true);
      var focus = this.editor.config.stayInEditMode ? isOutsideNote : true;
      this.editor.enterEditMode(focus);
    } else {
      this.editor.dispatchEvent({type:uno.Editor.EventType.ACTION_DENIED, reason:{readOnly:true}});
    }
  };
  NoteListener.prototype.handleDelayedChange = function() {
    var lastNode = goog.dom.getLastElementChild(this.editor.field);
    if (!lastNode) {
      return;
    }
    var addNewLine = goog.array.some(lastNode.childNodes, function(node) {
      return util.dom.isBlockNode(node) || util.dom.isImageLikeElement(node) && !util.todo.isTodo(node);
    });
    if (addNewLine) {
      var newDiv = goog.dom.createDom("div", {}, goog.dom.createDom("br"));
      this.editor.field.appendChild(newDiv);
    }
  };
})();
goog.provide("uno.listeners.ForwardDeleteListener");
goog.require("goog.debug.Logger");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
goog.require("uno.util.paragraph");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.ForwardDeleteListener");
  var DELETE = goog.events.KeyCodes.DELETE;
  var ForwardDeleteListener = uno.listeners.ForwardDeleteListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ForwardDeleteListener, uno.BasePlugin);
  ForwardDeleteListener.prototype.handleKeyDown = function(event) {
    if (event.keyCode === DELETE) {
      if (this.editor.execCommand("delete", null, {forward:true, native:true}, true)) {
        event.preventDefault();
        return true;
      } else {
        setTimeout(this.editor.dispatchChange.bind(this.editor));
      }
    }
  };
})();
goog.provide("uno.listeners.HighlightListener");
goog.require("goog.debug.Logger");
goog.require("uno.util.dom");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.HighlightListener");
  var util = uno.util;
  var HighlightListener = uno.listeners.HighlightListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(HighlightListener, uno.BasePlugin);
  HighlightListener.prototype.handleNativeSelectionChange = function() {
    var range = this.editor.getRange();
    if (range) {
      var node = range.getStartNode();
      if (node && node.nodeType === Node.TEXT_NODE) {
        node = node.parentNode;
      }
      if (util.dom.isElementNode(node)) {
        var style = window.getComputedStyle(node);
        if (style.backgroundColor === "rgb(255, 255, 255)") {
          node.style.backgroundColor = "";
        }
      }
    }
  };
})();
goog.provide("uno.listeners.imglistener.generic");
goog.require("goog.events");
goog.require("goog.events.KeyCodes");
goog.require("goog.functions");
goog.require("uno.util.img");
goog.require("uno.util.preview");
goog.require("uno.util.resource");
(function() {
  var generic = uno.listeners.imglistener.generic;
  var util = uno.util;
  generic.handleImgResourceClick = function(event, editor) {
    var target = event.target;
    if (editor.readOnly || !util.img.isResource(target)) {
      return false;
    }
    if (util.img.isSelected(target)) {
      util.preview.requestOpen(editor, target);
    } else {
      util.img.setSelected(target);
    }
    editor.dispatchEvent({type:uno.Editor.EventType.IMAGE_CLICK, name:"", src:util.resource.urlFor(target), tagname:"img", reference:target.getAttribute("data-reference") || ""});
    return true;
  };
  generic.handleImgResourceKeyDown = function(evt, editor) {
    var img = util.img.getSelectedImage();
    if (img && evt.keyCode === goog.events.KeyCodes.SPACE) {
      evt.preventDefault();
      util.preview.requestOpen(editor, img);
      return true;
    }
    return false;
  };
})();
goog.provide("uno.listeners.imglistener.ios");
goog.require("uno.util.img");
goog.require("uno.util.resource");
(function() {
  var ios = uno.listeners.imglistener.ios;
  var util = uno.util;
  ios.handleImgResourceClick = function(event, editor) {
    var target = event.target;
    if (!util.img.isResource(target)) {
      return false;
    }
    var a;
    var offsetX = event.offsetX;
    var horizontalThreshold = editor.config.images.horizontalThreshold;
    var thresholdWidth = horizontalThreshold * 3;
    if (target.width > thresholdWidth && (offsetX < horizontalThreshold || offsetX > target.offsetWidth - horizontalThreshold)) {
      if (editor.inEditMode()) {
        setTimeout(function() {
          goog.editor.range.placeCursorNextTo(target, offsetX < horizontalThreshold);
        });
      } else {
        var parent = target.parentElement;
        var offset = offsetX < horizontalThreshold ? 0 : 1;
        var index = util.dom.index(target) + offset;
        var newRange = goog.dom.Range.createFromNodes(parent, index, parent, index);
        editor.enterEditMode(newRange);
      }
    } else {
      a = goog.dom.getAncestorByTagNameAndClass(target, "a");
      editor.dispatchEvent({type:"linkclick", target:event.target, data:{action:"open", eventType:"tap", hash:util.resource.hashFor(target), href:util.resource.urlFor(target), mime:util.resource.mimeTypeFor(target), module:"resource", reference:util.resource.referenceFor(target), anchorHref:a && a.href || undefined}});
      event.preventDefault();
    }
    return true;
  };
  ios.handleImgResourceKeyDown = goog.functions.FALSE;
})();
goog.provide("uno.listeners.imglistener.android");
goog.require("uno.util.img");
goog.require("uno.util.resource");
goog.require("uno.listeners.imglistener.ios");
(function() {
  var ios = uno.listeners.imglistener.ios;
  var android = uno.listeners.imglistener.android;
  var util = uno.util;
  android.handleImgResourceClick = ios.handleImgResourceClick;
  android.handleLongTouch = function(event, editor) {
    var target = event.target;
    if (!util.img.isResource(target)) {
      return false;
    }
    editor.dispatchEvent({type:"linkclick", target:event.target, data:{action:"open", eventType:"press", hash:util.resource.hashFor(target), href:util.resource.urlFor(target), mime:util.resource.mimeTypeFor(target), module:"resource", reference:util.resource.referenceFor(target)}});
    return true;
  };
  android.handleImgResourceKeyDown = goog.functions.FALSE;
})();
goog.provide("uno.listeners.imglistener.mac");
goog.require("uno.util.img");
(function() {
  var mac = uno.listeners.imglistener.mac;
  var generic = uno.listeners.imglistener.generic;
  var util = uno.util;
  mac.handleImgResourceClick = generic.handleImgResourceClick;
  mac.handleImgResourceKeyDown = function(evt, editor) {
    var img = util.img.getSelectedImage();
    if (img && evt.keyCode === goog.events.KeyCodes.SPACE) {
      evt.preventDefault();
      setTimeout(function() {
        util.preview.requestOpen(editor, img);
      }, 250);
      return true;
    }
    return false;
  };
})();
goog.provide("uno.listeners.ImgListener");
goog.require("goog.debug.Logger");
goog.require("goog.editor.style");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.listeners.imglistener.generic");
goog.require("uno.listeners.imglistener.android");
goog.require("uno.listeners.imglistener.ios");
goog.require("uno.listeners.imglistener.mac");
goog.require("uno.util.img");
goog.require("uno.util.resource");
goog.require("uno.util.zoomscale");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.ImgListener");
  var util = uno.util;
  var ImgListener = uno.listeners.ImgListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ImgListener, uno.BasePlugin);
  ImgListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  ImgListener.prototype.handleClick = function(event) {
    if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {
      return false;
    }
    return this.client.handleImgResourceClick(event, this.editor);
  };
  ImgListener.prototype.handleLongTouch = function(event) {
    if (this.client.handleLongTouch) {
      return this.client.handleLongTouch(event, this.editor);
    }
  };
  ImgListener.prototype.handleNativeSelectionChange = function() {
    if (!util.img.isSelected(this.editor.getRange())) {
      util.img.setSelected(null);
    }
  };
  ImgListener.prototype.handleKeyDown = function(event) {
    return this.client.handleImgResourceKeyDown(event, this.editor);
  };
  ImgListener.prototype.handleMouseOver = function(event) {
    if (util.img.isResource(event.target)) {
      util.img.setToolbar(event.target, handleToolbarButtonClick.bind(this));
    } else {
      if (!util.img.isToolbarButton(event.target)) {
        util.img.setToolbar(null);
      }
    }
  };
  ImgListener.prototype.handleScroll = function(event) {
    util.img.hideToolsOnScrollIfNeeded(event.target);
  };
  function handleToolbarButtonClick(img, name) {
    this.editor.dispatchEvent({type:name, module:"ui-img-buttons", src:util.resource.urlFor(img)});
  }
})();
goog.provide("uno.listeners.linklistener.web");
(function() {
  var web = uno.listeners.linklistener.web;
  web.handleClick = function(event) {
    event.preventDefault();
  };
})();
goog.provide("uno.listeners.LinkListener");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("goog.style");
goog.require("uno.BasePlugin");
goog.require("uno.listeners.linklistener.web");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.LinkListener");
  var util = uno.util;
  var LinkListener = uno.listeners.LinkListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(LinkListener, uno.BasePlugin);
  LinkListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  LinkListener.prototype.handleClick = function(event) {
    var bounds;
    var el = event.target;
    if (el != null) {
      var checkLink = function(node) {
        el = node;
        return util.dom.isA(node);
      };
      if (goog.dom.getAncestor(el, checkLink, true)) {
        var href = el.href;
        if (href != null && href.length > 0) {
          bounds = goog.style.getBounds(el);
          this.editor.dispatchEvent({type:"linkclick", target:el, data:{href:el.href, module:"link", left:bounds.left, top:bounds.top, width:bounds.width, height:bounds.height}});
        }
        if (this.client.handleClick) {
          this.client.handleClick(event);
        }
        return true;
      }
    }
  };
})();
goog.provide("uno.listeners.ListListener");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.editor.Command");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
goog.require("uno.util.list");
goog.require("uno.util.dom");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.ListListener");
  var util = uno.util;
  var KeyCodes = goog.events.KeyCodes;
  var ZERO_WIDTH_SPACE = uno.defs.unicode.ZERO_WIDTH_SPACE;
  var ListListener = uno.listeners.ListListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ListListener, uno.BasePlugin);
  ListListener.prototype.handleKeyDown = function(event) {
    var range = this.editor.getRange();
    if (event.keyCode === KeyCodes.ENTER && event.shiftKey && util.list.for(range.getStartNode())) {
      event.preventDefault();
      var br = goog.dom.createDom("br");
      var zws = goog.dom.createTextNode(uno.defs.unicode.ZERO_WIDTH_SPACE);
      range.insertNode(zws);
      range.insertNode(br);
      goog.editor.range.placeCursorNextTo(zws);
      document.execCommand("delete");
      this.editor.dispatchChange();
      return true;
    } else {
      if (event.keyCode === KeyCodes.ENTER) {
        var innerNode = goog.editor.range.getDeepEndPoint(range, true).node;
        var node = util.list.itemFor(innerNode);
        var sibling = node ? node.nextElementSibling : null;
        var siblingList = util.dom.isUl(sibling) || util.dom.isOl(sibling);
        if (siblingList && util.dom.isLi(node) && util.dom.isEmpty(node)) {
          event.stopPropagation();
          event.preventDefault();
          document.execCommand("outdent");
          return true;
        }
        if (node && innerNode && innerNode.textContent === ZERO_WIDTH_SPACE) {
          var parentNode = innerNode.parentNode;
          var nextNode = parentNode.nextSibling;
          if (util.dom.isBr(nextNode)) {
            parentNode.replaceChild(nextNode, innerNode);
          }
        }
      } else {
        if (event.keyCode === KeyCodes.TAB) {
          var parentLi = util.dom.parent(range.getContainerElement(), "li") || goog.iter.some(range, util.dom.isLi);
          if (parentLi) {
            this.editor.execCommand(event.shiftKey ? "outdent" : "indent");
            event.preventDefault();
            return true;
          }
        }
      }
    }
    return false;
  };
  function isAfterLinefeed(node, range) {
    if (!range.isCollapsed()) {
      return false;
    }
    while (node && !util.dom.isLi(node)) {
      if (util.dom.isLi(node.parentNode)) {
        break;
      }
      node = node.parentNode;
    }
    var prevSiblings = util.dom.getPreviousSiblings(node);
    var siblingBr = goog.array.find(prevSiblings, function(sibling) {
      return sibling.nodeName.toLowerCase() === "br";
    });
    return !!siblingBr;
  }
})();
goog.provide("uno.listeners.RichlinkListener");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.RichlinkListener");
  var util = uno.util;
  var RichlinkListener = uno.listeners.RichlinkListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(RichlinkListener, uno.BasePlugin);
  RichlinkListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  RichlinkListener.prototype.handleClick = function(event) {
    var el = util.richlink.componentElementFor(event.target);
    if (el) {
      return util.richlink.handleClick(el, event, this.editor);
    }
  };
  RichlinkListener.prototype.handleMouseMove = function(event) {
    var el = util.richlink.componentElementFor(event.target);
    if (el) {
      return util.richlink.handleMouseMove(el, event, this.editor);
    }
  };
  RichlinkListener.prototype.handleMouseOut = function(event) {
    var el = util.richlink.componentElementFor(event.target);
    if (el) {
      return util.richlink.handleMouseOut(el, event, this.editor);
    }
  };
})();
goog.provide("goog.async.Debouncer");
goog.require("goog.Disposable");
goog.require("goog.Timer");
goog.async.Debouncer = function(listener, interval, opt_handler) {
  goog.async.Debouncer.base(this, "constructor");
  this.listener_ = opt_handler != null ? goog.bind(listener, opt_handler) : listener;
  this.interval_ = interval;
  this.callback_ = goog.bind(this.onTimer_, this);
  this.shouldFire_ = false;
  this.pauseCount_ = 0;
  this.timer_ = null;
  this.refireAt_ = null;
  this.args_ = [];
};
goog.inherits(goog.async.Debouncer, goog.Disposable);
goog.async.Debouncer.prototype.fire = function(var_args) {
  this.args_ = arguments;
  this.shouldFire_ = false;
  if (this.timer_) {
    this.refireAt_ = goog.now() + this.interval_;
    return;
  }
  this.timer_ = goog.Timer.callOnce(this.callback_, this.interval_);
};
goog.async.Debouncer.prototype.stop = function() {
  if (this.timer_) {
    goog.Timer.clear(this.timer_);
    this.timer_ = null;
  }
  this.refireAt_ = null;
  this.shouldFire_ = false;
  this.args_ = [];
};
goog.async.Debouncer.prototype.pause = function() {
  ++this.pauseCount_;
};
goog.async.Debouncer.prototype.resume = function() {
  if (!this.pauseCount_) {
    return;
  }
  --this.pauseCount_;
  if (!this.pauseCount_ && this.shouldFire_) {
    this.doAction_();
  }
};
goog.async.Debouncer.prototype.disposeInternal = function() {
  this.stop();
  goog.async.Debouncer.base(this, "disposeInternal");
};
goog.async.Debouncer.prototype.onTimer_ = function() {
  if (this.refireAt_) {
    this.timer_ = goog.Timer.callOnce(this.callback_, this.refireAt_ - goog.now());
    this.refireAt_ = null;
    return;
  }
  this.timer_ = null;
  if (!this.pauseCount_) {
    this.doAction_();
  } else {
    this.shouldFire_ = true;
  }
};
goog.async.Debouncer.prototype.doAction_ = function() {
  this.shouldFire_ = false;
  this.listener_.apply(null, this.args_);
};
goog.provide("uno.listeners.SearchResizeListener");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("goog.async.Debouncer");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.SearchResizeListener");
  var editor;
  var SearchResizeListener = uno.listeners.SearchResizeListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(SearchResizeListener, uno.BasePlugin);
  var debouncer = new goog.async.Debouncer(function(editor) {
    editor.queryCommandValue("search");
  }, 300);
  SearchResizeListener.prototype.handleWindowResize = function() {
    log.fine("SearchResizeListener.prototype.handleWindowResize");
    debouncer.fire(this.editor);
  };
})();
goog.provide("goog.editor.plugins.LinkShortcutPlugin");
goog.require("goog.editor.Command");
goog.require("goog.editor.Plugin");
goog.editor.plugins.LinkShortcutPlugin = function() {
  goog.editor.plugins.LinkShortcutPlugin.base(this, "constructor");
};
goog.inherits(goog.editor.plugins.LinkShortcutPlugin, goog.editor.Plugin);
goog.editor.plugins.LinkShortcutPlugin.prototype.getTrogClassId = function() {
  return "LinkShortcutPlugin";
};
goog.editor.plugins.LinkShortcutPlugin.prototype.handleKeyboardShortcut = function(e, key, isModifierPressed) {
  if (isModifierPressed && key == "k" && !e.shiftKey) {
    var link = this.getFieldObject().execCommand(goog.editor.Command.LINK);
    if (link) {
      link.finishLinkCreation(this.getFieldObject());
    }
    return true;
  }
  return false;
};
goog.provide("goog.editor.plugins.HeaderFormatter");
goog.require("goog.editor.Command");
goog.require("goog.editor.Plugin");
goog.require("goog.userAgent");
goog.editor.plugins.HeaderFormatter = function() {
  goog.editor.Plugin.call(this);
};
goog.inherits(goog.editor.plugins.HeaderFormatter, goog.editor.Plugin);
goog.editor.plugins.HeaderFormatter.prototype.getTrogClassId = function() {
  return "HeaderFormatter";
};
goog.editor.plugins.HeaderFormatter.HEADER_COMMAND = {H1:"H1", H2:"H2", H3:"H3", H4:"H4"};
goog.editor.plugins.HeaderFormatter.prototype.handleKeyboardShortcut = function(e, key, isModifierPressed) {
  if (!isModifierPressed) {
    return false;
  }
  var command = null;
  switch(key) {
    case "1":
      command = goog.editor.plugins.HeaderFormatter.HEADER_COMMAND.H1;
      break;
    case "2":
      command = goog.editor.plugins.HeaderFormatter.HEADER_COMMAND.H2;
      break;
    case "3":
      command = goog.editor.plugins.HeaderFormatter.HEADER_COMMAND.H3;
      break;
    case "4":
      command = goog.editor.plugins.HeaderFormatter.HEADER_COMMAND.H4;
      break;
  }
  if (command) {
    this.getFieldObject().execCommand(goog.editor.Command.FORMAT_BLOCK, command);
    if (goog.userAgent.GECKO) {
      e.stopPropagation();
    }
    return true;
  }
  return false;
};
goog.provide("uno.listeners.ShortcutListener");
goog.require("goog.debug.Logger");
goog.require("goog.editor.plugins.UndoRedo");
goog.require("goog.editor.plugins.RemoveFormatting");
goog.require("goog.editor.plugins.LinkShortcutPlugin");
goog.require("goog.editor.plugins.HeaderFormatter");
goog.require("goog.editor.plugins.BasicTextFormatter");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.ShortcutListener");
  var ShortcutListener = uno.listeners.ShortcutListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(ShortcutListener, uno.BasePlugin);
  goog.editor.plugins.UndoRedo.prototype.handleKeyboardShortcut = goog.functions.FALSE;
  goog.editor.plugins.RemoveFormatting.prototype.handleKeyboardShortcut = goog.functions.FALSE;
  goog.editor.plugins.LinkShortcutPlugin.prototype.handleKeyboardShortcut = goog.functions.FALSE;
  goog.editor.plugins.HeaderFormatter.prototype.handleKeyboardShortcut = goog.functions.FALSE;
  goog.editor.plugins.BasicTextFormatter.prototype.handleKeyboardShortcut = goog.functions.FALSE;
})();
goog.provide("uno.listeners.SmartScrollListener");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.util.range");
goog.require("goog.events.KeyCodes");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.SmartScrollListener");
  var util = uno.util;
  var SmartScrollListener = uno.listeners.SmartScrollListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(SmartScrollListener, uno.BasePlugin);
  var delayedScrollTimerID = 0;
  SmartScrollListener.prototype._triggerDelayedScroll = function() {
    var editor = this.editor;
    if (delayedScrollTimerID) {
      clearTimeout(delayedScrollTimerID);
    }
    delayedScrollTimerID = setTimeout(function() {
      log.fine("  SmartScrollListener.prototype._triggerDelayedScroll");
      util.range.scrollSelectionIntoView(editor);
    });
  };
  SmartScrollListener.prototype.handleSelectionChange = function() {
    if (this.editor.config.smartScrollEnabled) {
      log.fine("SmartScrollListener.prototype.handleSelectionChange");
      this._triggerDelayedScroll();
    }
  };
  SmartScrollListener.prototype.handleNativeSelectionChange = function() {
    if (this.editor.config.smartScrollEnabled) {
      log.fine("  SmartScrollListener.prototype.handleNativeSelectionChange");
      var range = this.editor.getRange();
      if (range && range.isCollapsed()) {
        this._triggerDelayedScroll();
      }
    }
  };
  SmartScrollListener.prototype.handleWindowResize = function() {
    log.fine("SmartScrollListener.prototype.handleWindowResize");
    util.range.scrollSelectionIntoView(this.editor);
  };
})();
goog.provide("goog.events.MouseWheelEvent");
goog.provide("goog.events.MouseWheelHandler");
goog.provide("goog.events.MouseWheelHandler.EventType");
goog.require("goog.dom");
goog.require("goog.events");
goog.require("goog.events.BrowserEvent");
goog.require("goog.events.EventTarget");
goog.require("goog.math");
goog.require("goog.style");
goog.require("goog.userAgent");
goog.events.MouseWheelHandler = function(element, opt_capture) {
  goog.events.EventTarget.call(this);
  this.element_ = element;
  var rtlElement = goog.dom.isElement(this.element_) ? this.element_ : this.element_ ? this.element_.body : null;
  this.isRtl_ = !!rtlElement && goog.style.isRightToLeft(rtlElement);
  var type = goog.userAgent.GECKO ? "DOMMouseScroll" : "mousewheel";
  this.listenKey_ = goog.events.listen(this.element_, type, this, opt_capture);
};
goog.inherits(goog.events.MouseWheelHandler, goog.events.EventTarget);
goog.events.MouseWheelHandler.EventType = {MOUSEWHEEL:"mousewheel"};
goog.events.MouseWheelHandler.prototype.maxDeltaX_;
goog.events.MouseWheelHandler.prototype.maxDeltaY_;
goog.events.MouseWheelHandler.prototype.setMaxDeltaX = function(maxDeltaX) {
  this.maxDeltaX_ = maxDeltaX;
};
goog.events.MouseWheelHandler.prototype.setMaxDeltaY = function(maxDeltaY) {
  this.maxDeltaY_ = maxDeltaY;
};
goog.events.MouseWheelHandler.prototype.handleEvent = function(e) {
  var deltaX = 0;
  var deltaY = 0;
  var detail = 0;
  var be = e.getBrowserEvent();
  if (be.type == "mousewheel") {
    var wheelDeltaScaleFactor = 40;
    detail = goog.events.MouseWheelHandler.smartScale_(-be.wheelDelta, wheelDeltaScaleFactor);
    if (goog.isDef(be.wheelDeltaX)) {
      deltaX = goog.events.MouseWheelHandler.smartScale_(-be.wheelDeltaX, wheelDeltaScaleFactor);
      deltaY = goog.events.MouseWheelHandler.smartScale_(-be.wheelDeltaY, wheelDeltaScaleFactor);
    } else {
      deltaY = detail;
    }
  } else {
    detail = be.detail;
    if (detail > 100) {
      detail = 3;
    } else {
      if (detail < -100) {
        detail = -3;
      }
    }
    if (goog.isDef(be.axis) && be.axis === be.HORIZONTAL_AXIS) {
      deltaX = detail;
    } else {
      deltaY = detail;
    }
  }
  if (goog.isNumber(this.maxDeltaX_)) {
    deltaX = goog.math.clamp(deltaX, -this.maxDeltaX_, this.maxDeltaX_);
  }
  if (goog.isNumber(this.maxDeltaY_)) {
    deltaY = goog.math.clamp(deltaY, -this.maxDeltaY_, this.maxDeltaY_);
  }
  if (this.isRtl_) {
    deltaX = -deltaX;
  }
  var newEvent = new goog.events.MouseWheelEvent(detail, be, deltaX, deltaY);
  this.dispatchEvent(newEvent);
};
goog.events.MouseWheelHandler.smartScale_ = function(mouseWheelDelta, scaleFactor) {
  if (goog.userAgent.WEBKIT && (goog.userAgent.MAC || goog.userAgent.LINUX) && mouseWheelDelta % scaleFactor != 0) {
    return mouseWheelDelta;
  } else {
    return mouseWheelDelta / scaleFactor;
  }
};
goog.events.MouseWheelHandler.prototype.disposeInternal = function() {
  goog.events.MouseWheelHandler.superClass_.disposeInternal.call(this);
  goog.events.unlistenByKey(this.listenKey_);
  this.listenKey_ = null;
};
goog.events.MouseWheelEvent = function(detail, browserEvent, deltaX, deltaY) {
  goog.events.BrowserEvent.call(this, browserEvent);
  this.type = goog.events.MouseWheelHandler.EventType.MOUSEWHEEL;
  this.detail = detail;
  this.deltaX = deltaX;
  this.deltaY = deltaY;
};
goog.inherits(goog.events.MouseWheelEvent, goog.events.BrowserEvent);
goog.provide("uno.listeners.tablelistener.generic");
goog.require("goog.events.KeyCodes");
(function() {
  var generic = uno.listeners.tablelistener.generic;
  generic.isToggleKey = function(event) {
    return event && event.metaKey;
  };
  generic.getDeltaX = function(event) {
    return event.deltaX * 0.5;
  };
})();
goog.provide("uno.listeners.tablelistener.win");
goog.require("goog.events.KeyCodes");
(function() {
  var win = uno.listeners.tablelistener.win;
  win.isToggleKey = function(event) {
    return event && event.ctrlKey;
  };
  win.getDeltaX = function(event) {
    return event.deltaX * 26;
  };
})();
goog.provide("uno.listeners.tablelistener.web");
goog.require("goog.events.KeyCodes");
(function() {
  var clients = uno.listeners.tablelistener;
  var web = clients.web;
  web.isToggleKey = function() {
    if (goog.userAgent.MAC) {
      return isMacToggleKey;
    }
    return isWinToggleKey;
  }();
  function isWinToggleKey(event) {
    return event && event.ctrlKey;
  }
  function isMacToggleKey(event) {
    return event && event.metaKey;
  }
  web.getDeltaX = function(event) {
    return event.deltaX;
  };
})();
goog.provide("uno.components.MenuAbstractItem");
goog.require("goog.dom");
(function() {
  uno.components.MenuAbstractItem = function() {
    this.focused_ = false;
    this.element = null;
  };
  uno.components.MenuAbstractItem.prototype.allowUserInteraction = true;
  uno.components.MenuAbstractItem.prototype.allowSubmenu = false;
  uno.components.MenuAbstractItem.prototype.setFocus = function(focused, sender) {
    if (this.allowUserInteraction) {
      this.focused_ = focused;
      this.element.classList.toggle("focused", focused);
    }
  };
  uno.components.MenuAbstractItem.prototype.getValue = function() {
    return null;
  };
  uno.components.MenuAbstractItem.prototype.handleMouseOver = function(evt) {
    return false;
  };
  uno.components.MenuAbstractItem.prototype.handleClick = function(evt) {
    return false;
  };
  uno.components.MenuAbstractItem.prototype.handleKey = function(keyCode) {
    return false;
  };
})();
goog.provide("uno.components.MenuColorPicker");
goog.require("goog.color");
goog.require("goog.dom");
goog.require("goog.events");
goog.require("goog.events.KeyCodes");
goog.require("uno.components.MenuAbstractItem");
(function() {
  uno.components.MenuColorPicker = function(text, defaultColor) {
    uno.components.MenuAbstractItem.call(this);
    if (typeof defaultColor === "string" && goog.color.isValidColor(defaultColor)) {
      defaultColor = goog.color.parse(defaultColor).hex;
    }
    this.colorPalette_ = ["#ffffff", "#eaeaea", "#d4d4d4", "#ddd1f3", "#f0d1f6", "#fbcfd6", "#fedec1", "#ffe697", "#cdedd8", "#cdeef0", "#cde6f9", "#ccd7ea", "#3f3f3f", "#737373", "#979797", "#8b65e0", "#c064d1", "#fc5356", "#fd7b39", "#ffc200", "#57b779", "#57bfc4", "#54a9e6", "#426bb3"];
    this.colorNodes_ = this.colorPalette_.map(function(code) {
      var cls = ["color"];
      if (code === "#ffffff") {
        cls.push("bordered");
      }
      if (code === defaultColor) {
        cls.push("default");
      }
      return goog.dom.createDom("div", {class:cls.join(" "), style:"background-color: " + code + ";", "data-color":code});
    });
    var titleNode = goog.dom.createDom("div", {class:"title"}, text);
    var container = goog.dom.createDom("div", {class:"colors"}, this.colorNodes_);
    var children = [titleNode, container];
    this.element = goog.dom.createDom("div", {class:"menu-colorpicker"}, children);
    this.defaultColorIndex_ = !!defaultColor ? this.colorPalette_.indexOf(defaultColor) : -1;
    this.focusedColorIndex_ = -1;
    this.cachedColorIndex_ = -1;
  };
  goog.inherits(uno.components.MenuColorPicker, uno.components.MenuAbstractItem);
  uno.components.MenuColorPicker.prototype.setColorFocus_ = function(index) {
    if (this.focusedColorIndex_ === index) {
      return;
    }
    if (this.focusedColorIndex_ > -1) {
      this.colorNodes_[this.focusedColorIndex_].classList.remove("selected");
    }
    if (index > -1) {
      this.colorNodes_[index].classList.add("selected");
      this.cachedColorIndex_ = index;
    }
    this.focusedColorIndex_ = index;
  };
  uno.components.MenuColorPicker.prototype.setFocus = function(focused, sender) {
    goog.base(this, "setFocus", focused);
    var KeyCodes = goog.events.KeyCodes;
    var cachedIndex = this.cachedColorIndex_;
    if (focused && [KeyCodes.DOWN, KeyCodes.RIGHT, KeyCodes.LEFT].indexOf(sender) > -1) {
      this.setColorFocus_(cachedIndex > -1 && cachedIndex < 6 ? cachedIndex : 0);
    } else {
      if (focused && sender === KeyCodes.UP) {
        this.setColorFocus_(cachedIndex >= this.colorPalette_.length - 6 ? cachedIndex : this.colorPalette_.length - 6);
      } else {
        if (focused) {
          this.cachedColorIndex_ = -1;
        } else {
          if (!focused) {
            this.setColorFocus_(-1);
          }
        }
      }
    }
  };
  uno.components.MenuColorPicker.prototype.getValue = function() {
    if (this.focusedColorIndex_ > -1) {
      return this.colorPalette_[this.focusedColorIndex_];
    } else {
      if (this.defaultColorIndex_ > -1) {
        return this.colorPalette_[this.defaultColorIndex_];
      }
    }
    return null;
  };
  uno.components.MenuColorPicker.prototype.handleClick = function(evt) {
    var index = this.colorNodes_.indexOf(evt.target);
    this.setColorFocus_(index);
    return index === -1;
  };
  uno.components.MenuColorPicker.prototype.handleKey = function(keyCode) {
    var KeyCodes = goog.events.KeyCodes;
    var columnCount = 6;
    var currentIndex = this.focusedColorIndex_;
    var cachedIndex = this.cachedColorIndex_;
    var index = -1;
    if (currentIndex === -1) {
      if (cachedIndex > -1 && [KeyCodes.RIGHT, KeyCodes.LEFT, KeyCodes.UP, KeyCodes.DOWN].indexOf(keyCode) > -1) {
        index = cachedIndex;
      } else {
        if ([KeyCodes.RIGHT, KeyCodes.DOWN].indexOf(keyCode) > -1) {
          index = 0;
        } else {
          if (keyCode === KeyCodes.LEFT) {
            index = columnCount - 1;
          } else {
            if (keyCode === KeyCodes.UP) {
              index = this.colorPalette_.length - columnCount;
            }
          }
        }
      }
      this.setColorFocus_(index);
      return index > -1;
    }
    if (keyCode === KeyCodes.RIGHT || keyCode === KeyCodes.LEFT) {
      var newIndex = currentIndex + (keyCode === KeyCodes.RIGHT ? 1 : -1);
      var newRow = Math.floor(newIndex / columnCount);
      var currentRow = Math.floor(currentIndex / columnCount);
      if (currentRow === newRow) {
        index = newIndex;
      }
    } else {
      if (keyCode === KeyCodes.UP && currentIndex - columnCount >= 0) {
        index = currentIndex - columnCount;
      } else {
        if (keyCode === KeyCodes.DOWN && currentIndex + columnCount <= this.colorPalette_.length - 1) {
          index = currentIndex + columnCount;
        }
      }
    }
    if (index > -1) {
      this.setColorFocus_(index);
      return true;
    }
    return false;
  };
  uno.components.MenuColorPicker.prototype.handleMouseOver = function(evt) {
    this.setColorFocus_(this.colorNodes_.indexOf(evt.target));
    return false;
  };
})();
goog.provide("uno.components.MenuItem");
goog.require("goog.dom");
goog.require("uno.components.MenuAbstractItem");
(function() {
  uno.components.MenuItem = function(text, disabled) {
    uno.components.MenuAbstractItem.call(this);
    this.element = goog.dom.createDom("div", {class:"menu-item"}, text);
    if (disabled === true) {
      this.element.classList.add("disabled");
      this.allowUserInteraction = false;
    }
  };
  goog.inherits(uno.components.MenuItem, uno.components.MenuAbstractItem);
  uno.components.MenuItem.prototype.allowSubmenu = true;
})();
goog.provide("uno.components.MenuOption");
goog.require("goog.dom");
goog.require("uno.components.MenuAbstractItem");
(function() {
  uno.components.MenuOption = function(text, checked) {
    uno.components.MenuAbstractItem.call(this);
    this.element = goog.dom.createDom("div", {class:"menu-item option" + (checked === true ? " checked" : "")}, text);
  };
  goog.inherits(uno.components.MenuOption, uno.components.MenuAbstractItem);
})();
goog.provide("uno.components.MenuSection");
goog.require("goog.dom");
goog.require("uno.components.MenuAbstractItem");
(function() {
  uno.components.MenuSection = function(text) {
    uno.components.MenuAbstractItem.call(this);
    this.element = goog.dom.createDom("div", {class:"menu-section"}, text);
  };
  goog.inherits(uno.components.MenuSection, uno.components.MenuAbstractItem);
  uno.components.MenuSection.prototype.allowUserInteraction = false;
})();
goog.provide("uno.components.MenuSeparator");
goog.require("goog.dom");
goog.require("uno.components.MenuAbstractItem");
(function() {
  uno.components.MenuSeparator = function() {
    uno.components.MenuAbstractItem.call(this);
    this.element = goog.dom.createDom("div", {class:"menu-separator"});
  };
  goog.inherits(uno.components.MenuSeparator, uno.components.MenuAbstractItem);
  uno.components.MenuSeparator.prototype.allowUserInteraction = false;
})();
goog.provide("uno.components.Menu");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.events");
goog.require("goog.events.KeyCodes");
goog.require("uno.util.dom");
goog.require("uno.util.tools");
goog.require("uno.components.MenuAbstractItem");
goog.require("uno.components.MenuColorPicker");
goog.require("uno.components.MenuItem");
goog.require("uno.components.MenuOption");
goog.require("uno.components.MenuSection");
goog.require("uno.components.MenuSeparator");
(function() {
  var Menu = uno.components.Menu = function(opt) {
    this.visible = false;
    this.scrollable_ = false;
    this.items_ = [];
    this.handlers_ = [];
    this.populators_ = [];
    this.originOverflowY_ = "";
    this.focusIndex_ = -1;
    this.dismissTimer_ = null;
    this.focusTimer_ = null;
    this.submenuTimer_ = null;
    this.submenu_ = null;
    opt = opt || {};
    this.onAction = typeof opt.onAction === "function" ? opt.onAction : null;
    this.onClose = typeof opt.onClose === "function" ? opt.onClose : null;
    this.actionClose_ = typeof opt.actionClose === "boolean" ? opt.actionClose : true;
    this.keyClose_ = typeof opt.keyClose === "boolean" ? opt.keyClose : true;
    this.blurClose_ = typeof opt.blurClose === "boolean" ? opt.blurClose : true;
    this.menuAutoFocused_ = typeof opt.menuAutoFocused === "boolean" ? opt.menuAutoFocused : true;
    this.itemAutoFocused_ = typeof opt.itemAutoFocused === "boolean" ? opt.itemAutoFocused : false;
    this.parentMenu_ = opt.parent || null;
    this.container_ = goog.dom.createDom("div", {class:"container"});
    this.element = goog.dom.createDom("div", {class:"en-menu", tabIndex:"-1"}, this.container_);
    goog.events.listen(this.element, "contextmenu", handleContextMenu);
    goog.events.listen(this.element, "keydown", handleKeyDown.bind(this), true);
    goog.events.listen(this.element, "mouseover", handleMouseOver.bind(this));
    goog.events.listen(this.element, "mouseout", handleMouseOut.bind(this));
    goog.events.listen(this.element, "click", handleClick.bind(this));
    goog.events.listen(this.element, "blur", handleBlur.bind(this), true);
  };
  Object.defineProperty(Menu.prototype, "focused", {get:function() {
    return this.element === document.activeElement;
  }});
  Menu.prototype.present = function(clientX, clientY) {
    if (this.visible) {
      return;
    }
    if (!this.parentMenu_) {
      this.originOverflowY_ = document.documentElement.style.overflowY;
      document.documentElement.style.overflowY = "hidden";
    }
    this.visible = true;
    uno.util.tools.append(this.element);
    var top = uno.util.dom.scrollTop(document.body);
    var vp = 4;
    var vh = window.innerHeight;
    var vw = window.innerWidth;
    var rect = this.element.getBoundingClientRect();
    var height = null;
    var y = clientY + top;
    var x = clientX + rect.width + vp > vw ? clientX - rect.width : clientX;
    x = Math.max(x, vp);
    if (rect.height + vp * 2 > vh) {
      y = top + vp;
      height = vh - vp * 2;
    } else {
      y = Math.max(y - 12, top + vp);
      if (y + rect.height > top + vh) {
        y = top + vh - rect.height - vp;
      }
    }
    this.element.style.top = y + "px";
    this.element.style.left = x + "px";
    this.element.style.height = height ? height + "px" : "";
    this.scrollable_ = !!height;
    if (this.menuAutoFocused_) {
      setTimeout(function() {
        this.element.focus();
        if (this.itemAutoFocused_) {
          this.setFocusAt_(this.getNextFocusIndex_());
        }
      }.bind(this), 10);
    }
  };
  Menu.prototype.dismiss = function() {
    if (!this.visible) {
      return;
    }
    this.visible = false;
    this.element.remove();
    if (this.parentMenu_) {
      this.parentMenu_.submenu_ = null;
      this.parentMenu_.element.focus();
      this.parentMenu_ = null;
    } else {
      if (this.submenu_) {
        this.submenu_.dismiss();
        this.submenu_ = null;
      }
      document.documentElement.style.overflowY = this.originOverflowY_;
      if (this.onClose) {
        this.onClose.call(this);
      }
    }
  };
  Menu.prototype.addItem = function(item, handler, populator) {
    if (item instanceof uno.components.MenuAbstractItem === false) {
      return;
    }
    var allowSubmenu = populator && item.allowSubmenu;
    var allowHandler = !allowSubmenu && handler && item.allowUserInteraction;
    this.items_.push(item);
    this.handlers_.push(allowHandler ? handler : null);
    this.populators_.push(allowSubmenu ? populator : null);
    if (allowSubmenu) {
      item.element.classList.add("submenu");
    }
    this.container_.appendChild(item.element);
  };
  Menu.prototype.addSubmenuItem = function(item, populator) {
    this.addItem(item, null, populator);
  };
  Menu.prototype.setFocusAt_ = function(index, sender) {
    clearTimeout(this.focusTimer_);
    if (this.focusIndex_ === index) {
      return;
    }
    clearTimeout(this.submenuTimer_);
    if (this.submenu_ && this.submenu_.index !== index) {
      this.submenu_.dismiss();
      this.submenu_ = null;
    } else {
      if (!sender && this.populators_[index]) {
        this.submenuTimer_ = setTimeout(function() {
          this.performActionAt_(index);
        }.bind(this), 200);
      }
    }
    if (this.focusIndex_ > -1) {
      var oldItem = this.items_[this.focusIndex_];
      if (oldItem) {
        oldItem.setFocus(false, sender);
      }
    }
    var item = this.items_[index];
    if (item && item.allowUserInteraction) {
      item.setFocus(true, sender);
      this.scrollItemIntoViewIfNeeded_(item);
      this.focusIndex_ = index;
      this.element.focus();
    } else {
      this.focusIndex_ = -1;
    }
  };
  Menu.prototype.scrollItemIntoViewIfNeeded_ = function(item) {
    if (!this.scrollable_) {
      return;
    }
    var rootRect = this.container_.getBoundingClientRect();
    var itemRect = item.element.getBoundingClientRect();
    if (itemRect.top < rootRect.top) {
      this.container_.scrollTop -= rootRect.top - itemRect.top;
    } else {
      if (itemRect.bottom > rootRect.bottom) {
        this.container_.scrollTop += itemRect.bottom - rootRect.bottom + 2;
      }
    }
  };
  Menu.prototype.getNextFocusIndex_ = function() {
    var index = -1;
    for (var i = this.focusIndex_ + 1, l = this.items_.length; i < l; i++) {
      if (this.items_[i].allowUserInteraction) {
        index = i;
        break;
      }
    }
    return index > -1 ? index : this.focusIndex_;
  };
  Menu.prototype.getPrevFocusIndex_ = function() {
    var index = -1;
    var startIndex = this.focusIndex_ > -1 ? this.focusIndex_ - 1 : this.items_.length - 1;
    for (var i = startIndex; i >= 0; i--) {
      if (this.items_[i].allowUserInteraction) {
        index = i;
        break;
      }
    }
    return index > -1 ? index : this.focusIndex_;
  };
  Menu.prototype.getItemIndex_ = function(item) {
    if (!item) {
      return -1;
    }
    if (uno.util.dom.isElementNode(item)) {
      var node = item;
      while (node.parentNode && node.parentNode !== this.container_) {
        node = node.parentNode;
      }
      return goog.array.findIndex(this.items_, function(i) {
        return i.element === node;
      });
    }
    return this.items_.indexOf(item);
  };
  Menu.prototype.performActionAt_ = function(index, sender) {
    var item = this.items_[index];
    var populator = this.populators_[index];
    if (this.submenu_ && this.submenu_.index === index) {
      this.submenu_.setFocusAt_(this.submenu_.getNextFocusIndex_(), sender);
    } else {
      if (item && populator) {
        var rect = item.element.getBoundingClientRect();
        var focused = !!sender;
        this.submenu_ = new Menu({parent:this, menuAutoFocused:focused, itemAutoFocused:focused});
        populator(this.submenu_);
        this.submenu_.index = index;
        this.submenu_.present(rect.left + rect.width, rect.top - 1);
      } else {
        if (item && item.allowUserInteraction) {
          var rootMenu = this.parentMenu_ || this;
          var handler = this.handlers_[index];
          var value = item.getValue();
          if (rootMenu.onAction) {
            var submenuIndex = this.parentMenu_ && this.index !== undefined ? this.index : -1;
            rootMenu.onAction.call(rootMenu, index, submenuIndex, value);
          }
          if (handler) {
            handler(value);
          }
          if (rootMenu.actionClose_) {
            rootMenu.dismiss();
          }
        }
      }
    }
  };
  Menu.prototype.addItemAt = function(item, n, handler) {
  };
  Menu.prototype.removeItem = function(item) {
  };
  Menu.prototype.removeItemAt = function(item, n) {
  };
  function handleKeyDown(evt) {
    var code = evt.keyCode;
    var item = this.items_[this.focusIndex_];
    if (item && item.handleKey(code)) {
      evt.preventDefault();
      evt.stopPropagation();
      return;
    }
    var KeyCodes = goog.events.KeyCodes;
    var rootMenu = this.parentMenu_ || this;
    var inSubmenu = this.parentMenu_ && this.focused;
    if (rootMenu.keyClose_ && code === KeyCodes.ESC) {
      rootMenu.dismiss();
    } else {
      if (code === KeyCodes.DOWN || !inSubmenu && this.focusIndex_ === -1 && [KeyCodes.RIGHT, KeyCodes.LEFT].indexOf(code) > -1) {
        this.setFocusAt_(this.getNextFocusIndex_(), code);
      } else {
        if (code === KeyCodes.UP) {
          this.setFocusAt_(this.getPrevFocusIndex_(), code);
        } else {
          if (code === KeyCodes.LEFT && !inSubmenu && this.submenu_) {
            this.submenu_.dismiss();
          } else {
            if (code === KeyCodes.LEFT && inSubmenu) {
              this.dismiss();
            } else {
              if (code === KeyCodes.RIGHT && !inSubmenu || this.focusIndex_ > -1 && [KeyCodes.ENTER, KeyCodes.SPACE].indexOf(code) > -1) {
                this.performActionAt_(this.focusIndex_, code);
              }
            }
          }
        }
      }
    }
    if (!evt.metaKey && !evt.ctrlKey && !evt.altKey && !evt.shiftKey) {
      evt.preventDefault();
      evt.stopPropagation();
    }
  }
  function handleMouseOver(evt) {
    var index = this.getItemIndex_(evt.target);
    var item = this.items_[index];
    if (item && !item.handleMouseOver(evt)) {
      this.setFocusAt_(index);
    }
  }
  function handleMouseOut() {
    clearTimeout(this.focusTimer_);
    this.focusTimer_ = setTimeout(function() {
      if (!this.submenu_ || this.submenu_.focusIndex_ === -1) {
        this.setFocusAt_(-1);
      }
    }.bind(this), 10);
  }
  function handleClick(evt) {
    var index = this.getItemIndex_(evt.target);
    var item = this.items_[index];
    if (this.submenu_ && this.submenu_.index === index && this.focusIndex_ === index && !this.focus && !this.submenu_.focus) {
      clearTimeout(this.dismissTimer_);
      this.element.focus();
      this.submenu_.setFocusAt_(-1);
    } else {
      if (item && !item.handleClick(evt) && !this.submenu_) {
        this.performActionAt_(index);
      }
    }
  }
  function handleBlur(evt) {
    if (this.parentMenu_ && this.parentMenu_.blurClose_ && this.visible && this.element === evt.target) {
      var context = this.parentMenu_;
      clearTimeout(context.dismissTimer_);
      context.dismissTimer_ = setTimeout(function() {
        context.dismiss();
      }, 10);
    } else {
      if (!this.parentMenu_ && this.blurClose_ && this.visible && !this.submenu_ && evt.target === this.element) {
        this.dismiss();
      }
    }
  }
  function handleContextMenu(evt) {
    evt.preventDefault();
    evt.stopPropagation();
  }
})();
goog.provide("uno.util.menu");
goog.require("goog.style");
goog.require("uno.components.Menu");
goog.require("uno.util.loc");
goog.require("uno.util.dom");
goog.require("uno.util.table");
goog.require("uno.util.table.selection");
goog.require("uno.util.zoomscale");
(function() {
  var util = uno.util;
  var t = util.loc.t;
  var comp = uno.components;
  var instance = null;
  util.menu.presentTableContextMenu = function(target, editor) {
    if (instance) {
      instance.dismiss();
    }
    if (!target) {
      return;
    }
    instance = new comp.Menu;
    var range = editor.getRange();
    var fn = function(command, arg) {
      return function(val) {
        range.select();
        editor.execCommand(command, val || arg, undefined, true);
      };
    };
    var columnIndexes = util.table.selection.getColumnIndexes();
    var cell = util.table.getActiveCell();
    var cells = !util.table.selection.isActive() && cell ? [cell] : util.table.selection.getCells();
    var defaultColor = cell.style.backgroundColor || "#ffffff";
    var valign = cell.style.verticalAlign;
    var isTop = !valign || valign === "top";
    var isMiddle = valign === "middle";
    var isBottom = valign === "bottom";
    var isMergeable = util.table.mergeable(cells);
    var isUnmergeable = util.table.unmergeable(cells);
    instance.addItem(new comp.MenuColorPicker(t("Cell Background"), defaultColor), fn("tablecellcolor"));
    instance.addItem(new comp.MenuSeparator);
    instance.addItem(new comp.MenuItem(t("Match Note Width")), fn("tablefitnote"));
    if (columnIndexes.length > 1) {
      instance.addItem(new comp.MenuItem(t("Distribute Columns Evenly")), fn("tableequalcol"));
    }
    instance.addSubmenuItem(new comp.MenuItem(t("Cell Alignment")), function(menu) {
      menu.addItem(new comp.MenuOption(t("Align content to top"), isTop), fn("tableverticalalign", "top"));
      menu.addItem(new comp.MenuOption(t("Align content to center"), isMiddle), fn("tableverticalalign", "middle"));
      menu.addItem(new comp.MenuOption(t("Align content to bottom"), isBottom), fn("tableverticalalign", "bottom"));
    });
    instance.addItem(new comp.MenuSeparator);
    if (isMergeable || isUnmergeable) {
      if (isMergeable) {
        instance.addItem(new comp.MenuItem(t("Merge Cells")), fn("mergecells", true));
      }
      if (isUnmergeable) {
        instance.addItem(new comp.MenuItem(t("Unmerge Cells")), fn("mergecells", false));
      }
      instance.addItem(new comp.MenuSeparator);
    }
    instance.addItem(new comp.MenuItem(t("Delete Selected Column(s)")), fn("deletetablecol"));
    instance.addItem(new comp.MenuItem(t("Delete Selected Row(s)")), fn("deletetablerow"));
    instance.addItem(new comp.MenuItem(t("Delete Table")), fn("deletetable"));
    var rect = target.getBoundingClientRect();
    instance.present(rect.left + rect.width + 1, rect.top + 6);
  };
  util.menu.presentCommentMenu = function(point, handlers) {
    if (instance) {
      instance.dismiss();
    }
    instance = new comp.Menu;
    instance.addItem(new comp.MenuItem("Edit"), handlers.edit);
    instance.addItem(new comp.MenuItem("Delete"), handlers.remove);
    instance.present(point.x, point.y);
  };
})();
goog.provide("uno.util.table.drag");
goog.require("goog.debug.Logger");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.table");
goog.require("uno.util.table.selection");
goog.require("uno.util.tools");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.table.drag");
  var util = uno.util;
  var State = util.table.State;
  var Axis = util.table.Axis;
  var model = null;
  util.table.drag.prepare = function(enTable, event) {
    var target = event.target;
    if (model || !target || !target.classList.contains("handle") || event.type !== "mousedown") {
      return;
    }
    var obj = util.table.handleToObject(target);
    var indexes = obj.axis === Axis.VERTICAL ? util.table.selection.getColumnIndexes(State.DRAGGABLE) : util.table.selection.getRowIndexes(State.DRAGGABLE);
    if (indexes.indexOf(obj.index) === -1) {
      return;
    }
    model = {enTable:enTable, baseX:event.clientX, baseY:event.clientY, baseIndex:obj.index, baseAxis:obj.axis};
  };
  util.table.drag.tryStart = function(enTable, event) {
    if (!model || !enTable || !event || model.preview || model.enTable !== enTable || !util.table.selection.isActive(enTable)) {
      return false;
    }
    if (["mousemove", "mouseover"].indexOf(event.type) === -1) {
      return false;
    }
    if (event.ctrlKey || event.shiftKey || event.metaKey || event.altKey) {
      return false;
    }
    if (event.type === "mousemove" && distance(model.baseX, model.baseY, event.clientX, event.clientY) <= 5) {
      return false;
    }
    var indexes = model.baseAxis === Axis.VERTICAL ? util.table.selection.getColumnIndexes(State.DRAGGABLE) : util.table.selection.getRowIndexes(State.DRAGGABLE);
    if (indexes.indexOf(model.baseIndex) === -1) {
      return false;
    }
    util.table.drag.start(enTable, event.clientX, event.clientY, indexes, model.baseAxis);
    return true;
  };
  util.table.drag.start = function(enTable, clientX, clientY, indexes, axis) {
    if (model) {
      util.table.drag.cancel();
    }
    document.documentElement.classList.add("table-dragging");
    var container = util.table.query_(enTable, ".container");
    var containerBounds = container.getBoundingClientRect();
    var bounds = false;
    var animated = !!bounds;
    if (!animated) {
      bounds = containerBounds;
    }
    var preview = createPreview(clientX, clientY, bounds, axis, indexes.length, animated);
    model = {enTable:enTable, preview:preview, axis:axis, indexes:indexes, sequence:isSequence(indexes), baseX:clientX, baseY:clientY, baseLeft:parseInt(preview.style.left, 10), baseTop:parseInt(preview.style.top, 10), zones:{}};
  };
  util.table.drag.move = function(enTable, clientX, clientY) {
    if (!model) {
      return;
    }
    if (model.zones.ownerEnTable !== enTable) {
      if (model.zones.current) {
        util.table.setLine(model.zones.ownerEnTable);
        model.zones.current = null;
      }
      clearAnimationFrame(model.zones.scroll);
      if (enTable) {
        model.zones = createZones(enTable, model.axis, enTable === model.enTable ? model.indexes : [], model.sequence);
      }
    }
    if (enTable) {
      var coordinate = model.axis === Axis.VERTICAL ? clientX : clientY;
      scrollIfNeeded(coordinate);
      updateIfNeeded(coordinate);
    }
    var left = model.baseLeft + (clientX - model.baseX);
    var top = model.baseTop + (clientY - model.baseY) + util.dom.scrollTop(document.body);
    model.preview.style.left = left + "px";
    model.preview.style.top = top + "px";
  };
  util.table.drag.end = function(multirange) {
    if (!model) {
      return false;
    }
    var changed = false;
    if (model.zones.current) {
      moveCells(model.enTable, model.zones.ownerEnTable, model.axis, model.indexes, model.zones.current.index, multirange);
      changed = true;
    }
    cleanup();
    return changed;
  };
  util.table.drag.cancel = function() {
    if (!model) {
      return;
    }
    cleanup();
  };
  function cleanup() {
    document.documentElement.classList.remove("table-dragging");
    if (model.preview) {
      model.preview.remove();
    }
    if (model.zones) {
      if (model.zones.ownerEnTable) {
        util.table.setLine(model.zones.ownerEnTable);
      }
      clearAnimationFrame(model.zones.scroll);
    }
    model = null;
  }
  function scrollIfNeeded(coordinate) {
    var sdata = model.zones.scroll;
    if (!sdata) {
      return;
    }
    var container = model.zones.container;
    var bounds = container.getBoundingClientRect();
    var offset = 0;
    var detectionWidth = 50;
    if (coordinate < bounds.left + detectionWidth) {
      offset = bounds.left + detectionWidth - coordinate;
    } else {
      if (coordinate > bounds.right - detectionWidth) {
        offset = bounds.right - detectionWidth - coordinate;
      }
    }
    sdata.direction = offset === 0 ? 0 : offset > 0 ? -1 : 1;
    sdata.coordinate = coordinate;
    if (sdata.direction === 0 || isScrolledToEnd(container, sdata.direction)) {
      clearAnimationFrame(sdata);
      return;
    }
    sdata.speed = Math.pow(Math.min(Math.max(Math.abs(offset), 1), detectionWidth) * 2, 1.7);
    if (sdata.rafID === null) {
      sdata.then = Date.now();
      scroll();
    }
  }
  function updateIfNeeded(coordinate) {
    var zone = findZone(model.zones, coordinate, model.axis);
    if (zone !== model.zones.current) {
      model.zones.current = zone;
      if (zone) {
        util.table.setLine(model.zones.ownerEnTable, zone.index, model.axis);
      } else {
        util.table.setLine(model.zones.ownerEnTable);
      }
    }
  }
  function scroll() {
    var sdata = model.zones.scroll;
    var container = model.zones.container;
    if (!sdata || sdata.direction === 0 || isScrolledToEnd(container, sdata.direction)) {
      clearAnimationFrame(sdata);
      return;
    }
    var now = Date.now();
    var delta = (now - sdata.then) / 1000;
    var velocity = sdata.speed * delta * sdata.direction;
    container.scrollLeft = Math.ceil(container.scrollLeft + velocity);
    updateIfNeeded(sdata.coordinate);
    sdata.then = now;
    sdata.rafID = requestAnimationFrame(scroll);
  }
  function moveCells(sourceEnTable, targetEnTable, axis, indexes, dropIndex, multirange) {
    var inPlace = sourceEnTable === targetEnTable;
    if (inPlace) {
      var refDropIndex = dropIndex;
      indexes.forEach(function(v) {
        if (v < refDropIndex) {
          dropIndex -= 1;
        }
      });
    }
    util.table.selection.clear();
    var diffSize = inPlace ? 0 : fitTargetTableSize(sourceEnTable, targetEnTable, axis);
    var transferObj = removeSubmatrix(sourceEnTable, indexes, diffSize, axis);
    if (!inPlace && sourceEnTable.parentNode) {
      util.table.normalizeCellBorders(util.table.query_(sourceEnTable, "table"));
      util.table.layout(sourceEnTable);
    }
    insertSubmatrix(targetEnTable, transferObj, dropIndex, axis);
    util.table.normalizeCellBorders(util.table.query_(targetEnTable, "table"));
    util.table.layout(targetEnTable);
    util.table.setActive(targetEnTable, targetEnTable.querySelector("td.selected"));
    util.table.selection.create(targetEnTable, multirange);
  }
  function removeSubmatrix(sourceEnTable, indexes, diffSize, axis) {
    var table = util.table.query_(sourceEnTable, "table");
    var matrix = util.table.matrix(table);
    var vert = axis === Axis.VERTICAL;
    var submatrix = [];
    var cols = [];
    var vector = vert ? matrix[0] : matrix;
    if (vert) {
      matrix.forEach(function(row, rowIndex) {
        var subitems = [];
        submatrix.push(subitems);
        indexes.forEach(function(colIndex) {
          var info = row[colIndex].info;
          var node = null;
          if (info.startColIndex === colIndex && info.startRowIndex === rowIndex) {
            node = info.node;
            node.classList.add("selected");
            node.remove();
          }
          subitems.push(node);
        });
      });
      for (var i = diffSize; i > 0; i--) {
        var subitems = [];
        submatrix.push(subitems);
        indexes.forEach(function() {
          subitems.push(util.table.createEmptyTd({class:"selected"}));
        });
      }
      var colgroup = util.table.query_(sourceEnTable, "colgroup");
      goog.array.forEachRight(indexes, function(rowIndex) {
        var col = colgroup.children[rowIndex];
        col.remove();
        cols.push(col);
      });
    } else {
      indexes.forEach(function(rowIndex) {
        var subitems = [];
        submatrix.push(subitems);
        matrix[rowIndex].forEach(function(obj, colIndex) {
          var info = obj.info;
          var node = null;
          if (info.startColIndex === colIndex && info.startRowIndex === rowIndex) {
            node = info.node;
            node.classList.add("selected");
            node.remove();
          }
          subitems.push(node);
        });
        for (var i = diffSize; i > 0; i--) {
          subitems.push(util.table.createEmptyTd({class:"selected"}));
        }
      });
      goog.array.forEachRight(indexes, function(rowIndex) {
        table.rows[rowIndex].remove();
      });
    }
    if (vector.length === indexes.length) {
      sourceEnTable.remove();
    }
    return {submatrix:submatrix, cols:cols};
  }
  function insertSubmatrix(targetEnTable, transferObj, dropIndex, axis) {
    var table = util.table.query_(targetEnTable, "table");
    var colgroup = axis === Axis.VERTICAL ? util.table.query_(targetEnTable, "colgroup") : null;
    transferObj.submatrix.forEach(function(row, rowIndex) {
      var tr = null;
      if (axis === Axis.HORIZONTAL) {
        tr = document.createElement("tr");
        table.tBodies[0].insertBefore(tr, table.rows[rowIndex + dropIndex] || null);
      }
      row.forEach(function(td, colIndex) {
        if (td && axis === Axis.HORIZONTAL) {
          tr.appendChild(td);
        } else {
          if (td) {
            util.table.insertTd(td, rowIndex, colIndex + dropIndex, table);
          }
        }
        if (rowIndex === 0 && axis === Axis.VERTICAL) {
          colgroup.insertBefore(transferObj.cols.pop(), colgroup.children[colIndex + dropIndex] || null);
        }
      });
    });
  }
  function fitTargetTableSize(sourceEnTable, targetEnTable, axis) {
    var vert = axis === Axis.VERTICAL;
    var sourceMatrix = util.table.matrix(sourceEnTable);
    var targetMatrix = util.table.matrix(targetEnTable);
    var sourceItemCount = vert ? sourceMatrix.length : sourceMatrix[0].length;
    var targetItemCount = vert ? targetMatrix.length : targetMatrix[0].length;
    if (targetItemCount < sourceItemCount) {
      fn = vert ? util.table.insertRows : util.table.insertColumns;
      fn(targetEnTable, targetItemCount, sourceItemCount - targetItemCount);
    }
    return targetItemCount - sourceItemCount;
  }
  function getVisibleSelectedBounds(enTable, x, y, axis, indexes) {
    var table = util.table.query_(enTable, "table");
    var container = util.table.query_(enTable, ".container");
    var contBounds = container.getBoundingClientRect();
    var groups = [];
    var low = null;
    var high = null;
    var vert = axis === Axis.VERTICAL;
    var lowProp = vert ? "left" : "top";
    var highProp = vert ? "right" : "bottom";
    var items = vert ? table.rows[0].children : table.rows;
    goog.array.forEach(items, function(item, i) {
      if (indexes.indexOf(i) === -1) {
        return;
      }
      var td = vert ? item : item.firstChild;
      var tdBounds = td.getBoundingClientRect();
      if (contBounds[highProp] > tdBounds[lowProp] && tdBounds[lowProp] < contBounds[highProp]) {
        var l = Math.max(tdBounds[lowProp], contBounds[lowProp]);
        var h = Math.min(tdBounds[highProp], contBounds[highProp]);
        var group = goog.array.peek(groups);
        if (!group || group.high !== l) {
          group = {low:l, high:null};
          groups.push(group);
        }
        group.high = h;
      }
    });
    if (groups.length === 0) {
      return null;
    }
    var axisVal = vert ? x : y;
    groups.forEach(function(group) {
      group.distance = Math.min(Math.abs(group.low - axisVal), Math.abs(group.high - axisVal));
    });
    var group = groups.sort(function(a, b) {
      return a.distance - b.distance;
    })[0];
    var bounds = axis === "y" ? {top:contBounds.top - 13, left:group.low, right:group.high, bottom:contBounds.bottom} : {top:group.low, left:contBounds.left - 13, right:contBounds.right, bottom:group.high};
    bounds.width = bounds.right - bounds.left;
    bounds.height = bounds.bottom - bounds.top;
    return bounds;
  }
  function findZone(zones, coordinate, axis) {
    if (!zones) {
      return null;
    }
    var contBounds = zones.container.getBoundingClientRect();
    if (axis === Axis.VERTICAL) {
      coordinate = coordinate - contBounds.left + (zones.scroll ? zones.container.scrollLeft : 0);
    } else {
      coordinate = coordinate - contBounds.top;
    }
    if (zones.current) {
      var b = zones.current.bounds;
      if (b[0] <= coordinate && b[1] > coordinate) {
        return zones.current;
      }
    }
    for (var i = zones.all.length - 1; i >= 0; i--) {
      var chunk = zones.all[i];
      var b = chunk.bounds;
      if (b[0] <= coordinate && b[1] > coordinate) {
        return chunk;
      }
    }
    return null;
  }
  function createZones(enTable, axis, dragIndexes, sequence) {
    var container = util.table.query_(enTable, ".container");
    var matrix = util.table.matrix(enTable);
    var scrollable = axis === Axis.VERTICAL && container.offsetWidth < container.scrollWidth;
    var dropIndexes = createDropIndexes(matrix, axis);
    var all = createZoneBounds(matrix, dragIndexes, dropIndexes, sequence, axis);
    return {all:all, container:container, current:null, ownerEnTable:enTable, scroll:scrollable ? {speed:0, direction:0, coordinate:null, then:null, rafID:null} : null};
  }
  function createZoneBounds(matrix, dragIndexes, dropIndexes, sequence, axis) {
    var vert = axis === Axis.VERTICAL;
    var items = vert ? matrix[0] : matrix;
    var posProp = vert ? "offsetLeft" : "offsetTop";
    var sizeProp = vert ? "offsetWidth" : "offsetHeight";
    var zones = [];
    var dragIndexObj = dragIndexes.reduce(function(obj, val) {
      obj[val] = true;
      return obj;
    }, {});
    var dropIndexObj = dropIndexes.reduce(function(obj, val) {
      obj[val] = true;
      return obj;
    }, {});
    for (var i = 0, length = items.length; i <= length; i++) {
      var selected = dragIndexObj[i];
      var selectedPrev = dragIndexObj[i - 1];
      if (!dropIndexObj[i] || sequence && (selected || selectedPrev) || !sequence && selected && selectedPrev) {
        continue;
      }
      var itemIndex = i === length ? i - 1 : i;
      var td = vert ? items[itemIndex].info.node : items[itemIndex][0].info.node;
      var lastTd;
      var lowBound;
      var highBound;
      if (i === 0) {
        lowBound = -34;
      } else {
        if (i === length && selectedPrev) {
          lowBound = td[posProp] + td[sizeProp] - 16;
        } else {
          if (i === length) {
            lowBound = td[posProp] + Math.ceil(td[sizeProp] / 2);
          } else {
            if (selectedPrev) {
              lowBound = td[posProp] - 16;
            } else {
              lastTd = vert ? items[itemIndex - 1].info.node : items[itemIndex - 1][0].info.node;
              lowBound = td[posProp] - Math.ceil(lastTd[sizeProp] / 2);
            }
          }
        }
      }
      if (i === length) {
        highBound = td[posProp] + td[sizeProp] + 34;
      } else {
        if (selected) {
          highBound = td[posProp] + 16;
        } else {
          highBound = td[posProp] + Math.ceil(td[sizeProp] / 2);
        }
      }
      zones.push({bounds:[lowBound, highBound], index:i});
    }
    return zones;
  }
  function createDropIndexes(matrix, axis) {
    var vert = axis === Axis.VERTICAL;
    var length = vert ? matrix[0].length : matrix.length;
    var blockedIndexes = {};
    var dropIndexes = [];
    matrix.forEach(function(row, rowIndex) {
      row.forEach(function(obj, colIndex) {
        var info = obj.info;
        if (vert && info.endColIndex > colIndex) {
          blockedIndexes[colIndex + 1] = true;
        } else {
          if (!vert && info.endRowIndex > rowIndex) {
            blockedIndexes[rowIndex + 1] = true;
          }
        }
      });
    });
    for (var i = 0; i <= length; i++) {
      if (!blockedIndexes[i]) {
        dropIndexes.push(i);
      }
    }
    return dropIndexes;
  }
  function createPreview(x, y, bounds, axis, count, animated) {
    var preview = util.tools.query(".en-drag-colrow");
    if (!preview) {
      preview = goog.dom.createDom("div", {class:"en-drag-colrow"});
      util.tools.append(preview);
    }
    preview.setAttribute("data-count", count);
    var width = 48;
    var height = 40;
    var left = 0;
    var top = 0;
    if (axis === "y") {
      height = Math.min(Math.max(bounds.height, height), 150);
      left = Math.round(x - width / 2);
      top = y - 10;
    } else {
      width = Math.min(Math.max(bounds.width, width), 200);
      left = x - 10;
      top = Math.round(y - height / 2);
    }
    preview.style.width = width + "px";
    preview.style.height = height + "px";
    preview.style.left = left + "px";
    preview.style.top = top + "px";
    if (animated) {
      preview.style.opacity = 0;
      preview.style.transform = ["translate3d(" + (bounds.left - left) + "px, " + (bounds.top - top) + "px, 0)", "scale(" + bounds.width / width + ", " + bounds.height / height + ")"].join(" ");
      setTimeout(function() {
        preview.style.opacity = 1;
        preview.style.transform = "translate3d(0, 0, 0) scale(1, 1)";
      }, 0);
    }
    return preview;
  }
  function clearAnimationFrame(scrollObj) {
    if (scrollObj && scrollObj.rafID) {
      cancelAnimationFrame(scrollObj.rafID);
      scrollObj.rafID = null;
    }
  }
  function isSequence(indexes) {
    if (indexes.length === 0) {
      return false;
    }
    if (indexes.length === 1) {
      return true;
    }
    for (var i = indexes.length - 2; i >= 0; i--) {
      if (indexes[i] + 1 !== indexes[i + 1]) {
        return false;
      }
    }
    return true;
  }
  function isScrolledToEnd(container, direction) {
    var sLeft = container.scrollLeft;
    var sWidth = container.scrollWidth;
    var oWidth = container.offsetWidth;
    return direction < 0 && sLeft === 0 || direction > 0 && sWidth - oWidth - sLeft === 0;
  }
  function distance(x1, y1, x2, y2) {
    var dx = x1 - x2;
    var dy = y1 - y2;
    return Math.sqrt(dx * dx + dy * dy);
  }
})();
goog.provide("uno.util.table.resizer");
goog.require("goog.debug.Logger");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.table.resizer");
  var util = uno.util;
  var model = null;
  util.table.resizer.start = function(enTable, yline, clientX, colIndex) {
    if (model) {
      util.table.resizer.end();
    }
    var table = util.table.query_(enTable, "table");
    var col = util.table.query_(enTable, "colgroup").children[colIndex];
    var minWidth = util.table.getColumnsMinWidth(enTable, colIndex)[colIndex];
    var baseColWidth = parseInt(col.style.width, 10);
    if (colIndex === 0) {
      minWidth += 1;
    }
    yline.classList.add("active");
    document.documentElement.classList.add("col-resizing");
    model = {enTable:enTable, col:col, yline:yline, baseX:clientX, baseYlineLeft:parseInt(yline.style.left, 10), baseColWidth:baseColWidth, baseTableWidth:parseInt(table.style.width, 10), minDelta:Math.min(minWidth - baseColWidth, 0)};
  };
  util.table.resizer.end = function() {
    document.documentElement.classList.remove("col-resizing");
    model.yline.classList.remove("active");
    model = null;
  };
  util.table.resizer.resize = function(clientX) {
    if (!model) {
      return;
    }
    var delta = Math.max(clientX - model.baseX, model.minDelta);
    model.yline.style.left = model.baseYlineLeft + delta + "px";
    model.col.style.width = model.baseColWidth + delta + "px";
    util.table.updateWidth(model.enTable, model.baseTableWidth + delta);
    util.table.updateAdornments(model.enTable);
    util.table.translateX(model.enTable);
    util.table.layoutMenuButton();
  };
  util.table.resizer.getTarget = function() {
    return model ? model.enTable : null;
  };
})();
goog.provide("uno.util.table.scroller");
goog.require("goog.debug.Logger");
goog.require("uno.util.table");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.table.scroller");
  var util = uno.util;
  var model = null;
  util.table.scroller.start = function(enTable, thumb, clientX) {
    if (model) {
      util.table.scroller.end();
    }
    var container = util.table.query_(enTable, ".container");
    var scrollLeft = container.scrollLeft;
    var scrollWidth = container.scrollWidth;
    var offsetWidth = container.offsetWidth;
    var scale = offsetWidth / scrollWidth;
    thumb.classList.add("active");
    document.documentElement.classList.add("table-scrolling");
    model = {enTable:enTable, container:container, thumb:thumb, baseX:clientX, baseLeft:scrollLeft, maxDelta:(scrollWidth - offsetWidth - scrollLeft) * scale, minDelta:-scrollLeft * scale, scale:scale};
  };
  util.table.scroller.end = function() {
    document.documentElement.classList.remove("table-scrolling");
    model.thumb.classList.remove("active");
    model = null;
  };
  util.table.scroller.scrollByDrag = function(clientX) {
    if (!model) {
      return;
    }
    var delta = Math.min(Math.max(clientX - model.baseX, model.minDelta), model.maxDelta);
    model.container.scrollLeft = model.baseLeft + delta / model.scale;
    util.table.translateX(model.enTable);
  };
  util.table.scroller.scrollByWheel = function(enTable, deltaX) {
    var container = util.table.query_(enTable, ".container");
    if (container.offsetWidth >= container.scrollWidth) {
      return false;
    }
    container.scrollLeft += deltaX;
    return true;
  };
  util.table.scroller.scrollByClick = function(enTable, scrollbarX) {
    var container = util.table.query_(enTable, ".container");
    var offsetWidth = container.offsetWidth;
    if (offsetWidth >= container.scrollWidth) {
      return false;
    }
    var thumb = util.table.query_(enTable, ".scrollbar-thumb");
    var transform = thumb.style.transform || thumb.style.webkitTransform || "";
    var match = transform.match(/translateX\((\d+)(?:\.\d+)?px\)?/);
    var x = match.length === 2 ? parseInt(match[1], 10) : null;
    if (x === null || isNaN(x)) {
      return false;
    }
    container.scrollLeft += x > scrollbarX ? -offsetWidth : offsetWidth;
    return true;
  };
})();
goog.provide("uno.listeners.TableListener");
goog.require("goog.debug.Logger");
goog.require("goog.array");
goog.require("goog.dom");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("goog.events.MouseWheelHandler");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
goog.require("uno.listeners.tablelistener.generic");
goog.require("uno.listeners.tablelistener.win");
goog.require("uno.listeners.tablelistener.web");
goog.require("uno.util.dom");
goog.require("uno.util.menu");
goog.require("uno.util.table");
goog.require("uno.util.table.drag");
goog.require("uno.util.table.resizer");
goog.require("uno.util.table.scroller");
goog.require("uno.util.table.selection");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.TableListener");
  var util = uno.util;
  var Axis = util.table.Axis;
  var KeyCodes = goog.events.KeyCodes;
  var MouseWheelHandler = goog.events.MouseWheelHandler;
  var TableListener = uno.listeners.TableListener = function() {
    uno.BasePlugin.call(this, log.getName());
    this.selectable = true;
    this.scrollable = false;
    this.scrolling = false;
    this.resizing = false;
    this.dragging = false;
    this.leftMouseDown = false;
    this.leftMouseMoving = false;
    this.clicked = false;
    this.clickTimer = null;
    this.mouseWheelHandler = new MouseWheelHandler(document.body);
    goog.events.listen(this.mouseWheelHandler, MouseWheelHandler.EventType.MOUSEWHEEL, this.handleMouseWheel, true, this);
    this.lastRangeState = null;
    this.lastKeyState = null;
    this.lastMouseDownEnTable = null;
    this.lastMouseOverEnTable = null;
    this.lastMouseOverSelectionTd = null;
    this.lastMouseMoveTd = null;
    this.lastMouseMoveInsertion = null;
    this.lastMouseMoveYIndex = -1;
  };
  goog.inherits(TableListener, uno.BasePlugin);
  TableListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  TableListener.prototype.handleKeyDown = function(event) {
    if (this.editor.readOnly) {
      return false;
    }
    var range = this.editor.getRange();
    var keyCode = event.keyCode;
    var enTable = util.table.getActive();
    var cell = util.table.getActiveCell();
    var ignoreKeyCodes = [KeyCodes.BACKSPACE, KeyCodes.DELETE];
    var arrowKeyCodes = [KeyCodes.LEFT, KeyCodes.RIGHT, KeyCodes.UP, KeyCodes.DOWN];
    var targetNode = null;
    this.lastKeyState = null;
    if (!cell || (event.metaKey || event.ctrlKey || event.altKey) || ignoreKeyCodes.indexOf(keyCode) > -1) {
      return false;
    }
    if (util.table.selection.isActive(enTable)) {
      if (keyCode === KeyCodes.ESC && this.dragging) {
        util.table.drag.cancel();
        this.dragging = false;
        return preventStop(event);
      } else {
        if (keyCode === KeyCodes.ESC) {
          util.table.selection.clear();
          goog.dom.Range.createCaret(cell, 0).select();
          return preventStop(event);
        } else {
          if (event.shiftKey && arrowKeyCodes.indexOf(keyCode) > -1) {
            var focusTd = util.table.navigatedFocusSelectionCell(util.table.createKeyState(enTable, cell, event));
            if (focusTd) {
              util.table.selection.selectTo(focusTd);
            }
            return preventStop(event);
          }
        }
      }
      if (!KeyCodes.isTextModifyingKeyEvent(event)) {
        return preventStop(event);
      }
      util.table.selection.clear();
      cell.innerHTML = uno.defs.table.CELL_HTML;
      goog.dom.Range.createCaret(cell, 0).select();
      this.editor.dispatchChange();
    }
    if (keyCode === KeyCodes.TAB && !goog.dom.getAncestor(range.getAnchorNode(), util.dom.isLi, true) && !goog.dom.getAncestor(range.getFocusNode(), util.dom.isLi, true)) {
      targetNode = event.shiftKey ? util.table.prevCell(cell, true) : util.table.nextCell(cell, true);
      if (!targetNode && !event.shiftKey) {
        this.editor.execCommand("inserttablerow", "after");
        targetNode = util.table.nextCell(cell, true);
      }
      if (targetNode) {
        uno.util.range.selectNodeContents(targetNode);
        util.table.scrollCellIntoView(targetNode);
      }
      return preventStop(event);
    } else {
      if (arrowKeyCodes.indexOf(keyCode) > -1) {
        this.lastKeyState = util.table.createKeyState(enTable, cell, event);
      }
    }
    return false;
  };
  TableListener.prototype.handleDoubleClick = function(event) {
    if (this.editor.readOnly) {
      return;
    }
    var target = event.target;
    if (target.classList.contains("yline") && util.table.fitColumnContent(this.lastMouseOverEnTable, this.lastMouseMoveYIndex - 1)) {
      this.editor.dispatchChange();
    }
  };
  TableListener.prototype.handleClick = function(event) {
    var target = event.target;
    this.activeCellCandidate = null;
    if (!target || this.editor.readOnly) {
      return false;
    }
    var enTable = util.table.getActive();
    var cell = util.table.getActiveCell();
    if (enTable && cell && target.classList.contains("en-cell-btn")) {
      util.menu.presentTableContextMenu(target, this.editor);
      return true;
    } else {
      if (target.classList.contains("insertion")) {
        var obj = util.table.insertionToObject(target);
        var fn = obj.axis === Axis.VERTICAL ? util.table.insertColumns : util.table.insertRows;
        var inserted = fn(this.lastMouseOverEnTable, obj.index);
        if (inserted) {
          if (util.table.selection.isActive(this.lastMouseOverEnTable)) {
            util.table.selection.create(this.lastMouseOverEnTable, this.editor.multirange);
          }
          this.editor.dispatchChange();
        }
        return true;
      } else {
        if (target.classList.contains("handle")) {
          var matrix = util.table.matrix(this.lastMouseOverEnTable);
          var obj = util.table.handleToObject(target);
          var focusTd = obj.axis === Axis.VERTICAL ? matrix[0][obj.index].info.node : matrix[obj.index][0].info.node;
          this.lastRangeState = null;
          var isActiveSelection = util.table.selection.isActive(this.lastMouseOverEnTable);
          if (isActiveSelection && (this.client.isToggleKey(event) || event.shiftKey)) {
            if (event.shiftKey) {
              util.table.selection.selectTo(focusTd, obj.axis);
            } else {
              util.table.selection.toggleAt(focusTd, obj.axis);
            }
            this.editor.dispatchStyleChange();
          } else {
            util.table.selection.create(this.lastMouseOverEnTable, this.editor.multirange, focusTd, null, obj.axis);
          }
          return true;
        } else {
          if (target.classList.contains("en-table-btn")) {
            var matrix = util.table.matrix(this.lastMouseOverEnTable);
            var lastCol = goog.array.peek(matrix[0]);
            var anchorTd = matrix[0][0].info.node;
            var focusTd = (lastCol.origin || lastCol.info).node;
            this.lastRangeState = null;
            util.table.selection.create(this.lastMouseOverEnTable, this.editor.multirange, anchorTd, focusTd, Axis.VERTICAL);
            return true;
          } else {
            if (enTable && this.client.isToggleKey(event) && !util.table.selection.isActive(enTable)) {
              var focusTd = goog.dom.getAncestor(target, util.dom.isTd, true);
              this.lastRangeState = null;
              util.table.selection.create(enTable, this.editor.multirange, focusTd);
              return true;
            }
          }
        }
      }
    }
    return false;
  };
  TableListener.prototype.handleMouseDown = function(event) {
    var target = event.target;
    this.leftMouseDown = true;
    if (!this.lastMouseOverEnTable) {
      return false;
    }
    if (target.classList.contains("handle")) {
      util.table.drag.prepare(this.lastMouseOverEnTable, event);
      event.preventDefault();
      return true;
    }
    if (target.classList.contains("en-cell-btn") || target.classList.contains("en-table-btn") || target.classList.contains("insertion")) {
      event.preventDefault();
      return true;
    }
    if (target.classList.contains("yline")) {
      util.table.layout(this.lastMouseOverEnTable);
      util.table.resizer.start(this.lastMouseOverEnTable, target, event.clientX, this.lastMouseMoveYIndex - 1);
      this.resizing = true;
      return preventStop(event);
    }
    if (target.classList.contains("scrollbar-thumb")) {
      util.table.scroller.start(this.lastMouseOverEnTable, target, event.clientX);
      this.scrolling = true;
      return preventStop(event);
    }
    if (target.classList.contains("scrollbar")) {
      util.table.scroller.scrollByClick(this.lastMouseOverEnTable, event.clientX - target.getBoundingClientRect().left);
      return preventStop(event);
    }
    var td = goog.dom.getAncestor(target, util.dom.isTd, true);
    if (td) {
      this.clicked = true;
      clearTimeout(this.clickTimer);
      this.clickTimer = setTimeout(function() {
        this.clicked = false;
      }.bind(this), 10);
      this.lastMouseDownEnTable = this.lastMouseOverEnTable;
      this.lastMouseDownEnTable.classList.add("selecting");
      var isSelection = util.table.selection.isActive(this.lastMouseOverEnTable);
      var isSelectionChange = isSelection && (event.shiftKey || this.client.isToggleKey(event));
      var isActive = util.table.getActive() === this.lastMouseOverEnTable && util.table.getActiveCell() !== td;
      if (isSelectionChange || isActive && event.shiftKey) {
        if (isSelectionChange) {
          if (event.shiftKey) {
            util.table.selection.selectTo(td);
          } else {
            util.table.selection.toggleAt(td);
          }
          this.editor.dispatchStyleChange();
        } else {
          this.lastRangeState = null;
          util.table.selection.create(this.lastMouseOverEnTable, this.editor.multirange, util.table.getActiveCell(), td);
        }
        return preventStop(event);
      }
      this.activeCellCandidate = td;
    }
    return false;
  };
  TableListener.prototype.handleWindowResize = function() {
    goog.array.forEach(this.editor.field.querySelectorAll("en-table"), util.table.translateX);
  };
  TableListener.prototype.handleWindowMouseUp = function() {
    this.leftMouseDown = false;
    this.leftMouseMoving = false;
    if (this.lastMouseDownEnTable) {
      this.lastMouseDownEnTable.classList.remove("selecting");
      this.lastMouseDownEnTable = null;
    }
    if (this.dragging) {
      this.dragging = false;
      if (util.table.drag.end(this.editor.multirange)) {
        this.editor.dispatchChange();
      }
      return true;
    }
    if (this.resizing) {
      util.table.resizer.end();
      this.resizing = false;
      this.editor.dispatchChange();
      return true;
    }
    if (this.scrolling) {
      util.table.scroller.end();
      this.scrolling = false;
      return true;
    }
    util.table.drag.cancel();
    return false;
  };
  TableListener.prototype.handleWindowMouseMove = function(event) {
    if (this.scrolling) {
      util.table.scroller.scrollByDrag(event.clientX);
      return preventStop(event);
    }
    if (this.resizing) {
      util.table.resizer.resize(event.clientX);
      return preventStop(event);
    }
    if (this.dragging) {
      util.table.drag.move(this.lastMouseOverEnTable, event.clientX, event.clientY);
      return preventStop(event);
    }
    return false;
  };
  TableListener.prototype.handleMouseMove = function(event) {
    if (this.editor.readOnly) {
      return false;
    }
    var target = event.target;
    this.leftMouseMoving = this.leftMouseDown;
    if (this.leftMouseMoving || this.resizing || this.scrolling || this.dragging || target.classList.contains("yline")) {
      if (this.leftMouseMoving && util.table.drag.tryStart(this.lastMouseOverEnTable, event)) {
        this.dragging = true;
        return preventStop(event);
      } else {
        if (this.leftMouseMoving && !this.resizing && !this.scrolling && !this.dragging && util.table.selection.isActive(this.lastMouseOverEnTable)) {
          return preventStop(event);
        }
      }
      return false;
    }
    if (this.lastMouseOverEnTable && util.dom.isTd(target) && !this.lastMouseOverEnTable.classList.contains("selected")) {
      var next = event.offsetX > target.offsetWidth / 2;
      var yIndex = event.offsetX > 6 && event.offsetX < target.offsetWidth - 6 ? -1 : util.table.colIndex(target, next);
      if (yIndex === 0) {
        yIndex = -1;
      }
      if (this.lastMouseMoveTd === target && this.lastMouseMoveYIndex === yIndex) {
        return false;
      }
      this.lastMouseMoveTd = target;
      this.lastMouseMoveYIndex = yIndex;
      if (yIndex > -1) {
        util.table.setLine(this.lastMouseOverEnTable, yIndex, Axis.VERTICAL);
      } else {
        util.table.setLine(this.lastMouseOverEnTable);
      }
    } else {
      if (target.classList.contains("insertion")) {
        if (target === this.lastMouseMoveInsertion) {
          return false;
        }
        this.lastMouseMoveInsertion = target;
        var obj = util.table.insertionToObject(target);
        util.table.setLine(this.lastMouseOverEnTable, obj.index, obj.axis);
      } else {
        if (this.lastMouseMoveTd || this.lastMouseMoveInsertion) {
          this.lastMouseMoveTd = null;
          this.lastMouseMoveInsertion = null;
          this.lastMouseMoveYIndex = -1;
          if (this.lastMouseOverEnTable) {
            util.table.setLine(this.lastMouseOverEnTable);
          }
        }
      }
    }
    return false;
  };
  TableListener.prototype.handleMouseOver = function(event) {
    var target = event.target;
    var oldEnTable = this.lastMouseOverEnTable;
    var overTable = false;
    var enTable = goog.dom.getAncestor(target, function(node) {
      if (util.dom.isTable(node)) {
        overTable = true;
      }
      return util.dom.isEntable(node);
    }, true);
    this.scrollable = !!(overTable && enTable);
    this.lastMouseOverEnTable = enTable;
    if (enTable !== oldEnTable && oldEnTable) {
      util.table.setLine(oldEnTable);
    }
    if (enTable && (!this.leftMouseMoving && enTable.getAttribute("data-lazy") || this.dragging && enTable.getAttribute("data-lazy"))) {
      util.table.layout(enTable, true);
      return;
    }
    if (this.resizing || this.scrolling || this.dragging || this.editor.readOnly || !enTable) {
      return;
    }
    if (this.leftMouseMoving && util.table.drag.tryStart(enTable, event)) {
      this.dragging = true;
      return;
    }
    if (this.leftMouseMoving && overTable && util.table.selection.isActive(enTable)) {
      var td = goog.dom.getAncestor(target, util.dom.isTd, true);
      if (td && td !== this.lastMouseOverSelectionTd) {
        this.lastMouseOverSelectionTd = td;
        util.table.selection.selectTo(td);
        this.editor.dispatchStyleChange();
      }
    }
  };
  TableListener.prototype.handleMouseWheel = function(event) {
    if (this.resizing || this.scrolling || !this.scrollable || this.lastMouseDownEnTable || !this.lastMouseOverEnTable || Math.abs(event.deltaX) <= Math.abs(event.deltaY)) {
      return;
    }
    if (util.table.scroller.scrollByWheel(this.lastMouseOverEnTable, this.client.getDeltaX(event))) {
      event.preventDefault();
    }
  };
  TableListener.prototype.handleScroll = function(event) {
    var target = event.target;
    if (target && util.dom.isEntable(target.parentNode)) {
      util.table.translateX(target.parentNode);
    }
  };
  TableListener.prototype.handleNativeSelectionChange = function() {
    var range = this.editor.getRange();
    if (!range || this.editor.readOnly) {
      return;
    }
    var activeCellCandidate = this.activeCellCandidate;
    this.activeCellCandidate = null;
    if (activeCellCandidate && range.isCollapsed() && !activeCellCandidate.contains(range.getStartNode())) {
      goog.dom.Range.createCaret(activeCellCandidate, 0).select();
      return;
    }
    if (util.table.selection.isPending() || this.leftMouseMoving && util.table.selection.isActive(this.lastMouseOverEnTable)) {
      return;
    }
    if (!util.table.isProcessedRange(range, this.lastRangeState)) {
      var source = this.clicked ? "multiclick" : this.lastKeyState ? "arrowkey" : null;
      var lks = this.lastKeyState;
      var lrs = util.table.processRange(range, this.editor.field.querySelectorAll("en-table"), source);
      this.lastRangeState = lrs;
      if (lks && lrs.cell && lks.cell !== lrs.cell && !lks.shiftKey && util.table.navigateByKeyState(lks)) {
        this.lastKeyState = null;
        return;
      }
      util.table.setActive(lrs.enTable, lrs.cell);
      util.table.selection.clear();
      if (this.selectable && lrs.enTable && lrs.isSelection) {
        var anchorCell = lrs.cell;
        var focusCell = lrs.focusCell;
        if (lks && lks.shiftKey) {
          focusCell = util.table.navigatedFocusSelectionCell(lks);
        }
        util.table.selection.create(lrs.enTable, this.editor.multirange, anchorCell, focusCell);
      }
      this.lastKeyState = null;
    }
  };
  TableListener.prototype.handleContextMenu = function(event) {
    this.selectable = false;
    setTimeout(function() {
      this.handleWindowMouseUp();
      this.selectable = true;
    }.bind(this), 0);
  };
  TableListener.prototype.handleBeforeExecCommand = function(event) {
    if (event.command === "undo" || event.command === "redo") {
      util.table.selection.clear();
      this.lastRangeState = null;
      this.selectable = false;
    }
  };
  TableListener.prototype.handleAfterExecCommand = function(event) {
    if (event.command === "undo" || event.command === "redo") {
      setTimeout(function() {
        goog.array.forEach(document.querySelectorAll("cursor-proxy"), goog.dom.removeNode);
        this.selectable = true;
        var td = this.editor.field.querySelector("en-table td.selected");
        var enTable = goog.dom.getAncestor(td, util.dom.isEntable);
        if (enTable) {
          util.table.setActive(enTable, td);
          util.table.selection.create(enTable, this.editor.multirange);
        }
      }.bind(this), 0);
    }
  };
  function preventStop(event) {
    event.preventDefault();
    event.stopPropagation();
    return true;
  }
})();
goog.provide("uno.listeners.textinputlistener.android");
(function() {
  var android = uno.listeners.textinputlistener.android;
  android.handleTextInput = function(event, editor) {
    var str = event.event_.data;
    if (!str) {
      return;
    }
    var c = str[str.length - 1];
    if (c !== " " && c !== "\n") {
      return;
    }
    setTimeout(function() {
      editor.execCommand("delete");
      if (editor.emitKeyboardEvent("keydown", c)) {
        if (editor.emitKeyboardEvent("keypress", c)) {
          document.execCommand("insertText", false, c);
          editor.emitKeyboardEvent("keyup", c);
        }
      }
    });
  };
})();
goog.provide("uno.listeners.TextInputListener");
goog.require("goog.debug.Logger");
goog.require("uno.BasePlugin");
goog.require("uno.listeners.textinputlistener.android");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.TextInputListener");
  var TextInputListener = uno.listeners.TextInputListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TextInputListener, uno.BasePlugin);
  TextInputListener.prototype.handleTextInput = function(event) {
    if (this.client.handleTextInput) {
      this.client.handleTextInput(event, this.editor);
    }
  };
})();
goog.provide("uno.listeners.TodoListener");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.BasePlugin");
goog.require("uno.util.todo");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.TodoListener");
  var util = uno.util;
  var TodoListener = uno.listeners.TodoListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TodoListener, uno.BasePlugin);
  TodoListener.prototype.activeOnUneditableFields = goog.functions.TRUE;
  TodoListener.prototype.handleClick = function(event) {
    if (util.todo.isTodo(event.target)) {
      if (this.editor.readOnly) {
        this.editor.dispatchEvent({type:uno.Editor.EventType.ACTION_DENIED, reason:{readOnly:true}});
        return false;
      }
      event.preventDefault();
      util.todo.toggle(event.target);
      this.editor.dispatchChange();
      return true;
    }
    return false;
  };
})();
goog.provide("uno.listeners.TodoListListener");
goog.require("goog.debug.Logger");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
goog.require("uno.util.paragraph");
goog.require("uno.util.range");
goog.require("uno.util.todo");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.TodoListListener");
  var ENTER_KEY = goog.events.KeyCodes.ENTER;
  var TAB_KEY = goog.events.KeyCodes.TAB;
  var util = uno.util;
  var TodoListListener = uno.listeners.TodoListListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(TodoListListener, uno.BasePlugin);
  TodoListListener.prototype.handleKeyPress = function(event) {
    var currentPar;
    var todo;
    if (event.keyCode === ENTER_KEY) {
      if (event.altKey) {
        this.editor.execCommand("inserttodo");
        event.preventDefault();
        event.stopPropagation();
        return true;
      }
      if ((currentPar = util.paragraph.for(this.editor.getRange().getStartNode())) == null) {
        return;
      }
      if ((todo = util.paragraph.getLeadingTodo(currentPar)) == null) {
        return;
      }
      if (util.range.atBeginningOfDiv(this.editor.getRange())) {
        return;
      }
      if (util.paragraph.hasVisibleContent(currentPar, {excluding:todo})) {
        this.editor.context.pendingTodo = !util.todo.tryToInsertTodo(this.editor);
      } else {
        util.todo.remove(todo);
        if (!util.paragraph.hasBr(currentPar)) {
          util.paragraph.appendBr(currentPar);
        }
        util.paragraph.placeCursorAtStart(currentPar);
      }
      if (!this.editor.context.pendingTodo) {
        event.preventDefault();
        event.stopPropagation();
      }
      return true;
    }
  };
  TodoListListener.prototype.handleKeyUp = function(event) {
    if ((event.keyCode === ENTER_KEY || event.keyCode === 0) && this.editor.context.pendingTodo) {
      this.editor.context.pendingTodo = false;
      this.editor.execCommand("inserttodo");
    }
  };
})();
goog.provide("uno.util.typebehind");
goog.require("goog.debug.Logger");
goog.require("goog.dom.classes");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.typebehind");
  var SPACE_KEY = goog.events.KeyCodes.SPACE;
  var TAB_KEY = goog.events.KeyCodes.TAB;
  var ENTER_KEY = goog.events.KeyCodes.ENTER;
  var util = uno.util;
  util.typebehind.tryReplacements = function(event, imps, checkBeginningOfLines, editor) {
    var keyCode = event.keyCode;
    var dom = goog.dom;
    var range = editor.getRange();
    if (!range || !range.isCollapsed()) {
      return false;
    }
    var startNode = range.getStartNode();
    var endNode = range.getEndNode();
    var node = endNode;
    var text = null;
    if (editor.config.typebehind.code) {
      if (goog.dom.classes.has(startNode, "en-code") || goog.dom.classes.has(dom.getParentElement(startNode), ".en-code")) {
        return false;
      }
    }
    var insideAnchor = goog.dom.getAncestor(startNode, function(element) {
      return util.dom.isA(element);
    }, true);
    if (insideAnchor) {
      return false;
    }
    text = node.textContent.substring(0, range.getEndOffset());
    var isBeginningOfLine = checkBeginningOfLines && !util.dom.isPrecededByInlineContent(node);
    if (text != null) {
      for (var i = 0; i < imps.length; i++) {
        var imp = imps[i];
        if (!imp.contextReplaceable(range, keyCode)) {
          continue;
        }
        if (imp.matchBeginningOfLine && !isBeginningOfLine) {
          continue;
        }
        if (imp.getGatekeeper) {
          if (!text.match(imp.getGatekeeper())) {
            continue;
          }
        }
        var rxs = imp.getRegexes();
        var response = util.typebehind.isReplacementPossible(text, rxs);
        if (response.possible) {
          var result = util.typebehind.runReplacements(imp, range, response.rx, text, editor);
          if (result.node != null) {
            node = result.node;
            if (keyCode === SPACE_KEY || keyCode === ENTER_KEY || result.trimWhitespace) {
              goog.editor.range.placeCursorNextTo(node, false);
            } else {
              if (keyCode === TAB_KEY && !result.trimWhitespace) {
                var tab = dom.createDom(goog.dom.TagName.SPAN, null, "\u00a0\u00a0 \u00a0");
                goog.dom.insertSiblingBefore(tab, node.nextSibling);
                goog.editor.range.placeCursorNextTo(tab, false);
                event.preventDefault();
              }
            }
          }
          if (result.trimWhitespace) {
            event.preventDefault();
          }
          editor.field.normalize();
          return true;
        }
      }
    }
    return false;
  };
  util.typebehind.isReplacementPossible = function(text, rxs) {
    if (text == null || !goog.isString(text) || rxs == null) {
      return {possible:false, rx:null};
    }
    for (var i = 0; i < rxs.length; i++) {
      if (util.typebehind.matchRegex(text, rxs[i])) {
        return {possible:true, rx:rxs[i]};
      }
    }
    return {possible:false, rx:null};
  };
  util.typebehind.matchRegex = function(text, rx) {
    if (text == null || rx == null) {
      return null;
    }
    var preRx = "(?:\\s+|\u00a0+|^)(";
    var postRx = ")(?:[\u00a0\\t ]*$)";
    var pattern = preRx + rx.source + postRx;
    var rxAtEnd = new RegExp(pattern, "gi");
    var matches = text.match(rxAtEnd);
    if (matches && matches.length > 1) {
      log.warning("Should not be multiple matches here!");
    }
    if (matches == null || matches.length <= 0) {
      return null;
    }
    var matchString = matches[0].trim();
    var index = text.lastIndexOf(matchString);
    return {matchString:matchString, index:index};
  };
  util.typebehind.runReplacements = function(imp, range, rx, text, editor) {
    editor.plugins_.UndoRedo.updateCurrentState_(editor);
    var textNode = range.getEndNode();
    goog.asserts.assert(textNode && textNode.nodeType === Node.TEXT_NODE, "typebehind: node must be text");
    goog.asserts.assert(rx != null, "must be given a regex to work");
    var match = util.typebehind.matchRegex(text, rx);
    var matchText = match.matchString;
    var matchIndex = match.index;
    var newRange = goog.dom.Range.createFromNodes(textNode, matchIndex, textNode, matchIndex + matchText.length);
    return imp.insertReplacement(newRange, rx, matchText, editor);
  };
})();
goog.provide("uno.util.typebehind.code");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.defs");
goog.require("uno.util.table");
goog.require("uno.util.list");
goog.require("uno.util.crypto");
goog.require("uno.util.codeblock");
goog.require("uno.util.structure");
(function() {
  var code = uno.util.typebehind.code;
  var util = uno.util;
  code.matchBeginningOfLine = false;
  code.rxs = [new RegExp(uno.defs.regex.CODEBLOCK, "gi")];
  code.contextReplaceable = function(range) {
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.CODE, range)) {
      return false;
    }
    return true;
  };
  code.getRegexes = function() {
    return code.rxs;
  };
  code.insertReplacement = function(range, rx, matchedText, editor) {
    for (var i = 0; i < matchedText.length; i++) {
      document.execCommand("delete");
    }
    editor.execCommand("codeblock");
    return {node:null, trimWhitespace:true};
  };
})();
goog.provide("uno.util.typebehind.email");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.defs");
(function() {
  var email = uno.util.typebehind.email;
  var log = goog.debug.Logger.getLogger("uno.util.typebehind.email");
  email.name = "email";
  email.matchBeginningOfLine = false;
  email.rxs = [new RegExp(uno.defs.regex.SIMPLE_EMAIL, "gi")];
  email.contextReplaceable = function(range, keyCode) {
    return true;
  };
  email.getRegexes = function() {
    return email.rxs;
  };
  email.insertReplacement = function(range, rx, matchedText) {
    var newNode = goog.dom.createDom("a");
    if (goog.isString(matchedText)) {
      newNode.setAttribute("href", "mailto:" + matchedText);
      newNode.textContent = matchedText;
    }
    range.replaceContentsWithNode(newNode);
    return {node:newNode, trimWhitespace:false};
  };
})();
goog.provide("uno.util.emoticon");
goog.require("goog.debug.Logger");
goog.require("uno.defs");
(function() {
  var util = uno.util;
  var onceList = {"smiling face with open mouth":{"icon":"\ud83d\ude03", "keystrokes":[":)", ":=)", ":-)"], "color":"yellow"}, "pensive":{"icon":"\ud83d\ude14", "keystrokes":[":(", ":=(", ":-("]}, "grinning face":{"icon":"\ud83d\ude00", "keystrokes":[":D", ":=D", ":-D"]}, "smiling face with sunglasses":{"icon":"\ud83d\ude0e", "keystrokes":["8=)", "8-)", "B=)", "B-)"]}, "winking face":{"icon":"\ud83d\ude09", "keystrokes":[";)", ";=)", ";-)"]}, "face with open mouth":{"icon":"\ud83d\ude2e", "keystrokes":[":o", 
  ":=o", ":-o", ":O", ":=O", ":-O"]}, "crying face":{"icon":"\ud83d\ude22", "keystrokes":[";(", ";=(", ";-("]}, "smiling face with open mouth and cold sweat":{"icon":"\ud83d\ude05", "keystrokes":["(:|", ":sweat:"]}, "neutral face":{"icon":"\ud83d\ude10", "keystrokes":[":|", ":=|", ":-|", ":neutral:"]}, "kissing face with closed eyes":{"icon":"\ud83d\ude1a", "keystrokes":[":*", ":=*", ":-*", ":kiss:"]}, "face with stuck-out tongue":{"icon":"\ud83d\ude1b", "keystrokes":[":P", ":=P", ":-P", ":p", ":=p", 
  ":-p"]}, "smiling face with smiling eyes":{"icon":"\ud83d\ude0a", "keystrokes":[":$", ":-$", ":=$", ":simple_smile:"]}, "rage":{"icon":"\ud83d\ude21", "keystrokes":[":@", ":-@", ":=@", "x(", "x-(", "x=(", "X(", "(X=(", ":rage:"]}, "smiling face with halo":{"icon":"\ud83d\ude07", "keystrokes":["O:)", "O:=)", "O:-)", "o:)", "o:=)", "o:-)", ":innocent:", ":angel:"]}, "heavy black heart":{"icon":"\u2665", "keystrokes":["<3", ":heart:"]}, "sleepy face":{"icon":"\ud83d\ude2a", "keystrokes":["|-)", "I-)", 
  "I=)", ":snooze:"]}, "smiling face with heart-shaped eyes":{"icon":"\ud83d\ude0d", "keystrokes":[":inlove:", ":in_love:"]}, "smiling face with horns":{"icon":"\ud83d\ude08", "keystrokes":[":devil:"]}, "ghost":{"icon":"\ud83d\udc7b", "keystrokes":[":ghost:"]}, "extraterrestrial alien":{"icon":"\ud83d\udc7d", "keystrokes":[":alien:"]}, "skull":{"icon":"\ud83d\udc80", "keystrokes":[":skull:"]}, "face screaming in fear":{"icon":"\ud83d\ude31", "keystrokes":[":scream:"]}, "slice of pizza":{"icon":"\ud83c\udf55", 
  "keystrokes":[":pizza:"]}, "purple heart":{"icon":"\ud83d\udc9c", "keystrokes":[":purple_heart:", ":purpleheart:"]}, "green heart":{"icon":"\ud83d\udc9a", "keystrokes":[":green_heart:", ":greenheart:"]}, "blue heart":{"icon":"\ud83d\udc99", "keystrokes":[":blue_heart:", ":blueheart:"]}, "yellow heart":{"icon":"\ud83d\udc9b", "keystrokes":[":yellow_heart:", ":yellowheart:"]}, "droplet":{"icon":"\ud83d\udca7", "keystrokes":[":droplet:"]}, 100:{"icon":"\ud83d\udcaf", "keystrokes":[":100:"]}, 1234:{"icon":"\ud83d\udd22", 
  "keystrokes":[":1234:"]}, "grinning":{"icon":"\ud83d\ude00", "keystrokes":[":grinning:"]}, "grimacing":{"icon":"\ud83d\ude2c", "keystrokes":[":grimacing:"]}, "grin":{"icon":"\ud83d\ude01", "keystrokes":[":grin:"]}, "joy":{"icon":"\ud83d\ude02", "keystrokes":[":joy:"]}, "rofl":{"icon":"\ud83e\udd23", "keystrokes":[":rofl:"]}, "smile":{"icon":"\ud83d\ude04", "keystrokes":[":smile:"]}, "laughing":{"icon":"\ud83d\ude06", "keystrokes":[":laughing:"]}, "wink":{"icon":"\ud83d\ude09", "keystrokes":[":wink:"]}, 
  "slightly smiling face":{"icon":"\ud83d\ude42", "keystrokes":[":slightly_smiling_face:", ":slightlysmilingface:"]}, "upside down face":{"icon":"\ud83d\ude43", "keystrokes":[":upside_down_face:", ":upsidedownface:"]}, "relaxed":{"icon":"\u263a\ufe0f", "keystrokes":[":relaxed:"]}, "yum":{"icon":"\ud83d\ude0b", "keystrokes":[":yum:"]}, "relieved":{"icon":"\ud83d\ude0c", "keystrokes":[":relieved:"]}, "kissing heart":{"icon":"\ud83d\ude18", "keystrokes":[":kissing_heart:", ":kissingheart:"]}, "kissing":{"icon":"\ud83d\ude17", 
  "keystrokes":[":kissing:"]}, "kissing smiling eyes":{"icon":"\ud83d\ude19", "keystrokes":[":kissing_smiling_eyes:", ":kissingsmilingeyes:"]}, "stuck out tongue winking eye":{"icon":"\ud83d\ude1c", "keystrokes":[":stuck_out_tongue_winking_eye:", ":stuckouttonguewinkingeye:"]}, "stuck out tongue closed eyes":{"icon":"\ud83d\ude1d", "keystrokes":[":stuck_out_tongue_closed_eyes:", ":stuckouttongueclosedeyes:"]}, "money mouth face":{"icon":"\ud83e\udd11", "keystrokes":[":money_mouth_face:", ":moneymouthface:"]}, 
  "nerd face":{"icon":"\ud83e\udd13", "keystrokes":[":nerd_face:", ":nerdface:"]}, "clown face":{"icon":"\ud83e\udd21", "keystrokes":[":clown_face:", ":clownface:"]}, "cowboy hat face":{"icon":"\ud83e\udd20", "keystrokes":[":cowboy_hat_face:", ":cowboyhatface:"]}, "hugs":{"icon":"\ud83e\udd17", "keystrokes":[":hugs:"]}, "smirk":{"icon":"\ud83d\ude0f", "keystrokes":[":smirk:"]}, "no mouth":{"icon":"\ud83d\ude36", "keystrokes":[":no_mouth:", ":nomouth:"]}, "expressionless":{"icon":"\ud83d\ude11", "keystrokes":[":expressionless:"]}, 
  "unamused":{"icon":"\ud83d\ude12", "keystrokes":[":unamused:"]}, "roll eyes":{"icon":"\ud83d\ude44", "keystrokes":[":roll_eyes:", ":rolleyes:"]}, "thinking":{"icon":"\ud83e\udd14", "keystrokes":[":thinking:"]}, "lying face":{"icon":"\ud83e\udd25", "keystrokes":[":lying_face:", ":lyingface:"]}, "flushed":{"icon":"\ud83d\ude33", "keystrokes":[":flushed:"]}, "disappointed":{"icon":"\ud83d\ude1e", "keystrokes":[":disappointed:"]}, "worried":{"icon":"\ud83d\ude1f", "keystrokes":[":worried:"]}, "angry":{"icon":"\ud83d\ude20", 
  "keystrokes":[":angry:"]}, "confused":{"icon":"\ud83d\ude15", "keystrokes":[":confused:"]}, "slightly frowning face":{"icon":"\ud83d\ude41", "keystrokes":[":slightly_frowning_face:", ":slightlyfrowningface:"]}, "frowning face":{"icon":"\u2639", "keystrokes":[":frowning_face:", ":frowningface:"]}, "persevere":{"icon":"\ud83d\ude23", "keystrokes":[":persevere:"]}, "confounded":{"icon":"\ud83d\ude16", "keystrokes":[":confounded:"]}, "tired face":{"icon":"\ud83d\ude2b", "keystrokes":[":tired_face:", 
  ":tiredface:"]}, "weary":{"icon":"\ud83d\ude29", "keystrokes":[":weary:"]}, "triumph":{"icon":"\ud83d\ude24", "keystrokes":[":triumph:"]}, "fearful":{"icon":"\ud83d\ude28", "keystrokes":[":fearful:"]}, "cold sweat":{"icon":"\ud83d\ude30", "keystrokes":[":cold_sweat:", ":coldsweat:"]}, "hushed":{"icon":"\ud83d\ude2f", "keystrokes":[":hushed:"]}, "frowning":{"icon":"\ud83d\ude26", "keystrokes":[":frowning:"]}, "anguished":{"icon":"\ud83d\ude27", "keystrokes":[":anguished:"]}, "cry":{"icon":"\ud83d\ude22", 
  "keystrokes":[":cry:"]}, "disappointed relieved":{"icon":"\ud83d\ude25", "keystrokes":[":disappointed_relieved:", ":disappointedrelieved:"]}, "drooling face":{"icon":"\ud83e\udd24", "keystrokes":[":drooling_face:", ":droolingface:"]}, "sweat":{"icon":"\ud83d\ude13", "keystrokes":[":sweat:"]}, "sob":{"icon":"\ud83d\ude2d", "keystrokes":[":sob:"]}, "dizzy face":{"icon":"\ud83d\ude35", "keystrokes":[":dizzy_face:", ":dizzyface:"]}, "astonished":{"icon":"\ud83d\ude32", "keystrokes":[":astonished:"]}, 
  "zipper mouth face":{"icon":"\ud83e\udd10", "keystrokes":[":zipper_mouth_face:", ":zippermouthface:"]}, "nauseated face":{"icon":"\ud83e\udd22", "keystrokes":[":nauseated_face:", ":nauseatedface:"]}, "sneezing face":{"icon":"\ud83e\udd27", "keystrokes":[":sneezing_face:", ":sneezingface:"]}, "mask":{"icon":"\ud83d\ude37", "keystrokes":[":mask:"]}, "face with thermometer":{"icon":"\ud83e\udd12", "keystrokes":[":face_with_thermometer:", ":facewiththermometer:"]}, "face with head bandage":{"icon":"\ud83e\udd15", 
  "keystrokes":[":face_with_head_bandage:", ":facewithheadbandage:"]}, "sleeping":{"icon":"\ud83d\ude34", "keystrokes":[":sleeping:"]}, "zzz":{"icon":"\ud83d\udca4", "keystrokes":[":zzz:"]}, "poop":{"icon":"\ud83d\udca9", "keystrokes":[":poop:"]}, "imp":{"icon":"\ud83d\udc7f", "keystrokes":[":imp:"]}, "japanese ogre":{"icon":"\ud83d\udc79", "keystrokes":[":japanese_ogre:", ":japaneseogre:"]}, "japanese goblin":{"icon":"\ud83d\udc7a", "keystrokes":[":japanese_goblin:", ":japanesegoblin:"]}, "robot":{"icon":"\ud83e\udd16", 
  "keystrokes":[":robot:"]}, "smiley cat":{"icon":"\ud83d\ude3a", "keystrokes":[":smiley_cat:", ":smileycat:"]}, "smile cat":{"icon":"\ud83d\ude38", "keystrokes":[":smile_cat:", ":smilecat:"]}, "joy cat":{"icon":"\ud83d\ude39", "keystrokes":[":joy_cat:", ":joycat:"]}, "heart eyes cat":{"icon":"\ud83d\ude3b", "keystrokes":[":heart_eyes_cat:", ":hearteyescat:"]}, "smirk cat":{"icon":"\ud83d\ude3c", "keystrokes":[":smirk_cat:", ":smirkcat:"]}, "kissing cat":{"icon":"\ud83d\ude3d", "keystrokes":[":kissing_cat:", 
  ":kissingcat:"]}, "scream cat":{"icon":"\ud83d\ude40", "keystrokes":[":scream_cat:", ":screamcat:"]}, "crying cat face":{"icon":"\ud83d\ude3f", "keystrokes":[":crying_cat_face:", ":cryingcatface:"]}, "pouting cat":{"icon":"\ud83d\ude3e", "keystrokes":[":pouting_cat:", ":poutingcat:"]}, "raised hands":{"icon":"\ud83d\ude4c", "keystrokes":[":raised_hands:", ":raisedhands:"]}, "clap":{"icon":"\ud83d\udc4f", "keystrokes":[":clap:"]}, "wave":{"icon":"\ud83d\udc4b", "keystrokes":[":wave:"]}, "call me hand":{"icon":"\ud83e\udd19", 
  "keystrokes":[":call_me_hand:", ":callmehand:"]}, "+1":{"icon":"\ud83d\udc4d", "keystrokes":[":+1:"]}, "-1":{"icon":"\ud83d\udc4e", "keystrokes":[":-1:"]}, "facepunch":{"icon":"\ud83d\udc4a", "keystrokes":[":facepunch:"]}, "fist":{"icon":"\u270a", "keystrokes":[":fist:"]}, "fist left":{"icon":"\ud83e\udd1b", "keystrokes":[":fist_left:", ":fistleft:"]}, "fist right":{"icon":"\ud83e\udd1c", "keystrokes":[":fist_right:", ":fistright:"]}, "v":{"icon":"\u270c", "keystrokes":[":v:"]}, "ok hand":{"icon":"\ud83d\udc4c", 
  "keystrokes":[":ok_hand:", ":okhand:"]}, "raised hand":{"icon":"\u270b", "keystrokes":[":raised_hand:", ":raisedhand:"]}, "raised back of hand":{"icon":"\ud83e\udd1a", "keystrokes":[":raised_back_of_hand:", ":raisedbackofhand:"]}, "open hands":{"icon":"\ud83d\udc50", "keystrokes":[":open_hands:", ":openhands:"]}, "muscle":{"icon":"\ud83d\udcaa", "keystrokes":[":muscle:"]}, "pray":{"icon":"\ud83d\ude4f", "keystrokes":[":pray:"]}, "handshake":{"icon":"\ud83e\udd1d", "keystrokes":[":handshake:"]}, 
  "point up":{"icon":"\u261d", "keystrokes":[":point_up:", ":pointup:"]}, "point up 2":{"icon":"\ud83d\udc46", "keystrokes":[":point_up_2:", ":pointup2:"]}, "point down":{"icon":"\ud83d\udc47", "keystrokes":[":point_down:", ":pointdown:"]}, "point left":{"icon":"\ud83d\udc48", "keystrokes":[":point_left:", ":pointleft:"]}, "point right":{"icon":"\ud83d\udc49", "keystrokes":[":point_right:", ":pointright:"]}, "fu":{"icon":"\ud83d\udd95", "keystrokes":[":fu:"]}, "raised hand with fingers splayed":{"icon":"\ud83d\udd90", 
  "keystrokes":[":raised_hand_with_fingers_splayed:", ":raisedhandwithfingerssplayed:"]}, "metal":{"icon":"\ud83e\udd18", "keystrokes":[":metal:"]}, "crossed fingers":{"icon":"\ud83e\udd1e", "keystrokes":[":crossed_fingers:", ":crossedfingers:"]}, "vulcan salute":{"icon":"\ud83d\udd96", "keystrokes":[":vulcan_salute:", ":vulcansalute:"]}, "writing hand":{"icon":"\u270d", "keystrokes":[":writing_hand:", ":writinghand:"]}, "selfie":{"icon":"\ud83e\udd33", "keystrokes":[":selfie:"]}, "nail care":{"icon":"\ud83d\udc85", 
  "keystrokes":[":nail_care:", ":nailcare:"]}, "lips":{"icon":"\ud83d\udc44", "keystrokes":[":lips:"]}, "tongue":{"icon":"\ud83d\udc45", "keystrokes":[":tongue:"]}, "ear":{"icon":"\ud83d\udc42", "keystrokes":[":ear:"]}, "nose":{"icon":"\ud83d\udc43", "keystrokes":[":nose:"]}, "eye":{"icon":"\ud83d\udc41", "keystrokes":[":eye:"]}, "eyes":{"icon":"\ud83d\udc40", "keystrokes":[":eyes:"]}, "bust in silhouette":{"icon":"\ud83d\udc64", "keystrokes":[":bust_in_silhouette:", ":bustinsilhouette:"]}, "busts in silhouette":{"icon":"\ud83d\udc65", 
  "keystrokes":[":busts_in_silhouette:", ":bustsinsilhouette:"]}, "speaking head":{"icon":"\ud83d\udde3", "keystrokes":[":speaking_head:", ":speakinghead:"]}, "baby":{"icon":"\ud83d\udc76", "keystrokes":[":baby:"]}, "boy":{"icon":"\ud83d\udc66", "keystrokes":[":boy:"]}, "girl":{"icon":"\ud83d\udc67", "keystrokes":[":girl:"]}, "man":{"icon":"\ud83d\udc68", "keystrokes":[":man:"]}, "woman":{"icon":"\ud83d\udc69", "keystrokes":[":woman:"]}, "blonde woman":{"icon":"\ud83d\udc71\u200d\u2640\ufe0f", "keystrokes":[":blonde_woman:", 
  ":blondewoman:"]}, "blonde man":{"icon":"\ud83d\udc71", "keystrokes":[":blonde_man:", ":blondeman:"]}, "older man":{"icon":"\ud83d\udc74", "keystrokes":[":older_man:", ":olderman:"]}, "older woman":{"icon":"\ud83d\udc75", "keystrokes":[":older_woman:", ":olderwoman:"]}, "man with gua pi mao":{"icon":"\ud83d\udc72", "keystrokes":[":man_with_gua_pi_mao:", ":manwithguapimao:"]}, "woman with turban":{"icon":"\ud83d\udc73\u200d\u2640\ufe0f", "keystrokes":[":woman_with_turban:", ":womanwithturban:"]}, 
  "man with turban":{"icon":"\ud83d\udc73", "keystrokes":[":man_with_turban:", ":manwithturban:"]}, "policewoman":{"icon":"\ud83d\udc6e\u200d\u2640\ufe0f", "keystrokes":[":policewoman:"]}, "policeman":{"icon":"\ud83d\udc6e", "keystrokes":[":policeman:"]}, "construction worker woman":{"icon":"\ud83d\udc77\u200d\u2640\ufe0f", "keystrokes":[":construction_worker_woman:", ":constructionworkerwoman:"]}, "construction worker man":{"icon":"\ud83d\udc77", "keystrokes":[":construction_worker_man:", ":constructionworkerman:"]}, 
  "guardswoman":{"icon":"\ud83d\udc82\u200d\u2640\ufe0f", "keystrokes":[":guardswoman:"]}, "guardsman":{"icon":"\ud83d\udc82", "keystrokes":[":guardsman:"]}, "female detective":{"icon":"\ud83d\udd75\ufe0f\u200d\u2640\ufe0f", "keystrokes":[":female_detective:", ":femaledetective:"]}, "male detective":{"icon":"\ud83d\udd75", "keystrokes":[":male_detective:", ":maledetective:"]}, "woman health worker":{"icon":"\ud83d\udc69\u200d\u2695\ufe0f", "keystrokes":[":woman_health_worker:", ":womanhealthworker:"]}, 
  "man health worker":{"icon":"\ud83d\udc68\u200d\u2695\ufe0f", "keystrokes":[":man_health_worker:", ":manhealthworker:"]}, "woman farmer":{"icon":"\ud83d\udc69\u200d\ud83c\udf3e", "keystrokes":[":woman_farmer:", ":womanfarmer:"]}, "man farmer":{"icon":"\ud83d\udc68\u200d\ud83c\udf3e", "keystrokes":[":man_farmer:", ":manfarmer:"]}, "woman cook":{"icon":"\ud83d\udc69\u200d\ud83c\udf73", "keystrokes":[":woman_cook:", ":womancook:"]}, "man cook":{"icon":"\ud83d\udc68\u200d\ud83c\udf73", "keystrokes":[":man_cook:", 
  ":mancook:"]}, "woman student":{"icon":"\ud83d\udc69\u200d\ud83c\udf93", "keystrokes":[":woman_student:", ":womanstudent:"]}, "man student":{"icon":"\ud83d\udc68\u200d\ud83c\udf93", "keystrokes":[":man_student:", ":manstudent:"]}, "woman singer":{"icon":"\ud83d\udc69\u200d\ud83c\udfa4", "keystrokes":[":woman_singer:", ":womansinger:"]}, "man singer":{"icon":"\ud83d\udc68\u200d\ud83c\udfa4", "keystrokes":[":man_singer:", ":mansinger:"]}, "woman teacher":{"icon":"\ud83d\udc69\u200d\ud83c\udfeb", 
  "keystrokes":[":woman_teacher:", ":womanteacher:"]}, "man teacher":{"icon":"\ud83d\udc68\u200d\ud83c\udfeb", "keystrokes":[":man_teacher:", ":manteacher:"]}, "woman factory worker":{"icon":"\ud83d\udc69\u200d\ud83c\udfed", "keystrokes":[":woman_factory_worker:", ":womanfactoryworker:"]}, "man factory worker":{"icon":"\ud83d\udc68\u200d\ud83c\udfed", "keystrokes":[":man_factory_worker:", ":manfactoryworker:"]}, "woman technologist":{"icon":"\ud83d\udc69\u200d\ud83d\udcbb", "keystrokes":[":woman_technologist:", 
  ":womantechnologist:"]}, "man technologist":{"icon":"\ud83d\udc68\u200d\ud83d\udcbb", "keystrokes":[":man_technologist:", ":mantechnologist:"]}, "woman office worker":{"icon":"\ud83d\udc69\u200d\ud83d\udcbc", "keystrokes":[":woman_office_worker:", ":womanofficeworker:"]}, "man office worker":{"icon":"\ud83d\udc68\u200d\ud83d\udcbc", "keystrokes":[":man_office_worker:", ":manofficeworker:"]}, "woman mechanic":{"icon":"\ud83d\udc69\u200d\ud83d\udd27", "keystrokes":[":woman_mechanic:", ":womanmechanic:"]}, 
  "man mechanic":{"icon":"\ud83d\udc68\u200d\ud83d\udd27", "keystrokes":[":man_mechanic:", ":manmechanic:"]}, "woman scientist":{"icon":"\ud83d\udc69\u200d\ud83d\udd2c", "keystrokes":[":woman_scientist:", ":womanscientist:"]}, "man scientist":{"icon":"\ud83d\udc68\u200d\ud83d\udd2c", "keystrokes":[":man_scientist:", ":manscientist:"]}, "woman artist":{"icon":"\ud83d\udc69\u200d\ud83c\udfa8", "keystrokes":[":woman_artist:", ":womanartist:"]}, "man artist":{"icon":"\ud83d\udc68\u200d\ud83c\udfa8", 
  "keystrokes":[":man_artist:", ":manartist:"]}, "woman firefighter":{"icon":"\ud83d\udc69\u200d\ud83d\ude92", "keystrokes":[":woman_firefighter:", ":womanfirefighter:"]}, "man firefighter":{"icon":"\ud83d\udc68\u200d\ud83d\ude92", "keystrokes":[":man_firefighter:", ":manfirefighter:"]}, "woman pilot":{"icon":"\ud83d\udc69\u200d\u2708\ufe0f", "keystrokes":[":woman_pilot:", ":womanpilot:"]}, "man pilot":{"icon":"\ud83d\udc68\u200d\u2708\ufe0f", "keystrokes":[":man_pilot:", ":manpilot:"]}, "woman astronaut":{"icon":"\ud83d\udc69\u200d\ud83d\ude80", 
  "keystrokes":[":woman_astronaut:", ":womanastronaut:"]}, "man astronaut":{"icon":"\ud83d\udc68\u200d\ud83d\ude80", "keystrokes":[":man_astronaut:", ":manastronaut:"]}, "woman judge":{"icon":"\ud83d\udc69\u200d\u2696\ufe0f", "keystrokes":[":woman_judge:", ":womanjudge:"]}, "man judge":{"icon":"\ud83d\udc68\u200d\u2696\ufe0f", "keystrokes":[":man_judge:", ":manjudge:"]}, "mrs claus":{"icon":"\ud83e\udd36", "keystrokes":[":mrs_claus:", ":mrsclaus:"]}, "santa":{"icon":"\ud83c\udf85", "keystrokes":[":santa:"]}, 
  "angel":{"icon":"\ud83d\udc7c", "keystrokes":[":angel:"]}, "pregnant woman":{"icon":"\ud83e\udd30", "keystrokes":[":pregnant_woman:", ":pregnantwoman:"]}, "princess":{"icon":"\ud83d\udc78", "keystrokes":[":princess:"]}, "prince":{"icon":"\ud83e\udd34", "keystrokes":[":prince:"]}, "bride with veil":{"icon":"\ud83d\udc70", "keystrokes":[":bride_with_veil:", ":bridewithveil:"]}, "man in tuxedo":{"icon":"\ud83e\udd35", "keystrokes":[":man_in_tuxedo:", ":manintuxedo:"]}, "running woman":{"icon":"\ud83c\udfc3\u200d\u2640\ufe0f", 
  "keystrokes":[":running_woman:", ":runningwoman:"]}, "running man":{"icon":"\ud83c\udfc3", "keystrokes":[":running_man:", ":runningman:"]}, "walking woman":{"icon":"\ud83d\udeb6\u200d\u2640\ufe0f", "keystrokes":[":walking_woman:", ":walkingwoman:"]}, "walking man":{"icon":"\ud83d\udeb6", "keystrokes":[":walking_man:", ":walkingman:"]}, "dancer":{"icon":"\ud83d\udc83", "keystrokes":[":dancer:"]}, "man dancing":{"icon":"\ud83d\udd7a", "keystrokes":[":man_dancing:", ":mandancing:"]}, "dancing women":{"icon":"\ud83d\udc6f", 
  "keystrokes":[":dancing_women:", ":dancingwomen:"]}, "dancing men":{"icon":"\ud83d\udc6f\u200d\u2642\ufe0f", "keystrokes":[":dancing_men:", ":dancingmen:"]}, "couple":{"icon":"\ud83d\udc6b", "keystrokes":[":couple:"]}, "two men holding hands":{"icon":"\ud83d\udc6c", "keystrokes":[":two_men_holding_hands:", ":twomenholdinghands:"]}, "two women holding hands":{"icon":"\ud83d\udc6d", "keystrokes":[":two_women_holding_hands:", ":twowomenholdinghands:"]}, "bowing woman":{"icon":"\ud83d\ude47\u200d\u2640\ufe0f", 
  "keystrokes":[":bowing_woman:", ":bowingwoman:"]}, "bowing man":{"icon":"\ud83d\ude47", "keystrokes":[":bowing_man:", ":bowingman:"]}, "man facepalming":{"icon":"\ud83e\udd26", "keystrokes":[":man_facepalming:", ":manfacepalming:"]}, "woman facepalming":{"icon":"\ud83e\udd26\u200d\u2640\ufe0f", "keystrokes":[":woman_facepalming:", ":womanfacepalming:"]}, "woman shrugging":{"icon":"\ud83e\udd37", "keystrokes":[":woman_shrugging:", ":womanshrugging:"]}, "man shrugging":{"icon":"\ud83e\udd37\u200d\u2642\ufe0f", 
  "keystrokes":[":man_shrugging:", ":manshrugging:"]}, "tipping hand woman":{"icon":"\ud83d\udc81", "keystrokes":[":tipping_hand_woman:", ":tippinghandwoman:"]}, "tipping hand man":{"icon":"\ud83d\udc81\u200d\u2642\ufe0f", "keystrokes":[":tipping_hand_man:", ":tippinghandman:"]}, "no good woman":{"icon":"\ud83d\ude45", "keystrokes":[":no_good_woman:", ":nogoodwoman:"]}, "no good man":{"icon":"\ud83d\ude45\u200d\u2642\ufe0f", "keystrokes":[":no_good_man:", ":nogoodman:"]}, "ok woman":{"icon":"\ud83d\ude46", 
  "keystrokes":[":ok_woman:", ":okwoman:"]}, "ok man":{"icon":"\ud83d\ude46\u200d\u2642\ufe0f", "keystrokes":[":ok_man:", ":okman:"]}, "raising hand woman":{"icon":"\ud83d\ude4b", "keystrokes":[":raising_hand_woman:", ":raisinghandwoman:"]}, "raising hand man":{"icon":"\ud83d\ude4b\u200d\u2642\ufe0f", "keystrokes":[":raising_hand_man:", ":raisinghandman:"]}, "pouting woman":{"icon":"\ud83d\ude4e", "keystrokes":[":pouting_woman:", ":poutingwoman:"]}, "pouting man":{"icon":"\ud83d\ude4e\u200d\u2642\ufe0f", 
  "keystrokes":[":pouting_man:", ":poutingman:"]}, "frowning woman":{"icon":"\ud83d\ude4d", "keystrokes":[":frowning_woman:", ":frowningwoman:"]}, "frowning man":{"icon":"\ud83d\ude4d\u200d\u2642\ufe0f", "keystrokes":[":frowning_man:", ":frowningman:"]}, "haircut woman":{"icon":"\ud83d\udc87", "keystrokes":[":haircut_woman:", ":haircutwoman:"]}, "haircut man":{"icon":"\ud83d\udc87\u200d\u2642\ufe0f", "keystrokes":[":haircut_man:", ":haircutman:"]}, "massage woman":{"icon":"\ud83d\udc86", "keystrokes":[":massage_woman:", 
  ":massagewoman:"]}, "massage man":{"icon":"\ud83d\udc86\u200d\u2642\ufe0f", "keystrokes":[":massage_man:", ":massageman:"]}, "couple with heart woman man":{"icon":"\ud83d\udc91", "keystrokes":[":couple_with_heart_woman_man:", ":couplewithheartwomanman:"]}, "couple with heart woman woman":{"icon":"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc69", "keystrokes":[":couple_with_heart_woman_woman:", ":couplewithheartwomanwoman:"]}, "couple with heart man man":{"icon":"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68", 
  "keystrokes":[":couple_with_heart_man_man:", ":couplewithheartmanman:"]}, "couplekiss man woman":{"icon":"\ud83d\udc8f", "keystrokes":[":couplekiss_man_woman:", ":couplekissmanwoman:"]}, "couplekiss woman woman":{"icon":"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69", "keystrokes":[":couplekiss_woman_woman:", ":couplekisswomanwoman:"]}, "couplekiss man man":{"icon":"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68", "keystrokes":[":couplekiss_man_man:", ":couplekissmanman:"]}, 
  "family man woman boy":{"icon":"\ud83d\udc6a", "keystrokes":[":family_man_woman_boy:", ":familymanwomanboy:"]}, "family man woman girl":{"icon":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67", "keystrokes":[":family_man_woman_girl:", ":familymanwomangirl:"]}, "family man woman girl boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66", "keystrokes":[":family_man_woman_girl_boy:", ":familymanwomangirlboy:"]}, "family man woman boy boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66", 
  "keystrokes":[":family_man_woman_boy_boy:", ":familymanwomanboyboy:"]}, "family man woman girl girl":{"icon":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67", "keystrokes":[":family_man_woman_girl_girl:", ":familymanwomangirlgirl:"]}, "family woman woman boy":{"icon":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66", "keystrokes":[":family_woman_woman_boy:", ":familywomanwomanboy:"]}, "family woman woman girl":{"icon":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67", "keystrokes":[":family_woman_woman_girl:", 
  ":familywomanwomangirl:"]}, "family woman woman girl boy":{"icon":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66", "keystrokes":[":family_woman_woman_girl_boy:", ":familywomanwomangirlboy:"]}, "family woman woman boy boy":{"icon":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66", "keystrokes":[":family_woman_woman_boy_boy:", ":familywomanwomanboyboy:"]}, "family woman woman girl girl":{"icon":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67", 
  "keystrokes":[":family_woman_woman_girl_girl:", ":familywomanwomangirlgirl:"]}, "family man man boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66", "keystrokes":[":family_man_man_boy:", ":familymanmanboy:"]}, "family man man girl":{"icon":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67", "keystrokes":[":family_man_man_girl:", ":familymanmangirl:"]}, "family man man girl boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66", "keystrokes":[":family_man_man_girl_boy:", 
  ":familymanmangirlboy:"]}, "family man man boy boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66", "keystrokes":[":family_man_man_boy_boy:", ":familymanmanboyboy:"]}, "family man man girl girl":{"icon":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67", "keystrokes":[":family_man_man_girl_girl:", ":familymanmangirlgirl:"]}, "family woman boy":{"icon":"\ud83d\udc69\u200d\ud83d\udc66", "keystrokes":[":family_woman_boy:", ":familywomanboy:"]}, "family woman girl":{"icon":"\ud83d\udc69\u200d\ud83d\udc67", 
  "keystrokes":[":family_woman_girl:", ":familywomangirl:"]}, "family woman girl boy":{"icon":"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66", "keystrokes":[":family_woman_girl_boy:", ":familywomangirlboy:"]}, "family woman boy boy":{"icon":"\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66", "keystrokes":[":family_woman_boy_boy:", ":familywomanboyboy:"]}, "family woman girl girl":{"icon":"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67", "keystrokes":[":family_woman_girl_girl:", ":familywomangirlgirl:"]}, 
  "family man boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc66", "keystrokes":[":family_man_boy:", ":familymanboy:"]}, "family man girl":{"icon":"\ud83d\udc68\u200d\ud83d\udc67", "keystrokes":[":family_man_girl:", ":familymangirl:"]}, "family man girl boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66", "keystrokes":[":family_man_girl_boy:", ":familymangirlboy:"]}, "family man boy boy":{"icon":"\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66", "keystrokes":[":family_man_boy_boy:", ":familymanboyboy:"]}, 
  "family man girl girl":{"icon":"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67", "keystrokes":[":family_man_girl_girl:", ":familymangirlgirl:"]}, "womans clothes":{"icon":"\ud83d\udc5a", "keystrokes":[":womans_clothes:", ":womansclothes:"]}, "tshirt":{"icon":"\ud83d\udc55", "keystrokes":[":tshirt:"]}, "jeans":{"icon":"\ud83d\udc56", "keystrokes":[":jeans:"]}, "necktie":{"icon":"\ud83d\udc54", "keystrokes":[":necktie:"]}, "dress":{"icon":"\ud83d\udc57", "keystrokes":[":dress:"]}, "bikini":{"icon":"\ud83d\udc59", 
  "keystrokes":[":bikini:"]}, "kimono":{"icon":"\ud83d\udc58", "keystrokes":[":kimono:"]}, "lipstick":{"icon":"\ud83d\udc84", "keystrokes":[":lipstick:"]}, "kiss":{"icon":"\ud83d\udc8b", "keystrokes":[":kiss:"]}, "footprints":{"icon":"\ud83d\udc63", "keystrokes":[":footprints:"]}, "high heel":{"icon":"\ud83d\udc60", "keystrokes":[":high_heel:", ":highheel:"]}, "sandal":{"icon":"\ud83d\udc61", "keystrokes":[":sandal:"]}, "boot":{"icon":"\ud83d\udc62", "keystrokes":[":boot:"]}, "mans shoe":{"icon":"\ud83d\udc5e", 
  "keystrokes":[":mans_shoe:", ":mansshoe:"]}, "athletic shoe":{"icon":"\ud83d\udc5f", "keystrokes":[":athletic_shoe:", ":athleticshoe:"]}, "womans hat":{"icon":"\ud83d\udc52", "keystrokes":[":womans_hat:", ":womanshat:"]}, "tophat":{"icon":"\ud83c\udfa9", "keystrokes":[":tophat:"]}, "rescue worker helmet":{"icon":"\u26d1", "keystrokes":[":rescue_worker_helmet:", ":rescueworkerhelmet:"]}, "mortar board":{"icon":"\ud83c\udf93", "keystrokes":[":mortar_board:", ":mortarboard:"]}, "crown":{"icon":"\ud83d\udc51", 
  "keystrokes":[":crown:"]}, "school satchel":{"icon":"\ud83c\udf92", "keystrokes":[":school_satchel:", ":schoolsatchel:"]}, "pouch":{"icon":"\ud83d\udc5d", "keystrokes":[":pouch:"]}, "purse":{"icon":"\ud83d\udc5b", "keystrokes":[":purse:"]}, "handbag":{"icon":"\ud83d\udc5c", "keystrokes":[":handbag:"]}, "briefcase":{"icon":"\ud83d\udcbc", "keystrokes":[":briefcase:"]}, "eyeglasses":{"icon":"\ud83d\udc53", "keystrokes":[":eyeglasses:"]}, "dark sunglasses":{"icon":"\ud83d\udd76", "keystrokes":[":dark_sunglasses:", 
  ":darksunglasses:"]}, "ring":{"icon":"\ud83d\udc8d", "keystrokes":[":ring:"]}, "closed umbrella":{"icon":"\ud83c\udf02", "keystrokes":[":closed_umbrella:", ":closedumbrella:"]}, "dog":{"icon":"\ud83d\udc36", "keystrokes":[":dog:"]}, "cat":{"icon":"\ud83d\udc31", "keystrokes":[":cat:"]}, "mouse":{"icon":"\ud83d\udc2d", "keystrokes":[":mouse:"]}, "hamster":{"icon":"\ud83d\udc39", "keystrokes":[":hamster:"]}, "rabbit":{"icon":"\ud83d\udc30", "keystrokes":[":rabbit:"]}, "fox face":{"icon":"\ud83e\udd8a", 
  "keystrokes":[":fox_face:", ":foxface:"]}, "bear":{"icon":"\ud83d\udc3b", "keystrokes":[":bear:"]}, "panda face":{"icon":"\ud83d\udc3c", "keystrokes":[":panda_face:", ":pandaface:"]}, "koala":{"icon":"\ud83d\udc28", "keystrokes":[":koala:"]}, "tiger":{"icon":"\ud83d\udc2f", "keystrokes":[":tiger:"]}, "lion":{"icon":"\ud83e\udd81", "keystrokes":[":lion:"]}, "cow":{"icon":"\ud83d\udc2e", "keystrokes":[":cow:"]}, "pig":{"icon":"\ud83d\udc37", "keystrokes":[":pig:"]}, "pig nose":{"icon":"\ud83d\udc3d", 
  "keystrokes":[":pig_nose:", ":pignose:"]}, "frog":{"icon":"\ud83d\udc38", "keystrokes":[":frog:"]}, "squid":{"icon":"\ud83e\udd91", "keystrokes":[":squid:"]}, "octopus":{"icon":"\ud83d\udc19", "keystrokes":[":octopus:"]}, "shrimp":{"icon":"\ud83e\udd90", "keystrokes":[":shrimp:"]}, "monkey face":{"icon":"\ud83d\udc35", "keystrokes":[":monkey_face:", ":monkeyface:"]}, "gorilla":{"icon":"\ud83e\udd8d", "keystrokes":[":gorilla:"]}, "see no evil":{"icon":"\ud83d\ude48", "keystrokes":[":see_no_evil:", 
  ":seenoevil:"]}, "hear no evil":{"icon":"\ud83d\ude49", "keystrokes":[":hear_no_evil:", ":hearnoevil:"]}, "speak no evil":{"icon":"\ud83d\ude4a", "keystrokes":[":speak_no_evil:", ":speaknoevil:"]}, "monkey":{"icon":"\ud83d\udc12", "keystrokes":[":monkey:"]}, "chicken":{"icon":"\ud83d\udc14", "keystrokes":[":chicken:"]}, "penguin":{"icon":"\ud83d\udc27", "keystrokes":[":penguin:"]}, "bird":{"icon":"\ud83d\udc26", "keystrokes":[":bird:"]}, "baby chick":{"icon":"\ud83d\udc24", "keystrokes":[":baby_chick:", 
  ":babychick:"]}, "hatching chick":{"icon":"\ud83d\udc23", "keystrokes":[":hatching_chick:", ":hatchingchick:"]}, "hatched chick":{"icon":"\ud83d\udc25", "keystrokes":[":hatched_chick:", ":hatchedchick:"]}, "duck":{"icon":"\ud83e\udd86", "keystrokes":[":duck:"]}, "eagle":{"icon":"\ud83e\udd85", "keystrokes":[":eagle:"]}, "owl":{"icon":"\ud83e\udd89", "keystrokes":[":owl:"]}, "bat":{"icon":"\ud83e\udd87", "keystrokes":[":bat:"]}, "wolf":{"icon":"\ud83d\udc3a", "keystrokes":[":wolf:"]}, "boar":{"icon":"\ud83d\udc17", 
  "keystrokes":[":boar:"]}, "horse":{"icon":"\ud83d\udc34", "keystrokes":[":horse:"]}, "unicorn":{"icon":"\ud83e\udd84", "keystrokes":[":unicorn:"]}, "honeybee":{"icon":"\ud83d\udc1d", "keystrokes":[":honeybee:"]}, "bug":{"icon":"\ud83d\udc1b", "keystrokes":[":bug:"]}, "butterfly":{"icon":"\ud83e\udd8b", "keystrokes":[":butterfly:"]}, "snail":{"icon":"\ud83d\udc0c", "keystrokes":[":snail:"]}, "beetle":{"icon":"\ud83d\udc1e", "keystrokes":[":beetle:"]}, "ant":{"icon":"\ud83d\udc1c", "keystrokes":[":ant:"]}, 
  "spider":{"icon":"\ud83d\udd77", "keystrokes":[":spider:"]}, "scorpion":{"icon":"\ud83e\udd82", "keystrokes":[":scorpion:"]}, "crab":{"icon":"\ud83e\udd80", "keystrokes":[":crab:"]}, "snake":{"icon":"\ud83d\udc0d", "keystrokes":[":snake:"]}, "lizard":{"icon":"\ud83e\udd8e", "keystrokes":[":lizard:"]}, "turtle":{"icon":"\ud83d\udc22", "keystrokes":[":turtle:"]}, "tropical fish":{"icon":"\ud83d\udc20", "keystrokes":[":tropical_fish:", ":tropicalfish:"]}, "fish":{"icon":"\ud83d\udc1f", "keystrokes":[":fish:"]}, 
  "blowfish":{"icon":"\ud83d\udc21", "keystrokes":[":blowfish:"]}, "dolphin":{"icon":"\ud83d\udc2c", "keystrokes":[":dolphin:"]}, "shark":{"icon":"\ud83e\udd88", "keystrokes":[":shark:"]}, "whale":{"icon":"\ud83d\udc33", "keystrokes":[":whale:"]}, "whale2":{"icon":"\ud83d\udc0b", "keystrokes":[":whale2:"]}, "crocodile":{"icon":"\ud83d\udc0a", "keystrokes":[":crocodile:"]}, "leopard":{"icon":"\ud83d\udc06", "keystrokes":[":leopard:"]}, "tiger2":{"icon":"\ud83d\udc05", "keystrokes":[":tiger2:"]}, "water buffalo":{"icon":"\ud83d\udc03", 
  "keystrokes":[":water_buffalo:", ":waterbuffalo:"]}, "ox":{"icon":"\ud83d\udc02", "keystrokes":[":ox:"]}, "cow2":{"icon":"\ud83d\udc04", "keystrokes":[":cow2:"]}, "deer":{"icon":"\ud83e\udd8c", "keystrokes":[":deer:"]}, "dromedary camel":{"icon":"\ud83d\udc2a", "keystrokes":[":dromedary_camel:", ":dromedarycamel:"]}, "camel":{"icon":"\ud83d\udc2b", "keystrokes":[":camel:"]}, "elephant":{"icon":"\ud83d\udc18", "keystrokes":[":elephant:"]}, "rhinoceros":{"icon":"\ud83e\udd8f", "keystrokes":[":rhinoceros:"]}, 
  "goat":{"icon":"\ud83d\udc10", "keystrokes":[":goat:"]}, "ram":{"icon":"\ud83d\udc0f", "keystrokes":[":ram:"]}, "sheep":{"icon":"\ud83d\udc11", "keystrokes":[":sheep:"]}, "racehorse":{"icon":"\ud83d\udc0e", "keystrokes":[":racehorse:"]}, "pig2":{"icon":"\ud83d\udc16", "keystrokes":[":pig2:"]}, "rat":{"icon":"\ud83d\udc00", "keystrokes":[":rat:"]}, "mouse2":{"icon":"\ud83d\udc01", "keystrokes":[":mouse2:"]}, "rooster":{"icon":"\ud83d\udc13", "keystrokes":[":rooster:"]}, "turkey":{"icon":"\ud83e\udd83", 
  "keystrokes":[":turkey:"]}, "dove":{"icon":"\ud83d\udd4a", "keystrokes":[":dove:"]}, "dog2":{"icon":"\ud83d\udc15", "keystrokes":[":dog2:"]}, "poodle":{"icon":"\ud83d\udc29", "keystrokes":[":poodle:"]}, "cat2":{"icon":"\ud83d\udc08", "keystrokes":[":cat2:"]}, "rabbit2":{"icon":"\ud83d\udc07", "keystrokes":[":rabbit2:"]}, "chipmunk":{"icon":"\ud83d\udc3f", "keystrokes":[":chipmunk:"]}, "paw prints":{"icon":"\ud83d\udc3e", "keystrokes":[":paw_prints:", ":pawprints:"]}, "dragon":{"icon":"\ud83d\udc09", 
  "keystrokes":[":dragon:"]}, "dragon face":{"icon":"\ud83d\udc32", "keystrokes":[":dragon_face:", ":dragonface:"]}, "cactus":{"icon":"\ud83c\udf35", "keystrokes":[":cactus:"]}, "christmas tree":{"icon":"\ud83c\udf84", "keystrokes":[":christmas_tree:", ":christmastree:"]}, "evergreen tree":{"icon":"\ud83c\udf32", "keystrokes":[":evergreen_tree:", ":evergreentree:"]}, "deciduous tree":{"icon":"\ud83c\udf33", "keystrokes":[":deciduous_tree:", ":deciduoustree:"]}, "palm tree":{"icon":"\ud83c\udf34", 
  "keystrokes":[":palm_tree:", ":palmtree:"]}, "seedling":{"icon":"\ud83c\udf31", "keystrokes":[":seedling:"]}, "herb":{"icon":"\ud83c\udf3f", "keystrokes":[":herb:"]}, "shamrock":{"icon":"\u2618", "keystrokes":[":shamrock:"]}, "four leaf clover":{"icon":"\ud83c\udf40", "keystrokes":[":four_leaf_clover:", ":fourleafclover:"]}, "bamboo":{"icon":"\ud83c\udf8d", "keystrokes":[":bamboo:"]}, "tanabata tree":{"icon":"\ud83c\udf8b", "keystrokes":[":tanabata_tree:", ":tanabatatree:"]}, "leaves":{"icon":"\ud83c\udf43", 
  "keystrokes":[":leaves:"]}, "fallen leaf":{"icon":"\ud83c\udf42", "keystrokes":[":fallen_leaf:", ":fallenleaf:"]}, "maple leaf":{"icon":"\ud83c\udf41", "keystrokes":[":maple_leaf:", ":mapleleaf:"]}, "ear of rice":{"icon":"\ud83c\udf3e", "keystrokes":[":ear_of_rice:", ":earofrice:"]}, "hibiscus":{"icon":"\ud83c\udf3a", "keystrokes":[":hibiscus:"]}, "sunflower":{"icon":"\ud83c\udf3b", "keystrokes":[":sunflower:"]}, "rose":{"icon":"\ud83c\udf39", "keystrokes":[":rose:"]}, "wilted flower":{"icon":"\ud83e\udd40", 
  "keystrokes":[":wilted_flower:", ":wiltedflower:"]}, "tulip":{"icon":"\ud83c\udf37", "keystrokes":[":tulip:"]}, "blossom":{"icon":"\ud83c\udf3c", "keystrokes":[":blossom:"]}, "cherry blossom":{"icon":"\ud83c\udf38", "keystrokes":[":cherry_blossom:", ":cherryblossom:"]}, "bouquet":{"icon":"\ud83d\udc90", "keystrokes":[":bouquet:"]}, "mushroom":{"icon":"\ud83c\udf44", "keystrokes":[":mushroom:"]}, "chestnut":{"icon":"\ud83c\udf30", "keystrokes":[":chestnut:"]}, "jack o lantern":{"icon":"\ud83c\udf83", 
  "keystrokes":[":jack_o_lantern:", ":jackolantern:"]}, "shell":{"icon":"\ud83d\udc1a", "keystrokes":[":shell:"]}, "spider web":{"icon":"\ud83d\udd78", "keystrokes":[":spider_web:", ":spiderweb:"]}, "earth americas":{"icon":"\ud83c\udf0e", "keystrokes":[":earth_americas:", ":earthamericas:"]}, "earth africa":{"icon":"\ud83c\udf0d", "keystrokes":[":earth_africa:", ":earthafrica:"]}, "earth asia":{"icon":"\ud83c\udf0f", "keystrokes":[":earth_asia:", ":earthasia:"]}, "full moon":{"icon":"\ud83c\udf15", 
  "keystrokes":[":full_moon:", ":fullmoon:"]}, "waning gibbous moon":{"icon":"\ud83c\udf16", "keystrokes":[":waning_gibbous_moon:", ":waninggibbousmoon:"]}, "last quarter moon":{"icon":"\ud83c\udf17", "keystrokes":[":last_quarter_moon:", ":lastquartermoon:"]}, "waning crescent moon":{"icon":"\ud83c\udf18", "keystrokes":[":waning_crescent_moon:", ":waningcrescentmoon:"]}, "new moon":{"icon":"\ud83c\udf11", "keystrokes":[":new_moon:", ":newmoon:"]}, "waxing crescent moon":{"icon":"\ud83c\udf12", "keystrokes":[":waxing_crescent_moon:", 
  ":waxingcrescentmoon:"]}, "first quarter moon":{"icon":"\ud83c\udf13", "keystrokes":[":first_quarter_moon:", ":firstquartermoon:"]}, "waxing gibbous moon":{"icon":"\ud83c\udf14", "keystrokes":[":waxing_gibbous_moon:", ":waxinggibbousmoon:"]}, "new moon with face":{"icon":"\ud83c\udf1a", "keystrokes":[":new_moon_with_face:", ":newmoonwithface:"]}, "full moon with face":{"icon":"\ud83c\udf1d", "keystrokes":[":full_moon_with_face:", ":fullmoonwithface:"]}, "first quarter moon with face":{"icon":"\ud83c\udf1b", 
  "keystrokes":[":first_quarter_moon_with_face:", ":firstquartermoonwithface:"]}, "last quarter moon with face":{"icon":"\ud83c\udf1c", "keystrokes":[":last_quarter_moon_with_face:", ":lastquartermoonwithface:"]}, "sun with face":{"icon":"\ud83c\udf1e", "keystrokes":[":sun_with_face:", ":sunwithface:"]}, "crescent moon":{"icon":"\ud83c\udf19", "keystrokes":[":crescent_moon:", ":crescentmoon:"]}, "star":{"icon":"\u2b50", "keystrokes":[":star:"]}, "star2":{"icon":"\ud83c\udf1f", "keystrokes":[":star2:"]}, 
  "dizzy":{"icon":"\ud83d\udcab", "keystrokes":[":dizzy:"]}, "sparkles":{"icon":"\u2728", "keystrokes":[":sparkles:"]}, "comet":{"icon":"\u2604", "keystrokes":[":comet:"]}, "sunny":{"icon":"\u2600\ufe0f", "keystrokes":[":sunny:"]}, "sun behind small cloud":{"icon":"\ud83c\udf24", "keystrokes":[":sun_behind_small_cloud:", ":sunbehindsmallcloud:"]}, "partly sunny":{"icon":"\u26c5", "keystrokes":[":partly_sunny:", ":partlysunny:"]}, "sun behind large cloud":{"icon":"\ud83c\udf25", "keystrokes":[":sun_behind_large_cloud:", 
  ":sunbehindlargecloud:"]}, "sun behind rain cloud":{"icon":"\ud83c\udf26", "keystrokes":[":sun_behind_rain_cloud:", ":sunbehindraincloud:"]}, "cloud":{"icon":"\u2601\ufe0f", "keystrokes":[":cloud:"]}, "cloud with rain":{"icon":"\ud83c\udf27", "keystrokes":[":cloud_with_rain:", ":cloudwithrain:"]}, "cloud with lightning and rain":{"icon":"\u26c8", "keystrokes":[":cloud_with_lightning_and_rain:", ":cloudwithlightningandrain:"]}, "cloud with lightning":{"icon":"\ud83c\udf29", "keystrokes":[":cloud_with_lightning:", 
  ":cloudwithlightning:"]}, "zap":{"icon":"\u26a1", "keystrokes":[":zap:"]}, "fire":{"icon":"\ud83d\udd25", "keystrokes":[":fire:"]}, "boom":{"icon":"\ud83d\udca5", "keystrokes":[":boom:"]}, "snowflake":{"icon":"\u2744\ufe0f", "keystrokes":[":snowflake:"]}, "cloud with snow":{"icon":"\ud83c\udf28", "keystrokes":[":cloud_with_snow:", ":cloudwithsnow:"]}, "snowman":{"icon":"\u26c4", "keystrokes":[":snowman:"]}, "snowman with snow":{"icon":"\u2603", "keystrokes":[":snowman_with_snow:", ":snowmanwithsnow:"]}, 
  "wind face":{"icon":"\ud83c\udf2c", "keystrokes":[":wind_face:", ":windface:"]}, "dash":{"icon":"\ud83d\udca8", "keystrokes":[":dash:"]}, "tornado":{"icon":"\ud83c\udf2a", "keystrokes":[":tornado:"]}, "fog":{"icon":"\ud83c\udf2b", "keystrokes":[":fog:"]}, "open umbrella":{"icon":"\u2602", "keystrokes":[":open_umbrella:", ":openumbrella:"]}, "umbrella":{"icon":"\u2614", "keystrokes":[":umbrella:"]}, "sweat drops":{"icon":"\ud83d\udca6", "keystrokes":[":sweat_drops:", ":sweatdrops:"]}, "ocean":{"icon":"\ud83c\udf0a", 
  "keystrokes":[":ocean:"]}, "green apple":{"icon":"\ud83c\udf4f", "keystrokes":[":green_apple:", ":greenapple:"]}, "apple":{"icon":"\ud83c\udf4e", "keystrokes":[":apple:"]}, "pear":{"icon":"\ud83c\udf50", "keystrokes":[":pear:"]}, "tangerine":{"icon":"\ud83c\udf4a", "keystrokes":[":tangerine:"]}, "lemon":{"icon":"\ud83c\udf4b", "keystrokes":[":lemon:"]}, "banana":{"icon":"\ud83c\udf4c", "keystrokes":[":banana:"]}, "watermelon":{"icon":"\ud83c\udf49", "keystrokes":[":watermelon:"]}, "grapes":{"icon":"\ud83c\udf47", 
  "keystrokes":[":grapes:"]}, "strawberry":{"icon":"\ud83c\udf53", "keystrokes":[":strawberry:"]}, "melon":{"icon":"\ud83c\udf48", "keystrokes":[":melon:"]}, "cherries":{"icon":"\ud83c\udf52", "keystrokes":[":cherries:"]}, "peach":{"icon":"\ud83c\udf51", "keystrokes":[":peach:"]}, "pineapple":{"icon":"\ud83c\udf4d", "keystrokes":[":pineapple:"]}, "kiwi fruit":{"icon":"\ud83e\udd5d", "keystrokes":[":kiwi_fruit:", ":kiwifruit:"]}, "avocado":{"icon":"\ud83e\udd51", "keystrokes":[":avocado:"]}, "tomato":{"icon":"\ud83c\udf45", 
  "keystrokes":[":tomato:"]}, "eggplant":{"icon":"\ud83c\udf46", "keystrokes":[":eggplant:"]}, "cucumber":{"icon":"\ud83e\udd52", "keystrokes":[":cucumber:"]}, "carrot":{"icon":"\ud83e\udd55", "keystrokes":[":carrot:"]}, "hot pepper":{"icon":"\ud83c\udf36", "keystrokes":[":hot_pepper:", ":hotpepper:"]}, "potato":{"icon":"\ud83e\udd54", "keystrokes":[":potato:"]}, "corn":{"icon":"\ud83c\udf3d", "keystrokes":[":corn:"]}, "sweet potato":{"icon":"\ud83c\udf60", "keystrokes":[":sweet_potato:", ":sweetpotato:"]}, 
  "peanuts":{"icon":"\ud83e\udd5c", "keystrokes":[":peanuts:"]}, "honey pot":{"icon":"\ud83c\udf6f", "keystrokes":[":honey_pot:", ":honeypot:"]}, "croissant":{"icon":"\ud83e\udd50", "keystrokes":[":croissant:"]}, "bread":{"icon":"\ud83c\udf5e", "keystrokes":[":bread:"]}, "baguette bread":{"icon":"\ud83e\udd56", "keystrokes":[":baguette_bread:", ":baguettebread:"]}, "cheese":{"icon":"\ud83e\uddc0", "keystrokes":[":cheese:"]}, "egg":{"icon":"\ud83e\udd5a", "keystrokes":[":egg:"]}, "bacon":{"icon":"\ud83e\udd53", 
  "keystrokes":[":bacon:"]}, "pancakes":{"icon":"\ud83e\udd5e", "keystrokes":[":pancakes:"]}, "poultry leg":{"icon":"\ud83c\udf57", "keystrokes":[":poultry_leg:", ":poultryleg:"]}, "meat on bone":{"icon":"\ud83c\udf56", "keystrokes":[":meat_on_bone:", ":meatonbone:"]}, "fried shrimp":{"icon":"\ud83c\udf64", "keystrokes":[":fried_shrimp:", ":friedshrimp:"]}, "fried egg":{"icon":"\ud83c\udf73", "keystrokes":[":fried_egg:", ":friedegg:"]}, "hamburger":{"icon":"\ud83c\udf54", "keystrokes":[":hamburger:"]}, 
  "fries":{"icon":"\ud83c\udf5f", "keystrokes":[":fries:"]}, "stuffed flatbread":{"icon":"\ud83e\udd59", "keystrokes":[":stuffed_flatbread:", ":stuffedflatbread:"]}, "hotdog":{"icon":"\ud83c\udf2d", "keystrokes":[":hotdog:"]}, "spaghetti":{"icon":"\ud83c\udf5d", "keystrokes":[":spaghetti:"]}, "taco":{"icon":"\ud83c\udf2e", "keystrokes":[":taco:"]}, "burrito":{"icon":"\ud83c\udf2f", "keystrokes":[":burrito:"]}, "green salad":{"icon":"\ud83e\udd57", "keystrokes":[":green_salad:", ":greensalad:"]}, 
  "shallow pan of food":{"icon":"\ud83e\udd58", "keystrokes":[":shallow_pan_of_food:", ":shallowpanoffood:"]}, "ramen":{"icon":"\ud83c\udf5c", "keystrokes":[":ramen:"]}, "stew":{"icon":"\ud83c\udf72", "keystrokes":[":stew:"]}, "fish cake":{"icon":"\ud83c\udf65", "keystrokes":[":fish_cake:", ":fishcake:"]}, "sushi":{"icon":"\ud83c\udf63", "keystrokes":[":sushi:"]}, "bento":{"icon":"\ud83c\udf71", "keystrokes":[":bento:"]}, "curry":{"icon":"\ud83c\udf5b", "keystrokes":[":curry:"]}, "rice ball":{"icon":"\ud83c\udf59", 
  "keystrokes":[":rice_ball:", ":riceball:"]}, "rice":{"icon":"\ud83c\udf5a", "keystrokes":[":rice:"]}, "rice cracker":{"icon":"\ud83c\udf58", "keystrokes":[":rice_cracker:", ":ricecracker:"]}, "oden":{"icon":"\ud83c\udf62", "keystrokes":[":oden:"]}, "dango":{"icon":"\ud83c\udf61", "keystrokes":[":dango:"]}, "shaved ice":{"icon":"\ud83c\udf67", "keystrokes":[":shaved_ice:", ":shavedice:"]}, "ice cream":{"icon":"\ud83c\udf68", "keystrokes":[":ice_cream:", ":icecream:"]}, "icecream":{"icon":"\ud83c\udf66", 
  "keystrokes":[":icecream:"]}, "cake":{"icon":"\ud83c\udf70", "keystrokes":[":cake:"]}, "birthday":{"icon":"\ud83c\udf82", "keystrokes":[":birthday:"]}, "custard":{"icon":"\ud83c\udf6e", "keystrokes":[":custard:"]}, "candy":{"icon":"\ud83c\udf6c", "keystrokes":[":candy:"]}, "lollipop":{"icon":"\ud83c\udf6d", "keystrokes":[":lollipop:"]}, "chocolate bar":{"icon":"\ud83c\udf6b", "keystrokes":[":chocolate_bar:", ":chocolatebar:"]}, "popcorn":{"icon":"\ud83c\udf7f", "keystrokes":[":popcorn:"]}, "doughnut":{"icon":"\ud83c\udf69", 
  "keystrokes":[":doughnut:"]}, "cookie":{"icon":"\ud83c\udf6a", "keystrokes":[":cookie:"]}, "milk glass":{"icon":"\ud83e\udd5b", "keystrokes":[":milk_glass:", ":milkglass:"]}, "beer":{"icon":"\ud83c\udf7a", "keystrokes":[":beer:"]}, "beers":{"icon":"\ud83c\udf7b", "keystrokes":[":beers:"]}, "clinking glasses":{"icon":"\ud83e\udd42", "keystrokes":[":clinking_glasses:", ":clinkingglasses:"]}, "wine glass":{"icon":"\ud83c\udf77", "keystrokes":[":wine_glass:", ":wineglass:"]}, "tumbler glass":{"icon":"\ud83e\udd43", 
  "keystrokes":[":tumbler_glass:", ":tumblerglass:"]}, "cocktail":{"icon":"\ud83c\udf78", "keystrokes":[":cocktail:"]}, "tropical drink":{"icon":"\ud83c\udf79", "keystrokes":[":tropical_drink:", ":tropicaldrink:"]}, "champagne":{"icon":"\ud83c\udf7e", "keystrokes":[":champagne:"]}, "sake":{"icon":"\ud83c\udf76", "keystrokes":[":sake:"]}, "tea":{"icon":"\ud83c\udf75", "keystrokes":[":tea:"]}, "coffee":{"icon":"\u2615", "keystrokes":[":coffee:"]}, "baby bottle":{"icon":"\ud83c\udf7c", "keystrokes":[":baby_bottle:", 
  ":babybottle:"]}, "spoon":{"icon":"\ud83e\udd44", "keystrokes":[":spoon:"]}, "fork and knife":{"icon":"\ud83c\udf74", "keystrokes":[":fork_and_knife:", ":forkandknife:"]}, "plate with cutlery":{"icon":"\ud83c\udf7d", "keystrokes":[":plate_with_cutlery:", ":platewithcutlery:"]}, "soccer":{"icon":"\u26bd", "keystrokes":[":soccer:"]}, "basketball":{"icon":"\ud83c\udfc0", "keystrokes":[":basketball:"]}, "football":{"icon":"\ud83c\udfc8", "keystrokes":[":football:"]}, "baseball":{"icon":"\u26be", "keystrokes":[":baseball:"]}, 
  "tennis":{"icon":"\ud83c\udfbe", "keystrokes":[":tennis:"]}, "volleyball":{"icon":"\ud83c\udfd0", "keystrokes":[":volleyball:"]}, "rugby football":{"icon":"\ud83c\udfc9", "keystrokes":[":rugby_football:", ":rugbyfootball:"]}, "8ball":{"icon":"\ud83c\udfb1", "keystrokes":[":8ball:"]}, "golf":{"icon":"\u26f3", "keystrokes":[":golf:"]}, "golfing woman":{"icon":"\ud83c\udfcc\ufe0f\u200d\u2640\ufe0f", "keystrokes":[":golfing_woman:", ":golfingwoman:"]}, "golfing man":{"icon":"\ud83c\udfcc", "keystrokes":[":golfing_man:", 
  ":golfingman:"]}, "ping pong":{"icon":"\ud83c\udfd3", "keystrokes":[":ping_pong:", ":pingpong:"]}, "badminton":{"icon":"\ud83c\udff8", "keystrokes":[":badminton:"]}, "goal net":{"icon":"\ud83e\udd45", "keystrokes":[":goal_net:", ":goalnet:"]}, "ice hockey":{"icon":"\ud83c\udfd2", "keystrokes":[":ice_hockey:", ":icehockey:"]}, "field hockey":{"icon":"\ud83c\udfd1", "keystrokes":[":field_hockey:", ":fieldhockey:"]}, "cricket":{"icon":"\ud83c\udfcf", "keystrokes":[":cricket:"]}, "ski":{"icon":"\ud83c\udfbf", 
  "keystrokes":[":ski:"]}, "skier":{"icon":"\u26f7", "keystrokes":[":skier:"]}, "snowboarder":{"icon":"\ud83c\udfc2", "keystrokes":[":snowboarder:"]}, "person fencing":{"icon":"\ud83e\udd3a", "keystrokes":[":person_fencing:", ":personfencing:"]}, "women wrestling":{"icon":"\ud83e\udd3c\u200d\u2640\ufe0f", "keystrokes":[":women_wrestling:", ":womenwrestling:"]}, "men wrestling":{"icon":"\ud83e\udd3c\u200d\u2642\ufe0f", "keystrokes":[":men_wrestling:", ":menwrestling:"]}, "woman cartwheeling":{"icon":"\ud83e\udd38\u200d\u2640\ufe0f", 
  "keystrokes":[":woman_cartwheeling:", ":womancartwheeling:"]}, "man cartwheeling":{"icon":"\ud83e\udd38\u200d\u2642\ufe0f", "keystrokes":[":man_cartwheeling:", ":mancartwheeling:"]}, "woman playing handball":{"icon":"\ud83e\udd3e\u200d\u2640\ufe0f", "keystrokes":[":woman_playing_handball:", ":womanplayinghandball:"]}, "man playing handball":{"icon":"\ud83e\udd3e\u200d\u2642\ufe0f", "keystrokes":[":man_playing_handball:", ":manplayinghandball:"]}, "ice skate":{"icon":"\u26f8", "keystrokes":[":ice_skate:", 
  ":iceskate:"]}, "bow and arrow":{"icon":"\ud83c\udff9", "keystrokes":[":bow_and_arrow:", ":bowandarrow:"]}, "fishing pole and fish":{"icon":"\ud83c\udfa3", "keystrokes":[":fishing_pole_and_fish:", ":fishingpoleandfish:"]}, "boxing glove":{"icon":"\ud83e\udd4a", "keystrokes":[":boxing_glove:", ":boxingglove:"]}, "martial arts uniform":{"icon":"\ud83e\udd4b", "keystrokes":[":martial_arts_uniform:", ":martialartsuniform:"]}, "rowing woman":{"icon":"\ud83d\udea3\u200d\u2640\ufe0f", "keystrokes":[":rowing_woman:", 
  ":rowingwoman:"]}, "rowing man":{"icon":"\ud83d\udea3", "keystrokes":[":rowing_man:", ":rowingman:"]}, "swimming woman":{"icon":"\ud83c\udfca\u200d\u2640\ufe0f", "keystrokes":[":swimming_woman:", ":swimmingwoman:"]}, "swimming man":{"icon":"\ud83c\udfca", "keystrokes":[":swimming_man:", ":swimmingman:"]}, "woman playing water polo":{"icon":"\ud83e\udd3d\u200d\u2640\ufe0f", "keystrokes":[":woman_playing_water_polo:", ":womanplayingwaterpolo:"]}, "man playing water polo":{"icon":"\ud83e\udd3d\u200d\u2642\ufe0f", 
  "keystrokes":[":man_playing_water_polo:", ":manplayingwaterpolo:"]}, "surfing woman":{"icon":"\ud83c\udfc4\u200d\u2640\ufe0f", "keystrokes":[":surfing_woman:", ":surfingwoman:"]}, "surfing man":{"icon":"\ud83c\udfc4", "keystrokes":[":surfing_man:", ":surfingman:"]}, "bath":{"icon":"\ud83d\udec0", "keystrokes":[":bath:"]}, "basketball woman":{"icon":"\u26f9\ufe0f\u200d\u2640\ufe0f", "keystrokes":[":basketball_woman:", ":basketballwoman:"]}, "basketball man":{"icon":"\u26f9", "keystrokes":[":basketball_man:", 
  ":basketballman:"]}, "weight lifting woman":{"icon":"\ud83c\udfcb\ufe0f\u200d\u2640\ufe0f", "keystrokes":[":weight_lifting_woman:", ":weightliftingwoman:"]}, "weight lifting man":{"icon":"\ud83c\udfcb", "keystrokes":[":weight_lifting_man:", ":weightliftingman:"]}, "biking woman":{"icon":"\ud83d\udeb4\u200d\u2640\ufe0f", "keystrokes":[":biking_woman:", ":bikingwoman:"]}, "biking man":{"icon":"\ud83d\udeb4", "keystrokes":[":biking_man:", ":bikingman:"]}, "mountain biking woman":{"icon":"\ud83d\udeb5\u200d\u2640\ufe0f", 
  "keystrokes":[":mountain_biking_woman:", ":mountainbikingwoman:"]}, "mountain biking man":{"icon":"\ud83d\udeb5", "keystrokes":[":mountain_biking_man:", ":mountainbikingman:"]}, "horse racing":{"icon":"\ud83c\udfc7", "keystrokes":[":horse_racing:", ":horseracing:"]}, "business suit levitating":{"icon":"\ud83d\udd74", "keystrokes":[":business_suit_levitating:", ":businesssuitlevitating:"]}, "trophy":{"icon":"\ud83c\udfc6", "keystrokes":[":trophy:"]}, "running shirt with sash":{"icon":"\ud83c\udfbd", 
  "keystrokes":[":running_shirt_with_sash:", ":runningshirtwithsash:"]}, "medal sports":{"icon":"\ud83c\udfc5", "keystrokes":[":medal_sports:", ":medalsports:"]}, "medal military":{"icon":"\ud83c\udf96", "keystrokes":[":medal_military:", ":medalmilitary:"]}, "1st place medal":{"icon":"\ud83e\udd47", "keystrokes":[":1st_place_medal:", ":1stplacemedal:"]}, "2nd place medal":{"icon":"\ud83e\udd48", "keystrokes":[":2nd_place_medal:", ":2ndplacemedal:"]}, "3rd place medal":{"icon":"\ud83e\udd49", "keystrokes":[":3rd_place_medal:", 
  ":3rdplacemedal:"]}, "reminder ribbon":{"icon":"\ud83c\udf97", "keystrokes":[":reminder_ribbon:", ":reminderribbon:"]}, "rosette":{"icon":"\ud83c\udff5", "keystrokes":[":rosette:"]}, "ticket":{"icon":"\ud83c\udfab", "keystrokes":[":ticket:"]}, "tickets":{"icon":"\ud83c\udf9f", "keystrokes":[":tickets:"]}, "performing arts":{"icon":"\ud83c\udfad", "keystrokes":[":performing_arts:", ":performingarts:"]}, "art":{"icon":"\ud83c\udfa8", "keystrokes":[":art:"]}, "circus tent":{"icon":"\ud83c\udfaa", 
  "keystrokes":[":circus_tent:", ":circustent:"]}, "woman juggling":{"icon":"\ud83e\udd39\u200d\u2640\ufe0f", "keystrokes":[":woman_juggling:", ":womanjuggling:"]}, "man juggling":{"icon":"\ud83e\udd39\u200d\u2642\ufe0f", "keystrokes":[":man_juggling:", ":manjuggling:"]}, "microphone":{"icon":"\ud83c\udfa4", "keystrokes":[":microphone:"]}, "headphones":{"icon":"\ud83c\udfa7", "keystrokes":[":headphones:"]}, "musical score":{"icon":"\ud83c\udfbc", "keystrokes":[":musical_score:", ":musicalscore:"]}, 
  "musical keyboard":{"icon":"\ud83c\udfb9", "keystrokes":[":musical_keyboard:", ":musicalkeyboard:"]}, "drum":{"icon":"\ud83e\udd41", "keystrokes":[":drum:"]}, "saxophone":{"icon":"\ud83c\udfb7", "keystrokes":[":saxophone:"]}, "trumpet":{"icon":"\ud83c\udfba", "keystrokes":[":trumpet:"]}, "guitar":{"icon":"\ud83c\udfb8", "keystrokes":[":guitar:"]}, "violin":{"icon":"\ud83c\udfbb", "keystrokes":[":violin:"]}, "clapper":{"icon":"\ud83c\udfac", "keystrokes":[":clapper:"]}, "video game":{"icon":"\ud83c\udfae", 
  "keystrokes":[":video_game:", ":videogame:"]}, "space invader":{"icon":"\ud83d\udc7e", "keystrokes":[":space_invader:", ":spaceinvader:"]}, "dart":{"icon":"\ud83c\udfaf", "keystrokes":[":dart:"]}, "game die":{"icon":"\ud83c\udfb2", "keystrokes":[":game_die:", ":gamedie:"]}, "slot machine":{"icon":"\ud83c\udfb0", "keystrokes":[":slot_machine:", ":slotmachine:"]}, "bowling":{"icon":"\ud83c\udfb3", "keystrokes":[":bowling:"]}, "red car":{"icon":"\ud83d\ude97", "keystrokes":[":red_car:", ":redcar:"]}, 
  "taxi":{"icon":"\ud83d\ude95", "keystrokes":[":taxi:"]}, "blue car":{"icon":"\ud83d\ude99", "keystrokes":[":blue_car:", ":bluecar:"]}, "bus":{"icon":"\ud83d\ude8c", "keystrokes":[":bus:"]}, "trolleybus":{"icon":"\ud83d\ude8e", "keystrokes":[":trolleybus:"]}, "racing car":{"icon":"\ud83c\udfce", "keystrokes":[":racing_car:", ":racingcar:"]}, "police car":{"icon":"\ud83d\ude93", "keystrokes":[":police_car:", ":policecar:"]}, "ambulance":{"icon":"\ud83d\ude91", "keystrokes":[":ambulance:"]}, "fire engine":{"icon":"\ud83d\ude92", 
  "keystrokes":[":fire_engine:", ":fireengine:"]}, "minibus":{"icon":"\ud83d\ude90", "keystrokes":[":minibus:"]}, "truck":{"icon":"\ud83d\ude9a", "keystrokes":[":truck:"]}, "articulated lorry":{"icon":"\ud83d\ude9b", "keystrokes":[":articulated_lorry:", ":articulatedlorry:"]}, "tractor":{"icon":"\ud83d\ude9c", "keystrokes":[":tractor:"]}, "kick scooter":{"icon":"\ud83d\udef4", "keystrokes":[":kick_scooter:", ":kickscooter:"]}, "motorcycle":{"icon":"\ud83c\udfcd", "keystrokes":[":motorcycle:"]}, "bike":{"icon":"\ud83d\udeb2", 
  "keystrokes":[":bike:"]}, "motor scooter":{"icon":"\ud83d\udef5", "keystrokes":[":motor_scooter:", ":motorscooter:"]}, "rotating light":{"icon":"\ud83d\udea8", "keystrokes":[":rotating_light:", ":rotatinglight:"]}, "oncoming police car":{"icon":"\ud83d\ude94", "keystrokes":[":oncoming_police_car:", ":oncomingpolicecar:"]}, "oncoming bus":{"icon":"\ud83d\ude8d", "keystrokes":[":oncoming_bus:", ":oncomingbus:"]}, "oncoming automobile":{"icon":"\ud83d\ude98", "keystrokes":[":oncoming_automobile:", 
  ":oncomingautomobile:"]}, "oncoming taxi":{"icon":"\ud83d\ude96", "keystrokes":[":oncoming_taxi:", ":oncomingtaxi:"]}, "aerial tramway":{"icon":"\ud83d\udea1", "keystrokes":[":aerial_tramway:", ":aerialtramway:"]}, "mountain cableway":{"icon":"\ud83d\udea0", "keystrokes":[":mountain_cableway:", ":mountaincableway:"]}, "suspension railway":{"icon":"\ud83d\ude9f", "keystrokes":[":suspension_railway:", ":suspensionrailway:"]}, "railway car":{"icon":"\ud83d\ude83", "keystrokes":[":railway_car:", ":railwaycar:"]}, 
  "train":{"icon":"\ud83d\ude8b", "keystrokes":[":train:"]}, "monorail":{"icon":"\ud83d\ude9d", "keystrokes":[":monorail:"]}, "bullettrain side":{"icon":"\ud83d\ude84", "keystrokes":[":bullettrain_side:", ":bullettrainside:"]}, "bullettrain front":{"icon":"\ud83d\ude85", "keystrokes":[":bullettrain_front:", ":bullettrainfront:"]}, "light rail":{"icon":"\ud83d\ude88", "keystrokes":[":light_rail:", ":lightrail:"]}, "mountain railway":{"icon":"\ud83d\ude9e", "keystrokes":[":mountain_railway:", ":mountainrailway:"]}, 
  "steam locomotive":{"icon":"\ud83d\ude82", "keystrokes":[":steam_locomotive:", ":steamlocomotive:"]}, "train2":{"icon":"\ud83d\ude86", "keystrokes":[":train2:"]}, "metro":{"icon":"\ud83d\ude87", "keystrokes":[":metro:"]}, "tram":{"icon":"\ud83d\ude8a", "keystrokes":[":tram:"]}, "station":{"icon":"\ud83d\ude89", "keystrokes":[":station:"]}, "helicopter":{"icon":"\ud83d\ude81", "keystrokes":[":helicopter:"]}, "small airplane":{"icon":"\ud83d\udee9", "keystrokes":[":small_airplane:", ":smallairplane:"]}, 
  "airplane":{"icon":"\u2708\ufe0f", "keystrokes":[":airplane:"]}, "flight departure":{"icon":"\ud83d\udeeb", "keystrokes":[":flight_departure:", ":flightdeparture:"]}, "flight arrival":{"icon":"\ud83d\udeec", "keystrokes":[":flight_arrival:", ":flightarrival:"]}, "sailboat":{"icon":"\u26f5", "keystrokes":[":sailboat:"]}, "motor boat":{"icon":"\ud83d\udee5", "keystrokes":[":motor_boat:", ":motorboat:"]}, "speedboat":{"icon":"\ud83d\udea4", "keystrokes":[":speedboat:"]}, "ferry":{"icon":"\u26f4", 
  "keystrokes":[":ferry:"]}, "passenger ship":{"icon":"\ud83d\udef3", "keystrokes":[":passenger_ship:", ":passengership:"]}, "rocket":{"icon":"\ud83d\ude80", "keystrokes":[":rocket:"]}, "artificial satellite":{"icon":"\ud83d\udef0", "keystrokes":[":artificial_satellite:", ":artificialsatellite:"]}, "seat":{"icon":"\ud83d\udcba", "keystrokes":[":seat:"]}, "canoe":{"icon":"\ud83d\udef6", "keystrokes":[":canoe:"]}, "anchor":{"icon":"\u2693", "keystrokes":[":anchor:"]}, "construction":{"icon":"\ud83d\udea7", 
  "keystrokes":[":construction:"]}, "fuelpump":{"icon":"\u26fd", "keystrokes":[":fuelpump:"]}, "busstop":{"icon":"\ud83d\ude8f", "keystrokes":[":busstop:"]}, "vertical traffic light":{"icon":"\ud83d\udea6", "keystrokes":[":vertical_traffic_light:", ":verticaltrafficlight:"]}, "traffic light":{"icon":"\ud83d\udea5", "keystrokes":[":traffic_light:", ":trafficlight:"]}, "checkered flag":{"icon":"\ud83c\udfc1", "keystrokes":[":checkered_flag:", ":checkeredflag:"]}, "ship":{"icon":"\ud83d\udea2", "keystrokes":[":ship:"]}, 
  "ferris wheel":{"icon":"\ud83c\udfa1", "keystrokes":[":ferris_wheel:", ":ferriswheel:"]}, "roller coaster":{"icon":"\ud83c\udfa2", "keystrokes":[":roller_coaster:", ":rollercoaster:"]}, "carousel horse":{"icon":"\ud83c\udfa0", "keystrokes":[":carousel_horse:", ":carouselhorse:"]}, "building construction":{"icon":"\ud83c\udfd7", "keystrokes":[":building_construction:", ":buildingconstruction:"]}, "foggy":{"icon":"\ud83c\udf01", "keystrokes":[":foggy:"]}, "tokyo tower":{"icon":"\ud83d\uddfc", "keystrokes":[":tokyo_tower:", 
  ":tokyotower:"]}, "factory":{"icon":"\ud83c\udfed", "keystrokes":[":factory:"]}, "fountain":{"icon":"\u26f2", "keystrokes":[":fountain:"]}, "rice scene":{"icon":"\ud83c\udf91", "keystrokes":[":rice_scene:", ":ricescene:"]}, "mountain":{"icon":"\u26f0", "keystrokes":[":mountain:"]}, "mountain snow":{"icon":"\ud83c\udfd4", "keystrokes":[":mountain_snow:", ":mountainsnow:"]}, "mount fuji":{"icon":"\ud83d\uddfb", "keystrokes":[":mount_fuji:", ":mountfuji:"]}, "volcano":{"icon":"\ud83c\udf0b", "keystrokes":[":volcano:"]}, 
  "japan":{"icon":"\ud83d\uddfe", "keystrokes":[":japan:"]}, "camping":{"icon":"\ud83c\udfd5", "keystrokes":[":camping:"]}, "tent":{"icon":"\u26fa", "keystrokes":[":tent:"]}, "national park":{"icon":"\ud83c\udfde", "keystrokes":[":national_park:", ":nationalpark:"]}, "motorway":{"icon":"\ud83d\udee3", "keystrokes":[":motorway:"]}, "railway track":{"icon":"\ud83d\udee4", "keystrokes":[":railway_track:", ":railwaytrack:"]}, "sunrise":{"icon":"\ud83c\udf05", "keystrokes":[":sunrise:"]}, "sunrise over mountains":{"icon":"\ud83c\udf04", 
  "keystrokes":[":sunrise_over_mountains:", ":sunriseovermountains:"]}, "desert":{"icon":"\ud83c\udfdc", "keystrokes":[":desert:"]}, "beach umbrella":{"icon":"\ud83c\udfd6", "keystrokes":[":beach_umbrella:", ":beachumbrella:"]}, "desert island":{"icon":"\ud83c\udfdd", "keystrokes":[":desert_island:", ":desertisland:"]}, "city sunrise":{"icon":"\ud83c\udf07", "keystrokes":[":city_sunrise:", ":citysunrise:"]}, "city sunset":{"icon":"\ud83c\udf06", "keystrokes":[":city_sunset:", ":citysunset:"]}, "cityscape":{"icon":"\ud83c\udfd9", 
  "keystrokes":[":cityscape:"]}, "night with stars":{"icon":"\ud83c\udf03", "keystrokes":[":night_with_stars:", ":nightwithstars:"]}, "bridge at night":{"icon":"\ud83c\udf09", "keystrokes":[":bridge_at_night:", ":bridgeatnight:"]}, "milky way":{"icon":"\ud83c\udf0c", "keystrokes":[":milky_way:", ":milkyway:"]}, "stars":{"icon":"\ud83c\udf20", "keystrokes":[":stars:"]}, "sparkler":{"icon":"\ud83c\udf87", "keystrokes":[":sparkler:"]}, "fireworks":{"icon":"\ud83c\udf86", "keystrokes":[":fireworks:"]}, 
  "rainbow":{"icon":"\ud83c\udf08", "keystrokes":[":rainbow:"]}, "houses":{"icon":"\ud83c\udfd8", "keystrokes":[":houses:"]}, "european castle":{"icon":"\ud83c\udff0", "keystrokes":[":european_castle:", ":europeancastle:"]}, "japanese castle":{"icon":"\ud83c\udfef", "keystrokes":[":japanese_castle:", ":japanesecastle:"]}, "stadium":{"icon":"\ud83c\udfdf", "keystrokes":[":stadium:"]}, "statue of liberty":{"icon":"\ud83d\uddfd", "keystrokes":[":statue_of_liberty:", ":statueofliberty:"]}, "house":{"icon":"\ud83c\udfe0", 
  "keystrokes":[":house:"]}, "house with garden":{"icon":"\ud83c\udfe1", "keystrokes":[":house_with_garden:", ":housewithgarden:"]}, "derelict house":{"icon":"\ud83c\udfda", "keystrokes":[":derelict_house:", ":derelicthouse:"]}, "office":{"icon":"\ud83c\udfe2", "keystrokes":[":office:"]}, "department store":{"icon":"\ud83c\udfec", "keystrokes":[":department_store:", ":departmentstore:"]}, "post office":{"icon":"\ud83c\udfe3", "keystrokes":[":post_office:", ":postoffice:"]}, "european post office":{"icon":"\ud83c\udfe4", 
  "keystrokes":[":european_post_office:", ":europeanpostoffice:"]}, "hospital":{"icon":"\ud83c\udfe5", "keystrokes":[":hospital:"]}, "bank":{"icon":"\ud83c\udfe6", "keystrokes":[":bank:"]}, "hotel":{"icon":"\ud83c\udfe8", "keystrokes":[":hotel:"]}, "convenience store":{"icon":"\ud83c\udfea", "keystrokes":[":convenience_store:", ":conveniencestore:"]}, "school":{"icon":"\ud83c\udfeb", "keystrokes":[":school:"]}, "love hotel":{"icon":"\ud83c\udfe9", "keystrokes":[":love_hotel:", ":lovehotel:"]}, "wedding":{"icon":"\ud83d\udc92", 
  "keystrokes":[":wedding:"]}, "classical building":{"icon":"\ud83c\udfdb", "keystrokes":[":classical_building:", ":classicalbuilding:"]}, "church":{"icon":"\u26ea", "keystrokes":[":church:"]}, "mosque":{"icon":"\ud83d\udd4c", "keystrokes":[":mosque:"]}, "synagogue":{"icon":"\ud83d\udd4d", "keystrokes":[":synagogue:"]}, "kaaba":{"icon":"\ud83d\udd4b", "keystrokes":[":kaaba:"]}, "shinto shrine":{"icon":"\u26e9", "keystrokes":[":shinto_shrine:", ":shintoshrine:"]}, "watch":{"icon":"\u231a", "keystrokes":[":watch:"]}, 
  "iphone":{"icon":"\ud83d\udcf1", "keystrokes":[":iphone:"]}, "calling":{"icon":"\ud83d\udcf2", "keystrokes":[":calling:"]}, "computer":{"icon":"\ud83d\udcbb", "keystrokes":[":computer:"]}, "keyboard":{"icon":"\u2328", "keystrokes":[":keyboard:"]}, "desktop computer":{"icon":"\ud83d\udda5", "keystrokes":[":desktop_computer:", ":desktopcomputer:"]}, "printer":{"icon":"\ud83d\udda8", "keystrokes":[":printer:"]}, "computer mouse":{"icon":"\ud83d\uddb1", "keystrokes":[":computer_mouse:", ":computermouse:"]}, 
  "trackball":{"icon":"\ud83d\uddb2", "keystrokes":[":trackball:"]}, "joystick":{"icon":"\ud83d\udd79", "keystrokes":[":joystick:"]}, "clamp":{"icon":"\ud83d\udddc", "keystrokes":[":clamp:"]}, "minidisc":{"icon":"\ud83d\udcbd", "keystrokes":[":minidisc:"]}, "floppy disk":{"icon":"\ud83d\udcbe", "keystrokes":[":floppy_disk:", ":floppydisk:"]}, "cd":{"icon":"\ud83d\udcbf", "keystrokes":[":cd:"]}, "dvd":{"icon":"\ud83d\udcc0", "keystrokes":[":dvd:"]}, "vhs":{"icon":"\ud83d\udcfc", "keystrokes":[":vhs:"]}, 
  "camera":{"icon":"\ud83d\udcf7", "keystrokes":[":camera:"]}, "camera flash":{"icon":"\ud83d\udcf8", "keystrokes":[":camera_flash:", ":cameraflash:"]}, "video camera":{"icon":"\ud83d\udcf9", "keystrokes":[":video_camera:", ":videocamera:"]}, "movie camera":{"icon":"\ud83c\udfa5", "keystrokes":[":movie_camera:", ":moviecamera:"]}, "film projector":{"icon":"\ud83d\udcfd", "keystrokes":[":film_projector:", ":filmprojector:"]}, "film strip":{"icon":"\ud83c\udf9e", "keystrokes":[":film_strip:", ":filmstrip:"]}, 
  "telephone receiver":{"icon":"\ud83d\udcde", "keystrokes":[":telephone_receiver:", ":telephonereceiver:"]}, "phone":{"icon":"\u260e\ufe0f", "keystrokes":[":phone:"]}, "pager":{"icon":"\ud83d\udcdf", "keystrokes":[":pager:"]}, "fax":{"icon":"\ud83d\udce0", "keystrokes":[":fax:"]}, "tv":{"icon":"\ud83d\udcfa", "keystrokes":[":tv:"]}, "radio":{"icon":"\ud83d\udcfb", "keystrokes":[":radio:"]}, "studio microphone":{"icon":"\ud83c\udf99", "keystrokes":[":studio_microphone:", ":studiomicrophone:"]}, "level slider":{"icon":"\ud83c\udf9a", 
  "keystrokes":[":level_slider:", ":levelslider:"]}, "control knobs":{"icon":"\ud83c\udf9b", "keystrokes":[":control_knobs:", ":controlknobs:"]}, "stopwatch":{"icon":"\u23f1", "keystrokes":[":stopwatch:"]}, "timer clock":{"icon":"\u23f2", "keystrokes":[":timer_clock:", ":timerclock:"]}, "alarm clock":{"icon":"\u23f0", "keystrokes":[":alarm_clock:", ":alarmclock:"]}, "mantelpiece clock":{"icon":"\ud83d\udd70", "keystrokes":[":mantelpiece_clock:", ":mantelpiececlock:"]}, "hourglass flowing sand":{"icon":"\u23f3", 
  "keystrokes":[":hourglass_flowing_sand:", ":hourglassflowingsand:"]}, "hourglass":{"icon":"\u231b", "keystrokes":[":hourglass:"]}, "satellite":{"icon":"\ud83d\udce1", "keystrokes":[":satellite:"]}, "battery":{"icon":"\ud83d\udd0b", "keystrokes":[":battery:"]}, "electric plug":{"icon":"\ud83d\udd0c", "keystrokes":[":electric_plug:", ":electricplug:"]}, "bulb":{"icon":"\ud83d\udca1", "keystrokes":[":bulb:"]}, "flashlight":{"icon":"\ud83d\udd26", "keystrokes":[":flashlight:"]}, "candle":{"icon":"\ud83d\udd6f", 
  "keystrokes":[":candle:"]}, "wastebasket":{"icon":"\ud83d\uddd1", "keystrokes":[":wastebasket:"]}, "oil drum":{"icon":"\ud83d\udee2", "keystrokes":[":oil_drum:", ":oildrum:"]}, "money with wings":{"icon":"\ud83d\udcb8", "keystrokes":[":money_with_wings:", ":moneywithwings:"]}, "dollar":{"icon":"\ud83d\udcb5", "keystrokes":[":dollar:"]}, "yen":{"icon":"\ud83d\udcb4", "keystrokes":[":yen:"]}, "euro":{"icon":"\ud83d\udcb6", "keystrokes":[":euro:"]}, "pound":{"icon":"\ud83d\udcb7", "keystrokes":[":pound:"]}, 
  "moneybag":{"icon":"\ud83d\udcb0", "keystrokes":[":moneybag:"]}, "credit card":{"icon":"\ud83d\udcb3", "keystrokes":[":credit_card:", ":creditcard:"]}, "gem":{"icon":"\ud83d\udc8e", "keystrokes":[":gem:"]}, "balance scale":{"icon":"\u2696", "keystrokes":[":balance_scale:", ":balancescale:"]}, "wrench":{"icon":"\ud83d\udd27", "keystrokes":[":wrench:"]}, "hammer":{"icon":"\ud83d\udd28", "keystrokes":[":hammer:"]}, "hammer and pick":{"icon":"\u2692", "keystrokes":[":hammer_and_pick:", ":hammerandpick:"]}, 
  "hammer and wrench":{"icon":"\ud83d\udee0", "keystrokes":[":hammer_and_wrench:", ":hammerandwrench:"]}, "pick":{"icon":"\u26cf", "keystrokes":[":pick:"]}, "nut and bolt":{"icon":"\ud83d\udd29", "keystrokes":[":nut_and_bolt:", ":nutandbolt:"]}, "gear":{"icon":"\u2699", "keystrokes":[":gear:"]}, "chains":{"icon":"\u26d3", "keystrokes":[":chains:"]}, "gun":{"icon":"\ud83d\udd2b", "keystrokes":[":gun:"]}, "bomb":{"icon":"\ud83d\udca3", "keystrokes":[":bomb:"]}, "hocho":{"icon":"\ud83d\udd2a", "keystrokes":[":hocho:"]}, 
  "dagger":{"icon":"\ud83d\udde1", "keystrokes":[":dagger:"]}, "crossed swords":{"icon":"\u2694", "keystrokes":[":crossed_swords:", ":crossedswords:"]}, "shield":{"icon":"\ud83d\udee1", "keystrokes":[":shield:"]}, "smoking":{"icon":"\ud83d\udeac", "keystrokes":[":smoking:"]}, "skull and crossbones":{"icon":"\u2620", "keystrokes":[":skull_and_crossbones:", ":skullandcrossbones:"]}, "coffin":{"icon":"\u26b0", "keystrokes":[":coffin:"]}, "funeral urn":{"icon":"\u26b1", "keystrokes":[":funeral_urn:", 
  ":funeralurn:"]}, "amphora":{"icon":"\ud83c\udffa", "keystrokes":[":amphora:"]}, "crystal ball":{"icon":"\ud83d\udd2e", "keystrokes":[":crystal_ball:", ":crystalball:"]}, "prayer beads":{"icon":"\ud83d\udcff", "keystrokes":[":prayer_beads:", ":prayerbeads:"]}, "barber":{"icon":"\ud83d\udc88", "keystrokes":[":barber:"]}, "alembic":{"icon":"\u2697", "keystrokes":[":alembic:"]}, "telescope":{"icon":"\ud83d\udd2d", "keystrokes":[":telescope:"]}, "microscope":{"icon":"\ud83d\udd2c", "keystrokes":[":microscope:"]}, 
  "hole":{"icon":"\ud83d\udd73", "keystrokes":[":hole:"]}, "pill":{"icon":"\ud83d\udc8a", "keystrokes":[":pill:"]}, "syringe":{"icon":"\ud83d\udc89", "keystrokes":[":syringe:"]}, "thermometer":{"icon":"\ud83c\udf21", "keystrokes":[":thermometer:"]}, "label":{"icon":"\ud83c\udff7", "keystrokes":[":label:"]}, "bookmark":{"icon":"\ud83d\udd16", "keystrokes":[":bookmark:"]}, "toilet":{"icon":"\ud83d\udebd", "keystrokes":[":toilet:"]}, "shower":{"icon":"\ud83d\udebf", "keystrokes":[":shower:"]}, "bathtub":{"icon":"\ud83d\udec1", 
  "keystrokes":[":bathtub:"]}, "key":{"icon":"\ud83d\udd11", "keystrokes":[":key:"]}, "old key":{"icon":"\ud83d\udddd", "keystrokes":[":old_key:", ":oldkey:"]}, "couch and lamp":{"icon":"\ud83d\udecb", "keystrokes":[":couch_and_lamp:", ":couchandlamp:"]}, "sleeping bed":{"icon":"\ud83d\udecc", "keystrokes":[":sleeping_bed:", ":sleepingbed:"]}, "bed":{"icon":"\ud83d\udecf", "keystrokes":[":bed:"]}, "door":{"icon":"\ud83d\udeaa", "keystrokes":[":door:"]}, "bellhop bell":{"icon":"\ud83d\udece", "keystrokes":[":bellhop_bell:", 
  ":bellhopbell:"]}, "framed picture":{"icon":"\ud83d\uddbc", "keystrokes":[":framed_picture:", ":framedpicture:"]}, "world map":{"icon":"\ud83d\uddfa", "keystrokes":[":world_map:", ":worldmap:"]}, "parasol on ground":{"icon":"\u26f1", "keystrokes":[":parasol_on_ground:", ":parasolonground:"]}, "moyai":{"icon":"\ud83d\uddff", "keystrokes":[":moyai:"]}, "shopping":{"icon":"\ud83d\udecd", "keystrokes":[":shopping:"]}, "shopping cart":{"icon":"\ud83d\uded2", "keystrokes":[":shopping_cart:", ":shoppingcart:"]}, 
  "balloon":{"icon":"\ud83c\udf88", "keystrokes":[":balloon:"]}, "flags":{"icon":"\ud83c\udf8f", "keystrokes":[":flags:"]}, "ribbon":{"icon":"\ud83c\udf80", "keystrokes":[":ribbon:"]}, "gift":{"icon":"\ud83c\udf81", "keystrokes":[":gift:"]}, "confetti ball":{"icon":"\ud83c\udf8a", "keystrokes":[":confetti_ball:", ":confettiball:"]}, "tada":{"icon":"\ud83c\udf89", "keystrokes":[":tada:"]}, "dolls":{"icon":"\ud83c\udf8e", "keystrokes":[":dolls:"]}, "wind chime":{"icon":"\ud83c\udf90", "keystrokes":[":wind_chime:", 
  ":windchime:"]}, "crossed flags":{"icon":"\ud83c\udf8c", "keystrokes":[":crossed_flags:", ":crossedflags:"]}, "izakaya lantern":{"icon":"\ud83c\udfee", "keystrokes":[":izakaya_lantern:", ":izakayalantern:"]}, "email":{"icon":"\u2709\ufe0f", "keystrokes":[":email:"]}, "envelope with arrow":{"icon":"\ud83d\udce9", "keystrokes":[":envelope_with_arrow:", ":envelopewitharrow:"]}, "incoming envelope":{"icon":"\ud83d\udce8", "keystrokes":[":incoming_envelope:", ":incomingenvelope:"]}, "e-mail":{"icon":"\ud83d\udce7", 
  "keystrokes":[":e-mail:"]}, "love letter":{"icon":"\ud83d\udc8c", "keystrokes":[":love_letter:", ":loveletter:"]}, "postbox":{"icon":"\ud83d\udcee", "keystrokes":[":postbox:"]}, "mailbox closed":{"icon":"\ud83d\udcea", "keystrokes":[":mailbox_closed:", ":mailboxclosed:"]}, "mailbox":{"icon":"\ud83d\udceb", "keystrokes":[":mailbox:"]}, "mailbox with mail":{"icon":"\ud83d\udcec", "keystrokes":[":mailbox_with_mail:", ":mailboxwithmail:"]}, "mailbox with no mail":{"icon":"\ud83d\udced", "keystrokes":[":mailbox_with_no_mail:", 
  ":mailboxwithnomail:"]}, "package":{"icon":"\ud83d\udce6", "keystrokes":[":package:"]}, "postal horn":{"icon":"\ud83d\udcef", "keystrokes":[":postal_horn:", ":postalhorn:"]}, "inbox tray":{"icon":"\ud83d\udce5", "keystrokes":[":inbox_tray:", ":inboxtray:"]}, "outbox tray":{"icon":"\ud83d\udce4", "keystrokes":[":outbox_tray:", ":outboxtray:"]}, "scroll":{"icon":"\ud83d\udcdc", "keystrokes":[":scroll:"]}, "page with curl":{"icon":"\ud83d\udcc3", "keystrokes":[":page_with_curl:", ":pagewithcurl:"]}, 
  "bookmark tabs":{"icon":"\ud83d\udcd1", "keystrokes":[":bookmark_tabs:", ":bookmarktabs:"]}, "bar chart":{"icon":"\ud83d\udcca", "keystrokes":[":bar_chart:", ":barchart:"]}, "chart with upwards trend":{"icon":"\ud83d\udcc8", "keystrokes":[":chart_with_upwards_trend:", ":chartwithupwardstrend:"]}, "chart with downwards trend":{"icon":"\ud83d\udcc9", "keystrokes":[":chart_with_downwards_trend:", ":chartwithdownwardstrend:"]}, "page facing up":{"icon":"\ud83d\udcc4", "keystrokes":[":page_facing_up:", 
  ":pagefacingup:"]}, "date":{"icon":"\ud83d\udcc5", "keystrokes":[":date:"]}, "calendar":{"icon":"\ud83d\udcc6", "keystrokes":[":calendar:"]}, "spiral calendar":{"icon":"\ud83d\uddd3", "keystrokes":[":spiral_calendar:", ":spiralcalendar:"]}, "card index":{"icon":"\ud83d\udcc7", "keystrokes":[":card_index:", ":cardindex:"]}, "card file box":{"icon":"\ud83d\uddc3", "keystrokes":[":card_file_box:", ":cardfilebox:"]}, "ballot box":{"icon":"\ud83d\uddf3", "keystrokes":[":ballot_box:", ":ballotbox:"]}, 
  "file cabinet":{"icon":"\ud83d\uddc4", "keystrokes":[":file_cabinet:", ":filecabinet:"]}, "clipboard":{"icon":"\ud83d\udccb", "keystrokes":[":clipboard:"]}, "spiral notepad":{"icon":"\ud83d\uddd2", "keystrokes":[":spiral_notepad:", ":spiralnotepad:"]}, "file folder":{"icon":"\ud83d\udcc1", "keystrokes":[":file_folder:", ":filefolder:"]}, "open file folder":{"icon":"\ud83d\udcc2", "keystrokes":[":open_file_folder:", ":openfilefolder:"]}, "card index dividers":{"icon":"\ud83d\uddc2", "keystrokes":[":card_index_dividers:", 
  ":cardindexdividers:"]}, "newspaper roll":{"icon":"\ud83d\uddde", "keystrokes":[":newspaper_roll:", ":newspaperroll:"]}, "newspaper":{"icon":"\ud83d\udcf0", "keystrokes":[":newspaper:"]}, "notebook":{"icon":"\ud83d\udcd3", "keystrokes":[":notebook:"]}, "closed book":{"icon":"\ud83d\udcd5", "keystrokes":[":closed_book:", ":closedbook:"]}, "green book":{"icon":"\ud83d\udcd7", "keystrokes":[":green_book:", ":greenbook:"]}, "blue book":{"icon":"\ud83d\udcd8", "keystrokes":[":blue_book:", ":bluebook:"]}, 
  "orange book":{"icon":"\ud83d\udcd9", "keystrokes":[":orange_book:", ":orangebook:"]}, "notebook with decorative cover":{"icon":"\ud83d\udcd4", "keystrokes":[":notebook_with_decorative_cover:", ":notebookwithdecorativecover:"]}, "ledger":{"icon":"\ud83d\udcd2", "keystrokes":[":ledger:"]}, "books":{"icon":"\ud83d\udcda", "keystrokes":[":books:"]}, "open book":{"icon":"\ud83d\udcd6", "keystrokes":[":open_book:", ":openbook:"]}, "link":{"icon":"\ud83d\udd17", "keystrokes":[":link:"]}, "paperclip":{"icon":"\ud83d\udcce", 
  "keystrokes":[":paperclip:"]}, "paperclips":{"icon":"\ud83d\udd87", "keystrokes":[":paperclips:"]}, "scissors":{"icon":"\u2702\ufe0f", "keystrokes":[":scissors:"]}, "triangular ruler":{"icon":"\ud83d\udcd0", "keystrokes":[":triangular_ruler:", ":triangularruler:"]}, "straight ruler":{"icon":"\ud83d\udccf", "keystrokes":[":straight_ruler:", ":straightruler:"]}, "pushpin":{"icon":"\ud83d\udccc", "keystrokes":[":pushpin:"]}, "round pushpin":{"icon":"\ud83d\udccd", "keystrokes":[":round_pushpin:", 
  ":roundpushpin:"]}, "triangular flag on post":{"icon":"\ud83d\udea9", "keystrokes":[":triangular_flag_on_post:", ":triangularflagonpost:"]}, "white flag":{"icon":"\ud83c\udff3", "keystrokes":[":white_flag:", ":whiteflag:"]}, "black flag":{"icon":"\ud83c\udff4", "keystrokes":[":black_flag:", ":blackflag:"]}, "rainbow flag":{"icon":"\ud83c\udff3\ufe0f\u200d\ud83c\udf08", "keystrokes":[":rainbow_flag:", ":rainbowflag:"]}, "closed lock with key":{"icon":"\ud83d\udd10", "keystrokes":[":closed_lock_with_key:", 
  ":closedlockwithkey:"]}, "lock":{"icon":"\ud83d\udd12", "keystrokes":[":lock:"]}, "unlock":{"icon":"\ud83d\udd13", "keystrokes":[":unlock:"]}, "lock with ink pen":{"icon":"\ud83d\udd0f", "keystrokes":[":lock_with_ink_pen:", ":lockwithinkpen:"]}, "pen":{"icon":"\ud83d\udd8a", "keystrokes":[":pen:"]}, "fountain pen":{"icon":"\ud83d\udd8b", "keystrokes":[":fountain_pen:", ":fountainpen:"]}, "black nib":{"icon":"\u2712\ufe0f", "keystrokes":[":black_nib:", ":blacknib:"]}, "memo":{"icon":"\ud83d\udcdd", 
  "keystrokes":[":memo:"]}, "pencil2":{"icon":"\u270f\ufe0f", "keystrokes":[":pencil2:"]}, "crayon":{"icon":"\ud83d\udd8d", "keystrokes":[":crayon:"]}, "paintbrush":{"icon":"\ud83d\udd8c", "keystrokes":[":paintbrush:"]}, "mag":{"icon":"\ud83d\udd0d", "keystrokes":[":mag:"]}, "mag right":{"icon":"\ud83d\udd0e", "keystrokes":[":mag_right:", ":magright:"]}, "heart":{"icon":"\u2764\ufe0f", "keystrokes":[":heart:"]}, "black heart":{"icon":"\ud83d\udda4", "keystrokes":[":black_heart:", ":blackheart:"]}, 
  "broken heart":{"icon":"\ud83d\udc94", "keystrokes":[":broken_heart:", ":brokenheart:"]}, "heavy heart exclamation":{"icon":"\u2763", "keystrokes":[":heavy_heart_exclamation:", ":heavyheartexclamation:"]}, "two hearts":{"icon":"\ud83d\udc95", "keystrokes":[":two_hearts:", ":twohearts:"]}, "revolving hearts":{"icon":"\ud83d\udc9e", "keystrokes":[":revolving_hearts:", ":revolvinghearts:"]}, "heartbeat":{"icon":"\ud83d\udc93", "keystrokes":[":heartbeat:"]}, "heartpulse":{"icon":"\ud83d\udc97", "keystrokes":[":heartpulse:"]}, 
  "sparkling heart":{"icon":"\ud83d\udc96", "keystrokes":[":sparkling_heart:", ":sparklingheart:"]}, "cupid":{"icon":"\ud83d\udc98", "keystrokes":[":cupid:"]}, "gift heart":{"icon":"\ud83d\udc9d", "keystrokes":[":gift_heart:", ":giftheart:"]}, "heart decoration":{"icon":"\ud83d\udc9f", "keystrokes":[":heart_decoration:", ":heartdecoration:"]}, "peace symbol":{"icon":"\u262e", "keystrokes":[":peace_symbol:", ":peacesymbol:"]}, "latin cross":{"icon":"\u271d", "keystrokes":[":latin_cross:", ":latincross:"]}, 
  "star and crescent":{"icon":"\u262a", "keystrokes":[":star_and_crescent:", ":starandcrescent:"]}, "om":{"icon":"\ud83d\udd49", "keystrokes":[":om:"]}, "wheel of dharma":{"icon":"\u2638", "keystrokes":[":wheel_of_dharma:", ":wheelofdharma:"]}, "star of david":{"icon":"\u2721", "keystrokes":[":star_of_david:", ":starofdavid:"]}, "six pointed star":{"icon":"\ud83d\udd2f", "keystrokes":[":six_pointed_star:", ":sixpointedstar:"]}, "menorah":{"icon":"\ud83d\udd4e", "keystrokes":[":menorah:"]}, "yin yang":{"icon":"\u262f", 
  "keystrokes":[":yin_yang:", ":yinyang:"]}, "orthodox cross":{"icon":"\u2626", "keystrokes":[":orthodox_cross:", ":orthodoxcross:"]}, "place of worship":{"icon":"\ud83d\uded0", "keystrokes":[":place_of_worship:", ":placeofworship:"]}, "ophiuchus":{"icon":"\u26ce", "keystrokes":[":ophiuchus:"]}, "aries":{"icon":"\u2648", "keystrokes":[":aries:"]}, "taurus":{"icon":"\u2649", "keystrokes":[":taurus:"]}, "gemini":{"icon":"\u264a", "keystrokes":[":gemini:"]}, "cancer":{"icon":"\u264b", "keystrokes":[":cancer:"]}, 
  "leo":{"icon":"\u264c", "keystrokes":[":leo:"]}, "virgo":{"icon":"\u264d", "keystrokes":[":virgo:"]}, "libra":{"icon":"\u264e", "keystrokes":[":libra:"]}, "scorpius":{"icon":"\u264f", "keystrokes":[":scorpius:"]}, "sagittarius":{"icon":"\u2650", "keystrokes":[":sagittarius:"]}, "capricorn":{"icon":"\u2651", "keystrokes":[":capricorn:"]}, "aquarius":{"icon":"\u2652", "keystrokes":[":aquarius:"]}, "pisces":{"icon":"\u2653", "keystrokes":[":pisces:"]}, "id":{"icon":"\ud83c\udd94", "keystrokes":[":id:"]}, 
  "atom symbol":{"icon":"\u269b", "keystrokes":[":atom_symbol:", ":atomsymbol:"]}, "u7a7a":{"icon":"\ud83c\ude33", "keystrokes":[":u7a7a:"]}, "u5272":{"icon":"\ud83c\ude39", "keystrokes":[":u5272:"]}, "radioactive":{"icon":"\u2622", "keystrokes":[":radioactive:"]}, "biohazard":{"icon":"\u2623", "keystrokes":[":biohazard:"]}, "mobile phone off":{"icon":"\ud83d\udcf4", "keystrokes":[":mobile_phone_off:", ":mobilephoneoff:"]}, "vibration mode":{"icon":"\ud83d\udcf3", "keystrokes":[":vibration_mode:", 
  ":vibrationmode:"]}, "u6709":{"icon":"\ud83c\ude36", "keystrokes":[":u6709:"]}, "u7121":{"icon":"\ud83c\ude1a", "keystrokes":[":u7121:"]}, "u7533":{"icon":"\ud83c\ude38", "keystrokes":[":u7533:"]}, "u55b6":{"icon":"\ud83c\ude3a", "keystrokes":[":u55b6:"]}, "u6708":{"icon":"\ud83c\ude37\ufe0f", "keystrokes":[":u6708:"]}, "eight pointed black star":{"icon":"\u2734\ufe0f", "keystrokes":[":eight_pointed_black_star:", ":eightpointedblackstar:"]}, "vs":{"icon":"\ud83c\udd9a", "keystrokes":[":vs:"]}, 
  "accept":{"icon":"\ud83c\ude51", "keystrokes":[":accept:"]}, "white flower":{"icon":"\ud83d\udcae", "keystrokes":[":white_flower:", ":whiteflower:"]}, "ideograph advantage":{"icon":"\ud83c\ude50", "keystrokes":[":ideograph_advantage:", ":ideographadvantage:"]}, "secret":{"icon":"\u3299\ufe0f", "keystrokes":[":secret:"]}, "congratulations":{"icon":"\u3297\ufe0f", "keystrokes":[":congratulations:"]}, "u5408":{"icon":"\ud83c\ude34", "keystrokes":[":u5408:"]}, "u6e80":{"icon":"\ud83c\ude35", "keystrokes":[":u6e80:"]}, 
  "u7981":{"icon":"\ud83c\ude32", "keystrokes":[":u7981:"]}, "a":{"icon":"\ud83c\udd70\ufe0f", "keystrokes":[":a:"]}, "b":{"icon":"\ud83c\udd71\ufe0f", "keystrokes":[":b:"]}, "ab":{"icon":"\ud83c\udd8e", "keystrokes":[":ab:"]}, "cl":{"icon":"\ud83c\udd91", "keystrokes":[":cl:"]}, "o2":{"icon":"\ud83c\udd7e\ufe0f", "keystrokes":[":o2:"]}, "sos":{"icon":"\ud83c\udd98", "keystrokes":[":sos:"]}, "no entry":{"icon":"\u26d4", "keystrokes":[":no_entry:", ":noentry:"]}, "name badge":{"icon":"\ud83d\udcdb", 
  "keystrokes":[":name_badge:", ":namebadge:"]}, "no entry sign":{"icon":"\ud83d\udeab", "keystrokes":[":no_entry_sign:", ":noentrysign:"]}, "x":{"icon":"\u274c", "keystrokes":[":x:"]}, "o":{"icon":"\u2b55", "keystrokes":[":o:"]}, "stop sign":{"icon":"\ud83d\uded1", "keystrokes":[":stop_sign:", ":stopsign:"]}, "anger":{"icon":"\ud83d\udca2", "keystrokes":[":anger:"]}, "hotsprings":{"icon":"\u2668\ufe0f", "keystrokes":[":hotsprings:"]}, "no pedestrians":{"icon":"\ud83d\udeb7", "keystrokes":[":no_pedestrians:", 
  ":nopedestrians:"]}, "do not litter":{"icon":"\ud83d\udeaf", "keystrokes":[":do_not_litter:", ":donotlitter:"]}, "no bicycles":{"icon":"\ud83d\udeb3", "keystrokes":[":no_bicycles:", ":nobicycles:"]}, "non-potable water":{"icon":"\ud83d\udeb1", "keystrokes":[":non-potable_water:", ":non-potablewater:"]}, "underage":{"icon":"\ud83d\udd1e", "keystrokes":[":underage:"]}, "no mobile phones":{"icon":"\ud83d\udcf5", "keystrokes":[":no_mobile_phones:", ":nomobilephones:"]}, "exclamation":{"icon":"\u2757", 
  "keystrokes":[":exclamation:"]}, "grey exclamation":{"icon":"\u2755", "keystrokes":[":grey_exclamation:", ":greyexclamation:"]}, "question":{"icon":"\u2753", "keystrokes":[":question:"]}, "grey question":{"icon":"\u2754", "keystrokes":[":grey_question:", ":greyquestion:"]}, "bangbang":{"icon":"\u203c\ufe0f", "keystrokes":[":bangbang:"]}, "interrobang":{"icon":"\u2049\ufe0f", "keystrokes":[":interrobang:"]}, "low brightness":{"icon":"\ud83d\udd05", "keystrokes":[":low_brightness:", ":lowbrightness:"]}, 
  "high brightness":{"icon":"\ud83d\udd06", "keystrokes":[":high_brightness:", ":highbrightness:"]}, "trident":{"icon":"\ud83d\udd31", "keystrokes":[":trident:"]}, "fleur de lis":{"icon":"\u269c", "keystrokes":[":fleur_de_lis:", ":fleurdelis:"]}, "part alternation mark":{"icon":"\u303d\ufe0f", "keystrokes":[":part_alternation_mark:", ":partalternationmark:"]}, "warning":{"icon":"\u26a0\ufe0f", "keystrokes":[":warning:"]}, "children crossing":{"icon":"\ud83d\udeb8", "keystrokes":[":children_crossing:", 
  ":childrencrossing:"]}, "beginner":{"icon":"\ud83d\udd30", "keystrokes":[":beginner:"]}, "recycle":{"icon":"\u267b\ufe0f", "keystrokes":[":recycle:"]}, "u6307":{"icon":"\ud83c\ude2f", "keystrokes":[":u6307:"]}, "chart":{"icon":"\ud83d\udcb9", "keystrokes":[":chart:"]}, "sparkle":{"icon":"\u2747\ufe0f", "keystrokes":[":sparkle:"]}, "eight spoked asterisk":{"icon":"\u2733\ufe0f", "keystrokes":[":eight_spoked_asterisk:", ":eightspokedasterisk:"]}, "negative squared cross mark":{"icon":"\u274e", "keystrokes":[":negative_squared_cross_mark:", 
  ":negativesquaredcrossmark:"]}, "white check mark":{"icon":"\u2705", "keystrokes":[":white_check_mark:", ":whitecheckmark:"]}, "diamond shape with a dot inside":{"icon":"\ud83d\udca0", "keystrokes":[":diamond_shape_with_a_dot_inside:", ":diamondshapewithadotinside:"]}, "cyclone":{"icon":"\ud83c\udf00", "keystrokes":[":cyclone:"]}, "loop":{"icon":"\u27bf", "keystrokes":[":loop:"]}, "globe with meridians":{"icon":"\ud83c\udf10", "keystrokes":[":globe_with_meridians:", ":globewithmeridians:"]}, "m":{"icon":"\u24c2\ufe0f", 
  "keystrokes":[":m:"]}, "atm":{"icon":"\ud83c\udfe7", "keystrokes":[":atm:"]}, "sa":{"icon":"\ud83c\ude02\ufe0f", "keystrokes":[":sa:"]}, "passport control":{"icon":"\ud83d\udec2", "keystrokes":[":passport_control:", ":passportcontrol:"]}, "customs":{"icon":"\ud83d\udec3", "keystrokes":[":customs:"]}, "baggage claim":{"icon":"\ud83d\udec4", "keystrokes":[":baggage_claim:", ":baggageclaim:"]}, "left luggage":{"icon":"\ud83d\udec5", "keystrokes":[":left_luggage:", ":leftluggage:"]}, "wheelchair":{"icon":"\u267f", 
  "keystrokes":[":wheelchair:"]}, "no smoking":{"icon":"\ud83d\udead", "keystrokes":[":no_smoking:", ":nosmoking:"]}, "wc":{"icon":"\ud83d\udebe", "keystrokes":[":wc:"]}, "parking":{"icon":"\ud83c\udd7f\ufe0f", "keystrokes":[":parking:"]}, "potable water":{"icon":"\ud83d\udeb0", "keystrokes":[":potable_water:", ":potablewater:"]}, "mens":{"icon":"\ud83d\udeb9", "keystrokes":[":mens:"]}, "womens":{"icon":"\ud83d\udeba", "keystrokes":[":womens:"]}, "baby symbol":{"icon":"\ud83d\udebc", "keystrokes":[":baby_symbol:", 
  ":babysymbol:"]}, "restroom":{"icon":"\ud83d\udebb", "keystrokes":[":restroom:"]}, "put litter in its place":{"icon":"\ud83d\udeae", "keystrokes":[":put_litter_in_its_place:", ":putlitterinitsplace:"]}, "cinema":{"icon":"\ud83c\udfa6", "keystrokes":[":cinema:"]}, "signal strength":{"icon":"\ud83d\udcf6", "keystrokes":[":signal_strength:", ":signalstrength:"]}, "koko":{"icon":"\ud83c\ude01", "keystrokes":[":koko:"]}, "ng":{"icon":"\ud83c\udd96", "keystrokes":[":ng:"]}, "ok":{"icon":"\ud83c\udd97", 
  "keystrokes":[":ok:"]}, "up":{"icon":"\ud83c\udd99", "keystrokes":[":up:"]}, "cool":{"icon":"\ud83c\udd92", "keystrokes":[":cool:"]}, "new":{"icon":"\ud83c\udd95", "keystrokes":[":new:"]}, "free":{"icon":"\ud83c\udd93", "keystrokes":[":free:"]}, "zero":{"icon":"0\ufe0f\u20e3", "keystrokes":[":zero:"]}, "one":{"icon":"1\ufe0f\u20e3", "keystrokes":[":one:"]}, "two":{"icon":"2\ufe0f\u20e3", "keystrokes":[":two:"]}, "three":{"icon":"3\ufe0f\u20e3", "keystrokes":[":three:"]}, "four":{"icon":"4\ufe0f\u20e3", 
  "keystrokes":[":four:"]}, "five":{"icon":"5\ufe0f\u20e3", "keystrokes":[":five:"]}, "six":{"icon":"6\ufe0f\u20e3", "keystrokes":[":six:"]}, "seven":{"icon":"7\ufe0f\u20e3", "keystrokes":[":seven:"]}, "eight":{"icon":"8\ufe0f\u20e3", "keystrokes":[":eight:"]}, "nine":{"icon":"9\ufe0f\u20e3", "keystrokes":[":nine:"]}, "keycap ten":{"icon":"\ud83d\udd1f", "keystrokes":[":keycap_ten:", ":keycapten:"]}, "asterisk":{"icon":"*\u20e3", "keystrokes":[":asterisk:"]}, "arrow forward":{"icon":"\u25b6\ufe0f", 
  "keystrokes":[":arrow_forward:", ":arrowforward:"]}, "pause button":{"icon":"\u23f8", "keystrokes":[":pause_button:", ":pausebutton:"]}, "next track button":{"icon":"\u23ed", "keystrokes":[":next_track_button:", ":nexttrackbutton:"]}, "stop button":{"icon":"\u23f9", "keystrokes":[":stop_button:", ":stopbutton:"]}, "record button":{"icon":"\u23fa", "keystrokes":[":record_button:", ":recordbutton:"]}, "play or pause button":{"icon":"\u23ef", "keystrokes":[":play_or_pause_button:", ":playorpausebutton:"]}, 
  "previous track button":{"icon":"\u23ee", "keystrokes":[":previous_track_button:", ":previoustrackbutton:"]}, "fast forward":{"icon":"\u23e9", "keystrokes":[":fast_forward:", ":fastforward:"]}, "rewind":{"icon":"\u23ea", "keystrokes":[":rewind:"]}, "twisted rightwards arrows":{"icon":"\ud83d\udd00", "keystrokes":[":twisted_rightwards_arrows:", ":twistedrightwardsarrows:"]}, "repeat":{"icon":"\ud83d\udd01", "keystrokes":[":repeat:"]}, "repeat one":{"icon":"\ud83d\udd02", "keystrokes":[":repeat_one:", 
  ":repeatone:"]}, "arrow backward":{"icon":"\u25c0\ufe0f", "keystrokes":[":arrow_backward:", ":arrowbackward:"]}, "arrow up small":{"icon":"\ud83d\udd3c", "keystrokes":[":arrow_up_small:", ":arrowupsmall:"]}, "arrow down small":{"icon":"\ud83d\udd3d", "keystrokes":[":arrow_down_small:", ":arrowdownsmall:"]}, "arrow double up":{"icon":"\u23eb", "keystrokes":[":arrow_double_up:", ":arrowdoubleup:"]}, "arrow double down":{"icon":"\u23ec", "keystrokes":[":arrow_double_down:", ":arrowdoubledown:"]}, 
  "arrow right":{"icon":"\u27a1\ufe0f", "keystrokes":[":arrow_right:", ":arrowright:"]}, "arrow left":{"icon":"\u2b05\ufe0f", "keystrokes":[":arrow_left:", ":arrowleft:"]}, "arrow up":{"icon":"\u2b06\ufe0f", "keystrokes":[":arrow_up:", ":arrowup:"]}, "arrow down":{"icon":"\u2b07\ufe0f", "keystrokes":[":arrow_down:", ":arrowdown:"]}, "arrow upper right":{"icon":"\u2197\ufe0f", "keystrokes":[":arrow_upper_right:", ":arrowupperright:"]}, "arrow lower right":{"icon":"\u2198\ufe0f", "keystrokes":[":arrow_lower_right:", 
  ":arrowlowerright:"]}, "arrow lower left":{"icon":"\u2199\ufe0f", "keystrokes":[":arrow_lower_left:", ":arrowlowerleft:"]}, "arrow upper left":{"icon":"\u2196\ufe0f", "keystrokes":[":arrow_upper_left:", ":arrowupperleft:"]}, "arrow up down":{"icon":"\u2195\ufe0f", "keystrokes":[":arrow_up_down:", ":arrowupdown:"]}, "left right arrow":{"icon":"\u2194\ufe0f", "keystrokes":[":left_right_arrow:", ":leftrightarrow:"]}, "arrows counterclockwise":{"icon":"\ud83d\udd04", "keystrokes":[":arrows_counterclockwise:", 
  ":arrowscounterclockwise:"]}, "arrow right hook":{"icon":"\u21aa\ufe0f", "keystrokes":[":arrow_right_hook:", ":arrowrighthook:"]}, "leftwards arrow with hook":{"icon":"\u21a9\ufe0f", "keystrokes":[":leftwards_arrow_with_hook:", ":leftwardsarrowwithhook:"]}, "arrow heading up":{"icon":"\u2934\ufe0f", "keystrokes":[":arrow_heading_up:", ":arrowheadingup:"]}, "arrow heading down":{"icon":"\u2935\ufe0f", "keystrokes":[":arrow_heading_down:", ":arrowheadingdown:"]}, "hash":{"icon":"#\ufe0f\u20e3", "keystrokes":[":hash:"]}, 
  "information source":{"icon":"\u2139\ufe0f", "keystrokes":[":information_source:", ":informationsource:"]}, "abc":{"icon":"\ud83d\udd24", "keystrokes":[":abc:"]}, "abcd":{"icon":"\ud83d\udd21", "keystrokes":[":abcd:"]}, "capital abcd":{"icon":"\ud83d\udd20", "keystrokes":[":capital_abcd:", ":capitalabcd:"]}, "symbols":{"icon":"\ud83d\udd23", "keystrokes":[":symbols:"]}, "musical note":{"icon":"\ud83c\udfb5", "keystrokes":[":musical_note:", ":musicalnote:"]}, "notes":{"icon":"\ud83c\udfb6", "keystrokes":[":notes:"]}, 
  "wavy dash":{"icon":"\u3030\ufe0f", "keystrokes":[":wavy_dash:", ":wavydash:"]}, "curly loop":{"icon":"\u27b0", "keystrokes":[":curly_loop:", ":curlyloop:"]}, "heavy check mark":{"icon":"\u2714\ufe0f", "keystrokes":[":heavy_check_mark:", ":heavycheckmark:"]}, "arrows clockwise":{"icon":"\ud83d\udd03", "keystrokes":[":arrows_clockwise:", ":arrowsclockwise:"]}, "heavy plus sign":{"icon":"\u2795", "keystrokes":[":heavy_plus_sign:", ":heavyplussign:"]}, "heavy minus sign":{"icon":"\u2796", "keystrokes":[":heavy_minus_sign:", 
  ":heavyminussign:"]}, "heavy division sign":{"icon":"\u2797", "keystrokes":[":heavy_division_sign:", ":heavydivisionsign:"]}, "heavy multiplication x":{"icon":"\u2716\ufe0f", "keystrokes":[":heavy_multiplication_x:", ":heavymultiplicationx:"]}, "heavy dollar sign":{"icon":"\ud83d\udcb2", "keystrokes":[":heavy_dollar_sign:", ":heavydollarsign:"]}, "currency exchange":{"icon":"\ud83d\udcb1", "keystrokes":[":currency_exchange:", ":currencyexchange:"]}, "copyright":{"icon":"\u00a9\ufe0f", "keystrokes":[":copyright:"]}, 
  "registered":{"icon":"\u00ae\ufe0f", "keystrokes":[":registered:"]}, "tm":{"icon":"\u2122\ufe0f", "keystrokes":[":tm:"]}, "end":{"icon":"\ud83d\udd1a", "keystrokes":[":end:"]}, "back":{"icon":"\ud83d\udd19", "keystrokes":[":back:"]}, "on":{"icon":"\ud83d\udd1b", "keystrokes":[":on:"]}, "top":{"icon":"\ud83d\udd1d", "keystrokes":[":top:"]}, "soon":{"icon":"\ud83d\udd1c", "keystrokes":[":soon:"]}, "ballot box with check":{"icon":"\u2611\ufe0f", "keystrokes":[":ballot_box_with_check:", ":ballotboxwithcheck:"]}, 
  "radio button":{"icon":"\ud83d\udd18", "keystrokes":[":radio_button:", ":radiobutton:"]}, "white circle":{"icon":"\u26aa", "keystrokes":[":white_circle:", ":whitecircle:"]}, "black circle":{"icon":"\u26ab", "keystrokes":[":black_circle:", ":blackcircle:"]}, "red circle":{"icon":"\ud83d\udd34", "keystrokes":[":red_circle:", ":redcircle:"]}, "large blue circle":{"icon":"\ud83d\udd35", "keystrokes":[":large_blue_circle:", ":largebluecircle:"]}, "small orange diamond":{"icon":"\ud83d\udd38", "keystrokes":[":small_orange_diamond:", 
  ":smallorangediamond:"]}, "small blue diamond":{"icon":"\ud83d\udd39", "keystrokes":[":small_blue_diamond:", ":smallbluediamond:"]}, "large orange diamond":{"icon":"\ud83d\udd36", "keystrokes":[":large_orange_diamond:", ":largeorangediamond:"]}, "large blue diamond":{"icon":"\ud83d\udd37", "keystrokes":[":large_blue_diamond:", ":largebluediamond:"]}, "small red triangle":{"icon":"\ud83d\udd3a", "keystrokes":[":small_red_triangle:", ":smallredtriangle:"]}, "black small square":{"icon":"\u25aa\ufe0f", 
  "keystrokes":[":black_small_square:", ":blacksmallsquare:"]}, "white small square":{"icon":"\u25ab\ufe0f", "keystrokes":[":white_small_square:", ":whitesmallsquare:"]}, "black large square":{"icon":"\u2b1b", "keystrokes":[":black_large_square:", ":blacklargesquare:"]}, "white large square":{"icon":"\u2b1c", "keystrokes":[":white_large_square:", ":whitelargesquare:"]}, "small red triangle down":{"icon":"\ud83d\udd3b", "keystrokes":[":small_red_triangle_down:", ":smallredtriangledown:"]}, "black medium square":{"icon":"\u25fc\ufe0f", 
  "keystrokes":[":black_medium_square:", ":blackmediumsquare:"]}, "white medium square":{"icon":"\u25fb\ufe0f", "keystrokes":[":white_medium_square:", ":whitemediumsquare:"]}, "black medium small square":{"icon":"\u25fe", "keystrokes":[":black_medium_small_square:", ":blackmediumsmallsquare:"]}, "white medium small square":{"icon":"\u25fd", "keystrokes":[":white_medium_small_square:", ":whitemediumsmallsquare:"]}, "black square button":{"icon":"\ud83d\udd32", "keystrokes":[":black_square_button:", 
  ":blacksquarebutton:"]}, "white square button":{"icon":"\ud83d\udd33", "keystrokes":[":white_square_button:", ":whitesquarebutton:"]}, "speaker":{"icon":"\ud83d\udd08", "keystrokes":[":speaker:"]}, "sound":{"icon":"\ud83d\udd09", "keystrokes":[":sound:"]}, "loud sound":{"icon":"\ud83d\udd0a", "keystrokes":[":loud_sound:", ":loudsound:"]}, "mute":{"icon":"\ud83d\udd07", "keystrokes":[":mute:"]}, "mega":{"icon":"\ud83d\udce3", "keystrokes":[":mega:"]}, "loudspeaker":{"icon":"\ud83d\udce2", "keystrokes":[":loudspeaker:"]}, 
  "bell":{"icon":"\ud83d\udd14", "keystrokes":[":bell:"]}, "no bell":{"icon":"\ud83d\udd15", "keystrokes":[":no_bell:", ":nobell:"]}, "black joker":{"icon":"\ud83c\udccf", "keystrokes":[":black_joker:", ":blackjoker:"]}, "mahjong":{"icon":"\ud83c\udc04", "keystrokes":[":mahjong:"]}, "spades":{"icon":"\u2660\ufe0f", "keystrokes":[":spades:"]}, "clubs":{"icon":"\u2663\ufe0f", "keystrokes":[":clubs:"]}, "hearts":{"icon":"\u2665\ufe0f", "keystrokes":[":hearts:"]}, "diamonds":{"icon":"\u2666\ufe0f", "keystrokes":[":diamonds:"]}, 
  "flower playing cards":{"icon":"\ud83c\udfb4", "keystrokes":[":flower_playing_cards:", ":flowerplayingcards:"]}, "thought balloon":{"icon":"\ud83d\udcad", "keystrokes":[":thought_balloon:", ":thoughtballoon:"]}, "right anger bubble":{"icon":"\ud83d\uddef", "keystrokes":[":right_anger_bubble:", ":rightangerbubble:"]}, "speech balloon":{"icon":"\ud83d\udcac", "keystrokes":[":speech_balloon:", ":speechballoon:"]}, "left speech bubble":{"icon":"\ud83d\udde8", "keystrokes":[":left_speech_bubble:", ":leftspeechbubble:"]}, 
  "clock1":{"icon":"\ud83d\udd50", "keystrokes":[":clock1:"]}, "clock2":{"icon":"\ud83d\udd51", "keystrokes":[":clock2:"]}, "clock3":{"icon":"\ud83d\udd52", "keystrokes":[":clock3:"]}, "clock4":{"icon":"\ud83d\udd53", "keystrokes":[":clock4:"]}, "clock5":{"icon":"\ud83d\udd54", "keystrokes":[":clock5:"]}, "clock6":{"icon":"\ud83d\udd55", "keystrokes":[":clock6:"]}, "clock7":{"icon":"\ud83d\udd56", "keystrokes":[":clock7:"]}, "clock8":{"icon":"\ud83d\udd57", "keystrokes":[":clock8:"]}, "clock9":{"icon":"\ud83d\udd58", 
  "keystrokes":[":clock9:"]}, "clock10":{"icon":"\ud83d\udd59", "keystrokes":[":clock10:"]}, "clock11":{"icon":"\ud83d\udd5a", "keystrokes":[":clock11:"]}, "clock12":{"icon":"\ud83d\udd5b", "keystrokes":[":clock12:"]}, "clock130":{"icon":"\ud83d\udd5c", "keystrokes":[":clock130:"]}, "clock230":{"icon":"\ud83d\udd5d", "keystrokes":[":clock230:"]}, "clock330":{"icon":"\ud83d\udd5e", "keystrokes":[":clock330:"]}, "clock430":{"icon":"\ud83d\udd5f", "keystrokes":[":clock430:"]}, "clock530":{"icon":"\ud83d\udd60", 
  "keystrokes":[":clock530:"]}, "clock630":{"icon":"\ud83d\udd61", "keystrokes":[":clock630:"]}, "clock730":{"icon":"\ud83d\udd62", "keystrokes":[":clock730:"]}, "clock830":{"icon":"\ud83d\udd63", "keystrokes":[":clock830:"]}, "clock930":{"icon":"\ud83d\udd64", "keystrokes":[":clock930:"]}, "clock1030":{"icon":"\ud83d\udd65", "keystrokes":[":clock1030:"]}, "clock1130":{"icon":"\ud83d\udd66", "keystrokes":[":clock1130:"]}, "clock1230":{"icon":"\ud83d\udd67", "keystrokes":[":clock1230:"]}, "afghanistan":{"icon":"\ud83c\udde6\ud83c\uddeb", 
  "keystrokes":[":afghanistan:"]}, "aland islands":{"icon":"\ud83c\udde6\ud83c\uddfd", "keystrokes":[":aland_islands:", ":alandislands:"]}, "albania":{"icon":"\ud83c\udde6\ud83c\uddf1", "keystrokes":[":albania:"]}, "algeria":{"icon":"\ud83c\udde9\ud83c\uddff", "keystrokes":[":algeria:"]}, "american samoa":{"icon":"\ud83c\udde6\ud83c\uddf8", "keystrokes":[":american_samoa:", ":americansamoa:"]}, "andorra":{"icon":"\ud83c\udde6\ud83c\udde9", "keystrokes":[":andorra:"]}, "angola":{"icon":"\ud83c\udde6\ud83c\uddf4", 
  "keystrokes":[":angola:"]}, "anguilla":{"icon":"\ud83c\udde6\ud83c\uddee", "keystrokes":[":anguilla:"]}, "antarctica":{"icon":"\ud83c\udde6\ud83c\uddf6", "keystrokes":[":antarctica:"]}, "antigua barbuda":{"icon":"\ud83c\udde6\ud83c\uddec", "keystrokes":[":antigua_barbuda:", ":antiguabarbuda:"]}, "argentina":{"icon":"\ud83c\udde6\ud83c\uddf7", "keystrokes":[":argentina:"]}, "armenia":{"icon":"\ud83c\udde6\ud83c\uddf2", "keystrokes":[":armenia:"]}, "aruba":{"icon":"\ud83c\udde6\ud83c\uddfc", "keystrokes":[":aruba:"]}, 
  "australia":{"icon":"\ud83c\udde6\ud83c\uddfa", "keystrokes":[":australia:"]}, "austria":{"icon":"\ud83c\udde6\ud83c\uddf9", "keystrokes":[":austria:"]}, "azerbaijan":{"icon":"\ud83c\udde6\ud83c\uddff", "keystrokes":[":azerbaijan:"]}, "bahamas":{"icon":"\ud83c\udde7\ud83c\uddf8", "keystrokes":[":bahamas:"]}, "bahrain":{"icon":"\ud83c\udde7\ud83c\udded", "keystrokes":[":bahrain:"]}, "bangladesh":{"icon":"\ud83c\udde7\ud83c\udde9", "keystrokes":[":bangladesh:"]}, "barbados":{"icon":"\ud83c\udde7\ud83c\udde7", 
  "keystrokes":[":barbados:"]}, "belarus":{"icon":"\ud83c\udde7\ud83c\uddfe", "keystrokes":[":belarus:"]}, "belgium":{"icon":"\ud83c\udde7\ud83c\uddea", "keystrokes":[":belgium:"]}, "belize":{"icon":"\ud83c\udde7\ud83c\uddff", "keystrokes":[":belize:"]}, "benin":{"icon":"\ud83c\udde7\ud83c\uddef", "keystrokes":[":benin:"]}, "bermuda":{"icon":"\ud83c\udde7\ud83c\uddf2", "keystrokes":[":bermuda:"]}, "bhutan":{"icon":"\ud83c\udde7\ud83c\uddf9", "keystrokes":[":bhutan:"]}, "bolivia":{"icon":"\ud83c\udde7\ud83c\uddf4", 
  "keystrokes":[":bolivia:"]}, "caribbean netherlands":{"icon":"\ud83c\udde7\ud83c\uddf6", "keystrokes":[":caribbean_netherlands:", ":caribbeannetherlands:"]}, "bosnia herzegovina":{"icon":"\ud83c\udde7\ud83c\udde6", "keystrokes":[":bosnia_herzegovina:", ":bosniaherzegovina:"]}, "botswana":{"icon":"\ud83c\udde7\ud83c\uddfc", "keystrokes":[":botswana:"]}, "brazil":{"icon":"\ud83c\udde7\ud83c\uddf7", "keystrokes":[":brazil:"]}, "british indian ocean territory":{"icon":"\ud83c\uddee\ud83c\uddf4", "keystrokes":[":british_indian_ocean_territory:", 
  ":britishindianoceanterritory:"]}, "british virgin islands":{"icon":"\ud83c\uddfb\ud83c\uddec", "keystrokes":[":british_virgin_islands:", ":britishvirginislands:"]}, "brunei":{"icon":"\ud83c\udde7\ud83c\uddf3", "keystrokes":[":brunei:"]}, "bulgaria":{"icon":"\ud83c\udde7\ud83c\uddec", "keystrokes":[":bulgaria:"]}, "burkina faso":{"icon":"\ud83c\udde7\ud83c\uddeb", "keystrokes":[":burkina_faso:", ":burkinafaso:"]}, "burundi":{"icon":"\ud83c\udde7\ud83c\uddee", "keystrokes":[":burundi:"]}, "cape verde":{"icon":"\ud83c\udde8\ud83c\uddfb", 
  "keystrokes":[":cape_verde:", ":capeverde:"]}, "cambodia":{"icon":"\ud83c\uddf0\ud83c\udded", "keystrokes":[":cambodia:"]}, "cameroon":{"icon":"\ud83c\udde8\ud83c\uddf2", "keystrokes":[":cameroon:"]}, "canada":{"icon":"\ud83c\udde8\ud83c\udde6", "keystrokes":[":canada:"]}, "canary islands":{"icon":"\ud83c\uddee\ud83c\udde8", "keystrokes":[":canary_islands:", ":canaryislands:"]}, "cayman islands":{"icon":"\ud83c\uddf0\ud83c\uddfe", "keystrokes":[":cayman_islands:", ":caymanislands:"]}, "central african republic":{"icon":"\ud83c\udde8\ud83c\uddeb", 
  "keystrokes":[":central_african_republic:", ":centralafricanrepublic:"]}, "chad":{"icon":"\ud83c\uddf9\ud83c\udde9", "keystrokes":[":chad:"]}, "chile":{"icon":"\ud83c\udde8\ud83c\uddf1", "keystrokes":[":chile:"]}, "cn":{"icon":"\ud83c\udde8\ud83c\uddf3", "keystrokes":[":cn:"]}, "christmas island":{"icon":"\ud83c\udde8\ud83c\uddfd", "keystrokes":[":christmas_island:", ":christmasisland:"]}, "cocos islands":{"icon":"\ud83c\udde8\ud83c\udde8", "keystrokes":[":cocos_islands:", ":cocosislands:"]}, "colombia":{"icon":"\ud83c\udde8\ud83c\uddf4", 
  "keystrokes":[":colombia:"]}, "comoros":{"icon":"\ud83c\uddf0\ud83c\uddf2", "keystrokes":[":comoros:"]}, "congo brazzaville":{"icon":"\ud83c\udde8\ud83c\uddec", "keystrokes":[":congo_brazzaville:", ":congobrazzaville:"]}, "congo kinshasa":{"icon":"\ud83c\udde8\ud83c\udde9", "keystrokes":[":congo_kinshasa:", ":congokinshasa:"]}, "cook islands":{"icon":"\ud83c\udde8\ud83c\uddf0", "keystrokes":[":cook_islands:", ":cookislands:"]}, "costa rica":{"icon":"\ud83c\udde8\ud83c\uddf7", "keystrokes":[":costa_rica:", 
  ":costarica:"]}, "croatia":{"icon":"\ud83c\udded\ud83c\uddf7", "keystrokes":[":croatia:"]}, "cuba":{"icon":"\ud83c\udde8\ud83c\uddfa", "keystrokes":[":cuba:"]}, "curacao":{"icon":"\ud83c\udde8\ud83c\uddfc", "keystrokes":[":curacao:"]}, "cyprus":{"icon":"\ud83c\udde8\ud83c\uddfe", "keystrokes":[":cyprus:"]}, "czech republic":{"icon":"\ud83c\udde8\ud83c\uddff", "keystrokes":[":czech_republic:", ":czechrepublic:"]}, "denmark":{"icon":"\ud83c\udde9\ud83c\uddf0", "keystrokes":[":denmark:"]}, "djibouti":{"icon":"\ud83c\udde9\ud83c\uddef", 
  "keystrokes":[":djibouti:"]}, "dominica":{"icon":"\ud83c\udde9\ud83c\uddf2", "keystrokes":[":dominica:"]}, "dominican republic":{"icon":"\ud83c\udde9\ud83c\uddf4", "keystrokes":[":dominican_republic:", ":dominicanrepublic:"]}, "ecuador":{"icon":"\ud83c\uddea\ud83c\udde8", "keystrokes":[":ecuador:"]}, "egypt":{"icon":"\ud83c\uddea\ud83c\uddec", "keystrokes":[":egypt:"]}, "el salvador":{"icon":"\ud83c\uddf8\ud83c\uddfb", "keystrokes":[":el_salvador:", ":elsalvador:"]}, "equatorial guinea":{"icon":"\ud83c\uddec\ud83c\uddf6", 
  "keystrokes":[":equatorial_guinea:", ":equatorialguinea:"]}, "eritrea":{"icon":"\ud83c\uddea\ud83c\uddf7", "keystrokes":[":eritrea:"]}, "estonia":{"icon":"\ud83c\uddea\ud83c\uddea", "keystrokes":[":estonia:"]}, "ethiopia":{"icon":"\ud83c\uddea\ud83c\uddf9", "keystrokes":[":ethiopia:"]}, "eu":{"icon":"\ud83c\uddea\ud83c\uddfa", "keystrokes":[":eu:"]}, "falkland islands":{"icon":"\ud83c\uddeb\ud83c\uddf0", "keystrokes":[":falkland_islands:", ":falklandislands:"]}, "faroe islands":{"icon":"\ud83c\uddeb\ud83c\uddf4", 
  "keystrokes":[":faroe_islands:", ":faroeislands:"]}, "fiji":{"icon":"\ud83c\uddeb\ud83c\uddef", "keystrokes":[":fiji:"]}, "finland":{"icon":"\ud83c\uddeb\ud83c\uddee", "keystrokes":[":finland:"]}, "fr":{"icon":"\ud83c\uddeb\ud83c\uddf7", "keystrokes":[":fr:"]}, "french guiana":{"icon":"\ud83c\uddec\ud83c\uddeb", "keystrokes":[":french_guiana:", ":frenchguiana:"]}, "french polynesia":{"icon":"\ud83c\uddf5\ud83c\uddeb", "keystrokes":[":french_polynesia:", ":frenchpolynesia:"]}, "french southern territories":{"icon":"\ud83c\uddf9\ud83c\uddeb", 
  "keystrokes":[":french_southern_territories:", ":frenchsouthernterritories:"]}, "gabon":{"icon":"\ud83c\uddec\ud83c\udde6", "keystrokes":[":gabon:"]}, "gambia":{"icon":"\ud83c\uddec\ud83c\uddf2", "keystrokes":[":gambia:"]}, "georgia":{"icon":"\ud83c\uddec\ud83c\uddea", "keystrokes":[":georgia:"]}, "de":{"icon":"\ud83c\udde9\ud83c\uddea", "keystrokes":[":de:"]}, "ghana":{"icon":"\ud83c\uddec\ud83c\udded", "keystrokes":[":ghana:"]}, "gibraltar":{"icon":"\ud83c\uddec\ud83c\uddee", "keystrokes":[":gibraltar:"]}, 
  "greece":{"icon":"\ud83c\uddec\ud83c\uddf7", "keystrokes":[":greece:"]}, "greenland":{"icon":"\ud83c\uddec\ud83c\uddf1", "keystrokes":[":greenland:"]}, "grenada":{"icon":"\ud83c\uddec\ud83c\udde9", "keystrokes":[":grenada:"]}, "guadeloupe":{"icon":"\ud83c\uddec\ud83c\uddf5", "keystrokes":[":guadeloupe:"]}, "guam":{"icon":"\ud83c\uddec\ud83c\uddfa", "keystrokes":[":guam:"]}, "guatemala":{"icon":"\ud83c\uddec\ud83c\uddf9", "keystrokes":[":guatemala:"]}, "guernsey":{"icon":"\ud83c\uddec\ud83c\uddec", 
  "keystrokes":[":guernsey:"]}, "guinea":{"icon":"\ud83c\uddec\ud83c\uddf3", "keystrokes":[":guinea:"]}, "guinea bissau":{"icon":"\ud83c\uddec\ud83c\uddfc", "keystrokes":[":guinea_bissau:", ":guineabissau:"]}, "guyana":{"icon":"\ud83c\uddec\ud83c\uddfe", "keystrokes":[":guyana:"]}, "haiti":{"icon":"\ud83c\udded\ud83c\uddf9", "keystrokes":[":haiti:"]}, "honduras":{"icon":"\ud83c\udded\ud83c\uddf3", "keystrokes":[":honduras:"]}, "hong kong":{"icon":"\ud83c\udded\ud83c\uddf0", "keystrokes":[":hong_kong:", 
  ":hongkong:"]}, "hungary":{"icon":"\ud83c\udded\ud83c\uddfa", "keystrokes":[":hungary:"]}, "iceland":{"icon":"\ud83c\uddee\ud83c\uddf8", "keystrokes":[":iceland:"]}, "india":{"icon":"\ud83c\uddee\ud83c\uddf3", "keystrokes":[":india:"]}, "indonesia":{"icon":"\ud83c\uddee\ud83c\udde9", "keystrokes":[":indonesia:"]}, "iran":{"icon":"\ud83c\uddee\ud83c\uddf7", "keystrokes":[":iran:"]}, "iraq":{"icon":"\ud83c\uddee\ud83c\uddf6", "keystrokes":[":iraq:"]}, "ireland":{"icon":"\ud83c\uddee\ud83c\uddea", 
  "keystrokes":[":ireland:"]}, "isle of man":{"icon":"\ud83c\uddee\ud83c\uddf2", "keystrokes":[":isle_of_man:", ":isleofman:"]}, "israel":{"icon":"\ud83c\uddee\ud83c\uddf1", "keystrokes":[":israel:"]}, "it":{"icon":"\ud83c\uddee\ud83c\uddf9", "keystrokes":[":it:"]}, "cote divoire":{"icon":"\ud83c\udde8\ud83c\uddee", "keystrokes":[":cote_divoire:", ":cotedivoire:"]}, "jamaica":{"icon":"\ud83c\uddef\ud83c\uddf2", "keystrokes":[":jamaica:"]}, "jp":{"icon":"\ud83c\uddef\ud83c\uddf5", "keystrokes":[":jp:"]}, 
  "jersey":{"icon":"\ud83c\uddef\ud83c\uddea", "keystrokes":[":jersey:"]}, "jordan":{"icon":"\ud83c\uddef\ud83c\uddf4", "keystrokes":[":jordan:"]}, "kazakhstan":{"icon":"\ud83c\uddf0\ud83c\uddff", "keystrokes":[":kazakhstan:"]}, "kenya":{"icon":"\ud83c\uddf0\ud83c\uddea", "keystrokes":[":kenya:"]}, "kiribati":{"icon":"\ud83c\uddf0\ud83c\uddee", "keystrokes":[":kiribati:"]}, "kosovo":{"icon":"\ud83c\uddfd\ud83c\uddf0", "keystrokes":[":kosovo:"]}, "kuwait":{"icon":"\ud83c\uddf0\ud83c\uddfc", "keystrokes":[":kuwait:"]}, 
  "kyrgyzstan":{"icon":"\ud83c\uddf0\ud83c\uddec", "keystrokes":[":kyrgyzstan:"]}, "laos":{"icon":"\ud83c\uddf1\ud83c\udde6", "keystrokes":[":laos:"]}, "latvia":{"icon":"\ud83c\uddf1\ud83c\uddfb", "keystrokes":[":latvia:"]}, "lebanon":{"icon":"\ud83c\uddf1\ud83c\udde7", "keystrokes":[":lebanon:"]}, "lesotho":{"icon":"\ud83c\uddf1\ud83c\uddf8", "keystrokes":[":lesotho:"]}, "liberia":{"icon":"\ud83c\uddf1\ud83c\uddf7", "keystrokes":[":liberia:"]}, "libya":{"icon":"\ud83c\uddf1\ud83c\uddfe", "keystrokes":[":libya:"]}, 
  "liechtenstein":{"icon":"\ud83c\uddf1\ud83c\uddee", "keystrokes":[":liechtenstein:"]}, "lithuania":{"icon":"\ud83c\uddf1\ud83c\uddf9", "keystrokes":[":lithuania:"]}, "luxembourg":{"icon":"\ud83c\uddf1\ud83c\uddfa", "keystrokes":[":luxembourg:"]}, "macau":{"icon":"\ud83c\uddf2\ud83c\uddf4", "keystrokes":[":macau:"]}, "macedonia":{"icon":"\ud83c\uddf2\ud83c\uddf0", "keystrokes":[":macedonia:"]}, "madagascar":{"icon":"\ud83c\uddf2\ud83c\uddec", "keystrokes":[":madagascar:"]}, "malawi":{"icon":"\ud83c\uddf2\ud83c\uddfc", 
  "keystrokes":[":malawi:"]}, "malaysia":{"icon":"\ud83c\uddf2\ud83c\uddfe", "keystrokes":[":malaysia:"]}, "maldives":{"icon":"\ud83c\uddf2\ud83c\uddfb", "keystrokes":[":maldives:"]}, "mali":{"icon":"\ud83c\uddf2\ud83c\uddf1", "keystrokes":[":mali:"]}, "malta":{"icon":"\ud83c\uddf2\ud83c\uddf9", "keystrokes":[":malta:"]}, "marshall islands":{"icon":"\ud83c\uddf2\ud83c\udded", "keystrokes":[":marshall_islands:", ":marshallislands:"]}, "martinique":{"icon":"\ud83c\uddf2\ud83c\uddf6", "keystrokes":[":martinique:"]}, 
  "mauritania":{"icon":"\ud83c\uddf2\ud83c\uddf7", "keystrokes":[":mauritania:"]}, "mauritius":{"icon":"\ud83c\uddf2\ud83c\uddfa", "keystrokes":[":mauritius:"]}, "mayotte":{"icon":"\ud83c\uddfe\ud83c\uddf9", "keystrokes":[":mayotte:"]}, "mexico":{"icon":"\ud83c\uddf2\ud83c\uddfd", "keystrokes":[":mexico:"]}, "micronesia":{"icon":"\ud83c\uddeb\ud83c\uddf2", "keystrokes":[":micronesia:"]}, "moldova":{"icon":"\ud83c\uddf2\ud83c\udde9", "keystrokes":[":moldova:"]}, "monaco":{"icon":"\ud83c\uddf2\ud83c\udde8", 
  "keystrokes":[":monaco:"]}, "mongolia":{"icon":"\ud83c\uddf2\ud83c\uddf3", "keystrokes":[":mongolia:"]}, "montenegro":{"icon":"\ud83c\uddf2\ud83c\uddea", "keystrokes":[":montenegro:"]}, "montserrat":{"icon":"\ud83c\uddf2\ud83c\uddf8", "keystrokes":[":montserrat:"]}, "morocco":{"icon":"\ud83c\uddf2\ud83c\udde6", "keystrokes":[":morocco:"]}, "mozambique":{"icon":"\ud83c\uddf2\ud83c\uddff", "keystrokes":[":mozambique:"]}, "myanmar":{"icon":"\ud83c\uddf2\ud83c\uddf2", "keystrokes":[":myanmar:"]}, "namibia":{"icon":"\ud83c\uddf3\ud83c\udde6", 
  "keystrokes":[":namibia:"]}, "nauru":{"icon":"\ud83c\uddf3\ud83c\uddf7", "keystrokes":[":nauru:"]}, "nepal":{"icon":"\ud83c\uddf3\ud83c\uddf5", "keystrokes":[":nepal:"]}, "netherlands":{"icon":"\ud83c\uddf3\ud83c\uddf1", "keystrokes":[":netherlands:"]}, "new caledonia":{"icon":"\ud83c\uddf3\ud83c\udde8", "keystrokes":[":new_caledonia:", ":newcaledonia:"]}, "new zealand":{"icon":"\ud83c\uddf3\ud83c\uddff", "keystrokes":[":new_zealand:", ":newzealand:"]}, "nicaragua":{"icon":"\ud83c\uddf3\ud83c\uddee", 
  "keystrokes":[":nicaragua:"]}, "niger":{"icon":"\ud83c\uddf3\ud83c\uddea", "keystrokes":[":niger:"]}, "nigeria":{"icon":"\ud83c\uddf3\ud83c\uddec", "keystrokes":[":nigeria:"]}, "niue":{"icon":"\ud83c\uddf3\ud83c\uddfa", "keystrokes":[":niue:"]}, "norfolk island":{"icon":"\ud83c\uddf3\ud83c\uddeb", "keystrokes":[":norfolk_island:", ":norfolkisland:"]}, "northern mariana islands":{"icon":"\ud83c\uddf2\ud83c\uddf5", "keystrokes":[":northern_mariana_islands:", ":northernmarianaislands:"]}, "north korea":{"icon":"\ud83c\uddf0\ud83c\uddf5", 
  "keystrokes":[":north_korea:", ":northkorea:"]}, "norway":{"icon":"\ud83c\uddf3\ud83c\uddf4", "keystrokes":[":norway:"]}, "oman":{"icon":"\ud83c\uddf4\ud83c\uddf2", "keystrokes":[":oman:"]}, "pakistan":{"icon":"\ud83c\uddf5\ud83c\uddf0", "keystrokes":[":pakistan:"]}, "palau":{"icon":"\ud83c\uddf5\ud83c\uddfc", "keystrokes":[":palau:"]}, "palestinian territories":{"icon":"\ud83c\uddf5\ud83c\uddf8", "keystrokes":[":palestinian_territories:", ":palestinianterritories:"]}, "panama":{"icon":"\ud83c\uddf5\ud83c\udde6", 
  "keystrokes":[":panama:"]}, "papua new guinea":{"icon":"\ud83c\uddf5\ud83c\uddec", "keystrokes":[":papua_new_guinea:", ":papuanewguinea:"]}, "paraguay":{"icon":"\ud83c\uddf5\ud83c\uddfe", "keystrokes":[":paraguay:"]}, "peru":{"icon":"\ud83c\uddf5\ud83c\uddea", "keystrokes":[":peru:"]}, "philippines":{"icon":"\ud83c\uddf5\ud83c\udded", "keystrokes":[":philippines:"]}, "pitcairn islands":{"icon":"\ud83c\uddf5\ud83c\uddf3", "keystrokes":[":pitcairn_islands:", ":pitcairnislands:"]}, "poland":{"icon":"\ud83c\uddf5\ud83c\uddf1", 
  "keystrokes":[":poland:"]}, "portugal":{"icon":"\ud83c\uddf5\ud83c\uddf9", "keystrokes":[":portugal:"]}, "puerto rico":{"icon":"\ud83c\uddf5\ud83c\uddf7", "keystrokes":[":puerto_rico:", ":puertorico:"]}, "qatar":{"icon":"\ud83c\uddf6\ud83c\udde6", "keystrokes":[":qatar:"]}, "reunion":{"icon":"\ud83c\uddf7\ud83c\uddea", "keystrokes":[":reunion:"]}, "romania":{"icon":"\ud83c\uddf7\ud83c\uddf4", "keystrokes":[":romania:"]}, "ru":{"icon":"\ud83c\uddf7\ud83c\uddfa", "keystrokes":[":ru:"]}, "rwanda":{"icon":"\ud83c\uddf7\ud83c\uddfc", 
  "keystrokes":[":rwanda:"]}, "st barthelemy":{"icon":"\ud83c\udde7\ud83c\uddf1", "keystrokes":[":st_barthelemy:", ":stbarthelemy:"]}, "st helena":{"icon":"\ud83c\uddf8\ud83c\udded", "keystrokes":[":st_helena:", ":sthelena:"]}, "st kitts nevis":{"icon":"\ud83c\uddf0\ud83c\uddf3", "keystrokes":[":st_kitts_nevis:", ":stkittsnevis:"]}, "st lucia":{"icon":"\ud83c\uddf1\ud83c\udde8", "keystrokes":[":st_lucia:", ":stlucia:"]}, "st pierre miquelon":{"icon":"\ud83c\uddf5\ud83c\uddf2", "keystrokes":[":st_pierre_miquelon:", 
  ":stpierremiquelon:"]}, "st vincent grenadines":{"icon":"\ud83c\uddfb\ud83c\udde8", "keystrokes":[":st_vincent_grenadines:", ":stvincentgrenadines:"]}, "samoa":{"icon":"\ud83c\uddfc\ud83c\uddf8", "keystrokes":[":samoa:"]}, "san marino":{"icon":"\ud83c\uddf8\ud83c\uddf2", "keystrokes":[":san_marino:", ":sanmarino:"]}, "sao tome principe":{"icon":"\ud83c\uddf8\ud83c\uddf9", "keystrokes":[":sao_tome_principe:", ":saotomeprincipe:"]}, "saudi arabia":{"icon":"\ud83c\uddf8\ud83c\udde6", "keystrokes":[":saudi_arabia:", 
  ":saudiarabia:"]}, "senegal":{"icon":"\ud83c\uddf8\ud83c\uddf3", "keystrokes":[":senegal:"]}, "serbia":{"icon":"\ud83c\uddf7\ud83c\uddf8", "keystrokes":[":serbia:"]}, "seychelles":{"icon":"\ud83c\uddf8\ud83c\udde8", "keystrokes":[":seychelles:"]}, "sierra leone":{"icon":"\ud83c\uddf8\ud83c\uddf1", "keystrokes":[":sierra_leone:", ":sierraleone:"]}, "singapore":{"icon":"\ud83c\uddf8\ud83c\uddec", "keystrokes":[":singapore:"]}, "sint maarten":{"icon":"\ud83c\uddf8\ud83c\uddfd", "keystrokes":[":sint_maarten:", 
  ":sintmaarten:"]}, "slovakia":{"icon":"\ud83c\uddf8\ud83c\uddf0", "keystrokes":[":slovakia:"]}, "slovenia":{"icon":"\ud83c\uddf8\ud83c\uddee", "keystrokes":[":slovenia:"]}, "solomon islands":{"icon":"\ud83c\uddf8\ud83c\udde7", "keystrokes":[":solomon_islands:", ":solomonislands:"]}, "somalia":{"icon":"\ud83c\uddf8\ud83c\uddf4", "keystrokes":[":somalia:"]}, "south africa":{"icon":"\ud83c\uddff\ud83c\udde6", "keystrokes":[":south_africa:", ":southafrica:"]}, "south georgia south sandwich islands":{"icon":"\ud83c\uddec\ud83c\uddf8", 
  "keystrokes":[":south_georgia_south_sandwich_islands:", ":southgeorgiasouthsandwichislands:"]}, "kr":{"icon":"\ud83c\uddf0\ud83c\uddf7", "keystrokes":[":kr:"]}, "south sudan":{"icon":"\ud83c\uddf8\ud83c\uddf8", "keystrokes":[":south_sudan:", ":southsudan:"]}, "es":{"icon":"\ud83c\uddea\ud83c\uddf8", "keystrokes":[":es:"]}, "sri lanka":{"icon":"\ud83c\uddf1\ud83c\uddf0", "keystrokes":[":sri_lanka:", ":srilanka:"]}, "sudan":{"icon":"\ud83c\uddf8\ud83c\udde9", "keystrokes":[":sudan:"]}, "suriname":{"icon":"\ud83c\uddf8\ud83c\uddf7", 
  "keystrokes":[":suriname:"]}, "swaziland":{"icon":"\ud83c\uddf8\ud83c\uddff", "keystrokes":[":swaziland:"]}, "sweden":{"icon":"\ud83c\uddf8\ud83c\uddea", "keystrokes":[":sweden:"]}, "switzerland":{"icon":"\ud83c\udde8\ud83c\udded", "keystrokes":[":switzerland:"]}, "syria":{"icon":"\ud83c\uddf8\ud83c\uddfe", "keystrokes":[":syria:"]}, "taiwan":{"icon":"\ud83c\uddf9\ud83c\uddfc", "keystrokes":[":taiwan:"]}, "tajikistan":{"icon":"\ud83c\uddf9\ud83c\uddef", "keystrokes":[":tajikistan:"]}, "tanzania":{"icon":"\ud83c\uddf9\ud83c\uddff", 
  "keystrokes":[":tanzania:"]}, "thailand":{"icon":"\ud83c\uddf9\ud83c\udded", "keystrokes":[":thailand:"]}, "timor leste":{"icon":"\ud83c\uddf9\ud83c\uddf1", "keystrokes":[":timor_leste:", ":timorleste:"]}, "togo":{"icon":"\ud83c\uddf9\ud83c\uddec", "keystrokes":[":togo:"]}, "tokelau":{"icon":"\ud83c\uddf9\ud83c\uddf0", "keystrokes":[":tokelau:"]}, "tonga":{"icon":"\ud83c\uddf9\ud83c\uddf4", "keystrokes":[":tonga:"]}, "trinidad tobago":{"icon":"\ud83c\uddf9\ud83c\uddf9", "keystrokes":[":trinidad_tobago:", 
  ":trinidadtobago:"]}, "tunisia":{"icon":"\ud83c\uddf9\ud83c\uddf3", "keystrokes":[":tunisia:"]}, "tr":{"icon":"\ud83c\uddf9\ud83c\uddf7", "keystrokes":[":tr:"]}, "turkmenistan":{"icon":"\ud83c\uddf9\ud83c\uddf2", "keystrokes":[":turkmenistan:"]}, "turks caicos islands":{"icon":"\ud83c\uddf9\ud83c\udde8", "keystrokes":[":turks_caicos_islands:", ":turkscaicosislands:"]}, "tuvalu":{"icon":"\ud83c\uddf9\ud83c\uddfb", "keystrokes":[":tuvalu:"]}, "uganda":{"icon":"\ud83c\uddfa\ud83c\uddec", "keystrokes":[":uganda:"]}, 
  "ukraine":{"icon":"\ud83c\uddfa\ud83c\udde6", "keystrokes":[":ukraine:"]}, "united arab emirates":{"icon":"\ud83c\udde6\ud83c\uddea", "keystrokes":[":united_arab_emirates:", ":unitedarabemirates:"]}, "uk":{"icon":"\ud83c\uddec\ud83c\udde7", "keystrokes":[":uk:"]}, "us":{"icon":"\ud83c\uddfa\ud83c\uddf8", "keystrokes":[":us:"]}, "us virgin islands":{"icon":"\ud83c\uddfb\ud83c\uddee", "keystrokes":[":us_virgin_islands:", ":usvirginislands:"]}, "uruguay":{"icon":"\ud83c\uddfa\ud83c\uddfe", "keystrokes":[":uruguay:"]}, 
  "uzbekistan":{"icon":"\ud83c\uddfa\ud83c\uddff", "keystrokes":[":uzbekistan:"]}, "vanuatu":{"icon":"\ud83c\uddfb\ud83c\uddfa", "keystrokes":[":vanuatu:"]}, "vatican city":{"icon":"\ud83c\uddfb\ud83c\udde6", "keystrokes":[":vatican_city:", ":vaticancity:"]}, "venezuela":{"icon":"\ud83c\uddfb\ud83c\uddea", "keystrokes":[":venezuela:"]}, "vietnam":{"icon":"\ud83c\uddfb\ud83c\uddf3", "keystrokes":[":vietnam:"]}, "wallis futuna":{"icon":"\ud83c\uddfc\ud83c\uddeb", "keystrokes":[":wallis_futuna:", ":wallisfutuna:"]}, 
  "western sahara":{"icon":"\ud83c\uddea\ud83c\udded", "keystrokes":[":western_sahara:", ":westernsahara:"]}, "yemen":{"icon":"\ud83c\uddfe\ud83c\uddea", "keystrokes":[":yemen:"]}, "zambia":{"icon":"\ud83c\uddff\ud83c\uddf2", "keystrokes":[":zambia:"]}, "zimbabwe":{"icon":"\ud83c\uddff\ud83c\uddfc", "keystrokes":[":zimbabwe:"]}};
  util.emoticon.list = function() {
    var list = {};
    Object.keys(onceList).forEach(function(name) {
      var entry = onceList[name];
      if (entry.keystrokes) {
        var regexp = entry.keystrokes.map(function(keystroke) {
          return keystroke.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
        }).join("|");
        list[regexp] = entry;
      }
    });
    return list;
  }();
  util.emoticon.gatekeeper = Object.keys(util.emoticon.list).join("|");
  util.emoticon.fromInfo = function(info) {
    if (!info) {
      return null;
    }
    return goog.dom.createTextNode(info.icon);
  };
  util.emoticon.fromPattern = function(pattern) {
    var info = util.emoticon.list[pattern];
    return util.emoticon.fromInfo(info);
  };
})();
goog.provide("uno.util.typebehind.emoticon");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.defs");
goog.require("uno.util.emoticon");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var util = uno.util;
  var emoticon = uno.util.typebehind.emoticon;
  var log = goog.debug.Logger.getLogger("uno.util.typebehind.emoticon");
  emoticon.name = "emoticon";
  emoticon.matchBeginningOfLine = false;
  emoticon.rxs = Object.keys(util.emoticon.list).map(function(key) {
    return new RegExp(key);
  });
  emoticon.gatekeeper = new RegExp(util.emoticon.gatekeeper);
  emoticon.contextReplaceable = function(range, keyCode) {
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.EMOTICON, range)) {
      return false;
    }
    return true;
  };
  emoticon.getRegexes = function() {
    return emoticon.rxs;
  };
  emoticon.getGatekeeper = function() {
    return emoticon.gatekeeper;
  };
  emoticon.insertReplacement = function(range, rx, matchedText) {
    var newNode = util.emoticon.fromPattern(rx.source);
    range.replaceContentsWithNode(newNode);
    return {node:newNode, trimWhitespace:false};
  };
})();
goog.provide("uno.util.typebehind.hr");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.defs");
goog.require("uno.util.table");
goog.require("uno.util.structure");
(function() {
  var hr = uno.util.typebehind.hr;
  var util = uno.util;
  var log = goog.debug.Logger.getLogger("uno.util.typebehind.hr");
  var ENTER_KEY = goog.events.KeyCodes.ENTER;
  hr.name = "hr";
  hr.matchBeginningOfLine = true;
  hr.rxs = [new RegExp(uno.defs.regex.HORIZONTAL_RULE, "gi")];
  hr.contextReplaceable = function(range, keyCode) {
    if (keyCode !== ENTER_KEY) {
      return false;
    }
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.HR, range)) {
      return false;
    }
    return true;
  };
  hr.getRegexes = function() {
    return hr.rxs;
  };
  hr.insertReplacement = function(range, rx, matchedText) {
    var newNode = goog.dom.createDom("hr");
    range.replaceContentsWithNode(newNode);
    return {node:newNode, trimWhitespace:false};
  };
})();
goog.provide("uno.util.typebehind.list");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.defs");
goog.require("uno.util.paragraph");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var list = uno.util.typebehind.list;
  var BULLETED_LIST = uno.defs.regex.BULLETED_LIST;
  var NUMBERED_LIST = uno.defs.regex.NUMBERED_LIST;
  var HYPHEN_LIST = uno.defs.regex.HYPHEN_LIST;
  var util = uno.util;
  list.name = "list";
  list.matchBeginningOfLine = true;
  list.rxs = [new RegExp(BULLETED_LIST, "gi"), new RegExp(NUMBERED_LIST, "gi"), new RegExp(HYPHEN_LIST, "gi")];
  list.contextReplaceable = function(range) {
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.TYPE_LIST, range)) {
      return false;
    }
    return true;
  };
  list.getRegexes = function() {
    return list.rxs;
  };
  list.insertReplacement = function(range, rx, matchedText, editor) {
    var p = util.paragraph.for(range.getStartNode());
    if (!util.paragraph.hasBr(p)) {
      util.paragraph.appendBr(p);
    }
    var zwsOffset = 0;
    if (range.getStartNode().textContent.indexOf(uno.defs.unicode.ZERO_WIDTH_SPACE) > -1) {
      zwsOffset = 1;
    }
    range.getStartNode().replaceData(range.getStartOffset() + zwsOffset, matchedText.length - zwsOffset, "");
    if (rx.source === BULLETED_LIST || rx.source === HYPHEN_LIST) {
      editor.execCommand("insertunorderedlist");
    } else {
      if (rx.source === NUMBERED_LIST) {
        editor.execCommand("insertorderedlist");
        var trimmedText = util.string.trimZWS(matchedText);
        var startNumber = parseInt(trimmedText, 10);
        var node = ed.getRange().getStartNode();
        var ol = goog.dom.getAncestor(node, function(element) {
          return util.dom.isOl(element);
        }, true);
        if (ol) {
          ol.setAttribute("start", startNumber);
        }
      }
    }
    return {node:null, trimWhitespace:true};
  };
})();
goog.provide("uno.util.typebehind.table");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.defs");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var table = uno.util.typebehind.table;
  var util = uno.util;
  table.name = "table";
  table.matchBeginningOfLine = true;
  table.rxs = [new RegExp(uno.defs.regex.TABLE, "gi")];
  table.contextReplaceable = function(range) {
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.TABLE, range)) {
      return false;
    }
    return true;
  };
  table.getRegexes = function() {
    return table.rxs;
  };
  table.insertReplacement = function(range, rx, matchedText, editor) {
    goog.dom.Range.createFromNodes(range.getStartNode(), 0, range.getStartNode(), matchedText.length).select();
    var cols = matchedText.split("][").length;
    var rowMatch = matchedText.match(/[0-9]+$/);
    var rows = 1;
    if (rowMatch) {
      rows = parseInt(rowMatch[0], 10);
    }
    editor.execCommand("inserttable", {columns:cols, rows:rows});
    return {node:null, trimWhitespace:true};
  };
})();
goog.provide("uno.util.typebehind.todo");
goog.require("goog.asserts");
goog.require("goog.dom");
goog.require("goog.dom.classes");
goog.require("goog.debug.Logger");
goog.require("goog.editor.range");
goog.require("goog.events.KeyCodes");
goog.require("uno.defs");
goog.require("uno.util.dom");
goog.require("uno.util.todo");
goog.require("uno.util.crypto");
goog.require("uno.util.structure");
(function() {
  var todo = uno.util.typebehind.todo;
  var util = uno.util;
  todo.name = "todo";
  todo.matchBeginningOfLine = false;
  todo.rxs = [new RegExp(uno.defs.regex.TODO, "gi")];
  todo.contextReplaceable = function(range) {
    if (!util.structure.itemAllowedInRange(uno.defs.structuretypes.TODO, range)) {
      return false;
    }
    return true;
  };
  todo.getRegexes = function() {
    return todo.rxs;
  };
  todo.insertReplacement = function(range, rx, matchedText) {
    var checked = matchedText.toLowerCase().indexOf("x") > 0;
    var newTodo = util.todo.create(checked);
    range.removeContents();
    var rangeParent = range.getStartNode().parentElement;
    if (util.dom.isEmpty(rangeParent)) {
      range.insertNode(document.createElement("br"));
    }
    range.insertNode(newTodo);
    return {node:newTodo, trimWhitespace:true};
  };
})();
goog.provide("uno.util.typebehind.url");
goog.require("goog.asserts");
goog.require("goog.debug.Logger");
goog.require("uno.defs");
(function() {
  var url = uno.util.typebehind.url;
  url.name = "url";
  url.matchBeginningOfLine = false;
  url.rxs = [new RegExp(uno.defs.regex.SIMPLE_URL, "gi")];
  url.contextReplaceable = goog.functions.TRUE;
  url.getRegexes = function() {
    return url.rxs;
  };
  url.insertReplacement = function(range, rx, matchedText) {
    var newNode;
    var href = /^[a-zA-Z]+:\/\//.test(matchedText) ? matchedText : "http://" + matchedText;
    newNode = goog.dom.createDom("a", {href:href});
    newNode.textContent = matchedText;
    range.replaceContentsWithNode(newNode);
    return {node:newNode, trimWhitespace:false};
  };
})();
goog.provide("uno.listeners.TypeBehindListener");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("uno.BasePlugin");
goog.require("uno.util.typebehind");
goog.require("uno.util.typebehind.code");
goog.require("uno.util.typebehind.email");
goog.require("uno.util.typebehind.emoticon");
goog.require("uno.util.typebehind.hr");
goog.require("uno.util.typebehind.list");
goog.require("uno.util.typebehind.table");
goog.require("uno.util.typebehind.todo");
goog.require("uno.util.typebehind.url");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.TypeBehindListener");
  var SPACE_KEY = goog.events.KeyCodes.SPACE;
  var TAB_KEY = goog.events.KeyCodes.TAB;
  var ENTER_KEY = goog.events.KeyCodes.ENTER;
  var util = uno.util;
  var TypeBehindListener = uno.listeners.TypeBehindListener = function() {
    uno.BasePlugin.call(this, log.getName());
    this.imps = [];
    this.checkBeginningOfLines = false;
  };
  goog.inherits(TypeBehindListener, uno.BasePlugin);
  TypeBehindListener.IMPLEMENTATIONS = {code:uno.util.typebehind.code, email:uno.util.typebehind.email, emoticon:uno.util.typebehind.emoticon, horizontalrule:uno.util.typebehind.hr, list:uno.util.typebehind.list, table:uno.util.typebehind.table, todo:uno.util.typebehind.todo, url:uno.util.typebehind.url};
  TypeBehindListener.prototype.registerFieldObject = function(fieldObject) {
    var me = this;
    uno.BasePlugin.prototype.registerFieldObject.call(this, fieldObject);
    Object.keys(TypeBehindListener.IMPLEMENTATIONS).forEach(function(name) {
      var imp;
      if (fieldObject.config.typebehind[name]) {
        imp = TypeBehindListener.IMPLEMENTATIONS[name];
        me.imps.push(imp);
        if (imp.matchBeginningOfLine) {
          me.checkBeginningOfLines = true;
        }
      }
    });
  };
  var canTypebehind = true;
  TypeBehindListener.prototype.handleAfterExecCommand = function(event) {
    canTypebehind = !(event.command === "undo");
  };
  TypeBehindListener.prototype.handleKeyDown = function(event) {
    var replaced = false;
    var keyCode = event.keyCode;
    var range = this.editor.getRange();
    if (range && range.isCollapsed() && canTypebehind && (keyCode === SPACE_KEY || keyCode === TAB_KEY || keyCode === ENTER_KEY)) {
      replaced = util.typebehind.tryReplacements(event, this.imps, this.checkBeginningOfLines, this.editor);
    }
    if (replaced) {
      this.editor.dispatchChange();
    }
    canTypebehind = true;
    return replaced;
  };
})();
goog.setTestOnly("goog.testing.stacktrace");
goog.provide("goog.testing.stacktrace");
goog.provide("goog.testing.stacktrace.Frame");
goog.testing.stacktrace.Frame = function(context, name, alias, path) {
  this.context_ = context;
  this.name_ = name;
  this.alias_ = alias;
  this.path_ = path;
};
goog.testing.stacktrace.Frame.prototype.getName = function() {
  return this.name_;
};
goog.testing.stacktrace.Frame.prototype.isAnonymous = function() {
  return !this.name_ || this.context_ == "[object Object]";
};
goog.testing.stacktrace.Frame.prototype.toCanonicalString = function() {
  var htmlEscape = goog.testing.stacktrace.htmlEscape_;
  var deobfuscate = goog.testing.stacktrace.maybeDeobfuscateFunctionName_;
  var canonical = [this.context_ ? htmlEscape(this.context_) + "." : "", this.name_ ? htmlEscape(deobfuscate(this.name_)) : "anonymous", this.alias_ ? " [as " + htmlEscape(deobfuscate(this.alias_)) + "]" : ""];
  if (this.path_) {
    canonical.push(" at ");
    canonical.push(htmlEscape(this.path_));
  }
  return canonical.join("");
};
goog.testing.stacktrace.MAX_DEPTH_ = 20;
goog.testing.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_ = 500000;
goog.testing.stacktrace.IDENTIFIER_PATTERN_ = "[a-zA-Z_$][\\w$]*";
goog.testing.stacktrace.V8_ALIAS_PATTERN_ = "(?: \\[as (" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ")\\])?";
goog.testing.stacktrace.V8_CONTEXT_PATTERN_ = "(?:((?:new )?(?:\\[object Object\\]|" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + "(?:\\." + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ")*))\\.)?";
goog.testing.stacktrace.V8_FUNCTION_NAME_PATTERN_ = "(?:new )?(?:" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + "|<anonymous>)";
goog.testing.stacktrace.V8_FUNCTION_CALL_PATTERN_ = " " + goog.testing.stacktrace.V8_CONTEXT_PATTERN_ + "(" + goog.testing.stacktrace.V8_FUNCTION_NAME_PATTERN_ + ")" + goog.testing.stacktrace.V8_ALIAS_PATTERN_;
goog.testing.stacktrace.URL_PATTERN_ = "((?:http|https|file)://[^\\s)]+|javascript:.*)";
goog.testing.stacktrace.CHROME_URL_PATTERN_ = " (?:" + "\\(unknown source\\)" + "|" + "\\(native\\)" + "|" + "\\((.+)\\)|(.+))";
goog.testing.stacktrace.V8_STACK_FRAME_REGEXP_ = new RegExp("^    at" + "(?:" + goog.testing.stacktrace.V8_FUNCTION_CALL_PATTERN_ + ")?" + goog.testing.stacktrace.CHROME_URL_PATTERN_ + "$");
goog.testing.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ = "(" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + "(?:\\." + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ")*" + ")?" + "(\\(.*\\))?@";
goog.testing.stacktrace.FIREFOX_STACK_FRAME_REGEXP_ = new RegExp("^" + goog.testing.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ + "(?::0|" + goog.testing.stacktrace.URL_PATTERN_ + ")$");
goog.testing.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ = "<anonymous function(?:\\: " + "(?:(" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + "(?:\\." + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ")*)\\.)?" + "(" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + "))?>";
goog.testing.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ = "(?:(?:(" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ")|" + goog.testing.stacktrace.OPERA_ANONYMOUS_FUNCTION_NAME_PATTERN_ + ")(\\(.*\\)))?@";
goog.testing.stacktrace.OPERA_STACK_FRAME_REGEXP_ = new RegExp("^" + goog.testing.stacktrace.OPERA_FUNCTION_CALL_PATTERN_ + goog.testing.stacktrace.URL_PATTERN_ + "?$");
goog.testing.stacktrace.FUNCTION_SOURCE_REGEXP_ = new RegExp("^function (" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ")");
goog.testing.stacktrace.IE_FUNCTION_CALL_PATTERN_ = "(" + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + "(?:\\." + goog.testing.stacktrace.IDENTIFIER_PATTERN_ + ")*" + "(?:\\s+\\w+)*)";
goog.testing.stacktrace.IE_STACK_FRAME_REGEXP_ = new RegExp("^   at " + goog.testing.stacktrace.IE_FUNCTION_CALL_PATTERN_ + "\\s*\\(" + "(" + "eval code:[^)]*" + "|" + "Unknown script code:[^)]*" + "|" + goog.testing.stacktrace.URL_PATTERN_ + ")\\)?$");
goog.testing.stacktrace.followCallChain_ = function() {
  var frames = [];
  var fn = arguments.callee.caller;
  var depth = 0;
  while (fn && depth < goog.testing.stacktrace.MAX_DEPTH_) {
    var fnString = Function.prototype.toString.call(fn);
    var match = fnString.match(goog.testing.stacktrace.FUNCTION_SOURCE_REGEXP_);
    var functionName = match ? match[1] : "";
    frames.push(new goog.testing.stacktrace.Frame("", functionName, "", ""));
    try {
      fn = fn.caller;
    } catch (e) {
      break;
    }
    depth++;
  }
  return frames;
};
goog.testing.stacktrace.parseStackFrame_ = function(frameStr) {
  var m = frameStr.match(goog.testing.stacktrace.V8_STACK_FRAME_REGEXP_);
  if (m) {
    return new goog.testing.stacktrace.Frame(m[1] || "", m[2] || "", m[3] || "", m[4] || m[5] || m[6] || "");
  }
  if (frameStr.length > goog.testing.stacktrace.MAX_FIREFOX_FRAMESTRING_LENGTH_) {
    return null;
  }
  m = frameStr.match(goog.testing.stacktrace.FIREFOX_STACK_FRAME_REGEXP_);
  if (m) {
    return new goog.testing.stacktrace.Frame("", m[1] || "", "", m[3] || "");
  }
  m = frameStr.match(goog.testing.stacktrace.OPERA_STACK_FRAME_REGEXP_);
  if (m) {
    return new goog.testing.stacktrace.Frame(m[2] || "", m[1] || m[3] || "", "", m[5] || "");
  }
  m = frameStr.match(goog.testing.stacktrace.IE_STACK_FRAME_REGEXP_);
  if (m) {
    return new goog.testing.stacktrace.Frame("", m[1] || "", "", m[2] || "");
  }
  return null;
};
goog.testing.stacktrace.deobfuscateFunctionName_;
goog.testing.stacktrace.setDeobfuscateFunctionName = function(fn) {
  goog.testing.stacktrace.deobfuscateFunctionName_ = fn;
};
goog.testing.stacktrace.maybeDeobfuscateFunctionName_ = function(name) {
  return goog.testing.stacktrace.deobfuscateFunctionName_ ? goog.testing.stacktrace.deobfuscateFunctionName_(name) : name;
};
goog.testing.stacktrace.htmlEscape_ = function(text) {
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
};
goog.testing.stacktrace.framesToString_ = function(frames) {
  var lastIndex = frames.length - 1;
  while (frames[lastIndex] && frames[lastIndex].isAnonymous()) {
    lastIndex--;
  }
  var privateAssertIndex = -1;
  for (var i = 0; i < frames.length; i++) {
    if (frames[i] && frames[i].getName() == "_assert") {
      privateAssertIndex = i;
      break;
    }
  }
  var canonical = [];
  for (var i = privateAssertIndex + 1; i <= lastIndex; i++) {
    canonical.push("> ");
    if (frames[i]) {
      canonical.push(frames[i].toCanonicalString());
    } else {
      canonical.push("(unknown)");
    }
    canonical.push("\n");
  }
  return canonical.join("");
};
goog.testing.stacktrace.parse_ = function(stack) {
  var lines = stack.replace(/\s*$/, "").split("\n");
  var frames = [];
  for (var i = 0; i < lines.length; i++) {
    frames.push(goog.testing.stacktrace.parseStackFrame_(lines[i]));
  }
  return frames;
};
goog.testing.stacktrace.canonicalize = function(stack) {
  var frames = goog.testing.stacktrace.parse_(stack);
  return goog.testing.stacktrace.framesToString_(frames);
};
goog.testing.stacktrace.getNativeStack_ = function() {
  var tmpError = new Error;
  if (tmpError.stack) {
    return tmpError.stack;
  }
  try {
    null.x();
  } catch (e) {
    return e.stack;
  }
  return "";
};
goog.testing.stacktrace.get = function() {
  var stack = goog.testing.stacktrace.getNativeStack_();
  var frames;
  if (!stack) {
    frames = goog.testing.stacktrace.followCallChain_();
  } else {
    if (goog.isArray(stack)) {
      frames = goog.testing.stacktrace.callSitesToFrames_(stack);
    } else {
      frames = goog.testing.stacktrace.parse_(stack);
    }
  }
  return goog.testing.stacktrace.framesToString_(frames);
};
goog.testing.stacktrace.callSitesToFrames_ = function(stack) {
  var frames = [];
  for (var i = 0; i < stack.length; i++) {
    var callSite = stack[i];
    var functionName = callSite.getFunctionName() || "unknown";
    var fileName = callSite.getFileName();
    var path = fileName ? fileName + ":" + callSite.getLineNumber() + ":" + callSite.getColumnNumber() : "unknown";
    frames.push(new goog.testing.stacktrace.Frame("", functionName, "", path));
  }
  return frames;
};
goog.exportSymbol("setDeobfuscateFunctionName", goog.testing.stacktrace.setDeobfuscateFunctionName);
goog.provide("goog.testing.JsUnitException");
goog.setTestOnly();
goog.require("goog.testing.stacktrace");
goog.testing.JsUnitException = function(comment, opt_message) {
  this.isJsUnitException = true;
  this.message = (comment ? comment : "") + (comment && opt_message ? "\n" : "") + (opt_message ? opt_message : "");
  this.stackTrace = goog.testing.stacktrace.get();
  this.comment = comment || null;
  this.jsUnitMessage = opt_message || "";
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, goog.testing.JsUnitException);
  } else {
    this.stack = (new Error).stack || "";
  }
};
goog.inherits(goog.testing.JsUnitException, Error);
goog.testing.JsUnitException.prototype.toString = function() {
  return this.message;
};
goog.provide("goog.testing.asserts");
goog.setTestOnly();
goog.require("goog.testing.JsUnitException");
var DOUBLE_EQUALITY_PREDICATE = function(var1, var2) {
  return var1 == var2;
};
var JSUNIT_UNDEFINED_VALUE = void 0;
var TO_STRING_EQUALITY_PREDICATE = function(var1, var2) {
  return var1.toString() === var2.toString();
};
var PredicateFunctionType;
var PRIMITIVE_EQUALITY_PREDICATES = {"String":DOUBLE_EQUALITY_PREDICATE, "Number":DOUBLE_EQUALITY_PREDICATE, "Boolean":DOUBLE_EQUALITY_PREDICATE, "Date":function(date1, date2) {
  return date1.getTime() == date2.getTime();
}, "RegExp":TO_STRING_EQUALITY_PREDICATE, "Function":TO_STRING_EQUALITY_PREDICATE};
goog.testing.asserts.numberRoughEqualityPredicate_ = function(var1, var2, tolerance) {
  return Math.abs(var1 - var2) <= tolerance;
};
goog.testing.asserts.primitiveRoughEqualityPredicates_ = {"Number":goog.testing.asserts.numberRoughEqualityPredicate_};
var _trueTypeOf = function(something) {
  var result = typeof something;
  try {
    switch(result) {
      case "string":
        break;
      case "boolean":
        break;
      case "number":
        break;
      case "object":
        if (something == null) {
          result = "null";
          break;
        }
      case "function":
        switch(something.constructor) {
          case (new String("")).constructor:
            result = "String";
            break;
          case (new Boolean(true)).constructor:
            result = "Boolean";
            break;
          case (new Number(0)).constructor:
            result = "Number";
            break;
          case (new Array).constructor:
            result = "Array";
            break;
          case (new RegExp).constructor:
            result = "RegExp";
            break;
          case (new Date).constructor:
            result = "Date";
            break;
          case Function:
            result = "Function";
            break;
          default:
            var m = something.constructor.toString().match(/function\s*([^( ]+)\(/);
            if (m) {
              result = m[1];
            } else {
              break;
            }
        }break;
    }
  } catch (e) {
  } finally {
    result = result.substr(0, 1).toUpperCase() + result.substr(1);
  }
  return result;
};
var _displayStringForValue = function(aVar) {
  var result;
  try {
    result = "<" + String(aVar) + ">";
  } catch (ex) {
    result = "<toString failed: " + ex.message + ">";
  }
  if (!(aVar === null || aVar === JSUNIT_UNDEFINED_VALUE)) {
    result += " (" + _trueTypeOf(aVar) + ")";
  }
  return result;
};
var fail = function(failureMessage) {
  goog.testing.asserts.raiseException("Call to fail()", failureMessage);
};
var argumentsIncludeComments = function(expectedNumberOfNonCommentArgs, args) {
  return args.length == expectedNumberOfNonCommentArgs + 1;
};
var commentArg = function(expectedNumberOfNonCommentArgs, args) {
  if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) {
    return args[0];
  }
  return null;
};
var nonCommentArg = function(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) {
  return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ? args[desiredNonCommentArgIndex] : args[desiredNonCommentArgIndex - 1];
};
var _validateArguments = function(expectedNumberOfNonCommentArgs, args) {
  var valid = args.length == expectedNumberOfNonCommentArgs || args.length == expectedNumberOfNonCommentArgs + 1 && goog.isString(args[0]);
  _assert(null, valid, "Incorrect arguments passed to assert function");
};
var _getCurrentTestCase = function() {
  var testRunner = goog.global["G_testRunner"];
  return testRunner ? testRunner.testCase : null;
};
var _assert = function(comment, booleanValue, failureMessage) {
  if (!booleanValue) {
    goog.testing.asserts.raiseException(comment, failureMessage);
  }
};
goog.testing.asserts.getDefaultErrorMsg_ = function(expected, actual) {
  var msg = "Expected " + _displayStringForValue(expected) + " but was " + _displayStringForValue(actual);
  if (typeof expected == "string" && typeof actual == "string") {
    var limit = Math.min(expected.length, actual.length);
    var commonPrefix = 0;
    while (commonPrefix < limit && expected.charAt(commonPrefix) == actual.charAt(commonPrefix)) {
      commonPrefix++;
    }
    var commonSuffix = 0;
    while (commonSuffix < limit && expected.charAt(expected.length - commonSuffix - 1) == actual.charAt(actual.length - commonSuffix - 1)) {
      commonSuffix++;
    }
    if (commonPrefix + commonSuffix > limit) {
      commonSuffix = 0;
    }
    if (commonPrefix > 2 || commonSuffix > 2) {
      var printString = function(str) {
        var startIndex = Math.max(0, commonPrefix - 2);
        var endIndex = Math.min(str.length, str.length - (commonSuffix - 2));
        return (startIndex > 0 ? "..." : "") + str.substring(startIndex, endIndex) + (endIndex < str.length ? "..." : "");
      };
      msg += "\nDifference was at position " + commonPrefix + ". Expected [" + printString(expected) + "] vs. actual [" + printString(actual) + "]";
    }
  }
  return msg;
};
var assert = function(a, opt_b) {
  _validateArguments(1, arguments);
  var comment = commentArg(1, arguments);
  var booleanValue = nonCommentArg(1, 1, arguments);
  _assert(comment, goog.isBoolean(booleanValue), "Bad argument to assert(boolean)");
  _assert(comment, booleanValue, "Call to assert(boolean) with false");
};
var assertThrows = function(a, opt_b) {
  _validateArguments(1, arguments);
  var func = nonCommentArg(1, 1, arguments);
  var comment = commentArg(1, arguments);
  _assert(comment, typeof func == "function", "Argument passed to assertThrows is not a function");
  try {
    func();
  } catch (e) {
    if (e && goog.isString(e["stacktrace"]) && goog.isString(e["message"])) {
      var startIndex = e["message"].length - e["stacktrace"].length;
      if (e["message"].indexOf(e["stacktrace"], startIndex) == startIndex) {
        e["message"] = e["message"].substr(0, startIndex - 14);
      }
    }
    var testCase = _getCurrentTestCase();
    if (e && e["isJsUnitException"] && testCase && testCase.failOnUnreportedAsserts) {
      goog.testing.asserts.raiseException(comment, "Function passed to assertThrows caught a JsUnitException (usually " + "from an assert or call to fail()). If this is expected, use " + "assertThrowsJsUnitException instead.");
    }
    return e;
  }
  goog.testing.asserts.raiseException(comment, "No exception thrown from function passed to assertThrows");
};
var assertNotThrows = function(a, opt_b) {
  _validateArguments(1, arguments);
  var comment = commentArg(1, arguments);
  var func = nonCommentArg(1, 1, arguments);
  _assert(comment, typeof func == "function", "Argument passed to assertNotThrows is not a function");
  try {
    return func();
  } catch (e) {
    comment = comment ? comment + "\n" : "";
    comment += "A non expected exception was thrown from function passed to " + "assertNotThrows";
    var stackTrace = e["stack"] || e["stacktrace"] || e.toString();
    goog.testing.asserts.raiseException(comment, stackTrace);
  }
};
var assertThrowsJsUnitException = function(callback, opt_expectedMessage) {
  try {
    goog.testing.asserts.callWithoutLogging(callback);
  } catch (e) {
    var testCase = _getCurrentTestCase();
    if (testCase) {
      testCase.invalidateAssertionException(e);
    } else {
      goog.global.console.error("Failed to remove expected exception: no test case is installed.");
    }
    if (!e.isJsUnitException) {
      fail("Expected a JsUnitException");
    }
    if (typeof opt_expectedMessage != "undefined" && e.message != opt_expectedMessage) {
      fail("Expected message [" + opt_expectedMessage + "] but got [" + e.message + "]");
    }
    return e;
  }
  var msg = "Expected a failure";
  if (typeof opt_expectedMessage != "undefined") {
    msg += ": " + opt_expectedMessage;
  }
  throw new goog.testing.JsUnitException(msg);
};
var assertTrue = function(a, opt_b) {
  _validateArguments(1, arguments);
  var comment = commentArg(1, arguments);
  var booleanValue = nonCommentArg(1, 1, arguments);
  _assert(comment, goog.isBoolean(booleanValue), "Bad argument to assertTrue(boolean)");
  _assert(comment, booleanValue, "Call to assertTrue(boolean) with false");
};
var assertFalse = function(a, opt_b) {
  _validateArguments(1, arguments);
  var comment = commentArg(1, arguments);
  var booleanValue = nonCommentArg(1, 1, arguments);
  _assert(comment, goog.isBoolean(booleanValue), "Bad argument to assertFalse(boolean)");
  _assert(comment, !booleanValue, "Call to assertFalse(boolean) with true");
};
var assertEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var var1 = nonCommentArg(1, 2, arguments);
  var var2 = nonCommentArg(2, 2, arguments);
  _assert(commentArg(2, arguments), var1 === var2, goog.testing.asserts.getDefaultErrorMsg_(var1, var2));
};
var assertNotEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var var1 = nonCommentArg(1, 2, arguments);
  var var2 = nonCommentArg(2, 2, arguments);
  _assert(commentArg(2, arguments), var1 !== var2, "Expected not to be " + _displayStringForValue(var2));
};
var assertNull = function(a, opt_b) {
  _validateArguments(1, arguments);
  var aVar = nonCommentArg(1, 1, arguments);
  _assert(commentArg(1, arguments), aVar === null, goog.testing.asserts.getDefaultErrorMsg_(null, aVar));
};
var assertNotNull = function(a, opt_b) {
  _validateArguments(1, arguments);
  var aVar = nonCommentArg(1, 1, arguments);
  _assert(commentArg(1, arguments), aVar !== null, "Expected not to be " + _displayStringForValue(null));
};
var assertUndefined = function(a, opt_b) {
  _validateArguments(1, arguments);
  var aVar = nonCommentArg(1, 1, arguments);
  _assert(commentArg(1, arguments), aVar === JSUNIT_UNDEFINED_VALUE, goog.testing.asserts.getDefaultErrorMsg_(JSUNIT_UNDEFINED_VALUE, aVar));
};
var assertNotUndefined = function(a, opt_b) {
  _validateArguments(1, arguments);
  var aVar = nonCommentArg(1, 1, arguments);
  _assert(commentArg(1, arguments), aVar !== JSUNIT_UNDEFINED_VALUE, "Expected not to be " + _displayStringForValue(JSUNIT_UNDEFINED_VALUE));
};
var assertNotNullNorUndefined = function(a, opt_b) {
  _validateArguments(1, arguments);
  assertNotNull.apply(null, arguments);
  assertNotUndefined.apply(null, arguments);
};
var assertNonEmptyString = function(a, opt_b) {
  _validateArguments(1, arguments);
  var aVar = nonCommentArg(1, 1, arguments);
  _assert(commentArg(1, arguments), aVar !== JSUNIT_UNDEFINED_VALUE && aVar !== null && typeof aVar == "string" && aVar !== "", "Expected non-empty string but was " + _displayStringForValue(aVar));
};
var assertNaN = function(a, opt_b) {
  _validateArguments(1, arguments);
  var aVar = nonCommentArg(1, 1, arguments);
  _assert(commentArg(1, arguments), isNaN(aVar), "Expected NaN");
};
var assertNotNaN = function(a, opt_b) {
  _validateArguments(1, arguments);
  var aVar = nonCommentArg(1, 1, arguments);
  _assert(commentArg(1, arguments), !isNaN(aVar), "Expected not NaN");
};
goog.testing.asserts.callWithoutLogging = function(fn) {
  var testRunner = goog.global["G_testRunner"];
  var oldLogTestFailure = testRunner["logTestFailure"];
  try {
    testRunner["logTestFailure"] = undefined;
    fn();
  } finally {
    testRunner["logTestFailure"] = oldLogTestFailure;
  }
};
goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS = null;
goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL = "";
goog.testing.asserts.findDifferences = function(expected, actual, opt_equalityPredicate) {
  var failures = [];
  var seen1 = [];
  var seen2 = [];
  function innerAssertWithCycleCheck(var1, var2, path) {
    for (var i = 0; i < seen1.length; ++i) {
      var match1 = seen1[i] === var1;
      var match2 = seen2[i] === var2;
      if (match1 || match2) {
        if (!match1 || !match2) {
          failures.push("Asymmetric cycle detected at " + path);
        }
        return;
      }
    }
    seen1.push(var1);
    seen2.push(var2);
    innerAssertImplementation(var1, var2, path);
    seen1.pop();
    seen2.pop();
  }
  var equalityPredicate = opt_equalityPredicate || function(type, var1, var2) {
    var typedPredicate = PRIMITIVE_EQUALITY_PREDICATES[type];
    if (!typedPredicate) {
      return goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS;
    }
    var equal = typedPredicate(var1, var2);
    return equal ? goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL : goog.testing.asserts.getDefaultErrorMsg_(var1, var2);
  };
  function innerAssertImplementation(var1, var2, path) {
    if (var1 === var2) {
      return;
    }
    var typeOfVar1 = _trueTypeOf(var1);
    var typeOfVar2 = _trueTypeOf(var2);
    if (typeOfVar1 == typeOfVar2) {
      var isArray = typeOfVar1 == "Array";
      var errorMessage = equalityPredicate(typeOfVar1, var1, var2);
      if (errorMessage != goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS) {
        if (errorMessage != goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL) {
          failures.push(path + ": " + errorMessage);
        }
      } else {
        if (isArray && var1.length != var2.length) {
          failures.push(path + ": Expected " + var1.length + "-element array " + "but got a " + var2.length + "-element array");
        } else {
          if (typeOfVar1 == "String") {
            if (var1 != var2) {
              failures.push(path + ': Expected String "' + var1 + '" ' + 'but got "' + var2 + '"');
            }
          } else {
            var childPath = path + (isArray ? "[%s]" : path ? ".%s" : "%s");
            if (typeof Map != "undefined" && var1 instanceof Map || typeof Set != "undefined" && var1 instanceof Set) {
              var1.forEach(function(value, key) {
                if (var2.has(key)) {
                  if (var2.get) {
                    innerAssertWithCycleCheck(value, var2.get(key), childPath.replace("%s", key));
                  }
                } else {
                  failures.push(key + " not present in actual " + (path || typeOfVar2));
                }
              });
              var2.forEach(function(value, key) {
                if (!var1.has(key)) {
                  failures.push(key + " not present in expected " + (path || typeOfVar1));
                }
              });
            } else {
              if (!var1["__iterator__"]) {
                for (var prop in var1) {
                  if (isArray && goog.testing.asserts.isArrayIndexProp_(prop)) {
                    continue;
                  }
                  if (prop in var2) {
                    innerAssertWithCycleCheck(var1[prop], var2[prop], childPath.replace("%s", prop));
                  } else {
                    failures.push("property " + prop + " not present in actual " + (path || typeOfVar2));
                  }
                }
                for (var prop in var2) {
                  if (isArray && goog.testing.asserts.isArrayIndexProp_(prop)) {
                    continue;
                  }
                  if (!(prop in var1)) {
                    failures.push("property " + prop + " not present in expected " + (path || typeOfVar1));
                  }
                }
                if (isArray) {
                  for (prop = 0; prop < var1.length; prop++) {
                    innerAssertWithCycleCheck(var1[prop], var2[prop], childPath.replace("%s", String(prop)));
                  }
                }
              } else {
                if (goog.isFunction(var1.equals)) {
                  if (!var1.equals(var2)) {
                    failures.push("equals() returned false for " + (path || typeOfVar1));
                  }
                } else {
                  if (var1.map_) {
                    innerAssertWithCycleCheck(var1.map_, var2.map_, childPath.replace("%s", "map_"));
                  } else {
                    failures.push("unable to check " + (path || typeOfVar1) + " for equality: it has an iterator we do not " + "know how to handle. please add an equals method");
                  }
                }
              }
            }
          }
        }
      }
    } else {
      failures.push(path + " " + goog.testing.asserts.getDefaultErrorMsg_(var1, var2));
    }
  }
  innerAssertWithCycleCheck(expected, actual, "");
  return failures.length == 0 ? null : goog.testing.asserts.getDefaultErrorMsg_(expected, actual) + "\n   " + failures.join("\n   ");
};
var assertObjectEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var v1 = nonCommentArg(1, 2, arguments);
  var v2 = nonCommentArg(2, 2, arguments);
  var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : "";
  var differences = goog.testing.asserts.findDifferences(v1, v2);
  _assert(failureMessage, !differences, differences);
};
var assertObjectRoughlyEquals = function(a, b, c, opt_d) {
  _validateArguments(3, arguments);
  var v1 = nonCommentArg(1, 3, arguments);
  var v2 = nonCommentArg(2, 3, arguments);
  var tolerance = nonCommentArg(3, 3, arguments);
  var failureMessage = commentArg(3, arguments) ? commentArg(3, arguments) : "";
  var equalityPredicate = function(type, var1, var2) {
    var typedPredicate = goog.testing.asserts.primitiveRoughEqualityPredicates_[type];
    if (!typedPredicate) {
      return goog.testing.asserts.EQUALITY_PREDICATE_CANT_PROCESS;
    }
    var equal = typedPredicate(var1, var2, tolerance);
    return equal ? goog.testing.asserts.EQUALITY_PREDICATE_VARS_ARE_EQUAL : goog.testing.asserts.getDefaultErrorMsg_(var1, var2) + " which was more than " + tolerance + " away";
  };
  var differences = goog.testing.asserts.findDifferences(v1, v2, equalityPredicate);
  _assert(failureMessage, !differences, differences);
};
var assertObjectNotEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var v1 = nonCommentArg(1, 2, arguments);
  var v2 = nonCommentArg(2, 2, arguments);
  var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : "";
  var differences = goog.testing.asserts.findDifferences(v1, v2);
  _assert(failureMessage, differences, "Objects should not be equal");
};
var assertArrayEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var v1 = nonCommentArg(1, 2, arguments);
  var v2 = nonCommentArg(2, 2, arguments);
  var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : "";
  var typeOfVar1 = _trueTypeOf(v1);
  _assert(failureMessage, typeOfVar1 == "Array", "Expected an array for assertArrayEquals but found a " + typeOfVar1);
  var typeOfVar2 = _trueTypeOf(v2);
  _assert(failureMessage, typeOfVar2 == "Array", "Expected an array for assertArrayEquals but found a " + typeOfVar2);
  assertObjectEquals(failureMessage, Array.prototype.concat.call(v1), Array.prototype.concat.call(v2));
};
var assertElementsEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var v1 = nonCommentArg(1, 2, arguments);
  var v2 = nonCommentArg(2, 2, arguments);
  var failureMessage = commentArg(2, arguments) ? commentArg(2, arguments) : "";
  if (!v1) {
    assert(failureMessage, !v2);
  } else {
    assertEquals("length mismatch: " + failureMessage, v1.length, v2.length);
    for (var i = 0; i < v1.length; ++i) {
      assertEquals("mismatch at index " + i + ": " + failureMessage, v1[i], v2[i]);
    }
  }
};
var assertElementsRoughlyEqual = function(a, b, c, opt_d) {
  _validateArguments(3, arguments);
  var v1 = nonCommentArg(1, 3, arguments);
  var v2 = nonCommentArg(2, 3, arguments);
  var tolerance = nonCommentArg(3, 3, arguments);
  var failureMessage = commentArg(3, arguments) ? commentArg(3, arguments) : "";
  if (!v1) {
    assert(failureMessage, !v2);
  } else {
    assertEquals("length mismatch: " + failureMessage, v1.length, v2.length);
    for (var i = 0; i < v1.length; ++i) {
      assertRoughlyEquals(failureMessage, v1[i], v2[i], tolerance);
    }
  }
};
var assertSameElements = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var expected = nonCommentArg(1, 2, arguments);
  var actual = nonCommentArg(2, 2, arguments);
  var message = commentArg(2, arguments);
  assertTrue("Bad arguments to assertSameElements(opt_message, expected: " + "ArrayLike, actual: ArrayLike)", goog.isArrayLike(expected) && goog.isArrayLike(actual));
  expected = goog.testing.asserts.toArray_(expected);
  actual = goog.testing.asserts.toArray_(actual);
  _assert(message, expected.length == actual.length, "Expected " + expected.length + " elements: [" + expected + "], " + "got " + actual.length + " elements: [" + actual + "]");
  var toFind = goog.testing.asserts.toArray_(expected);
  for (var i = 0; i < actual.length; i++) {
    var index = goog.testing.asserts.indexOf_(toFind, actual[i]);
    _assert(message, index != -1, "Expected [" + expected + "], got [" + actual + "]");
    toFind.splice(index, 1);
  }
};
var assertEvaluatesToTrue = function(a, opt_b) {
  _validateArguments(1, arguments);
  var value = nonCommentArg(1, 1, arguments);
  if (!value) {
    _assert(commentArg(1, arguments), false, "Expected to evaluate to true");
  }
};
var assertEvaluatesToFalse = function(a, opt_b) {
  _validateArguments(1, arguments);
  var value = nonCommentArg(1, 1, arguments);
  if (value) {
    _assert(commentArg(1, arguments), false, "Expected to evaluate to false");
  }
};
var assertHTMLEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var var1 = nonCommentArg(1, 2, arguments);
  var var2 = nonCommentArg(2, 2, arguments);
  var var1Standardized = standardizeHTML(var1);
  var var2Standardized = standardizeHTML(var2);
  _assert(commentArg(2, arguments), var1Standardized === var2Standardized, goog.testing.asserts.getDefaultErrorMsg_(var1Standardized, var2Standardized));
};
var assertCSSValueEquals = function(a, b, c, opt_d) {
  _validateArguments(3, arguments);
  var propertyName = nonCommentArg(1, 3, arguments);
  var expectedValue = nonCommentArg(2, 3, arguments);
  var actualValue = nonCommentArg(3, 3, arguments);
  var expectedValueStandardized = standardizeCSSValue(propertyName, expectedValue);
  var actualValueStandardized = standardizeCSSValue(propertyName, actualValue);
  _assert(commentArg(3, arguments), expectedValueStandardized == actualValueStandardized, goog.testing.asserts.getDefaultErrorMsg_(expectedValueStandardized, actualValueStandardized));
};
var assertHashEquals = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var var1 = nonCommentArg(1, 2, arguments);
  var var2 = nonCommentArg(2, 2, arguments);
  var message = commentArg(2, arguments);
  for (var key in var1) {
    _assert(message, key in var2, "Expected hash had key " + key + " that was not found");
    _assert(message, var1[key] == var2[key], "Value for key " + key + " mismatch - expected = " + var1[key] + ", actual = " + var2[key]);
  }
  for (var key in var2) {
    _assert(message, key in var1, "Actual hash had key " + key + " that was not expected");
  }
};
var assertRoughlyEquals = function(a, b, c, opt_d) {
  _validateArguments(3, arguments);
  var expected = nonCommentArg(1, 3, arguments);
  var actual = nonCommentArg(2, 3, arguments);
  var tolerance = nonCommentArg(3, 3, arguments);
  _assert(commentArg(3, arguments), goog.testing.asserts.numberRoughEqualityPredicate_(expected, actual, tolerance), "Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away");
};
var assertContains = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var contained = nonCommentArg(1, 2, arguments);
  var container = nonCommentArg(2, 2, arguments);
  _assert(commentArg(2, arguments), goog.testing.asserts.contains_(container, contained), "Expected '" + container + "' to contain '" + contained + "'");
};
var assertNotContains = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var contained = nonCommentArg(1, 2, arguments);
  var container = nonCommentArg(2, 2, arguments);
  _assert(commentArg(2, arguments), !goog.testing.asserts.contains_(container, contained), "Expected '" + container + "' not to contain '" + contained + "'");
};
var assertRegExp = function(a, b, opt_c) {
  _validateArguments(2, arguments);
  var regexp = nonCommentArg(1, 2, arguments);
  var string = nonCommentArg(2, 2, arguments);
  if (typeof regexp == "string") {
    regexp = new RegExp(regexp);
  }
  _assert(commentArg(2, arguments), regexp.test(string), "Expected '" + string + "' to match RegExp " + regexp.toString());
};
goog.testing.asserts.toArray_ = function(arrayLike) {
  var ret = [];
  for (var i = 0; i < arrayLike.length; i++) {
    ret[i] = arrayLike[i];
  }
  return ret;
};
goog.testing.asserts.indexOf_ = function(container, contained) {
  if (container.indexOf) {
    return container.indexOf(contained);
  } else {
    for (var i = 0; i < container.length; i++) {
      if (container[i] === contained) {
        return i;
      }
    }
    return -1;
  }
};
goog.testing.asserts.contains_ = function(container, contained) {
  return goog.testing.asserts.indexOf_(container, contained) != -1;
};
var standardizeHTML = function(html) {
  var translator = document.createElement("DIV");
  translator.innerHTML = html;
  return translator.innerHTML.replace(/^\s+|\s+$/g, "");
};
var standardizeCSSValue = function(propertyName, value) {
  var styleDeclaration = document.createElement("DIV").style;
  styleDeclaration[propertyName] = value;
  return styleDeclaration[propertyName];
};
goog.testing.asserts.raiseException = function(comment, opt_message) {
  var e = new goog.testing.JsUnitException(comment, opt_message);
  var testCase = _getCurrentTestCase();
  if (testCase) {
    testCase.raiseAssertionException(e);
  } else {
    goog.global.console.error("Failed to save thrown exception: no test case is installed.");
    throw e;
  }
};
goog.testing.asserts.isArrayIndexProp_ = function(prop) {
  return (prop | 0) == prop;
};
goog.exportSymbol("fail", fail);
goog.exportSymbol("assert", assert);
goog.exportSymbol("assertThrows", assertThrows);
goog.exportSymbol("assertNotThrows", assertNotThrows);
goog.exportSymbol("assertThrowsJsUnitException", assertThrowsJsUnitException);
goog.exportSymbol("assertTrue", assertTrue);
goog.exportSymbol("assertFalse", assertFalse);
goog.exportSymbol("assertEquals", assertEquals);
goog.exportSymbol("assertNotEquals", assertNotEquals);
goog.exportSymbol("assertNull", assertNull);
goog.exportSymbol("assertNotNull", assertNotNull);
goog.exportSymbol("assertUndefined", assertUndefined);
goog.exportSymbol("assertNotUndefined", assertNotUndefined);
goog.exportSymbol("assertNotNullNorUndefined", assertNotNullNorUndefined);
goog.exportSymbol("assertNonEmptyString", assertNonEmptyString);
goog.exportSymbol("assertNaN", assertNaN);
goog.exportSymbol("assertNotNaN", assertNotNaN);
goog.exportSymbol("assertObjectEquals", assertObjectEquals);
goog.exportSymbol("assertObjectRoughlyEquals", assertObjectRoughlyEquals);
goog.exportSymbol("assertObjectNotEquals", assertObjectNotEquals);
goog.exportSymbol("assertArrayEquals", assertArrayEquals);
goog.exportSymbol("assertElementsEquals", assertElementsEquals);
goog.exportSymbol("assertElementsRoughlyEqual", assertElementsRoughlyEqual);
goog.exportSymbol("assertSameElements", assertSameElements);
goog.exportSymbol("assertEvaluatesToTrue", assertEvaluatesToTrue);
goog.exportSymbol("assertEvaluatesToFalse", assertEvaluatesToFalse);
goog.exportSymbol("assertHTMLEquals", assertHTMLEquals);
goog.exportSymbol("assertHashEquals", assertHashEquals);
goog.exportSymbol("assertRoughlyEquals", assertRoughlyEquals);
goog.exportSymbol("assertContains", assertContains);
goog.exportSymbol("assertNotContains", assertNotContains);
goog.exportSymbol("assertRegExp", assertRegExp);
goog.setTestOnly("goog.testing.editor.dom");
goog.provide("goog.testing.editor.dom");
goog.require("goog.dom.NodeType");
goog.require("goog.dom.TagIterator");
goog.require("goog.dom.TagWalkType");
goog.require("goog.iter");
goog.require("goog.string");
goog.require("goog.testing.asserts");
goog.testing.editor.dom.getPreviousNonEmptyTextNode = function(node, opt_stopAt, opt_skipDescendants) {
  return goog.testing.editor.dom.getPreviousNextNonEmptyTextNodeHelper_(node, opt_stopAt, opt_skipDescendants, true);
};
goog.testing.editor.dom.getNextNonEmptyTextNode = function(node, opt_stopAt, opt_skipDescendants) {
  return goog.testing.editor.dom.getPreviousNextNonEmptyTextNodeHelper_(node, opt_stopAt, opt_skipDescendants, false);
};
goog.testing.editor.dom.getPreviousNextNonEmptyTextNodeHelper_ = function(node, opt_stopAt, opt_skipDescendants, opt_isPrevious) {
  opt_stopAt = opt_stopAt || node.ownerDocument.body;
  var iter = new goog.dom.TagIterator(opt_stopAt, opt_isPrevious);
  var walkType;
  var depth = goog.testing.editor.dom.getRelativeDepth_(node, opt_stopAt);
  if (depth == -1) {
    return null;
  }
  if (node.nodeType == goog.dom.NodeType.ELEMENT) {
    if (opt_skipDescendants) {
      walkType = opt_isPrevious ? goog.dom.TagWalkType.START_TAG : goog.dom.TagWalkType.END_TAG;
    } else {
      depth++;
    }
  }
  iter.setPosition(node, walkType, depth);
  try {
    iter.next();
  } catch (e) {
    return null;
  }
  var filter = goog.iter.filter(iter, goog.testing.editor.dom.isNonEmptyTextNode_);
  try {
    return filter.next();
  } catch (e$12) {
    return null;
  }
};
goog.testing.editor.dom.isNonEmptyTextNode_ = function(node) {
  return !!node && node.nodeType == goog.dom.NodeType.TEXT && node.length > 0;
};
goog.testing.editor.dom.getRelativeDepth_ = function(node, parentNode) {
  var depth = 0;
  while (node) {
    if (node == parentNode) {
      return depth;
    }
    node = node.parentNode;
    depth++;
  }
  return -1;
};
goog.testing.editor.dom.assertRangeBetweenText = function(before, after, range, opt_stopAt) {
  var previousText = goog.testing.editor.dom.getTextFollowingRange_(range, true, opt_stopAt);
  if (before == "") {
    assertNull("Expected nothing before range but found <" + previousText + ">", previousText);
  } else {
    assertNotNull("Expected <" + before + "> before range but found nothing", previousText);
    assertTrue("Expected <" + before + "> before range but found <" + previousText + ">", goog.string.endsWith(previousText, before));
  }
  var nextText = goog.testing.editor.dom.getTextFollowingRange_(range, false, opt_stopAt);
  if (after == "") {
    assertNull("Expected nothing after range but found <" + nextText + ">", nextText);
  } else {
    assertNotNull("Expected <" + after + "> after range but found nothing", nextText);
    assertTrue("Expected <" + after + "> after range but found <" + nextText + ">", goog.string.startsWith(nextText, after));
  }
};
goog.testing.editor.dom.getTextFollowingRange_ = function(range, isBefore, opt_stopAt) {
  var followingTextNode;
  var endpointNode = isBefore ? range.getStartNode() : range.getEndNode();
  var endpointOffset = isBefore ? range.getStartOffset() : range.getEndOffset();
  var getFollowingTextNode = isBefore ? goog.testing.editor.dom.getPreviousNonEmptyTextNode : goog.testing.editor.dom.getNextNonEmptyTextNode;
  if (endpointNode.nodeType == goog.dom.NodeType.TEXT) {
    var endText = endpointNode.nodeValue;
    if (isBefore ? endpointOffset > 0 : endpointOffset < endText.length) {
      return isBefore ? endText.substr(0, endpointOffset) : endText.substr(endpointOffset);
    } else {
      followingTextNode = getFollowingTextNode(endpointNode, opt_stopAt);
      return followingTextNode && followingTextNode.nodeValue;
    }
  } else {
    var numChildren = endpointNode.childNodes.length;
    if (isBefore ? endpointOffset > 0 : endpointOffset < numChildren) {
      var followingChild = endpointNode.childNodes[isBefore ? endpointOffset - 1 : endpointOffset];
      if (goog.testing.editor.dom.isNonEmptyTextNode_(followingChild)) {
        return followingChild.nodeValue;
      } else {
        followingTextNode = getFollowingTextNode(followingChild, opt_stopAt);
        return followingTextNode && followingTextNode.nodeValue;
      }
    } else {
      followingTextNode = getFollowingTextNode(endpointNode, opt_stopAt, true);
      return followingTextNode && followingTextNode.nodeValue;
    }
  }
};
goog.provide("uno.listeners.SelectionListener");
goog.require("goog.debug.Logger");
goog.require("goog.events.KeyCodes");
goog.require("goog.testing.editor.dom");
goog.require("uno.BasePlugin");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.listeners.SelectionListener");
  var SelectionListener = uno.listeners.SelectionListener = function() {
    uno.BasePlugin.call(this, log.getName());
  };
  goog.inherits(SelectionListener, uno.BasePlugin);
  SelectionListener.prototype.handleKeyDown = function(event) {
    var range = this.editor.getRange();
    if (!range || !range.isCollapsed()) {
      return;
    }
    var startNode = range.getStartNode();
    var startOffset = range.getStartOffset();
    if ((event.keyCode === 37 || event.keyCode === 39) && startNode.nodeType === Node.TEXT_NODE) {
      var char;
      var newIndex;
      if (event.keyCode === 37) {
        if (startOffset === 0) {
          var prevSibling = goog.testing.editor.dom.getPreviousNonEmptyTextNode(startNode);
          if (prevSibling && prevSibling.nodeType === Node.TEXT_NODE) {
            char = prevSibling.textContent[prevSibling.length - 1];
            startNode = prevSibling;
            newIndex = prevSibling.length - 1;
          }
        } else {
          char = startNode.textContent[startOffset - 1];
          newIndex = startOffset - 1;
        }
      } else {
        if (event.keyCode === 39) {
          if (startOffset === startNode.length) {
            var nextSibling = goog.testing.editor.dom.getNextNonEmptyTextNode(startNode);
            if (nextSibling && nextSibling.nodeType === Node.TEXT_NODE) {
              char = nextSibling.textContent[0];
              startNode = nextSibling;
              newIndex = 1;
            }
          } else {
            char = startNode.textContent[startOffset];
            newIndex = startOffset + 1;
          }
        }
      }
      if (char === uno.defs.unicode.ZERO_WIDTH_SPACE) {
        var newRange = goog.dom.Range.createFromNodes(startNode, newIndex, startNode, newIndex);
        newRange.select();
      }
    }
  };
})();
goog.provide("uno.util.http");
goog.require("goog.debug.Logger");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.http");
  var util = uno.util;
  util.http.fetchAsync = function(input, init) {
    log.fine("Fetching : " + (input.url || input));
    return fetch(input, init).then(function(response) {
      log.fine("Fetch response from : " + (input.url || input));
      log.fine(response);
      if (response.status >= 200 && response.status < 300) {
        return response;
      } else {
        var error = new Error(response.statusText);
        error.response = response;
        throw error;
      }
    });
  };
})();
goog.provide("uno.util.richlink.googledrive.android");
goog.require("uno.util.loc");
goog.require("uno.util.img.fixtures.android");
(function() {
  var android = uno.util.richlink.googledrive.android;
  var util = uno.util;
  android.getAccessRequestString = function() {
    return util.loc.t("Tap to request access");
  };
  android.getTapToConnectString = function() {
    return util.loc.t("Connect");
  };
  android.activateDrag = function(el) {
    return el;
  };
  android.getImagePath = function(editor) {
    return editor.config.images.path;
  };
  android.getImageDimensions = function() {
    return {width:320, height:60};
  };
  android.fixtures = uno.util.img.fixtures.android;
})();
goog.provide("uno.util.richlink.googledrive.generic");
goog.require("uno.util.loc");
(function() {
  var generic = uno.util.richlink.googledrive.generic;
  var util = uno.util;
  generic.getAccessRequestString = function() {
    return util.loc.t("Click to request access");
  };
  generic.getTapToConnectString = function() {
    return util.loc.t("Connect to see more");
  };
  generic.activateDrag = function(el) {
    return el;
  };
  generic.getImagePath = function(editor) {
    return editor.config.images.path;
  };
  generic.getImageDimensions = function() {
    return {width:380, height:55};
  };
})();
goog.provide("uno.util.richlink.googledrive.ios");
goog.require("uno.util.loc");
goog.require("uno.util.richlink.googledrive.generic");
(function() {
  var ios = uno.util.richlink.googledrive.ios;
  var util = uno.util;
  ios.getAccessRequestString = function() {
    return util.loc.t("Tap to request access");
  };
  ios.getTapToConnectString = function() {
    return util.loc.t("Connect");
  };
  ios.activateDrag = function(el) {
    return el;
  };
  ios.getImagePath = function(editor) {
    return util.richlink.googledrive.generic.getImagePath(editor);
  };
  ios.getImageDimensions = util.richlink.googledrive.generic.getImageDimensions;
})();
goog.provide("uno.util.img.fixtures.win");
goog.require("uno.util.img.fixtures.generic");
(function() {
  var util = uno.util;
  var generic = util.img.fixtures.generic;
  var fixtures = util.img.fixtures.win;
  fixtures.map = generic.map;
})();
goog.provide("uno.util.richlink.googledrive.win");
goog.require("uno.util.loc");
goog.require("uno.util.img.fixtures.win");
goog.require("uno.util.richlink.googledrive.generic");
(function() {
  var win = uno.util.richlink.googledrive.win;
  var util = uno.util;
  win.getAccessRequestString = function() {
    return util.loc.t("Click to request access");
  };
  win.getTapToConnectString = function() {
    return util.loc.t("Connect to see more");
  };
  win.activateDrag = function(el) {
    el.setAttribute("draggable", "false");
    return el;
  };
  win.getImagePath = function(editor) {
    return util.richlink.googledrive.generic.getImagePath(editor);
  };
  win.fixtures = uno.util.img.fixtures.win;
  win.getImageDimensions = util.richlink.googledrive.generic.getImageDimensions;
})();
goog.provide("uno.util.richlink.googledrive");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.editor.range");
goog.require("goog.string");
goog.require("uno.Auth");
goog.require("uno.defs");
goog.require("uno.util.canvas");
goog.require("uno.util.http");
goog.require("uno.util.img");
goog.require("uno.util.richlink");
goog.require("uno.util.richlink.googledrive.android");
goog.require("uno.util.richlink.googledrive.ios");
goog.require("uno.util.richlink.googledrive.generic");
goog.require("uno.util.richlink.googledrive.win");
goog.require("uno.util.attachment");
goog.require("uno.util.loc");
(function() {
  var log = goog.debug.Logger.getLogger("uno.util.richlink.googledrive");
  var defs = uno.defs;
  var util = uno.util;
  var googledrive = util.richlink.googledrive;
  var DRIVE_META_URL = "https://www.googleapis.com/drive/v2/files/";
  var DRIVE_LINK_RX = /https:\/\/(docs|drive).google.com\/[^\s\"]+[\/\=]([^\s\/<#=%&@."?]{20,120})([^\"\<\>\s&]*)/gi;
  var GOOGLE_DATE_RX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3})Z$/;
  var THUMBNAIL_RX = /s\d+$/g;
  var client = googledrive.generic;
  var imagePath = "images";
  googledrive.name = "google-drive";
  googledrive.lastInfo = {};
  googledrive.lastImageUrl = {};
  googledrive.uniqueIdCounter = 0;
  googledrive.setClient = function(clientName) {
    client = googledrive[clientName] || googledrive.generic;
  };
  googledrive.canDecorate = function(url) {
    DRIVE_LINK_RX.lastIndex = 0;
    return url && DRIVE_LINK_RX.test(url);
  };
  googledrive.decorate = function(el, editor) {
    imagePath = client.getImagePath(editor);
    var richlink = googledrive.convertAnchorToRichlink(el);
    var range = editor.getRange();
    if (range && range.isCollapsed() && editor.context.format === uno.defs.format.CLIPBOARD) {
      goog.editor.range.placeCursorNextTo(richlink);
    }
    googledrive.renderRichlinkAsync(richlink).then(function(richlink) {
      googledrive.updateRichlinkAsync(richlink, false, editor).catch(function(error) {
        if (error.refreshAuth) {
          googledrive.updateRichlinkAsync(richlink, true, editor);
        }
      });
    });
    client.activateDrag(richlink);
  };
  googledrive.updateRichlinkAsync = function(richlink, refreshAuth, editor) {
    var cancelCachePromise = false;
    var cachedData = editor.cache.readMem(richlink.getAttribute("data-href"));
    if (cachedData) {
      googledrive.injectDataAsync(richlink, cachedData, editor);
    }
    editor.cache.readDiskAsync(richlink.getAttribute("data-href")).then(function(data) {
      if (!cancelCachePromise && data) {
        googledrive.injectDataAsync(richlink, data, editor);
        editor.cache.writeMem(richlink.getAttribute("data-href"), data);
      }
    });
    return editor.auth.getTokenAsync("google-drive", refreshAuth).then(function(token) {
      return googledrive.getDataFromProviderAsync(richlink, token, editor);
    }).then(function(data) {
      cancelCachePromise = true;
      return googledrive.injectDataAsync(richlink, data, editor);
    }).then(function() {
      editor.refreshUndoRedoState();
    }).catch(function(error) {
      return googledrive.injectErrorAsync(richlink, error, editor).then(function() {
        return editor.refreshUndoRedoState();
      });
    });
  };
  googledrive.undecorate = function(el) {
    var anchor = document.createElement("a");
    goog.array.forEach(el.attributes, function(attribute) {
      if (!/^(src|width|height)$/i.test(attribute.name)) {
        anchor.setAttribute(attribute.name, attribute.value);
      }
    });
    goog.dom.replaceNode(anchor, el);
    return anchor;
  };
  googledrive.getDataFromProviderAsync = function(el, token, editor) {
    DRIVE_LINK_RX.lastIndex = 0;
    var match = DRIVE_LINK_RX.exec(el.getAttribute("data-href"));
    var driveId = match[2];
    var url = DRIVE_META_URL + driveId;
    return util.http.fetchAsync(url, {headers:new Headers({"Authorization":"Bearer " + token})}).then(function(response) {
      return response.json();
    }).then(function(data) {
      data.driveId = driveId;
      if (data.parents && data.parents.length > 0) {
        data.parentFolderLink = data.parents[0].parentLink;
      }
      el.setAttribute("data-parent-folder-link", data.parentFolderLink);
      if (data.mimeType) {
        el.setAttribute("data-type", data.mimeType);
      }
      if (data.title) {
        el.setAttribute("data-title", data.title);
      }
      el.setAttribute("data-alternate-link", data.alternateLink);
      editor.cache.write(el.getAttribute("data-href"), data);
      return data;
    }).catch(function(error) {
      if (error.response) {
        error.errorCode = error.errorCode || error.response.status;
      }
      throw error;
    });
  };
  googledrive.convertAnchorToRichlink = function(el) {
    var richlink = el;
    var displayType = util.richlink.getDisplayType(richlink);
    switch(displayType) {
      case util.richlink.DISPLAY_TYPE.MINIMAL:
        richlink = el;
        break;
      case util.richlink.DISPLAY_TYPE.SMALL:
      default:
        richlink = document.createElement("img");
        goog.array.forEach(el.attributes, function(attribute) {
          richlink.setAttribute(attribute.name, attribute.value);
        });
        goog.dom.replaceNode(richlink, el);
        break;
    }
    richlink.setAttribute("data-title", el.textContent);
    goog.dom.classlist.add(richlink, "en-richlink");
    return richlink;
  };
  googledrive.renderRichlinkAsync = function(richlink, iconSrc, line1, line2, connectText, thumbnailSrc, imageMeta, videoMeta) {
    richlink.setAttribute("data-icon", iconSrc || imagePath + "/loading_progress.svg");
    richlink.setAttribute("data-line1", line1 || richlink.getAttribute("data-line1") || richlink.getAttribute("data-title") || richlink.getAttribute("data-href"));
    richlink.setAttribute("data-line2", line2 || richlink.getAttribute("data-line2") || util.loc.t("Google Drive"));
    richlink.setAttribute("data-connect-text", connectText || "");
    richlink.setAttribute("data-connect-box", "");
    richlink.setAttribute("data-thumbnail", thumbnailSrc || "");
    switch(richlink.getAttribute("rev")) {
      case util.richlink.DISPLAY_TYPE.MINIMAL:
        return googledrive.renderMinimalRichlinkAsync(richlink, iconSrc, line1);
        break;
      case util.richlink.DISPLAY_TYPE.SMALL:
      default:
        return googledrive.renderSmallRichlinkAsync(richlink, iconSrc, line1, line2, connectText, thumbnailSrc, imageMeta, videoMeta);
        break;
    }
  };
  googledrive.renderMinimalRichlinkAsync = function(richlink, iconSrc, line1) {
    return Promise.try(function() {
      if (line1) {
        richlink.innerText = line1;
      }
      var mimeType = richlink.getAttribute("data-type") || googledrive.getMimeType(richlink.getAttribute("data-href"));
      var displayType = util.richlink.getDisplayType(richlink);
      var icon = util.attachment.getIconInfoFromFile(displayType, mimeType, line1 || richlink.getAttribute("data-title") || richlink.getAttribute("data-href"));
      goog.dom.classlist.removeAll(richlink, ["en-attach-icon-unknown", "en-attach-icon-generic"]);
      goog.dom.classlist.addAll(richlink, ["google-drive-minimal-title", icon]);
      return richlink;
    });
  };
  googledrive.renderSmallRichlinkAsync = function(richlink, iconSrc, line1, line2, connectText, thumbnailSrc, imageMeta, videoMeta) {
    var width = 380;
    var height = 55;
    var dimensions = client.getImageDimensions();
    if (dimensions) {
      width = dimensions.width;
      height = dimensions.height;
    }
    var canvas = util.canvas.create(width, height);
    var context = canvas.getContext("2d");
    var asyncRenderers;
    var showIconOverlay;
    richlink.setAttribute("width", width);
    richlink.style.minWidth = width + "px";
    richlink.setAttribute("height", height);
    showIconOverlay = richlink.getAttribute("data-icon") !== imagePath + "/loading_progress.svg";
    googledrive.renderMiddle(richlink.getAttribute("data-line1"), richlink.getAttribute("data-line2"), richlink.getAttribute("data-connect-text"), richlink, context);
    asyncRenderers = [googledrive.renderIconAsync(richlink.getAttribute("data-icon"), showIconOverlay, richlink, context), googledrive.renderMenuAsync(richlink, context)];
    if (thumbnailSrc) {
      asyncRenderers.push(googledrive.loadThumbnailAsync(richlink.getAttribute("data-thumbnail"), richlink, imageMeta, videoMeta));
    }
    return Promise.all(asyncRenderers.map(function(p) {
      return p.reflect();
    })).then(function(results) {
      if (thumbnailSrc) {
        var thumbnailPromise = results[2];
        if (thumbnailPromise.isFulfilled()) {
          canvas = googledrive.renderThumbnail(thumbnailPromise.value(), richlink, canvas);
        }
      }
      richlink.src = canvas.toDataURL();
      return richlink;
    });
  };
  googledrive.renderIconAsync = function(iconSrc, showOverlay, richlink, context) {
    var iconX;
    var iconY;
    var iconWidth;
    var iconHeight;
    var overlayPromise;
    var iconPromise = util.img.loadFromClientAsync(iconSrc, client);
    if (showOverlay) {
      overlayPromise = util.img.loadFromClientAsync(imagePath + "/att_src_icon_google_28.svg", client);
    } else {
      overlayPromise = Promise.resolve();
    }
    return iconPromise.then(function(img) {
      iconWidth = img.naturalWidth;
      iconHeight = img.naturalHeight;
      iconX = Math.floor((64 - iconWidth) / 2);
      iconY = Math.floor((richlink.height - iconHeight) / 2) + 2;
      context.drawImage(img, iconX, iconY);
      return overlayPromise;
    }).then(function(img) {
      if (img) {
        var x = iconX + iconWidth - 20;
        var y = iconY + iconHeight - 20;
        context.drawImage(img, x, y, 20, 20);
      }
    });
  };
  googledrive.renderMiddle = function(line1, line2, connectText, richlink, context) {
    var line2width;
    context.save();
    context.fillStyle = "#2e2e2e";
    context.font = "500 14px sans-serif";
    var maxWidth = richlink.getAttribute("width");
    util.canvas.fillText(context, line1, 64, 25, maxWidth - 110);
    context.fillStyle = "#727272";
    context.font = "10px sans-serif";
    util.canvas.fillText(context, line2, 64, 43, maxWidth - 110);
    line2width = context.measureText(line2).width;
    context.restore();
    if (connectText) {
      googledrive.renderConnectText(connectText, line2width + 84, richlink, context);
    }
  };
  googledrive.renderConnectText = function(text, x, richlink, context) {
    var textWidth;
    context.save();
    context.fillStyle = "#37adfc";
    context.strokeStyle = "#37adfc";
    context.lineWidth = 1;
    context.font = "12px sans-serif";
    textWidth = context.measureText(text).width;
    util.canvas.fillText(context, text, x, 43, 270);
    context.beginPath();
    context.moveTo(x, 46);
    context.lineTo(x + textWidth, 46);
    context.stroke();
    context.restore();
    richlink.setAttribute("data-connect-box", JSON.stringify({left:x - 5, top:29, width:textWidth + 10, height:19}));
  };
  googledrive.renderMenuAsync = function(richlink, context) {
    return util.img.loadFromClientAsync(imagePath + "/overflow_menu.svg", client).then(function(img) {
      var x = richlink.width - 20 - 3;
      var y = Math.floor((richlink.height - 12) / 2);
      context.drawImage(img, x, y);
    });
  };
  googledrive.loadThumbnailAsync = function(url, richlink, imageMeta, videoMeta) {
    var width = richlink.width;
    var height = 0;
    var ratio = -1;
    if (imageMeta && imageMeta.width && imageMeta.height) {
      ratio = imageMeta.height / imageMeta.width;
    }
    if (ratio < 0 || ratio > 0.62) {
      ratio = 0.62;
    }
    height = Math.round(ratio * width);
    var sizeString = "w" + width + (height > 0 ? "-h" + height : "") + "-p-k-nu";
    var thumbnailUrl = url.replace(THUMBNAIL_RX, sizeString);
    return util.img.loadFromClientAsync(thumbnailUrl, client);
  };
  googledrive.renderThumbnail = function(thumbnail, richlink, origCanvas) {
    var canvas = util.canvas.create(richlink.width, richlink.height + thumbnail.height);
    var context = canvas.getContext("2d");
    context.drawImage(origCanvas, 0, 0, util.canvas.width(origCanvas), util.canvas.height(origCanvas));
    context.drawImage(thumbnail, 0, richlink.height);
    richlink.src = "";
    richlink.width = util.canvas.width(canvas);
    richlink.height = util.canvas.height(canvas);
    return canvas;
  };
  googledrive.injectErrorAsync = function(el, error, editor) {
    var line2;
    var connectText;
    var displayType = util.richlink.getDisplayType(el);
    var lastErrorCode = editor.auth.getLastErrorCode(googledrive.name);
    if (displayType === util.richlink.DISPLAY_TYPE.MINIMAL) {
    } else {
      switch(error.errorCode) {
        case uno.Auth.ERROR_CODE_NO_AUTH:
        case uno.Auth.ERROR_CODE_INVALID_AUTH:
        case 401:
          if (lastErrorCode === uno.Auth.ERROR_CODE_NO_AUTH || lastErrorCode === uno.Auth.ERROR_CODE_INVALID_AUTH || lastErrorCode === 401) {
            line2 = util.loc.t("Google Drive");
            connectText = client.getTapToConnectString();
          } else {
            var authError = new Error;
            authError.refreshAuth = true;
            throw authError;
          }
          break;
        case uno.Auth.ERROR_CODE_NETWORK_ERROR:
        case 0:
          line2 = util.loc.t("Google Drive") + ": " + util.loc.t("Not available offline");
          break;
        case 403:
        case 404:
          line2 = client.getAccessRequestString();
          break;
        default:
          line2 = util.loc.t("Google Drive") + ": " + util.loc.t("Not available");
      }
    }
    var mimeType = googledrive.getMimeType(el.getAttribute("data-href"));
    var icon = imagePath + "/" + util.attachment.getIconInfoFromFile(displayType, mimeType, el.getAttribute("data-title") || el.getAttribute("data-href")) + ".svg";
    return googledrive.renderRichlinkAsync(el, icon, null, line2, connectText);
  };
  googledrive.getMimeType = function(url, data) {
    var mimeType = data ? data.mimeType : null;
    if (!mimeType) {
      if (url.indexOf("/document/") > -1) {
        mimeType = "application/vnd.google-apps.document";
      } else {
        if (url.indexOf("/spreadsheets/") > -1) {
          mimeType = "application/vnd.google-apps.spreadsheet";
        } else {
          if (url.indexOf("/presentation/") > -1) {
            mimeType = "application/vnd.google-apps.presentation";
          }
        }
      }
    }
    return mimeType;
  };
  googledrive.injectDataAsync = function(el, data) {
    if (!data) {
      return;
    }
    var icon;
    var line1;
    var line2;
    var displayType = util.richlink.getDisplayType(el);
    var url = el.getAttribute("data-href");
    var title = data.title;
    var mimeType = googledrive.getMimeType(url, data);
    var thumbnail;
    var imageMeta;
    var videoMeta;
    if (title) {
      line1 = title;
    }
    if (displayType == util.richlink.DISPLAY_TYPE.SMALL) {
      var fileDescription = util.attachment.getFileTypeDescription(mimeType) || util.loc.t("Google Drive");
      var dateVal = googledrive.parseGoogleDate(data.modifiedDate);
      var dateString = dateVal && dateVal.toLocaleDateString();
      line2 = fileDescription;
      if (dateString) {
        line2 += ": " + util.loc.t("Modified") + " " + dateString;
      }
      icon = imagePath + "/" + uno.util.attachment.getIconInfoFromFile(displayType, mimeType, title || url) + ".svg";
      if (data.thumbnailLink && util.attachment.isThumbnailableMimeType(mimeType)) {
        thumbnail = data.thumbnailLink;
        imageMeta = data.imageMediaMetadata;
        videoMeta = data.videoMediaMetadata;
      }
    }
    return googledrive.renderRichlinkAsync(el, icon, line1, line2, null, thumbnail, imageMeta, videoMeta);
  };
  googledrive.parseGoogleDate = function(d) {
    try {
      var m = GOOGLE_DATE_RX.exec(d);
      var year = +m[1];
      var month = +m[2];
      var day = +m[3];
      var hour = +m[4];
      var minute = +m[5];
      var second = +m[6];
      var msec = +m[7];
      var tzOffset = (new Date).getTimezoneOffset();
      return new Date(year, month - 1, day, hour, minute - tzOffset, second, msec);
    } catch (exception) {
      log.info("error parsing date: " + (exception.stack || exception));
      log.fine(err.stack || err);
    }
  };
  googledrive.reloadAsync = function(el, askUserForPermission, editor) {
    return editor.auth.getTokenAsync(googledrive.name, true, !!askUserForPermission).then(function(token) {
      return googledrive.getDataFromProviderAsync(el, token, editor);
    }).then(function(data) {
      googledrive.injectDataAsync(el, data, editor);
    }).catch(function(error) {
      googledrive.injectErrorAsync(el, error, editor);
    });
  };
  googledrive.openDoc = function(url, target, editor) {
    editor.dispatchEvent({type:"linkclick", target:target, data:{module:googledrive.name || "link", href:url}});
  };
  googledrive.buildOptions = function(el, optionsEl, editor) {
    var rect = optionsEl.getBoundingClientRect();
    var options = {href:el.getAttribute("data-href"), module:googledrive.name, ceOptions:{"elementId":optionsEl.id, "boundingbox":{"left":rect.left, "right":rect.right, "top":rect.top, "bottom":rect.bottom, "height":rect.height, "width":rect.width}, "optionsArray":[{"id":"open", "text":util.loc.t("Open")}]}};
    var lastErrorCode = editor.auth.getLastErrorCode(googledrive.name);
    if (lastErrorCode === uno.Auth.ERROR_CODE_NO_AUTH || lastErrorCode === uno.Auth.ERROR_CODE_INVALID_AUTH || lastErrorCode === 401) {
      options.ceOptions.optionsArray.push({"id":"connect", "text":util.loc.t("Connect Google account")});
    }
    return options;
  };
  googledrive.isOverMenu = function(richlink, event) {
    var box = goog.style.getBounds(richlink);
    var overMenu = event.target === richlink && event.clientX > box.left + box.width - 46 && event.clientY <= box.top + 55;
    return overMenu;
  };
  googledrive.isOverConnectText = function(richlink, event) {
    var box = goog.style.getBounds(richlink);
    var overConnectText = false;
    if (!richlink.getAttribute("data-connect-box")) {
      return false;
    }
    try {
      var connectBox = JSON.parse(richlink.getAttribute("data-connect-box"));
      overConnectText = event.clientX > box.left + connectBox.left && event.clientX < box.left + connectBox.left + connectBox.width && event.clientY > box.top + connectBox.top && event.clientY < box.top + connectBox.top + connectBox.height;
    } catch (ex) {
      log.info(ex.stack || ex);
    }
    return overConnectText;
  };
  googledrive.handleClick = function(el, event, editor) {
    if (util.richlink.getDisplayType(el) === util.richlink.DISPLAY_TYPE.MINIMAL) {
      return;
    }
    if (googledrive.isOverMenu(el, event)) {
      var options = googledrive.buildOptions(el, el, editor);
      editor.router.toHostAsync("showOptions", options).then(function(response) {
        if (response.selectedOptionId === "open") {
          googledrive.openDoc(el.getAttribute("data-href") || el.getAttribute("data-alternate-link"), el, editor);
        } else {
          if (response.selectedOptionId === "folder" && el.getAttribute("data-parent-folder-link")) {
            googledrive.openDoc(el.getAttribute("data-parent-folder-link"), el, editor);
          } else {
            if (response.selectedOptionId === "connect") {
              googledrive.reloadAsync(el, true, editor);
            }
          }
        }
      });
      event.preventDefault();
    } else {
      if (googledrive.isOverConnectText(el, event)) {
        googledrive.reloadAsync(el, true, editor);
        event.preventDefault();
      } else {
        googledrive.openDoc(el.getAttribute("data-href") || el.getAttribute("data-alternate-link"), el, editor);
      }
    }
    return true;
  };
  googledrive.handleMouseMove = function(el, event, editor) {
    if (util.richlink.getDisplayType(el) === util.richlink.DISPLAY_TYPE.MINIMAL) {
      return;
    }
    if (googledrive.isOverMenu(el, event)) {
      goog.dom.classlist.add(el, "google-drive-menu-hover");
    } else {
      goog.dom.classlist.remove(el, "google-drive-menu-hover");
    }
  };
  googledrive.handleMouseOut = function(el, event, editor) {
    if (util.richlink.getDisplayType(el) === util.richlink.DISPLAY_TYPE.MINIMAL) {
      return;
    }
    goog.dom.classlist.remove(el, "google-drive-menu-hover");
  };
})();
goog.provide("uno.util.touch");
(function() {
  var util = uno.util;
  var timer = 0;
  var pressure = 0;
  var longTouch = false;
  var x;
  var y;
  function handleTouch(e, editor) {
    timer = window.setTimeout(function() {
      pressure++;
      if (pressure > 5) {
        if (Math.abs(x - e.clientX) < 5 && Math.abs(y - e.clientY) < 5) {
          sendEvent(e, "longtouch");
          longTouch = true;
        }
      } else {
        handleTouch(e, editor);
      }
    }, 100);
  }
  function handleTouchEnd() {
    window.clearTimeout(timer);
    pressure = 0;
    longTouch = false;
    x = null;
    y = null;
  }
  function sendEvent(e, eventName) {
    if (e.touches && e.touches.length) {
      e = e.touches[0];
    }
    var event = new MouseEvent(eventName, {target:e.target, touch:true, view:window, bubbles:true, cancelable:true, clientX:e.clientX, clientY:e.clientY});
    var preventDefault = event.preventDefault.bind(event);
    event.preventDefault = function() {
      e.preventDefault();
      preventDefault();
    };
    var target = e.target;
    target.dispatchEvent(event);
  }
  util.touch.init = function(editor) {
    editor.addListener("touchstart", function(e) {
      x = e.clientX;
      y = e.clientY;
      handleTouch(e, editor);
    }, false, editor);
    editor.addListener("touchend", function(e) {
      if (x == null || y == null) {
        handleTouchEnd();
        return;
      }
      if (Math.abs(x - e.clientX) < 5 && Math.abs(y - e.clientY) < 5) {
        if (editor.inEditMode() && !longTouch) {
          sendEvent(e, "click");
        }
      }
      handleTouchEnd();
    }, false, editor);
    editor.addListener("touchcancel", function() {
      handleTouchEnd();
    }, false, editor);
  };
})();
goog.provide("uno.Editor");
goog.require("goog.array");
goog.require("goog.dom.classes");
goog.require("goog.dom.Range");
goog.require("goog.editor.Field.EventType");
goog.require("goog.editor.SeamlessField");
goog.require("goog.editor.Plugin");
goog.require("goog.editor.plugins.BasicTextFormatter");
goog.require("goog.editor.plugins.EnterHandler");
goog.require("goog.editor.plugins.RemoveFormatting");
goog.require("goog.editor.plugins.SpacesTabHandler");
goog.require("goog.editor.plugins.TableEditor");
goog.require("uno.ConsoleLogger");
goog.require("uno.defs");
goog.require("uno.env");
goog.require("uno.EditorMultiRange");
goog.require("uno.EditorSelection");
goog.require("uno.commands.Accentuate");
goog.require("uno.commands.Active");
goog.require("uno.commands.BasicTextFormatter");
goog.require("uno.commands.Bounds");
goog.require("uno.commands.Capitalize");
goog.require("uno.commands.CaretLocation");
goog.require("uno.commands.Changes");
goog.require("uno.commands.CodeBlock");
goog.require("uno.commands.Content");
goog.require("uno.commands.ControlTodos");
goog.require("uno.commands.Copy");
goog.require("uno.commands.Count");
goog.require("uno.commands.CreateLink");
goog.require("uno.commands.Crypt");
goog.require("uno.commands.Cut");
goog.require("uno.commands.Delete");
goog.require("uno.commands.DeleteTable");
goog.require("uno.commands.DeleteTableCol");
goog.require("uno.commands.DeleteTableRow");
goog.require("uno.commands.Editable");
goog.require("uno.commands.Find");
goog.require("uno.commands.Focus");
goog.require("uno.commands.FontSize");
goog.require("uno.commands.ForeColor");
goog.require("uno.commands.ForwardDelete");
goog.require("uno.commands.Highlight");
goog.require("uno.commands.InsertHorizontalRule");
goog.require("uno.commands.InsertHtml");
goog.require("uno.commands.InsertText");
goog.require("uno.commands.InsertParagraph");
goog.require("uno.commands.InsertTable");
goog.require("uno.commands.InsertTableCol");
goog.require("uno.commands.InsertTableRow");
goog.require("uno.commands.FullSize");
goog.require("uno.commands.MergeCells");
goog.require("uno.commands.MigrateTable");
goog.require("uno.commands.Shutdown");
goog.require("uno.commands.TableAlign");
goog.require("uno.commands.TableBorderColor");
goog.require("uno.commands.TableBorderWidth");
goog.require("uno.commands.TableCellColor");
goog.require("uno.commands.TableEqualCol");
goog.require("uno.commands.TableFitNote");
goog.require("uno.commands.TableVerticalAlign");
goog.require("uno.commands.Indent");
goog.require("uno.commands.InsertTodo");
goog.require("uno.commands.InsertDrawing");
goog.require("uno.commands.Lowercase");
goog.require("uno.commands.Margin");
goog.require("uno.commands.Paste");
goog.require("uno.commands.PlainText");
goog.require("uno.commands.PrintPreview");
goog.require("uno.commands.Redo");
goog.require("uno.commands.RemoveFormat");
goog.require("uno.commands.Resources");
goog.require("uno.commands.RichlinksConvert");
goog.require("uno.commands.RichlinksRefresh");
goog.require("uno.commands.Search");
goog.require("uno.commands.SelectAll");
goog.require("uno.commands.Selection");
goog.require("uno.commands.SimpleText");
goog.require("uno.commands.Stats");
goog.require("uno.commands.Strikethrough");
goog.require("uno.commands.Tab");
goog.require("uno.commands.Underline");
goog.require("uno.commands.Undo");
goog.require("uno.commands.UndoRedo");
goog.require("uno.commands.Unlink");
goog.require("uno.commands.Uppercase");
goog.require("uno.commands.ZoomScale");
goog.require("uno.filters.All");
goog.require("uno.listeners.AccentuateListener");
goog.require("uno.listeners.AttachmentListener");
goog.require("uno.listeners.AutoCorrectListener");
goog.require("uno.listeners.ChangeListener");
goog.require("uno.listeners.ClipboardListener");
goog.require("uno.listeners.CodeBlockListener");
goog.require("uno.listeners.CryptListener");
goog.require("uno.listeners.DeleteListener");
goog.require("uno.listeners.DragDropListener");
goog.require("uno.listeners.EnterListener");
goog.require("uno.listeners.NoteListener");
goog.require("uno.listeners.ForwardDeleteListener");
goog.require("uno.listeners.HighlightListener");
goog.require("uno.listeners.ImgListener");
goog.require("uno.listeners.LinkListener");
goog.require("uno.listeners.ListListener");
goog.require("uno.listeners.RichlinkListener");
goog.require("uno.listeners.SearchResizeListener");
goog.require("uno.listeners.ShortcutListener");
goog.require("uno.listeners.SmartScrollListener");
goog.require("uno.listeners.TableListener");
goog.require("uno.listeners.TextInputListener");
goog.require("uno.listeners.TodoListener");
goog.require("uno.listeners.TodoListListener");
goog.require("uno.listeners.TypeBehindListener");
goog.require("uno.listeners.SelectionListener");
goog.require("uno.util.canvas");
goog.require("uno.util.dom");
goog.require("uno.util.font");
goog.require("uno.util.img");
goog.require("uno.util.loc");
goog.require("uno.util.objects");
goog.require("uno.util.preview");
goog.require("uno.util.resource");
goog.require("uno.util.richlink.googledrive");
goog.require("uno.util.touch");
goog.require("uno.util.todo");
goog.require("uno.util.tools");
(function() {
  var Field = goog.editor.Field;
  var log = goog.debug.Logger.getLogger("uno.Editor");
  var SeamlessField = goog.editor.SeamlessField;
  var Plugin = goog.editor.Plugin;
  var util = uno.util;
  var dispatchStyleChangeTimer = 0;
  if (goog.userAgent.GECKO) {
    goog.editor.BrowserFeature.HAS_CONTENT_EDITABLE = true;
  }
  var Editor = uno.Editor = function(id, options) {
    SeamlessField.call(this, id || "editor");
    this.initConfig(options);
    this.cache = options.cache;
    this.auth = options.auth;
    this.router = options.router;
    this.dirty = false;
    this.empty = true;
    this.focused = false;
    this.isSetup = false;
    this.readOnly = options.rte.active === false || options.realtime != null;
    this.multirange = new uno.EditorMultiRange(this);
    this.lastCommand = null;
    this.showVirtualKeyboardOnFocus = true;
    goog.dom.classes.add(document.body, this.config.client);
    this.config.defaults.foreColor = getComputedStyle(document.body).color;
    util.font.setClient(this.config.client);
    util.preview.setClient(this.config.client);
    util.resource.setClient(this.config.client);
    util.todo.setClient(this.config.client);
    util.richlink.googledrive.setClient(this.config.client);
    this.listeners = {};
    this.handlers = [{name:"click", handler:"handleClick"}, {name:"longtouch", handler:"handleLongTouch"}, {name:"dblclick", handler:"handleDoubleClick"}, {name:"mousedown", handler:"handleMouseDown"}, {name:"mouseup", handler:"handleMouseUp"}, {name:"mouseover", handler:"handleMouseOver"}, {name:"mouseout", handler:"handleMouseOut"}, {name:"mousemove", handler:"handleMouseMove"}, {name:"dragstart", handler:"handleDragStart"}, {name:"dragover", handler:"handleDragOver"}, {name:"dragenter", handler:"handleDragEnter"}, 
    {name:"dragleave", handler:"handleDragLeave"}, {name:"dragexit", handler:"handleDragExit"}, {name:"drop", handler:"handleDrop"}, {name:"dragend", handler:"handleDragEnd"}, {name:"textInput", handler:"handleTextInput"}, {name:"input", handler:"handleInput"}, {name:"copy", handler:"handleCopy"}, {name:"cut", handle:"handleCut"}, {name:"paste", handler:"handlePaste"}, {name:"domupdate", target:this, handler:"handleDomUpdate"}, {name:"beforeexeccommand", target:this, handler:"handleBeforeExecCommand"}, 
    {name:"afterexeccommand", target:this, handler:"handleAfterExecCommand"}, {name:"delayedchange", target:this, handler:"handleDelayedChange"}, {name:"selectionchange", target:document, handler:"handleNativeSelectionChange"}, {name:"selectstart", target:document, handler:"handleSelectStart"}, {name:"resize", target:window, handler:"handleWindowResize"}, {name:"scroll", target:window, handler:"handleScroll", capture:true}, {name:"contextmenu", target:window, handler:"handleContextMenu"}, {name:"winmouseup", 
    eventname:"mouseup", target:window, handler:"handleWindowMouseUp"}, {name:"winmousemove", eventname:"mousemove", target:window, handler:"handleWindowMouseMove"}];
    this.handlers.forEach(function(property) {
      this.listeners[property.name] = [];
    }.bind(this));
    this.importDomFilters = [];
    this.allPluginsInOrder = [];
    this.queryCommandEnabledPlugins = [];
    this.richlinkProviders = [uno.util.richlink.googledrive];
    this.setFollowLinkInNewWindow(false);
    util.loc.init(this.config.locale);
    this.initEvents();
    this.initPlugins();
    if (this.config.richlinks.cacheSupported) {
      this.cache.enableDisk();
    } else {
      this.cache.disableDisk();
    }
  };
  goog.inherits(Editor, SeamlessField);
  uno.EditorSelection(Editor);
  Editor.EventType = {PRINT_READY:"printReady", IMAGE_CLICK:"imageclick", RESOURCE_DOUBLECLICK:"resourcedoubleclick", IMAGE_DOUBLECLICK:"imagedoubleclick", IMAGE_ANNOTATE:"annotate", IMAGE_PREVIEW:"preview", IMAGE_ROTATE:"rotate", CONTENT_LOADED:"contentloaded", LINK_CLICK:"linkclick", OPEN_LINK:"openLink", ENCRYPT:"encrypt", DECRYPT:"decrypt", CRYPT_DOUBLECLICK:"cryptdoubleclick", STYLE_CHANGED:"stylechanged", EDIT_MODE_CHANGED:"editmodechanged", CONTENT_CHANGED:"contentchanged", ACTION_DENIED:"actiondenied", 
  DOM_UPDATE:"domupdate", SHUTDOWN_COMPLETE:"shutdownComplete"};
  Object.keys(Field.EventType).forEach(function(key) {
    if (Field.EventType.hasOwnProperty(key)) {
      Editor.EventType[key] = Field.EventType[key];
    }
  });
  Editor.prototype.setup = function() {
    var options = {type:this.config.initialContentFormat, content:this.config.initialContent || this.config.defaults.html};
    this.makeEditable();
    if (this.readOnly) {
      this.leaveEditMode();
    }
    this.field.removeAttribute("role");
    this.execCommand("margin", this.config.margin);
    this.multirange.clear();
    if (goog.isDef(this.config.initialContent)) {
      this.execCommand("content", options);
    } else {
      this.setHtml(false, this.config.defaults.html, true);
    }
    this.updateEmpty();
    this.isSetup = true;
  };
  Editor.prototype.makeEditable = function() {
    SeamlessField.prototype.makeEditable.call(this);
  };
  Editor.prototype.initEvents = function() {
    this.listen(Editor.EventType.DELAYEDCHANGE, this.onDelayedChange);
    this.listen(Editor.EventType.LOAD, this.onLoad);
    this.listen(Editor.EventType.UNLOAD, this.onUnload);
    this.listen(Editor.EventType.FOCUS, this.onFocus);
    this.listen(Editor.EventType.BLUR, this.onBlur);
    this.listen(Editor.EventType.BEFORESELECTIONCHANGE, this.onBeforeSelectionChange);
    this.listen(Editor.EventType.SELECTIONCHANGE, this.onSelectionChange);
    this.eventRegister.listen(document, "selectionchange", this.onSelectionChange);
    this.eventRegister.listenWithScope(document.body, "textInput", this.onTextInput, false, this);
    this.eventRegister.listenWithScope(document.body, "input", this.onInput, false, this);
  };
  Editor.prototype.registerPlugin = function(plugin) {
    SeamlessField.prototype.registerPlugin.call(this, plugin);
    this.handlers.forEach(function(property) {
      if (plugin[property.handler]) {
        this.listeners[property.name].push(plugin);
      }
    }, this);
    this.allPluginsInOrder.push(plugin);
    if (plugin.prepareContentsDom) {
      this.importDomFilters.push(plugin);
    }
    if (plugin.queryCommandEnabled) {
      this.queryCommandEnabledPlugins.push(plugin);
    }
  };
  Editor.prototype.unregisterPlugin = function(plugin) {
    SeamlessField.prototype.unregisterPlugin.call(this, plugin);
    this.handlers.forEach(function(property) {
      goog.array.remove(this.listeners[property.name], plugin);
    }, this);
    goog.array.remove(this.allPluginsInOrder, plugin);
    if (plugin.prepareContentsDom) {
      goog.array.remove(this.importDomFilters, plugin);
    }
    if (plugin.queryCommandEnabled) {
      goog.array.remove(this.queryCommandEnabledPlugins, plugin);
    }
  };
  Editor.prototype.initPlugins = function() {
    this.registerPlugin(new uno.listeners.ShortcutListener);
    this.registerPlugin(new goog.editor.plugins.BasicTextFormatter);
    this.registerPlugin(new goog.editor.plugins.RemoveFormatting);
    this.registerPlugin(new goog.editor.plugins.TableEditor);
    this.registerPlugin(new uno.commands.Accentuate);
    this.registerPlugin(new uno.commands.Active);
    this.registerPlugin(new uno.commands.BasicTextFormatter);
    this.registerPlugin(new uno.commands.Bounds);
    this.registerPlugin(new uno.commands.Capitalize);
    this.registerPlugin(new uno.commands.CaretLocation);
    this.registerPlugin(new uno.commands.Changes);
    this.registerPlugin(new uno.commands.CodeBlock);
    this.registerPlugin(new uno.commands.Content);
    this.registerPlugin(new uno.commands.ControlTodos);
    this.registerPlugin(new uno.commands.Copy);
    this.registerPlugin(new uno.commands.Count);
    this.registerPlugin(new uno.commands.CreateLink);
    this.registerPlugin(new uno.commands.Crypt);
    this.registerPlugin(new uno.commands.Cut);
    this.registerPlugin(new uno.commands.Delete);
    this.registerPlugin(new uno.commands.DeleteTable);
    this.registerPlugin(new uno.commands.DeleteTableCol);
    this.registerPlugin(new uno.commands.DeleteTableRow);
    this.registerPlugin(new uno.commands.Editable);
    this.registerPlugin(new uno.commands.Find(this.config));
    this.registerPlugin(new uno.commands.Focus);
    this.registerPlugin(new uno.commands.FontSize);
    this.registerPlugin(new uno.commands.ForeColor);
    this.registerPlugin(new uno.commands.ForwardDelete);
    this.registerPlugin(new uno.commands.Highlight);
    this.registerPlugin(new uno.commands.InsertHorizontalRule);
    this.registerPlugin(new uno.commands.InsertHtml);
    this.registerPlugin(new uno.commands.InsertText);
    this.registerPlugin(new uno.commands.InsertParagraph);
    this.registerPlugin(new uno.commands.InsertTable);
    this.registerPlugin(new uno.commands.InsertTableCol);
    this.registerPlugin(new uno.commands.InsertTableRow);
    this.registerPlugin(new uno.commands.MergeCells);
    this.registerPlugin(new uno.commands.MigrateTable);
    this.registerPlugin(new uno.commands.Shutdown);
    this.registerPlugin(new uno.commands.FullSize);
    this.registerPlugin(new uno.commands.TableAlign);
    this.registerPlugin(new uno.commands.TableBorderColor);
    this.registerPlugin(new uno.commands.TableBorderWidth);
    this.registerPlugin(new uno.commands.TableCellColor);
    this.registerPlugin(new uno.commands.TableEqualCol);
    this.registerPlugin(new uno.commands.TableFitNote);
    this.registerPlugin(new uno.commands.TableVerticalAlign);
    this.registerPlugin(new uno.commands.Indent);
    this.registerPlugin(new uno.commands.InsertTodo);
    this.registerPlugin(new uno.commands.InsertDrawing);
    this.registerPlugin(new uno.commands.Lowercase);
    this.registerPlugin(new uno.commands.Margin);
    this.registerPlugin(new uno.commands.Paste(this.config));
    this.registerPlugin(new uno.commands.PlainText);
    this.registerPlugin(new uno.commands.PrintPreview);
    this.registerPlugin(new uno.commands.Redo);
    this.registerPlugin(new uno.commands.RemoveFormat);
    this.registerPlugin(new uno.commands.Resources);
    this.registerPlugin(new uno.commands.RichlinksConvert);
    this.registerPlugin(new uno.commands.RichlinksRefresh);
    this.registerPlugin(new uno.commands.Search);
    this.registerPlugin(new uno.commands.SelectAll);
    this.registerPlugin(new uno.commands.Selection);
    this.registerPlugin(new uno.commands.SimpleText);
    this.registerPlugin(new uno.commands.Stats);
    this.registerPlugin(new uno.commands.Strikethrough);
    this.registerPlugin(new uno.commands.Tab);
    this.registerPlugin(new uno.commands.Underline);
    this.registerPlugin(new uno.commands.Undo);
    this.registerPlugin(new uno.commands.UndoRedo);
    this.registerPlugin(new uno.commands.Unlink);
    this.registerPlugin(new uno.commands.Uppercase);
    this.registerPlugin(new uno.commands.ZoomScale);
    var allFiltersPM = uno.filters.All();
    var self = this;
    allFiltersPM.forEach(function(plugin) {
      self.registerPlugin(plugin);
    });
    this.registerPlugin(new uno.listeners.ClipboardListener);
    this.registerPlugin(new uno.listeners.TableListener);
    this.registerPlugin(new goog.editor.plugins.EnterHandler);
    this.registerPlugin(new uno.listeners.AccentuateListener);
    this.registerPlugin(new uno.listeners.AttachmentListener);
    this.registerPlugin(new uno.listeners.AutoCorrectListener);
    this.registerPlugin(new uno.listeners.ChangeListener);
    this.registerPlugin(new uno.listeners.CodeBlockListener);
    this.registerPlugin(new uno.listeners.CryptListener);
    this.registerPlugin(new uno.listeners.DeleteListener);
    this.registerPlugin(new uno.listeners.EnterListener);
    this.registerPlugin(new uno.listeners.ForwardDeleteListener);
    this.registerPlugin(new uno.listeners.HighlightListener);
    this.registerPlugin(new uno.listeners.RichlinkListener);
    this.registerPlugin(new uno.listeners.TodoListener);
    this.registerPlugin(new uno.listeners.LinkListener);
    this.registerPlugin(new uno.listeners.ImgListener);
    this.registerPlugin(new uno.listeners.ListListener);
    this.registerPlugin(new goog.editor.plugins.SpacesTabHandler);
    this.registerPlugin(new uno.listeners.TextInputListener);
    this.registerPlugin(new uno.listeners.TodoListListener);
    this.registerPlugin(new uno.listeners.TypeBehindListener);
    this.registerPlugin(new uno.listeners.DragDropListener);
    this.registerPlugin(new uno.listeners.NoteListener);
    this.registerPlugin(new uno.listeners.SearchResizeListener);
    this.registerPlugin(new uno.listeners.SmartScrollListener);
    this.registerPlugin(new uno.listeners.SelectionListener);
  };
  Editor.prototype.initConfig = function(opt) {
    var options = opt || {};
    options.env = options.env || {};
    options.env.margin = options.env.margin || {};
    options.env.margin.scroll = options.env.margin.scroll || {};
    options.env.margin.offset = options.env.margin.offset || {};
    options.rte = options.rte || {};
    options.rte.imageConfig = options.rte.imageConfig || {};
    options.rte.resourceConfig = options.rte.resourceConfig || {};
    options.rte.typebehind = options.rte.typebehind || {};
    options.rte.locale = options.rte.locale || "en_US";
    options.note = options.note || {};
    options.clipboard = options.clipboard || {};
    this.context = {crypt:{uniqueIdCounter:0, incrementUniqueId:function() {
      return ++this.uniqueIdCounter;
    }}, dragState:{dataTransferContent:{}}, hasTempStyles:false, copyPaste:{}, format:uno.defs.format.CLIENT_HTML, images:{annotateButton:null, annotateHoverButton:null, previewButton:null, previewHoverButton:null, rotateButton:null, rotateHoverButton:null}, pendingTodo:false, resources:options.rte.resources || {}, style:{state:{}, value:{}, enabled:{}}, tempStyles:{state:{}, value:{}, enabled:{}}};
    this.config = {accentuate:options.accentuate || {clearOnClickSelector:"en-note"}, trackchanges:{state:options.rte.trackStateChanges || [], value:options.rte.trackValueChanges || [], enabled:options.rte.trackEnabledChanges || []}, crypt:{unveilCryptElementOnClick:false, readOnly:options.rte.cryptReadOnly || false}, debug:!!options.debug, defaults:{html:"<div><br></div>", placeholderText:options.rte.placeholder || "Drag files here or start typing", plainTextFont:options.env.defaultPlainTextFont || 
    "Courier New", richTextFont:options.env.defaultNoteFont || "sans-serif", selectionColor:"rgb(178, 215, 255)", fontSize:"", fontFamily:"", foreColor:"rgb(0, 0, 0)"}, find:options.find || {}, images:{path:options.rte.imageConfig.path || "images", annotate:!!options.rte.imageConfig.annotate, preview:!!options.rte.imageConfig.preview, resize:!!options.rte.imageConfig.resize || !!options.rte.imageResizing, rotate:!!options.rte.imageConfig.rotate, horizontalThreshold:options.rte.smartMarginThreshold || 
    0, androidPath:"http://android.local/images"}, initialContent:options.rte.enml || options.rte.html, initialContentFormat:options.rte.enml ? uno.defs.format.ENML : uno.defs.format.CLIENT_HTML, locale:options.rte.locale || "en_US", margin:{note:options.env.margin.note, scroll:{top:options.env.margin.scroll.top || 0, left:options.env.margin.scroll.left || 0, bottom:options.env.margin.scroll.bottom || 0, right:options.env.margin.scroll.right || 0}, offset:{height:options.env.margin.offset.height || 
    0, width:options.env.margin.offset.width || 0}}, multirange:true, noNormalize:options.noNormalize, note:{contentClass:options.note.contentClass, source:options.note.source, sourceURL:options.note.sourceURL, sourceApplication:options.note.sourceApplication, title:options.note.title}, client:options.env.client || uno.env.getClient(), userid:options.userid || null, resourceConfig:{openLinkNotifications:!!options.rte.resourceConfig.openLinkNotifications}, smartScrollEnabled:options.rte.smartScroll, 
    stayInEditMode:options.stayInEditMode !== false, richlinks:{enabled:options.rte.richLinks || false, cacheSupported:options.rte.richLinkCaching || false}, style:{table:{borderCollapse:"collapse", tableLayout:"fixed", cell:{width:264, borderWidth:1, borderColor:"#d3d3d3", borderStyle:"solid", padding:"10px", margin:"0px"}}}, typebehind:{code:options.rte.typebehind.code || false, email:options.rte.typebehind.email || false, emoticon:options.rte.typebehind.emoticon || false, horizontalrule:options.rte.typebehind.horizontalrule || 
    false, inline:options.rte.typebehind.inline || false, list:options.rte.typebehind.list || false, table:options.rte.typebehind.table || false, todo:options.rte.typebehind.todo || false, url:options.rte.typebehind.url || false}, clipboard:{intercept:options.clipboard.intercept || false}, disableBackgroundPrint:!!options.disableBackgroundPrint};
    util.tools.preloadImages();
    util.img.preloadTools(this);
  };
  Editor.prototype.onLoad = function() {
    var el = this.getElement();
    var me = this;
    me.handlers.forEach(function(property) {
      var src = property.target || me.field;
      var type = property.eventname || property.name;
      var capture = property.capture === true;
      var handler = function(event) {
        me.listeners[property.name].some(function(plugin) {
          if (property.name === "selectionchange" && me.multirange.isInvoking()) {
            return false;
          }
          return plugin.isEnabled(me) && plugin[property.handler](event);
        });
      };
      me.eventRegister.listenWithScope(src, type, handler, capture, me);
    });
    uno.util.touch.init(this);
    el.setAttribute("data-en-placeholder", this.config.defaults.placeholderText);
    this.updateEmpty();
    var computedStyle = window.getComputedStyle(el);
    this.config.defaults.fontSize = computedStyle.fontSize;
    this.config.defaults.fontFamily = computedStyle.fontFamily.replace(/["']/g, "");
    setTimeout(function() {
      me.leaveEditMode();
    });
  };
  Editor.prototype.onUnload = function() {
    this.isSetup = false;
  };
  Editor.prototype.isFocused = function() {
    return this.focused;
  };
  Editor.prototype.suppressFocusDuring = function(fn) {
    function focusListener(e) {
      e.stopPropagation();
      this.blur();
    }
    this.listen(Editor.EventType.FOCUS, focusListener, true, this);
    try {
      return fn.apply(this);
    } finally {
      this.unlisten(Editor.EventType.FOCUS, focusListener, true, this);
    }
  };
  Editor.prototype.inEditMode = function() {
    return this.field && this.field.getAttribute("contenteditable") === "true";
  };
  Editor.prototype.enablePlugins = function() {
    var editor = this;
    editor.allPluginsInOrder.forEach(function(plugin) {
      plugin.enable(editor);
    });
  };
  Editor.prototype.disablePlugins = function() {
    var editor = this;
    editor.allPluginsInOrder.forEach(function(plugin) {
      if (!plugin.activeOnUneditableFields()) {
        plugin.disable(editor);
      }
    });
  };
  Editor.prototype.hasProtectedContent = function(frag) {
    var node = frag || this.field;
    var source = this.config.note.source;
    var hasContentClass = !!this.config.note.contentClass;
    var hasWebclipSource = ["Clearly", "External", "web.clip", "web.clip7"].indexOf(source) > -1;
    var hasEmailSource = /^e?mail/i.test(source);
    var hasMarxicoSource = /maxiang/i.test(source);
    var hasPostboxSourceUrl = /postbox/i.test(this.config.note.sourceURL);
    var hasBlockSpans = !!node && !!node.querySelector('span[style*="display: block"],span[style*="display:block"]');
    return hasContentClass || hasWebclipSource || hasEmailSource || hasMarxicoSource || hasPostboxSourceUrl || hasBlockSpans;
  };
  Editor.prototype.hasForeignSource = function() {
    var source = this.config.note.source;
    var hasContentClass = !!this.config.note.contentClass;
    var hasWebclipSource = ["Clearly", "External", "web.clip", "web.clip7"].indexOf(source) > -1;
    var hasEmailSource = /^e?mail/i.test(source);
    var hasMarxicoSource = /maxiang/i.test(source);
    var hasPostboxSourceUrl = /postbox/i.test(this.config.note.sourceURL);
    return hasContentClass || hasWebclipSource || hasEmailSource || hasMarxicoSource || hasPostboxSourceUrl;
  };
  Editor.prototype.enterEditMode = function(rangeOrFocus) {
    if (this.readOnly) {
      return;
    }
    var changed = false;
    var range = rangeOrFocus;
    var focus = true;
    if (goog.isBoolean(rangeOrFocus) && rangeOrFocus === false) {
      focus = false;
    }
    if (!this.inEditMode()) {
      this.field.setAttribute("contenteditable", "true");
      goog.dom.classlist.add(this.field, "editmode");
      goog.dom.classlist.remove(this.field, "viewmode");
      this.enablePlugins();
      if (range) {
        this.restoreRange(range);
      }
      changed = true;
    }
    if (focus) {
      this.focus();
      this.updateUndoCursorPosition();
    }
    if (changed) {
      this.dispatchEvent(Editor.EventType.EDIT_MODE_CHANGED);
    }
  };
  Editor.prototype.setHtml = function() {
    SeamlessField.prototype.setHtml.apply(this, arguments);
    var note = this.field;
    var startNode = note.firstChild || note;
    var startOffset = 0;
    var endNode = note.lastChild || note;
    var endOffset = note.lastChild ? note.lastChild.childNodes.length : 0;
    var range = goog.dom.Range.createFromNodes(startNode, startOffset, endNode, endOffset);
    this.dispatchEvent({type:Editor.EventType.DOM_UPDATE, range:range, paste:false});
  };
  Editor.prototype.leaveEditMode = function(force) {
    if (!this.readOnly && force !== true) {
      if (!this.inEditMode() || this.config.stayInEditMode) {
        return;
      }
    }
    if (this.field) {
      this.field.removeAttribute("contenteditable");
      goog.dom.classlist.add(this.field, "viewmode");
      goog.dom.classlist.remove(this.field, "editmode");
      this.disablePlugins();
      this.field.blur();
    }
    this.dispatchEvent(Editor.EventType.EDIT_MODE_CHANGED);
  };
  Editor.prototype.openFullSize = function(sender, opt) {
    var state = this.context.fullsize;
    if (state && state.enabled) {
      log.warning("Fullsize mode is already opened, blocking redundant request.");
      return;
    } else {
      if (state && state.pending) {
        log.warning("Fullsize request is pending, blocking redundant request.");
        return;
      }
    }
    this.context.fullsize = {scrollY:window.scrollY, enabled:false, pending:true, owner:sender};
    EN.notification("fullsize", Object.assign(opt || {}, {action:"open", sender:sender}));
  };
  Editor.prototype.closeFullSize = function(sender) {
    var state = this.context.fullsize;
    if (!state || state && !state.enabled) {
      log.warning("Fullsize mode is not enabled, blocking wrong request.");
      return;
    } else {
      if (state && state.pending) {
        log.warning("Fullsize request is pending, blocking redundant request.");
        return;
      }
    }
    this.context.fullsize.pending = true;
    EN.notification("fullsize", {action:"close", sender:sender});
  };
  Editor.prototype.onFocus = function() {
    this.enterEditMode();
    this.focused = true;
    this.dispatchStyleChange();
    var range = this.getRange();
    if (range && range.getStartNode() === this.field && range.getStartOffset() === 0) {
      if (!this.field.firstChild) {
        this.field.innerHTML = this.config.defaults.html;
      }
      goog.dom.Range.createCaret(this.field.firstChild, 0).select();
    }
  };
  Editor.prototype.onBlur = function() {
    this.leaveEditMode();
    this.focused = false;
  };
  Editor.prototype.blur = function() {
    var range = this.saveRange();
    if (this.field) {
      this.field.blur();
    }
    if (range) {
      range.select();
    }
  };
  Editor.prototype.saveRange = function() {
    var range = this.getRange();
    if (range) {
      this.savedRange = range.saveUsingDom();
      this.currentRange = range;
    }
    return range;
  };
  Editor.prototype.restoreRange = function(range) {
    if (goog.isObject(range)) {
      range.select();
    } else {
      var didSetSelection = false;
      if (this.savedRange != null && this.savedRange.isDisposed && !this.savedRange.isDisposed()) {
        try {
          this.savedRange.restore().select();
          var newRange = this.getRange();
          newRange.collapse();
          newRange.select();
          didSetSelection = true;
        } catch (err$13) {
          log.fine(err$13.stack || err$13);
        }
      }
      if (!didSetSelection) {
        this.placeCursorAtEnd();
      }
      this.savedRange = null;
    }
  };
  Editor.prototype.cleanup = function() {
    if (this.isSetup) {
      var field = this.field;
      this.makeUneditable(true);
      while (field.firstChild) {
        field.removeChild(field.firstChild);
      }
      this.dispose();
      window.ed = null;
    }
  };
  Editor.prototype.onBeforeSelectionChange = function() {
    this.updateUndoCursorPosition();
  };
  Editor.prototype.onDelayedChange = function() {
    this.dirty = true;
  };
  function shouldCalculateStyleChange(currentRange, newRange) {
    if (currentRange && newRange) {
      var startNode = newRange.getStartNode();
      var newStartNode = currentRange.getStartNode();
      var endNode = newRange.getEndNode();
      var newEndNode = currentRange.getEndNode();
      if (startNode !== newStartNode || endNode !== newEndNode || util.dom.isElementNode(startNode) || util.dom.isElementNode(endNode)) {
        return true;
      }
    }
    return false;
  }
  function calculateNewStyle(trackchanges, currentStyle) {
    var hasChanges = false;
    var ed = this;
    var newStyle = {state:{}, value:{}, enabled:{}};
    trackchanges.state.forEach(function(command) {
      var result = ed.queryCommandState(command);
      if (currentStyle.state[command] !== result) {
        newStyle.state[command] = result;
        hasChanges = true;
      }
    });
    trackchanges.value.forEach(function(command) {
      var result = ed.queryCommandValue(command);
      if (currentStyle.value[command] !== result) {
        newStyle.value[command] = result;
        hasChanges = true;
      }
    });
    trackchanges.enabled.forEach(function(command) {
      var result = ed.queryCommandEnabled(command);
      if (currentStyle.enabled[command] !== result) {
        newStyle.enabled[command] = result;
        hasChanges = true;
      }
    });
    return {style:newStyle, hasChanges:hasChanges};
  }
  Editor.prototype.dispatchStyleChange = function(style, force) {
    if (!this.multirange.isEmpty() && !force) {
      return;
    }
    if (force || !style || shouldCalculateStyleChange(this.getRange(), this.currentRange)) {
      var result = calculateNewStyle.call(this, this.config.trackchanges, this.context.style);
      if (result.hasChanges) {
        style = result.style;
      } else {
        return;
      }
    }
    goog.object.extend(this.context.style.enabled, style.enabled);
    goog.object.extend(this.context.style.value, style.value);
    goog.object.extend(this.context.style.state, style.state);
    this.context.style.hasChanges = true;
    clearTimeout(dispatchStyleChangeTimer);
    var editor = this;
    dispatchStyleChangeTimer = setTimeout(function() {
      if (editor.context.style.hasChanges) {
        editor.dispatchEvent({type:uno.Editor.EventType.STYLE_CHANGED, style:editor.context.style});
        editor.context.style.hasChanges = false;
      }
    });
  };
  Editor.prototype.onSelectionChange = function() {
    this.updateEmpty();
    if (!this.readOnly) {
      this.dispatchStyleChange();
    }
    this.saveRange();
  };
  Editor.prototype.onTextInput = function(event) {
    if (event.target !== this.field) {
      return;
    }
    this.dispatchChange();
  };
  Editor.prototype.emitKeyboardEvent = function(type, char) {
    var code = char.charCodeAt();
    if (code === 10) {
      code = 13;
    }
    var e = new KeyboardEvent(type, {bubble:true, cancelable:true, key:char, keyCode:code, which:code});
    Object.defineProperty(e, "keyCode", {get:function() {
      return code;
    }});
    Object.defineProperty(e, "which", {get:function() {
      return code;
    }});
    return this.field.dispatchEvent(e);
  };
  Editor.prototype.onInput = function(event) {
    if (event.target !== this.field) {
      return;
    }
    this.updateEmpty();
    var _this = this;
    setTimeout(function() {
      _this.dispatchChange();
    });
  };
  Editor.prototype.updateEmpty = function() {
    if (this.field == null) {
      return;
    }
    var empty = util.dom.isEmpty(this.field);
    if (empty && this.field.innerHTML !== this.config.defaults.html) {
      this.context.format = uno.defs.format.CLIENT_HTML;
      this.setHtml(false, this.config.defaults.html, true);
      util.dom.scrollLeft(document.body, 0);
      util.dom.scrollTop(document.body, 0);
    }
    if (empty) {
      goog.dom.classes.add(this.field, "en-note-is-empty");
    } else {
      goog.dom.classes.remove(this.field, "en-note-is-empty");
    }
    this.empty = empty;
  };
  Editor.prototype.queryCommandValueInternal_ = function(command, isLoaded, opt, isTopLevelCall) {
    var logic = function() {
      var plugins = this.indexedPlugins_[Plugin.Op.QUERY_COMMAND];
      for (var i = 0; i < plugins.length; ++i) {
        var plugin = plugins[i];
        if (plugin.isEnabled(this) && plugin.isSupportedCommand(command) && (isLoaded || plugin.activeOnUneditableFields())) {
          return plugin.queryCommandValue(command, opt);
        }
      }
      return isLoaded ? null : false;
    }.bind(this);
    return logic();
  };
  Editor.prototype.queryCommandValue = function(command, options, isTopLevelCall) {
    return this.queryCommandValueInternal_(command, this.isLoaded(), options, isTopLevelCall);
  };
  Editor.prototype.queryCommandState = function(command, options) {
    var result = this.queryCommandValue(command, options);
    if (result === "true") {
      result = true;
    }
    if (result === "false") {
      result = false;
    }
    if (command === "justifyleft") {
      result = result === "left";
    } else {
      if (command === "justifycenter") {
        result = result === "center";
      } else {
        if (command === "justifyright") {
          result = result === "right";
        } else {
          if (command === "justifyfull") {
            result = result === "justify";
          } else {
            if (command === "insertorderedlist") {
              result = result === "ol";
            } else {
              if (command === "insertunorderedlist") {
                result = result === "ul";
              }
            }
          }
        }
      }
    }
    return !!result;
  };
  Editor.prototype.queryCommandEnabledInternal_ = function(command, isLoaded, opt, isTopLevelCall) {
    var mode = isTopLevelCall ? uno.EditorMultiRange.Mode.FIRST : uno.EditorMultiRange.Mode.NONE;
    return this.multirange.invoke(mode, function() {
      var plugins = this.queryCommandEnabledPlugins;
      for (var i = 0; i < plugins.length; ++i) {
        var plugin = plugins[i];
        if (plugin.isEnabled(this) && plugin.isSupportedCommand(command) && (isLoaded || plugin.activeOnUneditableFields())) {
          return plugin.queryCommandEnabled(command, opt);
        }
      }
      return true;
    });
  };
  Editor.prototype.queryCommandEnabled = function(command, options, isTopLevelCall) {
    return !!this.queryCommandEnabledInternal_(command, this.isLoaded(), options, isTopLevelCall);
  };
  Editor.prototype.execCommand = function(command, value, options, isTopLevelCall) {
    if (isTopLevelCall == null) {
      isTopLevelCall = false;
    }
    var plugins = this.indexedPlugins_[Plugin.Op.EXEC_COMMAND];
    var targetPlugin = null;
    for (var i = 0; i < plugins.length && targetPlugin == null; ++i) {
      if (plugins[i].isEnabled(this) && plugins[i].isSupportedCommand(command) && (this.isLoaded() || plugins[i].activeOnUneditableFields())) {
        targetPlugin = plugins[i];
      }
    }
    if (!targetPlugin || !goog.isFunction(targetPlugin.execCommand)) {
      return false;
    }
    if (goog.isFunction(targetPlugin.queryCommandEnabled) && targetPlugin.queryCommandEnabled(command, value) === false) {
      return false;
    }
    var mode = uno.EditorMultiRange.Mode.NONE;
    if (isTopLevelCall && targetPlugin.multiRangeMode === uno.EditorMultiRange.Mode.ALL) {
      mode = uno.EditorMultiRange.Mode.ALL;
    }
    var finalResult = this.multirange.invoke(mode, function() {
      var result = null;
      this.dispatchEvent({type:"beforeexeccommand", command:command});
      result = targetPlugin.execCommand.call(targetPlugin, command, value, options);
      this.updateUndoCursorPosition();
      this.dispatchEvent({type:"afterexeccommand", command:command});
      return result;
    });
    this.lastCommand = command;
    return finalResult;
  };
  Editor.prototype.isSupportedCommand = function(command) {
    if (!this.isLoaded()) {
      return false;
    }
    return this.allPluginsInOrder.some(function(plugin) {
      return plugin.isSupportedCommand(command);
    });
  };
  Editor.prototype.invokeOp_ = function(op) {
    if (op === Plugin.Op.CLEAN_CONTENTS_DOM) {
      return this.invokeOpRight_.apply(this, arguments);
    }
    return SeamlessField.prototype.apply.invokeOp_.apply(this, arguments);
  };
  Editor.prototype.invokeOpRight_ = function(op) {
    var plugins = this.indexedPlugins_[op];
    var argList = goog.array.slice(arguments, 1);
    for (var i = plugins.length - 1; i >= 0; i--) {
      var plugin = plugins[i];
      plugin[Plugin.OPCODE[op]].apply(plugin, argList);
    }
  };
  Editor.prototype.reduceOp_ = function(op, arg, varArgs) {
    var result;
    if (op === Plugin.Op.CLEAN_CONTENTS_DOM || op === Plugin.Op.CLEAN_CONTENTS_HTML) {
      result = this.reduceOpRight_(op, arg, varArgs);
    } else {
      result = SeamlessField.prototype.reduceOp_.apply(this, arguments);
    }
    if (op === Plugin.Op.PREPARE_CONTENTS_HTML) {
      result = this.prepareContentsDom(result);
    }
    return result;
  };
  Editor.prototype.reduceOpRight_ = function(op) {
    var plugins = this.indexedPlugins_[op];
    var argList = goog.array.slice(arguments, 1);
    for (var i = plugins.length - 1; i >= 0; i--) {
      var plugin = plugins[i];
      argList[0] = plugin[Plugin.OPCODE[op]].apply(plugin, argList);
    }
    return argList[0];
  };
  Editor.prototype.prepareContentsHtml = function(html) {
    var styles = {};
    return this.reduceOp_(goog.editor.Plugin.Op.PREPARE_CONTENTS_HTML, html || "", styles);
  };
  Editor.prototype.prepareContentsDom = function(html) {
    if (!html) {
      return "";
    }
    var frag = util.dom.fragFromString(html);
    this.importDomFilters.forEach(function(filter) {
      filter.prepareContentsDom(frag);
    });
    return util.dom.stringFromFrag(frag);
  };
  Editor.prototype.getFormField = function() {
    var target = document.activeElement;
    if (target && ["TEXTAREA", "INPUT"].indexOf(target.nodeName) > -1) {
      return target;
    }
    return null;
  };
  Editor.prototype.getAllPluginsInOrder = function() {
    return this.allPluginsInOrder;
  };
  Editor.prototype.getClipboardContent = function(frag) {
    this.context.format = uno.defs.format.CLIPBOARD;
    this.invokeOp_(goog.editor.Plugin.Op.CLEAN_CONTENTS_DOM, frag);
    return this.reduceOp_(goog.editor.Plugin.Op.CLEAN_CONTENTS_HTML, frag.innerHTML);
  };
  Editor.prototype.updateUndoCursorPosition = function() {
    var undoPlugin = this.plugins_.UndoRedo;
    var current = undoPlugin.currentStates_[this.getHashCode()];
    var previous = undoPlugin.undoManager_.undoPeek();
    if (current && this.field && current.undoContent_ === this.field.innerHTML) {
      current.undoCursorPosition_ = undoPlugin.getCursorPosition_(this);
      if (previous) {
        previous.redoCursorPosition_ = current.undoCursorPosition_;
      }
    }
  };
  Editor.prototype.refreshUndoRedoState = function() {
    var undoPlugin = this.plugins_.UndoRedo;
    undoPlugin.refreshCurrentState(this);
    var current = undoPlugin.currentStates_[this.getHashCode()];
    var previous = undoPlugin.undoManager_.undoPeek();
    if (previous) {
      previous.redoContent_ = current.undoContent_;
      previous.redoCursorPosition_ = current.undoCursorPosition_;
    }
  };
})();
goog.provide("uno.util.string");
goog.require("goog.string");
(function() {
  var util = uno.util;
  util.string.removeInvalidHtmlCharacters = function(line) {
    var invalidCharacters = /[\u0000\u0001-\u0008\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\u000B\uFFFE\uFFFF]|[\x01-\x10][\uFFFE-\uFFFF]/g;
    return line.replace(invalidCharacters, "");
  };
  util.string.trimZWS = function(str) {
    return str.replace(/(^[\s\u200b]*|[\s\u200b]*$)/g, "");
  };
  util.string.isEmpty = function(s) {
    var rxEmptyString = /^[\x00-\x20\s]*$/g;
    if (goog.string.isEmptySafe(s)) {
      rxEmptyString.lastIndex = 0;
      return s.length === 0 || rxEmptyString.test(s);
    }
    return false;
  };
})();
goog.provide("uno.template.util");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.array");
goog.require("uno.util.string");
goog.require("uno.util.dom");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.template.util");
  var util = uno.util;
  var tmpl = uno.template.util;
  tmpl.TEMPLATE_STYLE_ATTR_CONTEXT_NAME = "-evernote-context-name";
  tmpl.FIELD_TYPES = ["title", "field", "textarea", "phone", "email", "twitter", "linkedin", "facebook", "weibo", "address", "profile-image"];
  tmpl.valueDidChangeForFieldInfo = function(fieldInfo) {
    fieldInfo.opt.fieldLastChanged = fieldInfo.name;
    fieldInfo.template.execCommand("changes", true);
  };
  tmpl.normalizeEditableTextElement = function(fieldInfo) {
    var element = fieldInfo.node;
    var text = tmpl.plainTextHTMLFromElement(element, fieldInfo.isMultiline);
    element.innerHTML = text;
    if (util.string.isEmpty(text) || text === "<div><br></div>") {
      goog.dom.classes.add(element, "en-editable-placeholder");
    } else {
      goog.dom.classes.remove(element, "en-editable-placeholder");
    }
    fieldInfo.html = element.innerHTML;
    return element;
  };
  tmpl.plainTextHTMLFromElement = function(element, wrapLines) {
    if (document.activeElement !== element) {
      element.innerHTML = element.innerHTML.replace(/(<\/div>)/gi, "\n$1");
    }
    var text = element.innerText.trim();
    var html;
    if (!wrapLines && util.string.isEmpty(text)) {
      html = "";
    } else {
      if (wrapLines) {
        var lines = text.split("\n");
        lines = lines.map(function(v) {
          if (util.string.isEmpty(v)) {
            return "<div><br></div>";
          }
          return "<div>" + goog.string.htmlEscape(v) + "</div>";
        });
        html = lines.join("");
      } else {
        html = goog.string.htmlEscape(text.replace(/\n/g, " "));
      }
    }
    return html;
  };
  tmpl.iterateFields = function(root) {
    var selector = "*[style*='-evernote-editable:']";
    var elements = goog.array.toArray(root.querySelectorAll(selector));
    return elements.map(function(el) {
      var fieldType = util.styles.getStyle(el, "-evernote-editable");
      if (!goog.array.contains(tmpl.FIELD_TYPES, fieldType)) {
        log.severe("Invalid -evernote-editable field mode! " + fieldType);
        return null;
      }
      var fieldName = util.styles.getStyle(el, "x-evernote");
      return {node:el, name:fieldName, type:fieldType};
    }, this).filter(function(el) {
      return el && el.node;
    });
  };
  tmpl.findSubElementByName = function(given, name) {
    var elements = given.querySelectorAll("*[style*='x-evernote:']");
    var found = null;
    goog.array.forEach(elements, function(node) {
      if (util.styles.getStyle(node, "x-evernote") === name) {
        found = node;
      }
    });
    return found;
  };
  tmpl.setupPlainTextFieldFormFieldInfo = function(fieldInfo) {
    var editorNode = fieldInfo.node;
    if (editorNode == null) {
      log.error("node missing in fieldinfo: " + JSON.stringify(fieldInfo));
    }
    var title = (fieldInfo.opt.localization[fieldInfo.name + "-placeholder-title"] || "...") + "\u00a0\u00a0\u00a0";
    editorNode.setAttribute("title", title);
    goog.dom.classes.add(editorNode, "en-editable");
    goog.dom.classes.add(editorNode, "en-editable-" + fieldInfo.type);
    editorNode.setAttribute("contenteditable", true);
    tmpl.normalizeEditableTextElement(fieldInfo);
    if (fieldInfo.opt.stripStyle) {
      editorNode.removeAttribute("style");
    }
    var oldValue = null;
    var context = tmpl.findSubElementByName(fieldInfo.container, "context");
    if (context) {
      var contextName = context.getAttribute("data" + tmpl.TEMPLATE_STYLE_ATTR_CONTEXT_NAME);
      var localized = fieldInfo.opt.localization[contextName + "-label"];
      if (context && localized) {
        goog.dom.removeChildren(context);
        context.textContent = localized;
      }
    }
    if (!context) {
      var fieldTitle = fieldInfo.opt.localization[fieldInfo.name + "-label"];
      if (fieldTitle) {
        context.textContent = fieldTitle;
      }
    }
    editorNode.addEventListener("focus", function() {
      oldValue = fieldInfo.object.getHTML();
      setTimeout(function() {
        var sel = window.getSelection();
        sel.selectAllChildren(editorNode);
      }, 0);
    });
    editorNode.addEventListener("input", function() {
      fieldInfo.template.execCommand("changes", true);
    });
    editorNode.addEventListener("blur", function() {
      window.getSelection().removeAllRanges();
      tmpl.normalizeEditableTextElement(fieldInfo);
      var newValue = fieldInfo.object.getHTML();
      if (oldValue !== newValue) {
        tmpl.valueDidChangeForFieldInfo(fieldInfo);
      }
    });
    editorNode.addEventListener("keydown", function(event) {
      var handled = false;
      if (event.keyCode === 13) {
        if (!fieldInfo.isMultiline) {
          editorNode.blur();
          handled = true;
        }
      } else {
        if (event.keyCode === 8) {
          document.execCommand("delete");
          handled = true;
        }
      }
      if (handled) {
        event.preventDefault();
        event.stopPropagation();
        return false;
      }
      return false;
    });
  };
  tmpl.setupContextFieldFromFieldInfo = function(fieldInfo, options) {
    fieldInfo.contextNode = tmpl.findSubElementByName(fieldInfo.container, "context");
    var node = fieldInfo.contextNode;
    var contextName = util.styles.getStyle(node, tmpl.TEMPLATE_STYLE_ATTR_CONTEXT_NAME);
    if (node && !contextName) {
      contextName = node.getAttribute("data" + tmpl.TEMPLATE_STYLE_ATTR_CONTEXT_NAME);
    }
    goog.dom.classes.add(node, "en-editable-context");
    goog.dom.removeChildren(node);
    var titleNode = goog.dom.createElement("span");
    node.appendChild(titleNode);
    if (contextName === "fax") {
      contextName = "work-fax";
    }
    var localizedTitle = fieldInfo.opt.localization[contextName + "-label"];
    if (!localizedTitle) {
      log.warning("No l18n option for template " + contextName + "-label");
      localizedTitle = contextName;
    }
    titleNode.textContent = localizedTitle;
    var optionElements = [];
    for (var i = 0; i < options.length; i++) {
      var optionName = options[i];
      var title = fieldInfo.opt.localization[optionName + "-label"];
      if (!title) {
        log.warning("No l18n option for template " + optionName + "-label");
        title = optionName;
      }
      var elem = goog.dom.createDom("option", {value:optionName}, document.createTextNode(title));
      if (optionName === contextName) {
        elem.setAttribute("selected", "selected");
      }
      optionElements.push(elem);
    }
    var selectField = goog.dom.createDom.bind(this, "select", {class:"en-editable-select-context", tabindex:"-1"}).apply(this, optionElements);
    node.insertBefore(selectField, null);
    selectField.addEventListener("change", function() {
      var newName = selectField.value;
      util.styles.setStyle(node, tmpl.TEMPLATE_STYLE_ATTR_CONTEXT_NAME, newName);
      titleNode.textContent = fieldInfo.opt.localization[newName + "-label"] || newName;
      tmpl.valueDidChangeForFieldInfo(fieldInfo);
    });
    node.parentElement.style.textDecoration = "none";
  };
})();
goog.provide("uno.template.Field");
goog.require("goog.debug.Logger");
goog.require("uno.template.util");
goog.require("uno.util.dom");
goog.require("uno.util.styles");
(function() {
  var log = goog.debug.Logger.getLogger("uno.template.Field");
  var tmpl = uno.template.util;
  var util = uno.util;
  var Field = uno.template.Field = function(fieldInfo) {
    this.fieldInfo = fieldInfo;
    this.setup();
  };
  Field.prototype.setup = function() {
  };
  Field.prototype.copyCurrentValueToDom = function(frag) {
    var allFields = tmpl.iterateFields(frag);
    var matchingContainer = null;
    if (allFields && allFields.length > this.fieldInfo.index) {
      var indexMatch = allFields[this.fieldInfo.index].node;
      var type = util.styles.getStyle(indexMatch, "-evernote-editable");
      if (indexMatch == null || type !== this.fieldInfo.type) {
        log.severe("Wrong field type at correct field index! " + this.fieldInfo.type + " @ index " + this.fieldInfo.index);
      }
      matchingContainer = indexMatch;
    }
    if (matchingContainer == null) {
      log.severe("No matching container found for " + this.fieldInfo.name + " @ index " + this.fieldInfo.index);
      return;
    }
    if (this.fieldInfo.contextNode && matchingContainer) {
      var contextName = util.styles.getStyle(this.fieldInfo.contextNode, tmpl.TEMPLATE_STYLE_ATTR_CONTEXT_NAME);
      if (contextName) {
        var contextSelector = "*[style*='x-evernote:context']";
        var matchingNode = matchingContainer.querySelector(contextSelector);
        if (matchingNode) {
          var label = contextName + "-label";
          var localization = this.fieldInfo.opt.localization[label];
          util.styles.setStyle(matchingNode, tmpl.TEMPLATE_STYLE_ATTR_CONTEXT_NAME, contextName);
          matchingNode.textContent = localization || contextName;
        } else {
          log.severe("No matching context node for " + contextName);
        }
      }
    }
    var neverUpdatedFields = ["card-image", "profile-image"];
    var updateable = neverUpdatedFields.indexOf(this.fieldInfo.name) < 0;
    if (matchingContainer && updateable) {
      var valueNodeSelector = "*[style*='x-evernote:value']";
      var matchingValueNode = matchingContainer.querySelector(valueNodeSelector);
      if (matchingValueNode == null) {
        matchingValueNode = matchingContainer;
      }
      matchingValueNode.innerHTML = this.getHTML() || "&nbsp;";
    }
  };
  Field.prototype.getHTML = function() {
    return this.fieldInfo.node.innerHTML;
  };
})();
goog.provide("uno.template.NoopField");
goog.require("uno.template.Field");
(function() {
  var NoopField = uno.template.NoopField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(NoopField, uno.template.Field);
})();
goog.provide("uno.template.TitleField");
goog.require("uno.template.util");
goog.require("uno.template.Field");
(function() {
  var tmpl = uno.template.util;
  var TitleField = uno.template.TitleField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(TitleField, uno.template.Field);
  TitleField.prototype.getHTML = function() {
    return tmpl.plainTextHTMLFromElement(this.fieldInfo.node);
  };
})();
goog.provide("uno.template.LinkField");
goog.require("uno.template.Field");
goog.require("uno.template.util");
goog.require("uno.util.string");
goog.require("goog.debug.Logger");
(function() {
  var log = goog.debug.Logger.getLogger("uno.template.LinkField");
  var tmpl = uno.template.util;
  var util = uno.util;
  var LinkField = uno.template.LinkField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(LinkField, uno.template.Field);
  LinkField.prototype.createRepresentationElement = function(value, attrs) {
    attrs.href = value;
    var link = goog.dom.createDom("a", attrs, document.createTextNode(value));
    return link;
  };
  LinkField.prototype.getValue = function() {
    var node = this.fieldInfo.node;
    if (node == null) {
      log.severe("couldnt get node of linkfield");
      return "";
    }
    var value = node.textContent;
    if (!value || util.string.isEmpty(value)) {
      return "";
    }
    return value.trim();
  };
  LinkField.prototype.setup = function() {
    var self = this;
    this.fieldInfo.node = tmpl.findSubElementByName(this.fieldInfo.container, "value");
    var node = this.fieldInfo.node;
    var value = this.getValue();
    node.style.textDecoration = "";
    goog.dom.removeChildren(node);
    var editable = goog.dom.createDom("div");
    node.appendChild(editable);
    editable.textContent = value;
    this.fieldInfo.node = editable;
    tmpl.setupPlainTextFieldFormFieldInfo(this.fieldInfo);
    var content = goog.dom.createDom("span");
    var preview = goog.dom.createDom("div", {class:"en-editable-preview"}, content);
    node.appendChild(preview);
    var updateEditableFieldVisibilityForStandby = function() {
      goog.dom.classes.remove(preview, "en-editable-hidden");
      goog.dom.classes.add(editable, "en-editable-hidden");
      goog.dom.removeChildren(content);
      var text = self.getValue();
      if (!util.string.isEmpty(text)) {
        content.appendChild(self.createRepresentationElement(text, {tabindex:"-1"}));
      } else {
        goog.dom.classes.remove(editable, "en-editable-hidden");
        goog.dom.classes.add(preview, "en-editable-hidden");
      }
      editable.textContent = text;
    };
    updateEditableFieldVisibilityForStandby();
    preview.addEventListener("click", function(e) {
      if (e.target && e.target.tagName.toLowerCase() === "a") {
        var href = e.target.getAttribute("href");
        EN.notification("openLink", {href:href, module:"template"});
      } else {
        editable.focus();
      }
    });
    editable.addEventListener("focus", function() {
      goog.dom.classes.remove(editable, "en-editable-hidden");
      goog.dom.classes.add(preview, "en-editable-hidden");
    });
    editable.addEventListener("blur", function() {
      updateEditableFieldVisibilityForStandby();
    });
    goog.dom.classes.add(this.fieldInfo.container, "en-editable-container");
  };
  LinkField.prototype.getHTML = function() {
    var text = this.fieldInfo.node.textContent;
    return util.string.isEmpty(text) ? uno.defs.nbsp.CHARACTER_SEQUENCE : util.dom.toHTML(this.createRepresentationElement(text, {}));
  };
})();
goog.provide("uno.template.AddressField");
goog.require("uno.template.LinkField");
goog.require("uno.util.string");
(function() {
  var AddressField = uno.template.AddressField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(AddressField, uno.template.LinkField);
  AddressField.prototype.createRepresentationElement = function(value, attrs) {
    value = value.trim();
    attrs.href = "http://maps.google.com/?q=" + encodeURIComponent(value);
    return goog.dom.createDom("a", attrs, document.createTextNode(value));
  };
})();
goog.provide("uno.template.PlainTextField");
goog.require("uno.template.util");
goog.require("uno.template.Field");
(function() {
  var tmpl = uno.template.util;
  var PlainTextField = uno.template.PlainTextField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(PlainTextField, uno.template.Field);
  PlainTextField.prototype.setup = function() {
    tmpl.setupPlainTextFieldFormFieldInfo(this.fieldInfo);
  };
  PlainTextField.prototype.getHTML = function() {
    return tmpl.plainTextHTMLFromElement(this.fieldInfo.node);
  };
})();
goog.provide("uno.template.PlainTextArea");
goog.require("goog.debug.Logger");
goog.require("uno.template.PlainTextField");
goog.require("uno.template.util");
(function() {
  var log = goog.debug.Logger.getLogger("uno.template.PlainTextArea");
  var tmpl = uno.template.util;
  var PlainTextArea = uno.template.PlainTextArea = function(fieldInfo) {
    fieldInfo.isMultiline = true;
    goog.base(this, fieldInfo);
  };
  goog.inherits(PlainTextArea, uno.template.PlainTextField);
  PlainTextArea.prototype.setup = function() {
    tmpl.setupPlainTextFieldFormFieldInfo(this.fieldInfo);
  };
  PlainTextArea.prototype.getHTML = function() {
    try {
      return tmpl.plainTextHTMLFromElement(this.fieldInfo.node, true);
    } catch (ex) {
      log.fine("getHTML 'PlainTextArea.prototype.getHTML' failed " + ex.stack);
    }
    return null;
  };
})();
goog.provide("uno.template.PhoneField");
goog.require("uno.template.util");
goog.require("uno.template.LinkField");
(function() {
  var tmpl = uno.template.util;
  var PhoneField = uno.template.PhoneField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(PhoneField, uno.template.LinkField);
  PhoneField.prototype.setup = function() {
    goog.base(this, "setup");
    tmpl.setupContextFieldFromFieldInfo(this.fieldInfo, ["phone", "home", "work", "mobile", "main", "home-fax", "work-fax", "other"]);
  };
  PhoneField.prototype.createRepresentationElement = function(value, attrs) {
    value = value.trim().replace(/^tel:/, "");
    attrs.href = "tel:" + encodeURIComponent(value);
    return goog.dom.createDom("a", attrs, document.createTextNode(value));
  };
  PhoneField.prototype.getHTML = function() {
    return tmpl.plainTextHTMLFromElement(this.fieldInfo.node);
  };
})();
goog.provide("uno.template.EmailField");
goog.require("uno.template.LinkField");
goog.require("uno.template.util");
(function() {
  var tmpl = uno.template.util;
  var EmailField = uno.template.EmailField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(EmailField, uno.template.LinkField);
  EmailField.prototype.setup = function() {
    goog.base(this, "setup");
    tmpl.setupContextFieldFromFieldInfo(this.fieldInfo, ["email", "home", "work", "other"]);
  };
  EmailField.prototype.createRepresentationElement = function(value, attrs) {
    value = value.trim().replace(/^mailto:/, "");
    attrs.href = "mailto:" + value;
    return goog.dom.createDom("a", attrs, document.createTextNode(value));
  };
})();
goog.provide("uno.template.TwitterField");
goog.require("uno.template.LinkField");
goog.require("uno.util.string");
(function() {
  var util = uno.util;
  var TwitterField = uno.template.TwitterField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(TwitterField, uno.template.LinkField);
  TwitterField.prototype.getValue = function() {
    var node = this.fieldInfo.node;
    var value = node.textContent;
    if (!value) {
      return "";
    }
    value = value.trim().replace(/^\@/, "");
    if (util.string.isEmpty(value)) {
      return "";
    }
    return value;
  };
  TwitterField.prototype.createRepresentationElement = function(value, attrs) {
    attrs.href = "http://twitter.com/" + encodeURIComponent(value);
    return goog.dom.createDom("a", attrs, document.createTextNode("@" + value));
  };
})();
goog.provide("uno.template.FacebookField");
goog.require("uno.template.LinkField");
(function() {
  var FacebookField = uno.template.FacebookField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(FacebookField, uno.template.LinkField);
})();
goog.provide("uno.template.LinkedInField");
goog.require("uno.template.LinkField");
(function() {
  var LinkedInField = uno.template.LinkedInField = function(fieldInfo) {
    var hrefElement = fieldInfo.node.querySelector("a[href]");
    this.originalHref = null;
    this.originalText = null;
    if (hrefElement != null) {
      this.originalHref = hrefElement.getAttribute("href");
      this.originalText = hrefElement.textContent;
    }
    goog.base(this, fieldInfo);
  };
  goog.inherits(LinkedInField, uno.template.LinkField);
  LinkedInField.prototype.createRepresentationElement = function(value, attrs) {
    attrs.href = null;
    if (this.getValue() === this.originalText) {
      attrs.href = this.originalHref;
    }
    if (attrs.href == null) {
      attrs.href = "http://www.linkedin.com/in/" + encodeURIComponent(value);
    }
    return goog.dom.createDom("a", attrs, document.createTextNode(value));
  };
})();
goog.provide("uno.template.WeiboField");
goog.require("uno.template.LinkField");
goog.require("uno.util.string");
(function() {
  var util = uno.util;
  var WeiboField = uno.template.WeiboField = function(fieldInfo) {
    goog.base(this, fieldInfo);
  };
  goog.inherits(WeiboField, uno.template.LinkField);
  WeiboField.prototype.getValue = function() {
    var node = this.fieldInfo.node;
    var value = node.textContent;
    if (!value) {
      return "";
    }
    value = value.trim().replace(/^\@/, "");
    if (util.string.isEmpty(value)) {
      return "";
    }
    return value;
  };
  WeiboField.prototype.createRepresentationElement = function(value) {
    return document.createTextNode("@" + value);
  };
})();
goog.provide("uno.template.Plugin");
goog.require("goog.editor.Plugin");
(function() {
  var TemplatePlugin = uno.template.Plugin = function(template) {
    goog.editor.Plugin.call(this);
    this.template = template;
  };
  goog.inherits(TemplatePlugin, goog.editor.Plugin);
  TemplatePlugin.prototype.getElement = function() {
    return this.template.templateElement;
  };
})();
goog.provide("uno.template.commands.Changes");
goog.require("goog.debug.Logger");
goog.require("uno.template.Plugin");
goog.require("uno.util.dom");
goog.require("uno.template.util");
(function() {
  var dirty = false;
  var debounceTimer = 0;
  var Changes = uno.template.commands.Changes = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(Changes, uno.template.Plugin);
  Changes.prototype.isSupportedCommand = function(command) {
    return command === "changes" || command === "rte.changes";
  };
  var sendContentChangedNotificationDebounce = function() {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(function() {
      window.EN.notification("contentChanged", {module:"content"});
    }, 1000);
  };
  Changes.prototype.execCommandInternal = function(command, value) {
    dirty = !!value;
    if (dirty) {
      sendContentChangedNotificationDebounce();
    }
    return true;
  };
  Changes.prototype.queryCommandValue = function() {
    return dirty;
  };
  Changes.prototype.queryCommandEnabled = function() {
    return true;
  };
})();
goog.provide("uno.template.commands.Content");
goog.require("goog.debug.Logger");
goog.require("goog.array");
goog.require("goog.object");
goog.require("uno.template.Plugin");
goog.require("uno.template.util");
goog.require("uno.util.dom");
goog.require("uno.util.string");
goog.require("uno.defs");
(function() {
  var log = goog.debug.Logger.getLogger("uno.template.commands.Content");
  var util = uno.util;
  var Content = uno.template.commands.Content = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(Content, uno.template.Plugin);
  Content.prototype.isSupportedCommand = function(command) {
    return command === "content";
  };
  Content.prototype.loadContent = function(opt) {
    if (opt.type === "enml" && opt.content) {
      window.ed.context.format = uno.defs.format.ENML;
    } else {
      if (opt.type === "html" && opt.content) {
        window.ed.context.format = uno.defs.format.CLIENT_HTML;
      } else {
        return false;
      }
    }
    var content = opt.content;
    goog.object.forEach(ed.getAllPluginsInOrder(), function(plugin) {
      if (plugin.prepareContentsHtml && plugin.trogClassId !== "uno.filters.NormalizeFilter") {
        content = plugin.prepareContentsHtml(content);
      }
    });
    var frag = util.dom.fragFromString(content);
    goog.object.forEach(ed.getAllPluginsInOrder(), function(plugin) {
      if (plugin.prepareContentsDom && plugin.trogClassId !== "uno.filters.NormalizeFilter") {
        plugin.prepareContentsDom(frag);
      }
    });
    this.template.templateElement.innerHTML = "";
    while (frag.childNodes && frag.childNodes[0]) {
      this.template.templateElement.appendChild(frag.childNodes[0]);
    }
    return true;
  };
  Content.prototype.getContent = function(opt) {
    if (!opt) {
      opt = {};
    }
    opt = {html:opt.html || false, cleanup:opt.cleanup || false, stripNS:opt.stripNS || false, trim:opt.trim || true, withInsertionPoint:opt.withInsertionPoint || false, hiddenCryptoData:opt.hiddenCryptoData || null, resetChangesState:opt.resetChangesState || false, wrap:opt.wrap || false, type:opt.type || uno.defs.format.ENML};
    if (opt.type !== uno.defs.format.CLIENT_HTML && opt.type !== uno.defs.format.ENML) {
      opt.type = uno.defs.format.ENML;
    }
    var failure = {success:false, value:"", type:opt.type};
    if (opt.resetChangesState) {
      this.template.execCommand("changes", false);
    }
    var enmlFilterPlugin = null;
    goog.object.forEach(ed.getAllPluginsInOrder(), function(plugin) {
      if (plugin instanceof uno.filters.EnmlFilter) {
        enmlFilterPlugin = plugin;
      }
    });
    if (!enmlFilterPlugin) {
      log.severe("Template couldnt necessary plugins from Editor!");
      return failure;
    }
    var startingDocument = this.template.originalDocument || "";
    startingDocument = enmlFilterPlugin.prepareContentsHtml(startingDocument);
    var frag = util.dom.fragFromString(startingDocument);
    goog.array.forEach(this.template.fields, function(fieldInfo) {
      var instance = fieldInfo.object;
      if (instance == null) {
        log.severe("No template fieldInfo.object in " + fieldInfo);
      }
      instance.copyCurrentValueToDom(frag);
    });
    goog.array.forEach(frag.querySelectorAll("en-media"), function(enmedia) {
      enmedia.innerHTML = "";
    });
    var content = (new XMLSerializer).serializeToString(frag).trim();
    content = enmlFilterPlugin.cleanContentsHtml(content);
    var template = this.template;
    return {success:!util.string.isEmpty(content.trim()), value:content.trim(), type:opt.type};
  };
  Content.prototype.execCommandInternal = function(command, value) {
    if (value.scrollToTop === true) {
      window.scrollTo(0, 0);
    }
    if (!goog.object.isEmpty(value.resources)) {
      ed.context.resources = value.resources;
    }
    this.template.originalDocument = value.content;
    var contentResult = this.loadContent(value);
    if (contentResult) {
      this.template.setupFields();
      EN.notification("contentLoaded");
    } else {
      log.severe("Template failed to load content", value);
    }
    return contentResult;
  };
  Content.prototype.queryCommandValue = function(command, value) {
    return this.getContent(value);
  };
  Content.prototype.queryCommandEnabled = function() {
    return true;
  };
})();
goog.provide("uno.template.commands.Copy");
goog.require("goog.debug.Logger");
goog.require("uno.template.Plugin");
goog.require("uno.util.dom");
goog.require("uno.template.util");
(function() {
  var util = uno.util;
  var Copy = uno.template.commands.Copy = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(Copy, uno.template.Plugin);
  Copy.prototype.isSupportedCommand = function(command) {
    return command === "copy";
  };
  Copy.prototype.execCommandInternal = function() {
    return false;
  };
  Copy.prototype.queryCommandValue = function() {
    var range = window.getSelection().getRangeAt(0);
    if (!range || range.collapsed) {
      return "";
    }
    var result = {};
    var frag = range.cloneContents();
    var child = document.createElement("div");
    child.appendChild(frag);
    util.dom.workOnTemporaryDOMNode(child, function(node) {
      result.plain = node.innerText;
    });
    return JSON.stringify(result);
  };
  Copy.prototype.queryCommandEnabled = function() {
    return true;
  };
})();
goog.provide("uno.template.commands.Focus");
goog.require("goog.debug.Logger");
goog.require("uno.template.Plugin");
goog.require("uno.util.dom");
(function() {
  var util = uno.util;
  var Focus = uno.template.commands.Focus = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(Focus, uno.template.Plugin);
  Focus.prototype.isSupportedCommand = function(command) {
    return command === "focus";
  };
  Focus.prototype.execCommandInternal = function() {
    if (this.template.fields && this.template.fields.length > 0) {
      this.template.fields[0].focus();
    }
  };
  Focus.prototype.queryCommandValue = function() {
    var selection = window.getSelection();
    if (!selection) {
      return false;
    }
    if (selection.rangeCount > 0) {
      var range = window.getSelection().getRangeAt(0);
      var ancestors = util.dom.ancestors(range.startContainer);
      for (var i = 0; i < ancestors.length; i++) {
        if (ancestors[i].contentEditable === "true") {
          return true;
        }
      }
    }
    return false;
  };
  Focus.prototype.queryCommandEnabled = function() {
    return true;
  };
})();
goog.provide("uno.template.commands.Margin");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.template.Plugin");
(function() {
  var Margin = uno.template.commands.Margin = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(Margin, uno.template.Plugin);
  Margin.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Margin.prototype.isSupportedCommand = function(command) {
    return command === "margin";
  };
  Margin.prototype.execCommand = function(command, value) {
    if (value == null) {
      return false;
    }
    if (this.template.templateElement == null) {
      return false;
    }
    var container = this.template.templateElement;
    if (value.note) {
      container.style.paddingTop = toCssValue(value.note.top, "px");
      container.style.paddingBottom = toCssValue(value.note.bottom, "px");
      container.style.paddingLeft = toCssValue(value.note.left, "px");
      container.style.paddingRight = toCssValue(value.note.right, "px");
    }
    if (value.scroll) {
      window.ed.config.margin.scroll = {top:value.scroll.top || 0, left:value.scroll.left || 0, bottom:value.scroll.bottom || 0, right:value.scroll.right || 0};
    }
    if (value.offset) {
      window.ed.config.margin.offset = {height:value.offset.height || 0, width:value.offset.width || 0};
    }
    return true;
  };
  var toCssValue = function(value, unit) {
    var result;
    switch(typeof value) {
      case "number":
        result = value + unit;
        break;
      case "string":
        if (value.indexOf(unit) > -1) {
          result = value;
        } else {
          result = value + unit;
        }
        break;
      case "undefined":
        result = null;
        break;
      default:
        result = value;
    }
    return result;
  };
})();
goog.provide("uno.template.commands.PassThrough");
goog.require("goog.debug.Logger");
goog.require("uno.template.Plugin");
goog.require("uno.util.dom");
(function() {
  var commands = ["delete", "forwarddelete"];
  var PassThrough = uno.template.commands.PassThrough = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(PassThrough, uno.template.Plugin);
  PassThrough.prototype.isSupportedCommand = function(command) {
    return commands.indexOf(command) >= 0;
  };
  PassThrough.prototype.execCommandInternal = function(command, value) {
    return document.execCommand(command, value);
  };
  PassThrough.prototype.queryCommandValue = function(command, value) {
    return document.queryCommandValue(command, value);
  };
  PassThrough.prototype.queryCommandEnabled = function(command, value) {
    return document.queryCommandEnabled(command, value);
  };
})();
goog.provide("uno.template.commands.Paste");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("uno.template.Plugin");
goog.require("uno.util.dom");
goog.require("uno.template.util");
(function() {
  var log = goog.debug.Logger.getLogger("uno.template.commands.Paste");
  var util = uno.util;
  var Paste = uno.template.commands.Paste = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(Paste, uno.template.Plugin);
  Paste.prototype.isSupportedCommand = function(command) {
    return command === "paste" || command === "pasteplain";
  };
  Paste.prototype.execCommandInternal = function(command, value) {
    var type = "plain";
    if (command === "pasteplain") {
      type = "plain";
    } else {
      if (value.type === "html") {
        type = "html";
      }
    }
    return pasteAction({type:type, value:value.value || ""});
  };
  Paste.prototype.queryCommandValue = function() {
    return "";
  };
  Paste.prototype.queryCommandEnabled = function() {
    return true;
  };
  var pasteAction = function(opt) {
    var content = opt.value;
    if (opt.type === "html") {
      var frag = util.dom.fragFromString(content);
      content = frag.textContent;
    }
    try {
      return document.execCommand("inserttext", false, content.replace(/\s+/gi, " "));
    } catch (ex) {
      log.severe("Error with document inserttext" + ex.stack);
    }
    return true;
  };
})();
goog.provide("uno.template.commands.Resources");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.template.Plugin");
goog.require("uno.util.resource");
(function() {
  var log = goog.debug.Logger.getLogger("uno.template.commands.Resources");
  var util = uno.util;
  var Resources = uno.template.commands.Resources = function(template) {
    uno.template.Plugin.call(this, template);
  };
  goog.inherits(Resources, uno.template.Plugin);
  Resources.prototype.activeOnUneditableFields = goog.functions.TRUE;
  Resources.prototype.queryCommandEnabled = goog.functions.TRUE;
  Resources.prototype.isSupportedCommand = function(command) {
    return command === "resources";
  };
  Resources.prototype.execCommand = function() {
    return false;
  };
  Resources.prototype.queryCommandValue = function(command, opt) {
    var templateRoot = this.template.getElement();
    var list = goog.array.map(util.resource.all(templateRoot), function(el) {
      var dict = util.resource.toDict(el);
      if (opt === "neighbors") {
        log.warning("opt.neighbors not supported for template resources");
      }
      return dict;
    });
    return list;
  };
})();
goog.provide("uno.template.Template");
goog.require("goog.array");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.classes");
goog.require("goog.string");
goog.require("goog.functions");
goog.require("uno.defs");
goog.require("uno.filters.EnmlFilter");
goog.require("uno.filters.ResourceFilter");
goog.require("uno.util.string");
goog.require("uno.util.dom");
goog.require("uno.util.objects");
goog.require("uno.PluginManager");
goog.require("uno.template.util");
goog.require("uno.template.Field");
goog.require("uno.template.NoopField");
goog.require("uno.template.TitleField");
goog.require("uno.template.AddressField");
goog.require("uno.template.PlainTextField");
goog.require("uno.template.PlainTextArea");
goog.require("uno.template.PhoneField");
goog.require("uno.template.LinkField");
goog.require("uno.template.EmailField");
goog.require("uno.template.TwitterField");
goog.require("uno.template.FacebookField");
goog.require("uno.template.LinkedInField");
goog.require("uno.template.WeiboField");
goog.require("uno.template.commands.Changes");
goog.require("uno.template.commands.Content");
goog.require("uno.template.commands.Copy");
goog.require("uno.template.commands.Focus");
goog.require("uno.template.commands.Margin");
goog.require("uno.template.commands.PassThrough");
goog.require("uno.template.commands.Paste");
goog.require("uno.template.commands.Resources");
(function() {
  var log = goog.debug.Logger.getLogger("uno.api.ce");
  var util = uno.util;
  var tmpl = uno.template.util;
  var TEMPLATE_ROOT_TAG = "en-template";
  var fieldTypeMap = {title:uno.template.TitleField, field:uno.template.PlainTextField, textarea:uno.template.PlainTextArea, phone:uno.template.PhoneField, email:uno.template.EmailField, twitter:uno.template.TwitterField, linkedin:uno.template.LinkedInField, facebook:uno.template.FacebookField, weibo:uno.template.WeiboField, address:uno.template.AddressField, "profile-image":uno.template.NoopField};
  var Template = uno.template.Template = function(rteID, options) {
    this.templateElement = document.querySelector(TEMPLATE_ROOT_TAG);
    this.initConfig(options);
    if (this.templateElement == null) {
      var rteElement = document.querySelector("#" + rteID);
      if (rteElement == null) {
        log.severe("Fatal: Couldn't find rte element " + rteID);
        return;
      }
      this.templateElement = goog.dom.createDom(TEMPLATE_ROOT_TAG);
      goog.dom.insertSiblingAfter(this.templateElement, rteElement);
    }
    this.PM = new uno.PluginManager;
    this.PM.add(new uno.template.commands.Changes(this));
    this.PM.add(new uno.template.commands.Content(this));
    this.PM.add(new uno.template.commands.Copy(this));
    this.PM.add(new uno.template.commands.Focus(this));
    this.PM.add(new uno.template.commands.Margin(this));
    this.PM.add(new uno.template.commands.PassThrough(this));
    this.PM.add(new uno.template.commands.Paste(this));
    this.PM.add(new uno.template.commands.Resources(this));
    this.execCommand = this.PM.execCommand.bind(this.PM);
    this.queryCommandEnabled = this.PM.queryCommandEnabled.bind(this.PM);
    this.queryCommandValue = this.PM.queryCommandValue.bind(this.PM);
  };
  Template.prototype.opt = {};
  Template.prototype.originalDocument = "";
  Template.prototype.fields = [];
  Template.prototype.PM = null;
  Template.prototype.templateElement = null;
  Template.prototype.contentCssClass = null;
  Template.prototype.isSetup = false;
  Template.prototype.setup = function(opt) {
    var contentClass = opt.template.contentClass;
    this.opt = opt;
    this.opt.localization = opt.template.localization || opt.localization || {"display-as-placeholder-title":"Add Name...", "contact-title-placeholder-title":"Add Title...", "contact-org-placeholder-title":"Add Company...", "note-body-placeholder-title":"Add Notes...", "linkedin-placeholder-title":"Add LinkedIn URL...", "facebook-placeholder-title":"Add Facebook URL...", "twitter-placeholder-title":"Add Twitter Name...", "weibo-placeholder-title":"Add Weibo Name...", "phone-placeholder-title":"Add Phone...", 
    "email-placeholder-title":"Add Email...", "address-placeholder-title":"Add Address...", "email-label":"Email", "home-label":"Home", "work-label":"Work", "other-label":"Other", "phone-label":"Phone", "mobile-label":"Mobile", "main-label":"Main", "home-fax-label":"Home Fax", "work-fax-label":"Work Fax", "twitter-label":"Twitter", "facebook-label":"Facebook", "weibo-label":"Weibo", "linkedin-label":"LinkedIn", "address-label":"Address"};
    this.isSetup = true;
    if (contentClass) {
      this.contentCssClass = contentClass.replace(/[^\w]+/gi, "-");
      this.templateElement.setAttribute("class", "");
      goog.dom.classes.add(this.templateElement, this.contentCssClass);
    } else {
      log.warning("Unnecessary setup of Template w/o contentClass");
      return;
    }
    if (!util.string.isEmpty(opt.template.html)) {
      this.originalDocument = opt.template.html;
      this.execCommand("content", {type:"html", content:opt.template.html});
      return;
    }
    if (!util.string.isEmpty(opt.template.enml)) {
      this.originalDocument = opt.template.enml;
      this.execCommand("content", {type:"enml", content:opt.template.enml});
      return;
    }
  };
  Template.prototype.isSupportedCommand = function(command) {
    return this.isSetup && !!this.PM.firstSupportedCommand(command);
  };
  this.execCommand = goog.functions.NULL;
  this.queryCommandEnabled = goog.functions.NULL;
  this.queryCommandValue = goog.functions.NULL;
  Template.prototype.setupFields = function() {
    var foundFields = tmpl.iterateFields(this.templateElement);
    this.fields = [];
    for (var i = 0; i < foundFields.length; i++) {
      var fieldInfo = foundFields[i];
      fieldInfo.index = i;
      fieldInfo.opt = this.opt;
      fieldInfo.template = this;
      fieldInfo.container = fieldInfo.node;
      if (Object.keys(fieldTypeMap).indexOf(fieldInfo.type) >= 0) {
        fieldInfo.object = new fieldTypeMap[fieldInfo.type](fieldInfo);
      } else {
        log.severe("Tmpl found invalid field type: " + fieldInfo.type);
      }
      this.fields.push(fieldInfo);
    }
  };
  Template.prototype.getElement = function() {
    return this.templateElement;
  };
  Template.prototype.initConfig = function(opt) {
    var options = opt || {};
    this.config = {crypt:{unveilCryptElementOnClick:false, readOnly:options.rte.cryptReadOnly || false}};
  };
  Template.prototype.cleanup = function() {
    if (this.isSetup) {
      this.getElement().remove();
    }
  };
})();
goog.provide("uno.Router");
goog.require("goog.debug.Logger");
(function() {
  var log = goog.debug.Logger.getLogger("uno.Router");
  var Router = uno.Router = function(options) {
    this.messages = {};
    this.routesToHost = options.routesToHost;
    this.routesFromHost = options.routesFromHost;
    this.sendMessage = options.sendMessage;
  };
  Router.correlationId = 0;
  Router.getCorrelationId = function() {
    return ++Router.correlationId;
  };
  Router.prototype.toHostAsync = function(name, data) {
    var deferred;
    var me = this;
    var route = this.routesToHost[name];
    var correlationId = data[route.identifier];
    if (!correlationId && !route.oneway) {
      correlationId = Router.getCorrelationId();
      data[route.identifier] = correlationId;
    }
    deferred = new Deferred(function() {
      me.sendMessage(name, data);
    });
    if (route.oneway) {
      deferred.resolve();
    } else {
      this.messages[correlationId] = deferred;
    }
    return deferred.promise;
  };
  Router.prototype.fromHost = function(name, data) {
    var correlationId;
    var deferred;
    if (this.routesFromHost[name]) {
      correlationId = goog.getObjectByName(this.routesFromHost[name].identifier, data);
      deferred = this.messages[correlationId];
      delete this.messages[correlationId];
      deferred.resolve(data);
      return true;
    }
    return false;
  };
  var Deferred = function(fn) {
    var me = this;
    this.promise = new Promise(function(resolve, reject) {
      me.resolve = resolve;
      me.reject = reject;
      fn();
    });
  };
})();
goog.provide("uno.context.Context");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.functions");
goog.require("goog.object");
goog.require("goog.string");
goog.require("goog.style");
goog.require("uno.util.dom");
goog.require("uno.util.zoomscale");
(function() {
  var log = goog.debug.Logger.getLogger("uno.context.Context");
  var util = uno.util;
  var moduleName = "context";
  var CLICK_EVENT_FLE_KIND = "firstLaunch";
  var CLICK_EVENT_FLE_BUTTON_HREF = "dismiss";
  var CLICK_EVENT_FLE_LEARN_MORE_HREF = "learnMore";
  var TITLE_CLASSNAME = "en-context-item-title";
  var WIDE_CLASSNAME = "en-context-wide";
  var BODY_ITALICS_CLASSNAME = "en-context-body-italics";
  var ITEM_BODY_CLASSNAME = "en-context-item-body";
  var ITEM_BODY_ONE_LINE_CLASSNAME = "en-context-item-body-one";
  var ITEM_BODY_TWO_LINE_CLASSNAME = "en-context-item-body-two";
  var ITEM_CLASSNAME = "en-context-item";
  var CONTEXT_LABEL_CLASSNAME = "en-context-label";
  var HIDE_CLASSNAME = "en-context-hide-label";
  var SHOW_CLASSNAME = "en-context-show-label";
  var MAIN_CONTAINER_CLASSNAME = "en-context";
  var CARD_HOLDER_CLASSNAME = "en-context-card-holder";
  var IMAGE_CLIPPER_CLASSNAME = "en-context-graphic-clipper";
  var IMAGE_CLASSNAME = "en-context-graphic";
  var IMAGE_BLUR_CLASSNAME = "en-context-graphic-blur";
  var IMAGE_HOVER_CLASSNAME = "en-context-graphic-hover";
  var IMAGE_HOVER_SOLID_CLASSNAME = "en-context-graphic-hover-solid";
  var IMAGE_HOVER_MESSAGE_ICON_CLASSNAME = "en-context-workchat";
  var IMAGE_HOVER_TEXT_CLASSNAME = "en-context-share-text";
  var NEWS_SOURCE_CONTAINER_CLASSNAME = "en-context-source";
  var NEWS_SOURCE_IMAGE_CLASSNAME = "en-context-source-img";
  var NEWS_SOURCE_TEXT_CLASSNAME = "en-context-source-text";
  var NEWS_SOURCE_TEXT_BLUE_CLASSNAME = "en-context-source-text-blue";
  var AUTHOR_CLASSNAME = "en-context-author";
  var SEPARATOR_CLASSNAME = "en-context-separator";
  var NOTE_DATE_CLASSNAME = "en-context-note-date";
  var NEWS_DATE_CLASSNAME = "en-context-news-date";
  var POPUP_CLASSNAME = "en-context-popup";
  var POPUP_WRAPPER_CLASSNAME = "en-context-popup-wrapper";
  var POPUP_HEADER_CLASSNAME = "en-context-popup-header";
  var POPUP_BODY_CLASSNAME = "en-context-popup-body";
  var POPUP_FOOTER_CLASSNAME = "en-context-popup-footer";
  var POPUP_ARROW_CLASSNAME = "en-context-popup-down-arrow";
  var POPUP_VISIBLE_CLASSNAME = "en-context-popup-visible";
  var FLE_CONTAINER_CLASSNAME = "en-context-fle-container";
  var FLE_HEADER_CLASSNAME = "en-context-fle-header";
  var FLE_BODY_CLASSNAME = "en-context-fle-body";
  var FLE_DISMISS_BUTTON_CLASSNAME = "en-context-fle-dismiss-button";
  var FLE_SUBHEADER_CLASSNAME = "en-context-fle-subheader";
  var FLE_LEARN_MORE_CLASSNAME = "en-context-fle-learn-more";
  var POPUP_DURATION = 5500;
  var POPUP_FADE_DURATION = 250;
  var POPUP_INITIAL_DELAY = 1500;
  var SCROLL_SPEED = 240;
  var EXPECTED_CARD_HEIGHT = 139;
  var EXPECTED_HEADER_HEIGHT = 32;
  var CONTEXT_KIND_NOTE = "note";
  var CONTEXT_KIND_NEWS = "news";
  var CONTEXT_KIND_PEOPLE = "people";
  var CONTEXT_KIND_COMPANY = "company";
  var SOURCEID_WSJ = "dowjones.wsj";
  var SOURCEID_LINKEDIN = "profile.linkedin";
  var SOURCEID_FACTIVA = "profile.factiva";
  var SOURCEID_EB_PEOPLE = "profile.evernote.business";
  var SOURCEID_EB_NOTE = "evernote.business";
  var SOURCEID_NIKKEI_BUSINESS_ONLINE = "nikkei.bp.business";
  var SOURCEID_NIKKEI_ITPRO = "nikkei.bp.itpro";
  var SOURCEID_NIKKEI_KEN_PLATZ = "nikkei.bp.kenplatz";
  var SOURCEID_NIKKEI_TECHON = "nikkei.bp.tech";
  var BUILT_IN_SOURCE_ICONS = ["factiva", "fastcompany", "inc", "lifehacker", "linkedin", "pandodaily", "techcrunch", "theverge", "evernote-business", "wsj", "forbes", "nikkei", "nikkeibp", "techon", "itpro", "kenplatz"];
  var TITLE_FALLBACK_STRING = "Untitled";
  var CONTEXT_LABEL_FALLBACK_STRING = "Context";
  var settings;
  var container = null;
  var popup = null;
  var popupTimerID;
  var contextSeen = false;
  var contextViewDeJitterTimeoutRef;
  var Context = uno.context.Context = function(opt) {
    if (!document.querySelector("." + MAIN_CONTAINER_CLASSNAME)) {
      container = goog.dom.createDom("div", {class:MAIN_CONTAINER_CLASSNAME, id:MAIN_CONTAINER_CLASSNAME, style:"display:none;"});
      document.body.insertBefore(container, null);
      window.addEventListener("scroll", contextOnScreenHandler);
      window.addEventListener("resize", contextOnScreenHandler);
      window.addEventListener("resize", centerCards);
    }
    contextOnScreenHandler(true);
    goog.object.extend(opt, {showPopup:true, maxRows:9999});
    settings = opt;
  };
  Context.prototype.isSupportedCommand = function(command) {
    return command === "context";
  };
  Context.prototype.execCommandInternal = function(command, value) {
    if (value == null || goog.isString(value) && value === "" || goog.isObject(value) && Object.keys(value).length === 0) {
      log.warning("Context called without data");
      return;
    }
    var opt = value;
    var visible = opt.visible;
    var expanded = opt.expanded;
    var hideLabelText = opt.hideIndicatorLabelWhenExpanded;
    var showLabelText = opt.hideIndicatorLabelWhenCollapsed;
    var chatLabelText = opt.chatButtonLabel || "Chat";
    var shareLabelText = opt.shareButtonLabel || "Share";
    var items = opt.items;
    var contextSectionLabel = opt.contextSectionLabel;
    var firstLaunchInfo = opt.firstLaunchInfo;
    contextSeen = false;
    if (visible != null) {
      goog.style.setElementShown(container, !!visible);
    }
    if (!items || items.length <= 0) {
      return;
    }
    goog.dom.removeChildren(container);
    var contextLabelNode = goog.dom.createDom("div", {class:CONTEXT_LABEL_CLASSNAME});
    contextLabelNode.textContent = contextSectionLabel || CONTEXT_LABEL_FALLBACK_STRING;
    container.appendChild(contextLabelNode);
    var showHideNode = goog.dom.createDom("div", {class:expanded ? HIDE_CLASSNAME : SHOW_CLASSNAME});
    container.appendChild(showHideNode);
    fleAction(firstLaunchInfo);
    var cardHolder = goog.dom.createDom("div", {class:CARD_HOLDER_CLASSNAME});
    container.appendChild(cardHolder);
    for (var i = 0; i < items.length; i++) {
      cardHolder.appendChild(makeCard(items[i], shareLabelText, chatLabelText));
    }
    container.style.maxHeight = EXPECTED_CARD_HEIGHT * settings.maxRows + EXPECTED_HEADER_HEIGHT + "px";
    if (expanded) {
      show(showHideNode, hideLabelText);
    } else {
      hide(showHideNode, showLabelText);
    }
    addShowHideClickHandler(showHideNode, hideLabelText, showLabelText);
    centerCards();
    setTimeout(centerCards, 500);
    contextOnScreenHandler(true);
    if (visible === true && expanded === true && items.length > 0) {
      setTimeout(function() {
        contextPopup(opt);
      }, POPUP_INITIAL_DELAY);
    }
  };
  Context.prototype.queryCommandValue = goog.functions.TRUE;
  var makeCard = function(data, shareLabelText, chatLabelText) {
    var link = data.link || "#";
    var kind = data.kind || "undefined";
    var text = document.createTextNode(goog.string.unescapeEntities(data.text || ""));
    var imgSrc = data.thumbnail || "";
    var hasImage = imgSrc !== "";
    var titleStr = goog.string.unescapeEntities(data.title || TITLE_FALLBACK_STRING);
    var sourceName = data.sourceName || "";
    var sourceId = data.sourceId || "";
    var date = data.date || "";
    var author = data.author || "";
    var canShare = data.canShare;
    var title = goog.dom.createDom("div", {class:hasImage ? TITLE_CLASSNAME : TITLE_CLASSNAME + " " + WIDE_CLASSNAME});
    title.setAttribute("href", link);
    title.setAttribute("name", kind);
    title.textContent = titleStr;
    var authorNode = goog.dom.createDom("span", {class:AUTHOR_CLASSNAME});
    if (author !== "") {
      authorNode.textContent = author;
    }
    var separator = goog.dom.createDom("span", {class:SEPARATOR_CLASSNAME});
    separator.textContent = "|";
    var dateNode = goog.dom.createDom("span", {class:kind === CONTEXT_KIND_NOTE ? NOTE_DATE_CLASSNAME : NEWS_DATE_CLASSNAME});
    if (date !== "") {
      dateNode.textContent = date;
    }
    var bodyContents = [];
    if (kind === CONTEXT_KIND_NEWS) {
      if (date !== "") {
        bodyContents.push(dateNode);
        if (author !== "") {
          bodyContents.push(separator);
          bodyContents.push(authorNode);
        }
      } else {
        if (author !== "") {
          bodyContents.push(authorNode);
        }
      }
    } else {
      if (date !== "") {
        bodyContents.push(dateNode);
      }
      bodyContents.push(text);
    }
    var bodyClasses = ITEM_BODY_CLASSNAME;
    if (!hasImage) {
      bodyClasses += " " + WIDE_CLASSNAME;
    }
    if (kind === CONTEXT_KIND_NEWS) {
      bodyClasses += " " + ITEM_BODY_ONE_LINE_CLASSNAME;
    } else {
      if (kind === CONTEXT_KIND_NOTE && sourceId === SOURCEID_EB_NOTE) {
        bodyClasses += " " + ITEM_BODY_TWO_LINE_CLASSNAME;
      } else {
        if (kind === CONTEXT_KIND_PEOPLE) {
          bodyClasses += " " + BODY_ITALICS_CLASSNAME;
        }
      }
    }
    var body = goog.dom.createDom("div", {class:bodyClasses}, bodyContents);
    var graphicClipper = goog.dom.createDom("div", {class:IMAGE_CLIPPER_CLASSNAME});
    var graphicClasses = IMAGE_CLASSNAME;
    if (canShare) {
      graphicClasses += " " + IMAGE_BLUR_CLASSNAME;
    }
    var graphic = goog.dom.createDom("img", {class:graphicClasses, alt:"graphic", src:imgSrc});
    var graphicOverlayClasses = IMAGE_HOVER_CLASSNAME;
    if (!hasImage) {
      graphicOverlayClasses += " " + IMAGE_HOVER_SOLID_CLASSNAME;
    }
    var graphicOverlay = goog.dom.createDom("div", {class:graphicOverlayClasses}, [goog.dom.createDom("div", {class:IMAGE_HOVER_MESSAGE_ICON_CLASSNAME}), goog.dom.createDom("div", {class:IMAGE_HOVER_TEXT_CLASSNAME}, [kind === CONTEXT_KIND_PEOPLE ? chatLabelText : shareLabelText])]);
    if (hasImage) {
      graphicClipper.appendChild(graphic);
    }
    if (canShare) {
      graphicClipper.appendChild(graphicOverlay);
      graphicClipper.addEventListener("click", function(e) {
        EN.notification("openLink", {href:title.getAttribute("href"), module:moduleName, kind:title.getAttribute("name"), sharing:true});
        e.stopPropagation();
      });
    }
    var sourceIconName = sourceId;
    if (sourceIconName === SOURCEID_WSJ) {
      sourceIconName = "wsj";
    }
    if (sourceIconName === SOURCEID_LINKEDIN) {
      sourceIconName = "linkedin";
    }
    if (sourceIconName === SOURCEID_EB_PEOPLE || sourceIconName === SOURCEID_EB_NOTE) {
      sourceIconName = "evernote-business";
    }
    if (sourceIconName === SOURCEID_FACTIVA) {
      sourceIconName = "factiva";
    }
    if (sourceIconName === SOURCEID_NIKKEI_BUSINESS_ONLINE) {
      sourceIconName = "nikkeibp";
    }
    if (sourceIconName === SOURCEID_NIKKEI_ITPRO) {
      sourceIconName = "itpro";
    }
    if (sourceIconName === SOURCEID_NIKKEI_KEN_PLATZ) {
      sourceIconName = "kenplatz";
    }
    if (sourceIconName === SOURCEID_NIKKEI_TECHON) {
      sourceIconName = "techon";
    }
    var sourceTextClasses = "";
    if (sourceId === SOURCEID_EB_PEOPLE || sourceId === SOURCEID_EB_NOTE) {
      sourceTextClasses = NEWS_SOURCE_TEXT_BLUE_CLASSNAME;
    }
    var sourceNameIcon = goog.dom.createDom("div", {class:NEWS_SOURCE_IMAGE_CLASSNAME + " " + sourceIconName});
    var sourceNameNode = goog.dom.createDom("div", {class:NEWS_SOURCE_TEXT_CLASSNAME + " " + sourceTextClasses});
    if (sourceId === SOURCEID_WSJ) {
      sourceNameNode.textContent = "";
    } else {
      if (sourceId === SOURCEID_EB_NOTE) {
        sourceNameNode.textContent = author;
      } else {
        sourceNameNode.textContent = sourceName;
      }
    }
    var sourceInfo = goog.dom.createDom("div", {class:NEWS_SOURCE_CONTAINER_CLASSNAME});
    if (BUILT_IN_SOURCE_ICONS.indexOf(sourceIconName) !== -1) {
      sourceInfo.appendChild(sourceNameIcon);
    }
    sourceInfo.appendChild(sourceNameNode);
    var cardContent = [title, body];
    cardContent.push(graphicClipper);
    if (kind === CONTEXT_KIND_NEWS || kind === CONTEXT_KIND_PEOPLE || kind === CONTEXT_KIND_COMPANY || kind === CONTEXT_KIND_NOTE && sourceId === SOURCEID_EB_NOTE) {
      cardContent.push(sourceInfo);
    }
    var card = goog.dom.createDom("div", {class:ITEM_CLASSNAME}, cardContent);
    card.addEventListener("click", function(e) {
      EN.notification("openLink", {href:title.getAttribute("href"), module:moduleName, kind:title.getAttribute("name"), sharing:false});
      e.preventDefault();
    });
    return card;
  };
  var contextOnScreenHandler = function(immediate) {
    if (immediate == null) {
      immediate = false;
    }
    var logic = function() {
      var firstCard = container.querySelector("." + ITEM_CLASSNAME);
      if (firstCard == null) {
        return;
      }
      if (util.dom.isOnScreen(firstCard, 100)) {
        if (contextSeen === false) {
          contextSeen = true;
          EN.notification("contextVisible", {module:moduleName});
        }
      }
    };
    if (immediate) {
      logic();
    } else {
      contextViewDeJitterTimeoutRef = setTimeout(logic, 100, contextViewDeJitterTimeoutRef);
    }
  };
  var hide = function(labelNode, showText) {
    var cardHolder = container.querySelector("." + CARD_HOLDER_CLASSNAME);
    var fle = container.querySelector("." + FLE_CONTAINER_CLASSNAME);
    if (cardHolder == null) {
      log.severe("Couldnt find card holder?!");
      return;
    }
    labelNode.textContent = showText;
    goog.dom.classes.remove(labelNode, HIDE_CLASSNAME);
    goog.dom.classes.add(labelNode, SHOW_CLASSNAME);
    cardHolder.style.display = "none";
    if (fle != null && fle.length === 1) {
      fle[0].style.display = "none";
    }
  };
  var show = function(labelNode, hideText) {
    var cardHolder = container.querySelector("." + CARD_HOLDER_CLASSNAME);
    var fle = container.querySelector("." + FLE_CONTAINER_CLASSNAME);
    if (cardHolder == null) {
      log.severe("Couldnt find card holder?!");
      return;
    }
    labelNode.textContent = hideText;
    goog.dom.classes.remove(labelNode, SHOW_CLASSNAME);
    goog.dom.classes.add(labelNode, HIDE_CLASSNAME);
    cardHolder.style.display = "";
    centerCards();
    if (fle != null && fle.length === 1) {
      fle[0].style.display = "";
    }
  };
  var addShowHideClickHandler = function(node, hideText, showText) {
    node.addEventListener("click", function() {
      if (node.textContent === hideText) {
        hide(node, showText);
        EN.notification("contextExpanded", {module:moduleName, expanded:false});
      } else {
        if (node.textContent === showText) {
          show(node, hideText);
          EN.notification("contextExpanded", {module:moduleName, expanded:true});
        }
      }
      contextOnScreenHandler(true);
    });
  };
  var contextPopup = function(opt) {
    if (contextSeen === true || settings.showPopup === false || popup != null || container == null || opt == null || opt.items == null || opt.items.length === 0) {
      return;
    }
    var items = opt.items;
    var headerLabel = opt.toastNotificationHeaderLabel || "FIX HEADER";
    var footerLabel = opt.toastNotificationFooterLabel || "FIX FOOTER";
    var titleStr = goog.string.unescapeEntities(items[0].title || TITLE_FALLBACK_STRING);
    var popupHeader = goog.dom.createDom("div", {class:POPUP_HEADER_CLASSNAME});
    popupHeader.textContent = headerLabel;
    var bodyClasses = POPUP_BODY_CLASSNAME;
    if (items[0].kind != null) {
      bodyClasses += " " + items[0].kind;
    }
    var popupBody = goog.dom.createDom("div", {class:bodyClasses});
    popupBody.textContent = titleStr;
    var popupFooter = goog.dom.createDom("div", {class:POPUP_FOOTER_CLASSNAME});
    popupFooter.textContent = footerLabel;
    popupFooter.appendChild(goog.dom.createDom("div", {class:POPUP_ARROW_CLASSNAME}));
    popup = goog.dom.createDom("div", {class:POPUP_CLASSNAME}, [goog.dom.createDom("div", {class:POPUP_WRAPPER_CLASSNAME}, [popupHeader, popupBody, popupFooter])]);
    goog.dom.insertSiblingAfter(popup, container);
    setTimeout(function() {
      goog.dom.classes.add(popup, POPUP_VISIBLE_CLASSNAME);
    }, 1);
    popup.addEventListener("mousedown", function() {
      clearTimeout(popupTimerID);
    });
    popup.addEventListener("mouseup", function() {
      var bounds = getBounds(container);
      util.dom.scrollTo(bounds.top - 15, SCROLL_SPEED);
      goog.dom.classes.remove(popup, POPUP_VISIBLE_CLASSNAME);
      popup.pointerEvents = "none";
    });
    popupTimerID = setTimeout(function() {
      goog.dom.classes.remove(popup, POPUP_VISIBLE_CLASSNAME);
      popup.pointerEvents = "none";
      setTimeout(function() {
        popup.style.display = "none";
      }, POPUP_FADE_DURATION);
    }, POPUP_DURATION, popupTimerID);
  };
  var getBounds = function(node) {
    return util.zoomscale.normalizeRect(goog.style.getBounds(node));
  };
  var getCardLayoutInfo = function() {
    var cardHolder = document.querySelector("." + CARD_HOLDER_CLASSNAME);
    var allCards = document.querySelectorAll("." + ITEM_CLASSNAME);
    var numCards = allCards.length || 0;
    var sampleCard = document.querySelector("." + ITEM_CLASSNAME);
    if (cardHolder == null || sampleCard == null) {
      return null;
    }
    var availableSpace = Math.round(getBounds(cardHolder).width);
    var compStyle = window.getComputedStyle(sampleCard);
    var cardMarginX = parseInt(compStyle["margin-left"], 10) + parseInt(compStyle["margin-right"], 10);
    var cardMarginY = parseInt(compStyle["margin-top"], 10) + parseInt(compStyle["margin-bottom"], 10);
    var cardWidth = Math.round(sampleCard.offsetWidth + cardMarginX);
    var cardHeight = Math.round(sampleCard.offsetHeight + cardMarginY);
    return {availableSpace:availableSpace, numCards:numCards, cardWidth:cardWidth, cardHeight:cardHeight, cardsPerRow:Math.floor(availableSpace / cardWidth)};
  };
  var centerCards = function() {
    var layoutInfo = getCardLayoutInfo();
    var cardHolder = document.querySelector("." + CARD_HOLDER_CLASSNAME);
    if (layoutInfo == null || cardHolder == null) {
      return;
    }
    var realNumCardsPerRow = Math.min(layoutInfo.numCards, layoutInfo.cardsPerRow);
    if (realNumCardsPerRow <= 0) {
      cardHolder.style.left = "0px";
      return;
    }
    var remainder = layoutInfo.availableSpace - layoutInfo.cardWidth * realNumCardsPerRow;
    cardHolder.style.left = remainder / 2 + "px";
  };
  var fleAction = function(firstLaunchInfo) {
    if (firstLaunchInfo == null || firstLaunchInfo.headline == null || firstLaunchInfo.subHeadline == null || firstLaunchInfo.learnMoreLinkLabel == null || firstLaunchInfo.dismissButtonLabel == null) {
      return;
    }
    log.warning("The FLE functionality has been merged into " + "the context-info command. Please switch " + "to that API.");
    var headline = firstLaunchInfo.headline;
    var subHeadline = firstLaunchInfo.subHeadline;
    var learnMoreLinkLabel = firstLaunchInfo.learnMoreLinkLabel;
    var dismissButtonLabel = firstLaunchInfo.dismissButtonLabel;
    var FLEContainer = goog.dom.createDom("div", {class:FLE_CONTAINER_CLASSNAME});
    container.appendChild(FLEContainer);
    var FLEHeader = goog.dom.createDom("div", {class:FLE_HEADER_CLASSNAME});
    FLEHeader.textContent = headline;
    FLEContainer.appendChild(FLEHeader);
    var FLEBody = goog.dom.createDom("div", {class:FLE_BODY_CLASSNAME});
    FLEContainer.appendChild(FLEBody);
    var FLESubHeader = goog.dom.createDom("span", {class:FLE_SUBHEADER_CLASSNAME});
    FLESubHeader.textContent = subHeadline + " ";
    FLEBody.appendChild(FLESubHeader);
    var FLELearnMore = goog.dom.createDom("span", {class:FLE_LEARN_MORE_CLASSNAME});
    FLELearnMore.textContent = learnMoreLinkLabel;
    FLEBody.appendChild(FLELearnMore);
    FLELearnMore.addEventListener("click", function(e) {
      EN.notification("openLink", {href:CLICK_EVENT_FLE_LEARN_MORE_HREF, module:moduleName, kind:CLICK_EVENT_FLE_KIND, sharing:false});
      e.preventDefault();
      e.stopPropagation();
      return false;
    });
    var FLEDismissButton = goog.dom.createDom("div", {class:FLE_DISMISS_BUTTON_CLASSNAME});
    FLEDismissButton.textContent = dismissButtonLabel;
    FLEContainer.appendChild(FLEDismissButton);
    FLEDismissButton.addEventListener("click", function(e) {
      EN.notification("openLink", {href:CLICK_EVENT_FLE_BUTTON_HREF, module:moduleName, kind:CLICK_EVENT_FLE_KIND, sharing:false});
      goog.dom.removeNode(FLEContainer);
      e.stopPropagation();
    });
  };
})();
goog.provide("uno.context.Info");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.functions");
goog.require("goog.style");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.context.Info");
  var util = uno.util;
  var moduleName = "context-info";
  var MAIN_CONTAINER_CLASSNAME = "en-context-info";
  var BODY_CONTAINER_CLASSNAME = "en-context-info-body";
  var CONTEXT_LOGO_CLASSNAME = "en-context-info-logo";
  var HEADLINE_CLASSNAME = "en-context-info-headline";
  var BUTTON_CLASSNAME = "en-context-info-button";
  var SECTION_CLASSNAME = "en-context-info-section";
  var SECTION_IMAGE_CLASSNAME = "en-context-info-section-image";
  var SECTION_TITLE_CLASSNAME = "en-context-info-section-title";
  var SECTION_TEXT_CLASSNAME = "en-context-info-section-text";
  var STRETCHER_CLASSNAME = "en-context-info-stretcher";
  var NUM_INFO_SECTIONS = 3;
  var ALLOWED_SECTION_TYPES = ["note", "article", "person"];
  var container = null;
  var bodyContainer = null;
  var contextSeen = false;
  var contextViewDeJitterTimeoutRef;
  var ContextInfo = uno.context.Info = function() {
    if (!document.querySelector("." + MAIN_CONTAINER_CLASSNAME)) {
      container = goog.dom.createDom("div", {class:MAIN_CONTAINER_CLASSNAME, style:"display:none;"});
      document.body.insertBefore(container, null);
      window.addEventListener("scroll", onScreenHandler);
      window.addEventListener("resize", onScreenHandler);
    }
    onScreenHandler(true);
  };
  ContextInfo.prototype.isSupportedCommand = function(command) {
    return command === "context-info";
  };
  ContextInfo.prototype.queryCommandEnabled = goog.functions.TRUE;
  ContextInfo.prototype.execCommandInternal = function(command, value) {
    if (value == null || goog.isString(value) && value === "" || goog.isObject(value) && Object.keys(value).length === 0) {
      return false;
    }
    var opt = value;
    var showLogo = opt.showLogo || false;
    var headline = opt.headline || "HEADLINE";
    var infoSections = opt.infoSections || [];
    var buttonLabel = opt.buttonLabel || "BUTTONLABEL";
    var hideOnButtonClick = opt.hideOnButtonClick || false;
    goog.dom.removeChildren(container);
    container.style.display = "";
    contextSeen = false;
    var logo = goog.dom.createDom("div", {class:CONTEXT_LOGO_CLASSNAME});
    if (showLogo) {
      container.appendChild(logo);
    }
    var headlineNode = goog.dom.createDom("div", {class:HEADLINE_CLASSNAME});
    headlineNode.textContent = headline;
    container.appendChild(headlineNode);
    bodyContainer = goog.dom.createDom("div", {id:BODY_CONTAINER_CLASSNAME});
    container.appendChild(bodyContainer);
    if (infoSections.length === NUM_INFO_SECTIONS) {
      for (var i = 0; i < infoSections.length; i++) {
        bodyContainer.appendChild(createSection(infoSections[i]));
        bodyContainer.appendChild(document.createTextNode(" "));
      }
      var stretcher = goog.dom.createDom("div", {class:STRETCHER_CLASSNAME});
      bodyContainer.appendChild(stretcher);
    }
    var buttonNode = goog.dom.createDom("div", {class:BUTTON_CLASSNAME});
    buttonNode.textContent = buttonLabel;
    container.appendChild(buttonNode);
    buttonNode.addEventListener("click", function(e) {
      EN.notification("openLink", {href:"http://evernote.com", module:moduleName, kind:"info", sharing:true});
      if (hideOnButtonClick) {
        container.style.display = "none";
      }
      e.preventDefault();
      e.stopPropagation();
      return false;
    });
    onScreenHandler(true);
    return true;
  };
  var onScreenHandler = function(immediate) {
    immediate = immediate === true;
    var logic = function() {
      var isOnScreen = container.style.display === "none" ? false : util.dom.isOnScreen(container, 75);
      if (isOnScreen) {
        if (contextSeen === false) {
          contextSeen = true;
          EN.notification("contextVisible", {module:moduleName});
        }
      }
    };
    if (immediate) {
      logic();
    } else {
      clearTimeout(contextViewDeJitterTimeoutRef);
      contextViewDeJitterTimeoutRef = setTimeout(logic, 250);
    }
  };
  var createSection = function(info) {
    if (info == null || !goog.isString(info.type) || !goog.isString(info.title) || !goog.isString(info.text)) {
      log.severe("Incomplete section info for context-info!");
    }
    var found = false;
    for (var i = 0; i < ALLOWED_SECTION_TYPES.length; i++) {
      if (info.type === ALLOWED_SECTION_TYPES[i]) {
        found = true;
      }
    }
    if (found === false) {
      log.severe("Invalid type given for context-info: " + info.type);
    }
    var section = goog.dom.createDom("div", {class:SECTION_CLASSNAME});
    var image = goog.dom.createDom("div", {class:SECTION_IMAGE_CLASSNAME + " " + info.type});
    section.appendChild(image);
    var title = goog.dom.createDom("div", {class:SECTION_TITLE_CLASSNAME});
    title.textContent = info.title;
    section.appendChild(title);
    var text = goog.dom.createDom("div", {class:SECTION_TEXT_CLASSNAME});
    text.textContent = info.text;
    section.appendChild(text);
    return section;
  };
})();
goog.provide("uno.context.Upsell");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.functions");
goog.require("goog.style");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.context.Upsell");
  var util = uno.util;
  var moduleName = "context-upsell";
  var MAIN_CONTAINER_CLASSNAME = "en-context-upsell";
  var BODY_CONTAINER_CLASSNAME = "en-context-upsell-body";
  var HIDE_CLASSNAME = "en-context-upsell-hide-label";
  var SHOW_CLASSNAME = "en-context-upsell-show-label";
  var HEADLINE_CLASSNAME = "en-context-upsell-headline";
  var SUBHEADLINE_CLASSNAME = "en-context-upsell-subheadline";
  var GO_PREMIUM_CLASSNAME = "en-context-upsell-go-premium";
  var HEADLINE_FALLBACK = "Get more Context with Premium";
  var SUBHEADLINE_FALLBACK = "Go Premium to view notes," + " articles, and people related to what you're working on.";
  var PREMIUM_FALLBACK = "Go Premium";
  var HIDE_FALLBACK = "Hide";
  var SHOW_FALLBACK = "Show";
  var container = null;
  var bodyContainer = null;
  var contextSeen = false;
  var contextViewDeJitterTimeoutRef;
  var ContextUpsell = uno.context.Upsell = function() {
    if (!document.querySelector("." + MAIN_CONTAINER_CLASSNAME)) {
      container = goog.dom.createDom("div", {class:MAIN_CONTAINER_CLASSNAME, id:MAIN_CONTAINER_CLASSNAME, style:"display:none;"});
      document.body.insertBefore(container, null);
      window.addEventListener("scroll", onScreenHandler);
      window.addEventListener("resize", onScreenHandler);
    }
    onScreenHandler(true);
  };
  ContextUpsell.prototype.isSupportedCommand = function(command) {
    return command === "context-upsell";
  };
  ContextUpsell.prototype.queryCommandEnabled = goog.functions.TRUE;
  ContextUpsell.prototype.execCommandInternal = function(command, value) {
    if (value == null || goog.isString(value) && value === "" || goog.isObject(value) && Object.keys(value).length === 0) {
      return false;
    }
    log.warning("The FLE functionality has been merged into " + "the context-info command. Please switch " + "to that API.");
    var opt = value;
    var expanded = opt.expanded;
    if (expanded == null) {
      expanded = false;
    }
    var headline = opt.headline || HEADLINE_FALLBACK;
    var subHeadline = opt.subHeadline || SUBHEADLINE_FALLBACK;
    var goPremium = opt.goPremiumLabel || PREMIUM_FALLBACK;
    var hideLabel = opt.hideIndicatorLabelWhenExpanded || HIDE_FALLBACK;
    var showLabel = opt.hideIndicatorLabelWhenCollapsed || SHOW_FALLBACK;
    goog.dom.removeChildren(container);
    container.style.display = "";
    contextSeen = false;
    bodyContainer = goog.dom.createDom("div", {class:BODY_CONTAINER_CLASSNAME});
    container.appendChild(bodyContainer);
    var showHideNode = goog.dom.createDom("div", {class:expanded ? HIDE_CLASSNAME : SHOW_CLASSNAME});
    container.appendChild(showHideNode);
    if (expanded) {
      show(showHideNode, hideLabel);
    } else {
      hide(showHideNode, showLabel);
    }
    addShowHideClickHandler(showHideNode, hideLabel, showLabel);
    var headlineNode = goog.dom.createDom("div", {class:HEADLINE_CLASSNAME});
    headlineNode.textContent = headline;
    bodyContainer.appendChild(headlineNode);
    var subheadlineNode = goog.dom.createDom("div", {class:SUBHEADLINE_CLASSNAME});
    subheadlineNode.textContent = subHeadline;
    bodyContainer.appendChild(subheadlineNode);
    var goPremiumNode = goog.dom.createDom("div", {class:GO_PREMIUM_CLASSNAME});
    goPremiumNode.textContent = goPremium;
    bodyContainer.appendChild(goPremiumNode);
    goPremiumNode.addEventListener("click", function(e) {
      EN.notification("openLink", {href:"http://evernote.com", module:moduleName, kind:"upsell", sharing:true});
      e.preventDefault();
      e.stopPropagation();
      return false;
    });
    onScreenHandler(true);
    return true;
  };
  var onScreenHandler = function(immediate) {
    immediate = immediate === true;
    var logic = function() {
      var isOnScreen = container.style.display === "none" ? false : util.dom.isOnScreen(container, 75);
      if (isOnScreen) {
        if (contextSeen === false) {
          contextSeen = true;
          EN.notification("contextVisible", {module:moduleName});
        }
      }
    };
    if (immediate) {
      logic();
    } else {
      clearTimeout(contextViewDeJitterTimeoutRef);
      contextViewDeJitterTimeoutRef = setTimeout(logic, 250);
    }
  };
  var hide = function(labelNode, showText) {
    if (bodyContainer == null) {
      return;
    }
    labelNode.textContent = showText;
    goog.dom.classes.remove(labelNode, HIDE_CLASSNAME);
    goog.dom.classes.add(labelNode, SHOW_CLASSNAME);
    bodyContainer.style.display = "none";
  };
  var show = function(labelNode, hideText) {
    if (bodyContainer == null) {
      return;
    }
    labelNode.textContent = hideText;
    goog.dom.classes.remove(labelNode, SHOW_CLASSNAME);
    goog.dom.classes.add(labelNode, HIDE_CLASSNAME);
    bodyContainer.style.display = "";
  };
  var addShowHideClickHandler = function(node, hideText, showText) {
    node.addEventListener("click", function() {
      if (node.textContent === hideText) {
        hide(node, showText);
        EN.notification("contextExpanded", {module:moduleName, expanded:false});
      } else {
        if (node.textContent === showText) {
          show(node, hideText);
          EN.notification("contextExpanded", {module:moduleName, expanded:true});
        }
      }
      onScreenHandler(true);
    });
  };
})();
goog.provide("uno.polyfill");
goog.require("goog.object");
if (!goog.isDef(Object.assign)) {
  Object.assign = function(target, source1, source2) {
    if (arguments.length < 2) {
      return target;
    }
    var args = Array.prototype.slice.call(arguments).filter(function(arg) {
      return goog.isObject(arg);
    });
    goog.object.extend.apply(goog.object, args);
    return target;
  };
}
;goog.provide("uno.realtime.Plugin");
goog.require("goog.functions");
(function() {
  var Plugin = uno.realtime.Plugin = function(yjsmodule) {
    this.yjsmodule = yjsmodule;
    this.editor = yjsmodule.editor;
  };
  Plugin.prototype.setupObservation = function() {
  };
  Plugin.prototype.socketConnect = goog.functions.NULL;
  Plugin.prototype.socketConnectError = goog.functions.NULL;
  Plugin.prototype.socketReconnect = goog.functions.NULL;
  Plugin.prototype.socketReconnectAttempt = goog.functions.NULL;
  Plugin.prototype.socketReconnectError = goog.functions.NULL;
  Plugin.prototype.socketDisconnect = goog.functions.NULL;
  Plugin.prototype.realtimeNoteSaved = goog.functions.NULL;
  Plugin.prototype.execCommand = goog.functions.FALSE;
  Plugin.prototype.queryCommandEnabled = goog.functions.FALSE;
  Plugin.prototype.queryCommandValue = goog.functions.NULL;
  Plugin.prototype.isSupportedCommand = goog.functions.FALSE;
})();
goog.provide("uno.realtime.util.common");
(function() {
  var util = uno.realtime.util;
  var diacriticsMap = {"\u00e0":"a", "\u00e1":"a", "\u00e2":"a", "\u00e3":"a", "\u00e4":"a", "\u00e5":"a", "\u1ea5":"a", "\u1eaf":"a", "\u1eb3":"a", "\u1eb5":"a", "\u1eb7":"a", "\u00e6":"ae", "\u1ea7":"a", "\u1eb1":"a", "\u0203":"a", "\u00e7":"c", "\u1e09":"c", "\u00e8":"e", "\u00e9":"e", "\u00ea":"e", "\u00eb":"e", "\u1ebf":"e", "\u1e17":"e", "\u1ec1":"e", "\u1e15":"e", "\u1e1d":"e", "\u0207":"e", "\u00ec":"i", "\u00ed":"i", "\u00ee":"i", "\u00ef":"i", "\u1e2f":"i", "\u020b":"i", "\u00f0":"d", "\u00f1":"n", 
  "\u00f2":"o", "\u00f3":"o", "\u00f4":"o", "\u00f5":"o", "\u00f6":"o", "\u00f8":"o", "\u1ed1":"o", "\u1e4d":"o", "\u1e53":"o", "\u020f":"o", "\u00f9":"u", "\u00fa":"u", "\u00fb":"u", "\u00fc":"u", "\u00fd":"y", "\u00df":"s", "\u00ff":"y", "\u0101":"a", "\u0103":"a", "\u0105":"a", "\u0107":"c", "\u0109":"c", "\u010b":"c", "\u010d":"c", "c\u0306":"c", "\u010f":"d", "\u0111":"d", "\u0113":"e", "\u0115":"e", "\u0117":"e", "\u0119":"e", "\u011b":"e", "\u011d":"g", "\u01f5":"g", "\u011f":"g", "\u0121":"g", 
  "\u0123":"g", "\u0125":"h", "\u0127":"h", "\u1e2b":"h", "\u0129":"i", "\u012b":"i", "\u012d":"i", "\u012f":"i", "i\u0307":"i", "\u0131":"i", "\u0133":"ij", "\u0135":"j", "\u0137":"k", "\u1e31":"k", "k\u0306":"k", "\u013a":"l", "\u013c":"l", "\u013e":"l", "\u0140":"l", "\u0142":"l", "\u1e3f":"m", "m\u0306":"m", "\u0144":"n", "\u0146":"n", "\u0148":"n", "\u0149":"n", "n\u0306":"n", "\u014d":"o", "\u014f":"o", "\u0151":"o", "\u0153":"oe", "p\u0306":"p", "\u0155":"r", "\u0157":"r", "\u0159":"r", "r\u0306":"r", 
  "\u0213":"r", "\u015b":"s", "\u015d":"s", "\u015f":"s", "\u0219":"s", "\u0161":"s", "\u0163":"t", "\u021b":"t", "\u0165":"t", "\u0167":"t", "t\u0306":"t", "\u0169":"u", "\u016b":"u", "\u016d":"u", "\u016f":"u", "\u0171":"u", "\u0173":"u", "\u0217":"u", "v\u0306":"v", "\u0175":"w", "\u1e83":"w", "x\u0306":"x", "\u0177":"y", "y\u0306":"y", "\u017a":"z", "\u017c":"z", "\u017e":"z", "\u017f":"s", "\u0192":"f", "\u01a1":"o", "\u01b0":"u", "\u01ce":"a", "\u01d0":"i", "\u01d2":"o", "\u01d4":"u", "\u01d6":"u", 
  "\u01d8":"u", "\u01da":"u", "\u01dc":"u", "\u1ee9":"u", "\u1e79":"u", "\u01fb":"a", "\u01fd":"ae", "\u01ff":"o", "\u00fe":"th", "\u1e55":"p", "\u1e65":"s", "x\u0301":"x", "\u0453":"\u0433", "\u045c":"\u043a", "a\u030b":"a", "e\u030b":"e", "i\u030b":"i", "\u01f9":"n", "\u1ed3":"o", "\u1e51":"o", "\u1eeb":"u", "\u1e81":"w", "\u1ef3":"y", "\u0201":"a", "\u0205":"e", "\u0209":"i", "\u020d":"o", "\u0211":"r", "\u0215":"u", "b\u030c":"b", "\u010d\u0323":"c", "\u00ea\u030c":"e", "f\u030c":"f", "\u01e7":"g", 
  "\u021f":"h", "j\u030c":"j", "\u01f0":"j", "\u01e9":"k", "m\u030c":"m", "p\u030c":"p", "q\u030c":"q", "\u0159\u0329":"r", "\u1e67":"s", "v\u030c":"v", "w\u030c":"w", "x\u030c":"x", "y\u030c":"y", "a\u0327":"a", "b\u0327":"b", "\u1e11":"d", "\u0229":"e", "\u025b\u0327":"e", "\u1e29":"h", "i\u0327":"i", "\u0268\u0327":"i", "m\u0327":"m", "o\u0327":"o", "q\u0327":"q", "u\u0327":"u", "x\u0327":"x", "z\u0327":"z"};
  var diacriticsPolyfillPattern = new RegExp(Object.keys(diacriticsMap).join("|"), "g");
  var diacriticsPattern = /[\u0300-\u036f]/g;
  util.common.guid = function() {
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
      var rnd = Math.random() * 16 | 0;
      var val = c === "x" ? rnd : rnd & 3 | 8;
      return val.toString(16);
    });
  };
  util.common.removeDiacritics = "".normalize === undefined ? function(value) {
    return value.replace(diacriticsPolyfillPattern, function(char) {
      return diacriticsMap[char];
    });
  } : function(value) {
    return value.normalize("NFD").replace(diacriticsPattern, "");
  };
})();
goog.provide("uno.realtime.util.user");
goog.require("uno.realtime.util.common");
(function() {
  var util = uno.realtime.util;
  var colorCache = {};
  var initialCache = {};
  var colorPickPalette = [];
  var colorPalette = ["#486460", "#84608b", "#607d8b", "#666666", "#7d6258", "#b9512a", "#ff7732", "#ffa900", "#ffc33e", "#ac1779", "#eb4f44", "#95ca2f", "#45cd66", "#35a951", "#32c8c3", "#429ddd", "#25b0ee", "#4a63d8", "#7844ff", "#cf44fe", "#f9475d", "#f3319e", "#973ded", "#6e12ca"];
  util.user.read = function(map, key) {
    var yUser = map.get(key);
    if (yUser) {
      var name = yUser.get("Name") || yUser.get("name");
      return {id:(yUser.get("id") || yUser.get("EvernoteUserID") || key) + "", initial:util.user.getInitial(name), color:util.user.getColor(name), name:name, username:yUser.get("username"), email:yUser.get("email"), photoUrl:yUser.get("photoUrl"), title:yUser.get("title"), location:yUser.get("location")};
    }
    return null;
  };
  util.user.readMany = function(map, keyName) {
    var users = {};
    if (!map || !map.keys()) {
      return users;
    }
    map.keys().forEach(function(key) {
      var user = util.user.read(map, key);
      if (user) {
        users[user[keyName] || key] = user;
      }
    });
    return users;
  };
  util.user.getInitial = function(name) {
    if (!name) {
      return "?";
    }
    var initial = initialCache[name];
    if (initial === undefined) {
      var parts = util.common.removeDiacritics(name.toLowerCase()).split(" ");
      var pattern = /^[a-z]/;
      if (parts.length > 0) {
        var p1 = parts[0] || "";
        var p2 = parts[1] || "";
        if (pattern.test(p1) && pattern.test(p2)) {
          initial = (p1[0] + p2[0]).toUpperCase();
        } else {
          if (pattern.test(p1)) {
            initial = p1[0].toUpperCase();
          }
        }
      }
      if (!initial) {
        initial = "?";
      }
      initialCache[name] = initial;
    }
    return initial;
  };
  util.user.getColor = function(username) {
    if (!username) {
      return "";
    }
    var color = colorCache[username];
    if (!color) {
      if (!colorPickPalette.length) {
        colorPickPalette = colorPalette.slice();
      }
      var index = Math.random() * colorPickPalette.length | 0;
      color = colorPickPalette[index];
      colorCache[username] = color;
      colorPickPalette.splice(index, 1);
    }
    return color;
  };
})();
goog.provide("uno.util.react");
(function() {
  var util = uno.util;
  var rootState = {};
  util.react.renderComments = function(state) {
    render(Object.assign(rootState, {comments:state}));
  };
  util.react.renderRealtime = function(state) {
    render(Object.assign(rootState, {realtime:state}));
  };
  util.react.renderPreview = function(state) {
    render(Object.assign(rootState, {preview:state}));
  };
  function render(state) {
    if (typeof window === "undefined" || window.reactRender === undefined) {
      return;
    }
    window.reactRender(state);
  }
})();
goog.provide("uno.realtime.StateManager");
goog.require("uno.realtime.Plugin");
goog.require("uno.realtime.util.user");
goog.require("uno.util.react");
goog.require("goog.events");
(function() {
  var util = uno.realtime.util;
  var isOverlapped = function(field) {
    return field.scrollHeight - window.innerHeight - window.scrollY > 20;
  };
  var StateManager = uno.realtime.StateManager = function(yjsmodule, onStateChangeHandler) {
    uno.realtime.Plugin.call(this, yjsmodule);
    this.props = {connected:true, saved:true};
    this.state = {actions:{}, message:"", users:[], overlap:false, version:EN.getVersion()};
    goog.events.listen(window, "scroll", this.handleScroll, true, this);
    this.onStateChangeHandler = onStateChangeHandler;
  };
  goog.inherits(StateManager, uno.realtime.Plugin);
  StateManager.prototype.setupObservation = function() {
    this.yjsmodule.y.define("content", Y.Map).observeDeep(this.changeHandler.bind(this));
    this.yjsmodule.y.define("metadata", Y.Map).observeDeep(this.userHandler.bind(this));
    this.userHandler();
    if (EN.getVersionString) {
      this.state.version = EN.getVersionString();
    }
    if (window.YINFO !== "undefined" && window.YINFO.debugURL) {
      this.state.actions.debug = function() {
        EN.notification("openLink", {href:window.YINFO.debugURL, kind:"debug", sharing:false});
      };
      this.state.actions.archive = function() {
        EN.execCommand("comment", {action:"openarchive"});
      };
    }
    uno.util.react.renderRealtime(this.state);
  };
  StateManager.prototype.set = function(key, value, info) {
    if (this.props[key] !== value) {
      this.props[key] = value;
      this.onStateChangeHandler(key, value);
      this.state.error = !this.props.connected;
      this.state.loading = !this.props.saved;
      uno.util.react.renderRealtime(this.state);
    }
  };
  StateManager.prototype.get = function(key) {
    return this.props[key];
  };
  StateManager.prototype.socketConnect = function(success, reason) {
    this.set("connected", !!success);
  };
  StateManager.prototype.socketConnectError = function() {
    this.set("connected", false);
  };
  StateManager.prototype.socketReconnect = function() {
    this.set("connected", true);
  };
  StateManager.prototype.socketReconnectError = function() {
    this.set("connected", false);
  };
  StateManager.prototype.socketDisconnect = function() {
    this.set("connected", false);
  };
  StateManager.prototype.realtimeNoteSaved = function() {
    this.set("saved", true);
  };
  StateManager.prototype.changeHandler = function(e) {
    this.handleScroll();
    if (e[0] != null && e[0].remote === false) {
      this.set("saved", false);
    }
  };
  StateManager.prototype.handleScroll = function() {
    var overlap = isOverlapped(this.editor.field);
    if (this.state.overlap !== overlap) {
      this.state.overlap = overlap;
      uno.util.react.renderRealtime(this.state);
    }
  };
  StateManager.prototype.userHandler = function() {
    var yUsers = this.yjsmodule.y.define("metadata", Y.Map).get("Users");
    var userId = this.yjsmodule.config.user.userID;
    var users = Object.values(util.user.readMany(yUsers));
    var currentUser = users.splice(users.findIndex(function(u) {
      return u.id === userId;
    }), 1)[0];
    if (currentUser !== undefined) {
      users.push(currentUser);
    }
    this.state.users = users.map(function(u, i) {
      if (!u.initial) {
        u.initial = users.length - i + "";
      }
      return u;
    });
    uno.util.react.renderRealtime(this.state);
  };
})();
goog.provide("uno.realtime.YJSHooks");
goog.require("uno.realtime.Plugin");
goog.require("uno.util.resource");
(function() {
  var util = uno.util;
  var YJSHooks = uno.realtime.YJSHooks = function(yjsmodule) {
    uno.realtime.Plugin.call(this, yjsmodule);
    setupXmlHooks(yjsmodule.editor);
  };
  goog.inherits(YJSHooks, uno.realtime.Plugin);
  YJSHooks.setHookProperties = function(dom) {
    dom.querySelectorAll("[data-hash]").forEach(function(resources) {
      resources.dataset.yjsHook = "en-resource";
    });
  };
  var setupXmlHooks = function(editor) {
    var knownHashes = [];
    Y.XmlHook.addHook("en-resource", {fillType:function(dom, type) {
      dom.dataset.yjsHook = "en-resource";
      if (!dom.classList.contains("en-media")) {
        dom = dom.querySelector(".en-media");
      }
      var props = {hash:dom.getAttribute("data-hash"), type:dom.getAttribute("data-type"), width:dom.getAttribute("data-width"), height:dom.getAttribute("data-height"), style:dom.getAttribute("style")};
      if (props.hash == null || props.type == null) {
        return;
      }
      var propKeys = Object.keys(props);
      for (var i = 0; i < propKeys.length; i++) {
        type.set(propKeys[i], props[propKeys[i]]);
        console.log("[HOOK] saved", propKeys[i], props[propKeys[i]]);
      }
    }, createDom:function(type) {
      var props = {state:"loading", filename:"F" + type.get("hash"), title:"T" + type.get("hash"), progress:0.05, filesize:"3mb", hash:type.get("hash"), mime:type.get("type"), width:type.get("width"), height:type.get("height"), style:type.get("style")};
      setTimeout(function() {
        editor.dispatchEvent({type:"resourceNeedsUpdate", props:props});
      }, 50);
      var media = util.resource.createMediaFromDict(props);
      var slug = util.resource.convertMediaToSlug(media, props, editor);
      return slug;
    }});
    var renderPath = d3.svg.line().x(function(d) {
      return d[0];
    }).y(function(d) {
      return d[1];
    }).interpolate("basis");
    function initDrawingBindings(type, dom) {
      dom.contentEditable = "false";
      dom.dataset.yjsHook = "magic-drawing";
      var resizingToken = false;
      var domResizeObserver = new MutationObserver(function() {
        if (!resizingToken) {
          resizingToken = true;
          setTimeout(function() {
            resizingToken = false;
            if (dom.style.height !== type.get("height")) {
              type.set("height", dom.style.height);
            }
            if (dom.style.width !== type.get("width")) {
              type.set("width", dom.style.width);
            }
          }, 50);
        }
      });
      domResizeObserver.observe(dom, {attributes:true});
      type.observe(function() {
        dom.style.height = type.get("height");
        dom.style.width = type.get("width");
      });
      dom.style.height = type.get("height") || "300px";
      dom.style.width = type.get("width") || "300px";
      var drawing = type.get("drawing");
      if (drawing === undefined) {
        drawing = type.set("drawing", new Y.Array);
      }
      var canvas = dom.querySelector(".drawingCanvas");
      if (canvas == null) {
        canvas = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        canvas.setAttribute("class", "drawingCanvas");
        canvas.setAttribute("viewbox", "0 0 100 100");
        dom.insertBefore(canvas, null);
      }
      var clearDrawingButton = dom.querySelector(".clearDrawingButton");
      if (clearDrawingButton == null) {
        clearDrawingButton = document.createElement("button");
        clearDrawingButton.setAttribute("type", "button");
        clearDrawingButton.setAttribute("class", "clearDrawingButton");
        clearDrawingButton.innerText = "Clear Drawing";
        dom.insertBefore(clearDrawingButton, null);
      }
      var svg = d3.select(canvas).call(d3.behavior.drag().on("dragstart", dragstart).on("drag", drag).on("dragend", dragend));
      function drawLine(yarray) {
        var line = svg.append("path").datum(yarray.toArray());
        line.attr("d", renderPath);
        yarray.observe(function(event) {
          line.remove();
          line = svg.append("path").datum(yarray.toArray());
          line.attr("d", renderPath);
        });
      }
      drawing.observe(function(event) {
        event.removedElements.forEach(function() {
          svg.selectAll("path").remove();
        });
        event.addedElements.forEach(function(path) {
          drawLine(path, svg);
        });
      });
      for (var i = 0; i < drawing.length; i++) {
        drawLine(drawing.get(i), svg);
      }
      clearDrawingButton.onclick = function() {
        drawing.delete(0, drawing.length);
      };
      var sharedLine = null;
      function dragstart() {
        drawing.insert(drawing.length, [Y.Array]);
        sharedLine = drawing.get(drawing.length - 1);
      }
      var ignoreDrag = null;
      function drag() {
        if (sharedLine != null && ignoreDrag == null) {
          ignoreDrag = window.setTimeout(function() {
            ignoreDrag = null;
          }, 10);
          sharedLine.push([d3.mouse(this)]);
        }
      }
      function dragend() {
        sharedLine = null;
        window.clearTimeout(ignoreDrag);
        ignoreDrag = null;
      }
    }
    Y.XmlHook.addHook("magic-drawing", {fillType:function(dom, type) {
      initDrawingBindings(type, dom);
    }, createDom:function(type) {
      var dom = document.createElement("magic-drawing");
      initDrawingBindings(type, dom);
      return dom;
    }});
  };
})();
goog.provide("uno.realtime.util.hyperjson");
goog.require("goog.debug.Logger");
goog.require("goog.object");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.realtime.util.hyperjson");
  var rutil = uno.realtime.util;
  var util = uno.util;
  var isUnusualNode = function(node) {
    return !!(node && node.nodeType != null && goog.isNumber(node.nodeType) && node.nodeType > Node.TEXT_NODE);
  };
  rutil.hyperjson.fromDOM = function(element, acceptFilter, afterTransforms) {
    var result = [];
    if (goog.isFunction(acceptFilter) && acceptFilter(element) === false) {
      return null;
    }
    if (util.dom.isTextNode(element)) {
      return element.textContent;
    } else {
      if (util.dom.isElementNode(element)) {
        result.push(util.dom.getTagName(element).toUpperCase());
        var clonedAttrs = {};
        for (var i = 0; i < element.attributes.length; i++) {
          clonedAttrs[element.attributes[i].name] = element.attributes[i].value;
        }
        result.push(clonedAttrs);
        var children = [];
        var tmpchild = null;
        for (var x = 0; x < element.childNodes.length; x++) {
          tmpchild = rutil.hyperjson.fromDOM(element.childNodes[x], acceptFilter, afterTransforms);
          if (tmpchild != null) {
            children.push(tmpchild);
          }
        }
        result.push(children);
      } else {
        if (isUnusualNode(element)) {
          log.warning("Cool, hyperjson saw a weird node (OK, skipped): " + element);
          return null;
        } else {
          log.error("Could not parse dom (skipped): " + element);
          return null;
        }
      }
    }
    if (goog.isFunction(afterTransforms)) {
      result = afterTransforms(result);
    }
    return result;
  };
  var isValidHyperJsonElement = function(hyperjson) {
    return goog.isString(hyperjson) || goog.isArray(hyperjson) && hyperjson.length === 3 && goog.isString(hyperjson[0]) && goog.isObject(hyperjson[1]) && goog.isArray(hyperjson[2]);
  };
  var tryFixJsonElement = function(hyperjson) {
    return false;
  };
  rutil.hyperjson.toDOM = function(hyperjson) {
    if (goog.isString(hyperjson)) {
      return goog.dom.createTextNode(hyperjson);
    }
    if (!isValidHyperJsonElement(hyperjson) && !tryFixJsonElement(hyperjson)) {
      console.log("Invalid HyperJSON structure (toDOM): ", hyperjson, JSON.stringify(hyperjson));
      return null;
    }
    var elem = goog.dom.createDom(hyperjson[0]);
    var keys = Object.keys(hyperjson[1]);
    for (var i = 0; i < keys.length; i++) {
      elem.setAttribute(keys[i], hyperjson[1][keys[i]]);
    }
    var tmpchild = null;
    for (var x = 0; x < hyperjson[2].length; x++) {
      tmpchild = rutil.hyperjson.toDOM(hyperjson[2][x]);
      if (tmpchild != null) {
        elem.appendChild(tmpchild);
      } else {
        return null;
      }
    }
    return elem;
  };
})();
goog.provide("uno.realtime.util.convert");
goog.require("goog.array");
goog.require("uno.realtime.util.hyperjson");
goog.require("uno.util.copy.plain");
goog.require("uno.util.dom");
(function() {
  var rutil = uno.realtime.util;
  var util = uno.util;
  var DEBUG_MODEL = false;
  function domFilter(nodeName, attributes) {
    attributes.forEach(function(value, key) {
      if (key != null && key.substr(0, 2) === "on") {
        attributes.delete(key);
      }
    });
    switch(nodeName) {
      case "SCRIPT":
        return null;
      case "EN-ADORNMENTS":
        return null;
      case "EN-TABLE":
        attributes.delete("class");
        return attributes;
      case "SPAN":
        return (attributes.get("id") || "").substr(0, 5) === "goog_" ? null : attributes;
      case "TD":
        attributes.delete("class");
        return attributes;
      case "EMBED":
        attributes.delete("src");
        attributes.delete("style");
        attributes.delete("data-reference");
        return attributes;
      default:
        return (nodeName || "").substr(0, 3) === "UI-" ? null : attributes;
    }
  }
  rutil.convert.snapToServerState = function(editor, xmlFragment) {
    xmlFragment.setDomFilter(domFilter);
    var editorElement = editor.getElement();
    xmlFragment.bindToDom(editorElement);
    xmlFragment.enableSmartScrolling(document.scrollingElement);
    var removePlaceholder = function() {
      if (editorElement.textContent.length > 0) {
        editorElement.setAttribute("data-en-placeholder", "");
        xmlFragment.unobserveDeep(removePlaceholder);
      }
    };
    xmlFragment.observeDeep(removePlaceholder);
    removePlaceholder();
  };
})();
goog.provide("uno.realtime.util.range");
goog.require("goog.dom");
goog.require("uno.util.dom");
goog.require("uno.util.tools");
(function() {
  var util = uno.util;
  var rutil = uno.realtime.util;
  var FAKE_MIN_WIDTH = 2;
  var FAKE_MIN_HEIGHT = 12;
  var domToXPath = function(node) {
    var stopAt = "en-note";
    var path = "";
    while (util.dom.getTagName(node) !== stopAt) {
      if (node == null || node.parentNode == null || node.nodeType == null) {
        return null;
      }
      if (node.nodeType === 1) {
        path = "/" + util.dom.getTagName(node) + "[" + util.dom.index(node) + "]" + path;
      } else {
        if (node.nodeType === 3) {
          path = "/" + "#text" + "[" + util.dom.index(node) + "]" + path;
        }
      }
      node = node.parentNode;
    }
    return path === "" ? "/" : path;
  };
  var xpathToDom = function(xpath) {
    var startAt = document.querySelector("en-note");
    if (startAt == null) {
      return document.body;
    }
    var pathSegments = xpath.split("/").slice(1);
    var segment = null;
    while (segment = pathSegments.shift()) {
      var offsetSegment = segment.split("[");
      var tagname = offsetSegment[0];
      var offset = parseInt(offsetSegment[1], 10);
      if (startAt == null || startAt.childNodes == null) {
        return null;
      }
      startAt = startAt.childNodes[offset];
      if (startAt && (startAt.nodeType === 1 && util.dom.getTagName(startAt) !== tagname || startAt.nodeType === 3 && tagname !== "#text")) {
        console.warn("Couldnt restore cursor perfectly, nodes moved.");
        break;
      }
    }
    return startAt;
  };
  rutil.range.isValidXPathRange = function(xpathRange) {
    return xpathRange.startNegativeOffset !== -1 && xpathRange.endNegativeOffset !== -1 && xpathRange.startPath != null && xpathRange.endPath != null && xpathRange.startPath.length != null && xpathRange.endPath.length != null && xpathRange.startPath.length > 0 && xpathRange.endPath.length > 0;
  };
  rutil.range.saveUsingXPath = function(googRange) {
    if (googRange == null) {
      return null;
    }
    var startNode = googRange.getStartNode();
    var endNode = googRange.getEndNode();
    var startNodeLength;
    var endNodeLength;
    if (startNode.length != null) {
      startNodeLength = startNode.length;
    } else {
      startNodeLength = startNode.childNodes.length;
    }
    if (endNode.length != null) {
      endNodeLength = endNode.length;
    } else {
      endNodeLength = endNode.childNodes.length;
    }
    var startNegativeOffset = startNodeLength - googRange.getStartOffset();
    var endNegativeOffset = endNodeLength - googRange.getEndOffset();
    var startPath = domToXPath(startNode);
    var endPath = domToXPath(endNode);
    if (startPath == null || endPath == null) {
      return null;
    }
    return {startPath:startPath, endPath:endPath, startNegativeOffset:startNegativeOffset, endNegativeOffset:endNegativeOffset};
  };
  rutil.range.restoreFromXPath = function(xpathRange) {
    if (xpathRange == null) {
      return null;
    }
    var startNode = xpathToDom(xpathRange.startPath);
    var endNode = xpathToDom(xpathRange.endPath);
    var startNodeLength;
    var endNodeLength;
    if (startNode == null || endNode == null) {
      return null;
    }
    if (startNode.length != null) {
      startNodeLength = startNode.length;
    } else {
      startNodeLength = startNode.childNodes.length;
    }
    if (endNode.length != null) {
      endNodeLength = endNode.length;
    } else {
      endNodeLength = endNode.childNodes.length;
    }
    var startOffset = startNodeLength - xpathRange.startNegativeOffset;
    var endOffset = endNodeLength - xpathRange.endNegativeOffset;
    return goog.dom.Range.createFromNodes(startNode, startOffset, endNode, endOffset);
  };
  var getToolsSection = function(section) {
    var specific = util.tools.query(".realtime-" + section);
    if (specific == null) {
      specific = document.createElement("div");
      specific.setAttribute("class", "realtime-" + section);
      util.tools.append(specific);
    }
    return specific;
  };
  rutil.range.fakeRenderRange = function(range, color, user, prettyName, style) {
    style = style || "default";
    color = color || "black";
    var tools = getToolsSection("selections");
    var clearFakeRangesForUser = function() {
      var userSels = tools.querySelectorAll('[data-user="' + user + '"]');
      for (var j = 0; j < userSels.length; j++) {
        goog.dom.removeNode(userSels[j]);
      }
    };
    if (range == null) {
      clearFakeRangesForUser();
      return;
    }
    if (range.getBrowserRangeObject != null) {
      try {
        range = range.getBrowserRangeObject();
      } catch (e) {
        console.warn("(weird) fake browser range out of sync for ", user);
        clearFakeRangesForUser();
        return;
      }
    }
    var clientrects = util.range.getBoundingBoxesFromTextSelection(range, true, true);
    if (clientrects == null) {
      clientrects = [];
    }
    if (clientrects.length === 0 && util.dom.isEmptyContent(range.startContainer)) {
      var nodeBox = util.dom.getBoundingBox(range.startContainer, true);
      if (nodeBox == null) {
        nodeBox = util.dom.getBoundingBox(range.startContainer.parentNode, true);
      }
      nodeBox.width = FAKE_MIN_WIDTH;
      clientrects = [nodeBox];
    }
    clearFakeRangesForUser();
    for (var i = 0; i < clientrects.length; i++) {
      var clientrect = clientrects[i];
      var box = document.createElement("div");
      var rgbValue = goog.color.hexToRgb(goog.color.parse(color).hex);
      var contrastColor = goog.color.highContrast(rgbValue, [[0, 0, 0], [255, 255, 255]]);
      clientrect.width = Math.max(clientrect.width, FAKE_MIN_WIDTH);
      clientrect.height = Math.max(clientrect.height, FAKE_MIN_HEIGHT);
      if (i === 0 && prettyName != null && style === "default") {
        var nameArea = document.createElement("div");
        nameArea.setAttribute("class", "name-area");
        box.appendChild(nameArea);
        nameArea.textContent = prettyName;
        nameArea.style.backgroundColor = color;
        nameArea.style.color = goog.color.rgbToHex.apply(goog.color, contrastColor);
      }
      box.setAttribute("data-user", user);
      box.style.backgroundColor = color;
      box.style.position = "absolute";
      box.style.top = clientrect.top + "px";
      box.style.left = clientrect.left + "px";
      box.style.height = clientrect.height + "px";
      box.style.width = clientrect.width + "px";
      if (style === "underline") {
        box.style.height = "2px";
        box.style.top = clientrect.top + (clientrect.height - 2) + "px";
      }
      tools.appendChild(box);
    }
  };
})();
goog.provide("uno.realtime.Editing");
goog.require("uno.realtime.Plugin");
goog.require("uno.realtime.util.convert");
goog.require("uno.realtime.util.range");
goog.require("goog.functions");
goog.require("goog.dom");
goog.require("goog.array");
goog.require("goog.dom.Range");
goog.require("uno.util.dom");
(function() {
  var util = uno.util;
  var rutil = uno.realtime.util;
  var Editing = uno.realtime.Editing = function(yjsmodule) {
    uno.realtime.Plugin.call(this, yjsmodule);
  };
  goog.inherits(Editing, uno.realtime.Plugin);
  var exclusionToken = true;
  var mutualExclusive = function(f) {
    if (exclusionToken) {
      exclusionToken = false;
      try {
        f();
      } catch (e) {
        exclusionToken = true;
        throw new Error(e);
      }
      exclusionToken = true;
    }
  };
  Editing.prototype.setupObservation = function() {
    var self = this;
    var y = self.yjsmodule.y;
    var contentShare = y.define("content", Y.Map);
    var editor = self.yjsmodule.editor;
    mutualExclusive(function() {
      var savedRange = rutil.range.saveUsingXPath(self.editor.getRange());
      function bindDocument() {
        var doc = contentShare.get("document");
        if (doc !== undefined) {
          rutil.convert.snapToServerState(self.yjsmodule.editor, doc);
        }
      }
      bindDocument();
      contentShare.observe(bindDocument);
      self.yjsmodule.serverContentLoaded();
      if (savedRange) {
        var range = rutil.range.restoreFromXPath(savedRange);
        if (rutil.range.isValidXPathRange(range)) {
          range.select();
        }
      }
    });
  };
})();
goog.provide("uno.realtime.Selecting");
goog.require("uno.realtime.Plugin");
goog.require("uno.realtime.util.user");
goog.require("uno.realtime.util.range");
(function() {
  var rutil = uno.realtime.util;
  var localContentChangeDejitter = 0;
  var transactionActive = false;
  var DEJITTER_DURATION = 30;
  var Selecting = uno.realtime.Selecting = function(yjsmodule) {
    uno.realtime.Plugin.call(this, yjsmodule);
  };
  goog.inherits(Selecting, uno.realtime.Plugin);
  var exclusionToken = true;
  var mutualExclusive = function(f) {
    if (exclusionToken) {
      exclusionToken = false;
      try {
        f();
      } catch (e) {
        exclusionToken = true;
        throw new Error(e);
      }
      exclusionToken = true;
    }
  };
  Selecting.prototype.setupObservation = function() {
    var self = this;
    var contentShare = self.yjsmodule.y.define("content", Y.Map);
    var editor = self.yjsmodule.editor;
    var sharedSelection = self.yjsmodule.y.define("selection", Y.Map);
    var metadataSection = self.yjsmodule.y.define("metadata", Y.Map);
    var myID = this.yjsmodule.y.connector.clientID + "";
    this.getSelectionSection(myID, true);
    contentShare.observeDeep(function() {
      setTimeout(function() {
        mutualExclusive(self.handleRemoteContentChange.bind(self));
        localUpdateHelper();
      }, 0);
    });
    var localUpdateHelper = function() {
      if (localContentChangeDejitter != null) {
        clearTimeout(localContentChangeDejitter);
      } else {
        mutualExclusive(self.handleLocalSelectionChange.bind(self));
      }
      localContentChangeDejitter = setTimeout(function() {
        mutualExclusive(self.handleLocalSelectionChange.bind(self));
        localContentChangeDejitter = null;
      }, DEJITTER_DURATION);
    };
    sharedSelection.observe(function(event) {
      event.keysChanged.forEach(function(userID) {
        if (!goog.isString(userID)) {
          console.warn("Invalid user id for selection change:", userID);
          return;
        }
        mutualExclusive(function() {
          self.renderRemoteUserSelection(userID);
        });
      });
    });
    metadataSection.get("Users").observe(function(event) {
      event.keysChanged.forEach(function(user) {
        if (user !== myID && !event.target.has(user)) {
          console.log("Saw User Left", user);
          rutil.range.fakeRenderRange(null, "black", user);
        }
      });
    });
    window.addEventListener("resize", function() {
      mutualExclusive(self.handleRemoteContentChange.bind(self, event));
    });
    editor.listen("selectionchange", function() {
      mutualExclusive(self.handleLocalSelectionChange.bind(self));
    });
    mutualExclusive(self.handleRemoteContentChange.bind(self, event));
  };
  Selecting.prototype.getSelectionSection = function(userID) {
    var sharedSelection = this.yjsmodule.y.share.selection;
    var clientSelection = sharedSelection.get(userID);
    if (clientSelection == null || clientSelection.start == null || clientSelection.end == null) {
      return null;
    } else {
      return clientSelection;
    }
  };
  Selecting.prototype.getRangeForUser = function(userID) {
    var clientSelection = this.getSelectionSection(userID);
    if (clientSelection != null) {
      var start = Y.utils.fromRelativePosition(this.yjsmodule.y, clientSelection.start);
      var end = Y.utils.fromRelativePosition(this.yjsmodule.y, clientSelection.end);
      if (start != null && end != null && !start.type._deleted && !end.type._deleted && start.type._dom && end.type._dom) {
        var range = document.createRange();
        range.setStart(start.type._dom, Math.min(start.offset, start.type._dom.length));
        range.setEnd(end.type._dom, Math.min(end.offset, end.type._dom.length));
        return range;
      }
    }
    return null;
  };
  Selecting.prototype.handleRemoteContentChange = function(event) {
    var users = this.yjsmodule.y.share.metadata.get("Users").keys() || [];
    for (var i = 0; i < users.length; i++) {
      this.renderRemoteUserSelection(users[i]);
    }
  };
  Selecting.prototype.renderRemoteUserSelection = function(userID) {
    var self = this;
    var myID = this.yjsmodule.y.connector.clientID + "";
    if (userID === myID) {
      return;
    }
    var range = self.getRangeForUser(userID);
    if (range != null) {
      var user = rutil.user.read(this.yjsmodule.y.share.metadata.get("Users"), userID);
      rutil.range.fakeRenderRange(range, user.color, userID, user.name);
    }
    if (range == null) {
      rutil.range.fakeRenderRange(null, "black", userID);
    }
  };
  function comparePositions(a, b) {
    return a === b || a != null && b != null && a.length === b.length && a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
  }
  Selecting.prototype.handleLocalSelectionChange = function() {
    var _range = this.yjsmodule.editor.getRange();
    if (_range == null) {
      return;
    }
    var range = _range.getBrowserRangeObject();
    var sharedSelection = this.yjsmodule.y.share.selection;
    var clientID = this.yjsmodule.y.connector.clientID + "";
    if (range.startContainer != null && range.startContainer._yxml != null && range.endContainer != null && range.endContainer._yxml != null) {
      var start = Y.utils.getRelativePosition(range.startContainer._yxml, range.startOffset);
      var end = Y.utils.getRelativePosition(range.endContainer._yxml, range.endOffset);
      var originalLocation = sharedSelection.get(clientID);
      if (originalLocation == null || !comparePositions(originalLocation.start, start) || !comparePositions(originalLocation.end, end)) {
        sharedSelection.set(clientID, {start:start, end:end});
      }
    }
  };
})();
goog.provide("uno.realtime.util.Trie");
(function() {
  var Trie = uno.realtime.util.Trie = function(parent, key, value) {
    if (parent && !parent.children) {
      parent.children = {};
    }
    if (key) {
      parent.children[key] = this;
      this.values = [value];
    }
  };
  Trie.prototype.insert = function(phrase, value) {
    var len = phrase.length;
    var t = this;
    var i = 0;
    var key = null;
    var child = null;
    while (t.children && i < len) {
      key = phrase[i++];
      child = t.children[key];
      if (child) {
        if (child.values.indexOf(value) === -1) {
          child.values.push(value);
        }
        t = child;
      } else {
        t = new Trie(t, key, value);
        break;
      }
    }
    for (; i < len; i++) {
      t = new Trie(t, phrase[i], value);
    }
  };
  Trie.prototype.find = function(phrase) {
    var len = phrase.length;
    var t = this;
    var i = 0;
    while (t && t.children && i < len) {
      t = t.children[phrase[i]];
      if (++i >= len && t) {
        return t.values;
      }
    }
    return [];
  };
})();
goog.provide("uno.realtime.util.commenting");
goog.require("uno.realtime.util.common");
goog.require("uno.realtime.util.user");
goog.require("uno.realtime.util.Trie");
goog.require("uno.util.dom");
goog.require("uno.util.react");
goog.require("uno.util.styles");
goog.require("goog.dom");
goog.require("goog.string");
(function() {
  var util = uno.realtime.util;
  var COMPACT_WIDTH = 688;
  var data = {comments:{}, threads:{}, threadPlaceholders:{}, users:{}, usersTrie:null, state:null};
  util.commenting.getState = function() {
    return data.state;
  };
  util.commenting.initState = function(y, userId, editor) {
    data.comments = {};
    data.threads = {};
    data.state = {user:util.user.readMany(y.share.metadata.get("Users"), "id")[userId], findMentions:findMentions, collapsed:true, compact:window.innerWidth <= COMPACT_WIDTH, archive:null, threads:[], readonly:!!editor.readOnly, field:editor.field};
    util.commenting.setUsers(y);
    var threadPlaceholders = {};
    var yComments = y.share.comments;
    yComments.keys().forEach(function(key) {
      var comment = util.commenting.read(yComments, key);
      if (comment) {
        var threadId = comment.parentId;
        comment.editable = comment.userId === userId;
        if (comment.parentId && data.threads[threadId]) {
          data.threads[threadId].comments.push(comment);
        } else {
          if (comment.parentId && threadPlaceholders[threadId]) {
            threadPlaceholders[threadId].push(comment);
          } else {
            if (comment.parentId) {
              threadPlaceholders[comment.parentId] = [comment];
            } else {
              var comments = threadPlaceholders[comment.id] || [];
              data.threads[comment.id] = {id:comment.id, active:false, y:null, comments:comments.concat(comment)};
            }
          }
        }
        data.comments[comment.id] = comment;
      }
    });
    Object.values(data.threads).forEach(function(t) {
      t.comments.sort(commentSortComparator);
    });
  };
  util.commenting.setState = function(y, events, rangeManager, editor) {
    var changed = false;
    events.forEach(function(event) {
      if (!event.remote) {
        return;
      }
      var comment = null;
      var remoteComment = null;
      var keys = Array.from(event.keysChanged);
      if (!event.path.length) {
        keys.forEach(function(key) {
          comment = data.comments[key];
          remoteComment = util.commenting.read(y.share.comments, key);
          if (comment && comment.saved === null) {
            changed = true;
            comment.saved = true;
          } else {
            if (!comment && remoteComment) {
              changed = true;
              remoteComment.editable = remoteComment.userId === data.state.user.id;
              util.commenting.append(remoteComment);
            }
          }
        });
      } else {
        if (event.path.length && data.comments[event.path[0]]) {
          var guid = event.path[0];
          comment = data.comments[guid];
          remoteComment = comment ? util.commenting.read(y.share.comments, guid) : null;
          var yComment = comment ? y.share.comments.get(guid) : null;
          if (!yComment) {
            return;
          }
          changed = true;
          if (!yComment.get("active")) {
            util.commenting.remove(null, {remote:true, id:guid, rangeManager:rangeManager, editor:editor});
          } else {
            if (remoteComment && remoteComment.resolved && !comment.resolved) {
              util.commenting.resolve(null, {remote:true, threadId:comment.parentId || comment.id, rangeManager:rangeManager, editor:editor});
            } else {
              if (remoteComment && !remoteComment.resolved && comment.resolved) {
                util.commenting.reopen(null, {remote:true, threadId:comment.parentId || comment.id, rangeManager:rangeManager, editor:editor});
              } else {
                if (remoteComment) {
                  util.commenting.edit(null, {remote:true, id:comment.id, text:remoteComment.text, updated:remoteComment.updated});
                }
              }
            }
          }
        }
      }
    });
    return changed;
  };
  util.commenting.setReadonly = function(y) {
  };
  util.commenting.setOnline = function(y) {
  };
  util.commenting.setUsers = function(y) {
    data.users = util.user.readMany(y.share.userConnections, "username");
    data.usersTrie = new util.Trie;
    Object.values(data.users).forEach(function(u) {
      if (u.name) {
        var name = util.common.removeDiacritics(u.name.toLowerCase());
        var names = name.split(" ").reverse().reduce(function(acc, val) {
          return acc.concat(acc.length > 0 ? val + " " + acc[acc.length - 1] : val);
        }, []);
        names.forEach(function(val) {
          data.usersTrie.insert(val, u);
        });
      }
      if (u.email) {
        data.usersTrie.insert(u.email.toLowerCase(), u);
      }
      if (u.username) {
        data.usersTrie.insert(u.username.toLowerCase(), u);
      }
    });
  };
  util.commenting.init = function(y, editor, rangeManager) {
    var range = editor.getRange();
    if (!range || !goog.dom.getAncestor(range.getContainer(), uno.util.dom.isEnnote, true)) {
      return;
    }
    var user = data.state.user;
    var thread = {id:util.common.guid(), active:true, comments:[]};
    data.threads[thread.id] = thread;
    var plainText = editor.queryCommandValue("copy").plain;
    plainText = goog.string.isEmptySafe(plainText) ? null : plainText;
    var markerRange = util.commenting.createMarkerRange(range, thread.id);
    rangeManager.set("comment." + thread.id, markerRange, user.color, null, "default");
    var point = util.commenting.getRangePoint(markerRange);
    thread.y = point.y;
    thread.x = point.x;
    thread.selectedText = plainText;
    var threads = data.state.threads;
    var index = threads.findIndex(function(t) {
      return threadPositionSortComparator(t, thread) > 0;
    });
    if (index === -1) {
      data.state.threads = threads.concat(thread);
    } else {
      data.state.threads = threads.slice(0, index).concat(thread, threads.slice(index));
    }
    data.state.collapsed = false;
    uno.util.react.renderComments(data.state);
  };
  util.commenting.edit = function(map, options) {
    var text = (options.text || "").trim();
    if (!text) {
      return false;
    }
    var comment = transform(options.id, {editing:false, updated:options.remote ? options.updated : Date.now(), text:text});
    if (!comment) {
      return false;
    }
    if (!options.remote) {
      util.commenting.write(map, comment);
      uno.util.react.renderComments(data.state);
    }
    return true;
  };
  util.commenting.setEditing = function(rangeManager, editor, id, flag) {
    var comment = transform(id, {editing:flag});
    if (!comment) {
      return false;
    }
    var threadId = comment.parentId || comment.id;
    var otherComment = data.threads[threadId].comments.find(function(c) {
      return c.id !== id && c.editing;
    });
    if (otherComment) {
      transform(otherComment.id, {editing:false});
    }
    util.commenting.highlight(rangeManager, editor, threadId, false);
    return true;
  };
  util.commenting.reopen = function(map, options) {
    return util.commenting.resolve(map, options, false);
  };
  util.commenting.resolve = function(map, options, flag) {
    var comment = transform(options.threadId, {resolved:flag === undefined ? true : flag});
    if (!comment) {
      return false;
    }
    if (!options.remote) {
      util.commenting.write(map, comment);
      uno.util.react.renderComments(data.state);
    }
    return true;
  };
  util.commenting.remove = function(map, options) {
    var comment = transform(options.id, {removed:true});
    if (!comment) {
      return false;
    }
    if (!options.remote) {
      if (!comment.parentId) {
        util.commenting.cleanMarkers(comment.id, options.rangeManager, options.editor);
      }
      util.commenting.write(map, comment);
      uno.util.react.renderComments(data.state);
    }
    return true;
  };
  util.commenting.insert = function(map, options) {
    var text = (options.text || "").trim();
    var thread = data.threads[options.threadId];
    var isThread = thread.comments.length === 0;
    if (!text) {
      return false;
    }
    var user = data.state.user;
    var id = isThread ? thread.id : util.common.guid();
    var comment = transform(id, {id:null, parentId:isThread ? null : thread.id, userId:data.state.user.id, name:user.name, initial:user.initial, color:user.color, created:Date.now(), updated:Date.now(), resolved:false, removed:false, text:text, saved:null, editable:true});
    if (thread.selectedText) {
      comment.selectedText = thread.selectedText;
      delete thread.selectedText;
    }
    util.commenting.write(map, comment);
    uno.util.react.renderComments(data.state);
    return true;
  };
  util.commenting.highlight = function(rangeManager, editor, threadId, collapsed) {
    var threads = data.state.threads;
    var thread = null;
    for (var i = threads.length - 1; i >= 0; i--) {
      var t = threads[i];
      if (t.id !== threadId && t.active && !t.comments.length) {
        thread = t;
        threads = threads.slice(0, i).concat(threads.slice(i + 1));
        delete data.threads[t.id];
        util.commenting.cleanMarkers(t.id, rangeManager, editor);
      } else {
        if (t.id === threadId && !t.active || t.id !== threadId && t.active) {
          var comments = t.comments;
          thread = data.threads[t.id] = Object.assign({}, t, {active:!t.active});
          threads = threads.slice(0, i).concat(thread, threads.slice(i + 1));
          if (t.active) {
            var index = comments.findIndex(function(c) {
              return c.editing;
            });
            if (index > -1) {
              transform(comments[index].id, {editing:false});
            }
          }
        }
      }
    }
    if (thread || collapsed !== undefined) {
      rangeManager.select(threadId);
      data.state.collapsed = !!collapsed;
      data.state.threads = threads;
      uno.util.react.renderComments(data.state);
      return true;
    }
    return false;
  };
  util.commenting.append = function(comment) {
    var threadId = comment.parentId || comment.id;
    var thread = data.threads[threadId];
    data.comments[comment.id] = comment;
    if (thread) {
      thread.comments = thread.comments.concat(comment).sort(commentSortComparator);
    } else {
      if (comment.parentId && data.threadPlaceholders[threadId]) {
        data.threadPlaceholders[threadId].push(comment);
      } else {
        if (comment.parentId) {
          data.threadPlaceholders[threadId] = [comment];
        } else {
          var comments = data.threadPlaceholders[threadId] || [];
          data.threads[threadId] = {id:threadId, active:false, y:null, comments:comments.concat(comment).sort(commentSortComparator)};
        }
      }
    }
    return true;
  };
  util.commenting.read = function(map, key) {
    var yComment = map.get(key);
    if (yComment && yComment.get("saved") && yComment.get("active")) {
      var name = yComment.get("tmpPrettyName");
      return {editable:false, id:key, userId:yComment.get("creator_info"), created:yComment.get("created_time"), updated:yComment.get("last_updated_time"), parentId:yComment.get("parent_comment_guid"), text:(yComment.get("content") || "").trim(), name:name, initial:util.user.getInitial(name), color:util.user.getColor(name), selectedText:yComment.get("selection_string"), removed:!yComment.get("active"), resolved:yComment.get("status") === "resolved", saved:yComment.get("saved")};
    }
    return null;
  };
  util.commenting.readMany = function(map) {
  };
  util.commenting.write = function(map, obj) {
    var yComment = map.get(obj.id);
    if (!yComment) {
      yComment = map.set(obj.id, window.Y.Map);
    }
    var status = obj.resolved ? "resolved" : "open";
    yComment._y.transact(function() {
      yComment.set("parent_comment_guid", obj.parentId);
      yComment.set("status", status);
      yComment.set("creator_info", obj.userId);
      yComment.set("content", obj.text);
      yComment.set("selection_string", obj.selectedText);
      yComment.set("created_time", obj.created);
      yComment.set("last_updated_time", obj.updated);
      yComment.set("tmpPrettyName", obj.name);
      yComment.set("saved", !!obj.saved);
      yComment.set("active", !obj.removed);
    });
  };
  util.commenting.fullsizeOpened = function(editor, opt) {
    data.state.archive = {threads:[], title:editor.config.note.title || "Untitled", close:editor.closeFullSize.bind(editor, "archive")};
    filterAndSortThreads();
    uno.util.react.renderComments(data.state);
    return true;
  };
  util.commenting.fullsizeClosed = function(editor) {
    data.state.archive = null;
    uno.util.react.renderComments(data.state);
  };
  util.commenting.cleanMarkers = function(threadId, rangeManager, editor) {
    var query = '[data-en-comment="' + threadId + '"]';
    var rangeID = "comment." + threadId;
    rangeManager.remove(rangeID);
    Array.from(editor.field.querySelectorAll(query)).forEach(function(node) {
      node.remove();
    });
  };
  util.commenting.updateRanges = function(rangeManager, field) {
    Object.values(data.threads).forEach(function(thread) {
      var threadId = thread.id;
      var rangeID = "comment." + threadId;
      if (!thread.comments.length && thread.active) {
        return;
      }
      data.threads[thread.id] = thread = Object.assign({}, thread, {y:null});
      var parent = thread.comments[0];
      if (!parent || parent.removed || parent.saved === false) {
        rangeManager.remove(rangeID);
      } else {
        var query = '[data-en-comment="' + threadId + '"]';
        var markers = field.querySelectorAll(query);
        if (markers.length > 1) {
          var markerRange = goog.dom.Range.createFromNodes(markers[0], 0, markers[markers.length - 1], 0);
          if (parent.resolved) {
            rangeManager.remove(rangeID);
          } else {
            rangeManager.set(rangeID, markerRange, thread.comments[0].color, thread.comments[0].name, thread.active ? "default" : "underline");
          }
          if (markers[0].parentNode) {
            var point = util.commenting.getRangePoint(markerRange);
            thread.y = point.y;
            thread.x = point.x;
          }
        }
      }
    });
    filterAndSortThreads();
    uno.util.react.renderComments(data.state);
  };
  util.commenting.createMarkerRange = function(range, key) {
    var caretRange = range.saveUsingCarets();
    var startSpan = caretRange.getCaret(true);
    var endSpan = caretRange.getCaret(false);
    var startMarker = goog.dom.createDom("en-comment");
    var endMarker = goog.dom.createDom("en-comment");
    goog.dom.replaceNode(startMarker, startSpan);
    goog.dom.replaceNode(endMarker, endSpan);
    startMarker.removeAttribute("id");
    endMarker.removeAttribute("id");
    uno.util.styles.setMetadata(startMarker, "-en-comment", key);
    uno.util.styles.setMetadata(endMarker, "-en-comment", key);
    return goog.dom.Range.createFromNodes(startMarker, 0, endMarker, 0);
  };
  util.commenting.getRangePoint = function(range) {
    var measureRange = document.createRange();
    measureRange.selectNode(range.getStartNode());
    var clientRects = measureRange.getClientRects();
    var clientRect = clientRects && clientRects.length > 0 ? clientRects[0] : null;
    return {x:clientRect ? clientRect.left : null, y:clientRect ? clientRect.top + window.scrollY : null};
  };
  util.commenting.changeColumnPaddingIfNeeded = function(rangeManager, field) {
    var oldWide = document.body.classList.contains("pr-comments");
    var newWide = window.innerWidth > COMPACT_WIDTH && data && !data.state.collapsed && data.state.threads.length > 0;
    var oldBase = document.body.classList.contains("pr80");
    var newBase = data && data.state.threads.length > 0;
    var compact = window.innerWidth <= COMPACT_WIDTH;
    var fullsize = document.body.classList.contains("fullsize");
    if (fullsize || oldWide === newWide && oldBase === newBase && compact === data.state.compact) {
      return false;
    }
    document.body.classList.toggle("pr80", newBase);
    document.body.classList.toggle("pr-comments", newWide);
    data.state.compact = compact;
    util.commenting.updateRanges(rangeManager, field);
    return true;
  };
  util.commenting.layoutAdder = function(range) {
    if (!range && data.state && data.state.focusY) {
      data.state.focusY = null;
      uno.util.react.renderComments(data.state);
      return true;
    } else {
      if (!data || !range) {
        return false;
      }
    }
    var rects = range.getBrowserRangeObject().getClientRects();
    var y = rects.length === 0 || rects[0].height === 0 ? null : window.scrollY + rects[0].top;
    if (data.state.focusY !== y) {
      data.state.focusY = y;
      uno.util.react.renderComments(data.state);
      return true;
    }
    return false;
  };
  function filterAndSortThreads() {
    var threads = Object.values(data.threads);
    data.state.threads = threads.filter(function(t) {
      return t.y !== null && (!t.comments.length || !t.comments[0].resolved);
    }).sort(threadPositionSortComparator);
    if (data.state.archive) {
      data.state.archive.threads = threads.filter(function(t) {
        return t.y == null || t.comments.length && t.comments[0].resolved;
      }).sort(threadDateSortComparator);
    }
  }
  function threadPositionSortComparator(a, b) {
    return a.y === b.y ? a.x - b.x : a.y - b.y;
  }
  function threadDateSortComparator(a, b) {
    var dateA = a.comments[a.comments.length - 1].created;
    var dateB = b.comments[b.comments.length - 1].created;
    return dateB - dateA;
  }
  function commentSortComparator(a, b) {
    if (a.parentId && !b.parentId) {
      return 1;
    } else {
      if (!a.parentId && b.parentId) {
        return -1;
      }
    }
    return a.created - b.created;
  }
  function findMentions(value, exact) {
    if (exact) {
      var user = data.users[value];
      return data.users[value] ? [user] : [];
    }
    var phrase = util.common.removeDiacritics(value.toLowerCase());
    return data.usersTrie.find(phrase).slice(0, 25);
  }
  function transform(id, obj) {
    var insert = obj.id === null;
    var comment = insert ? {id:id} : data.comments[id];
    var threadId = comment ? obj.parentId || comment.parentId || comment.id : null;
    var thread = comment ? data.threads[threadId] : null;
    if (insert) {
      obj.id = id;
    } else {
      if (!thread) {
        return null;
      }
    }
    data.comments[id] = comment = Object.assign({}, comment, obj);
    var comments = thread.comments;
    var index = comments.findIndex(function(c) {
      return c.id === id;
    });
    if (insert) {
      index = thread.comments.length;
    } else {
      if (index === -1) {
        return comment;
      }
    }
    var lhs = comments.slice(0, index);
    var rhs = comments.slice(index + 1);
    data.threads[threadId] = thread = Object.assign({}, thread, {comments:obj.removed ? lhs.concat(rhs) : lhs.concat(comment, rhs)});
    var threads = data.state.threads;
    index = threads.findIndex(function(t) {
      return t.id === threadId;
    });
    if (index > -1) {
      lhs = threads.slice(0, index);
      rhs = threads.slice(index + 1);
      data.state.threads = !comment.parentId && obj.removed ? lhs.concat(rhs) : lhs.concat(thread, rhs);
    }
    return comment;
  }
})();
goog.provide("uno.realtime.util.rangemanager");
goog.require("goog.dom");
goog.require("uno.util.dom");
goog.require("uno.realtime.util.range");
(function() {
  var util = uno.util;
  var rutil = uno.realtime.util;
  var RangeManager = uno.realtime.util.rangemanager.RangeManager = function() {
    this.ranges = {};
  };
  RangeManager.prototype.set = function(guid, googRange, color, prettyName, style) {
    var config = this.ranges[guid];
    if (config == null) {
      config = this.ranges[guid] = {range:null, color:null, prettyName:null, style:null};
    }
    config.range = googRange || config.range;
    config.color = color || config.color;
    config.prettyName = prettyName || config.prettyName;
    config.style = style || config.style;
    this.render(guid);
  };
  RangeManager.prototype.select = function(threadID) {
    var guidFromThreadID = threadID ? "comment." + threadID : null;
    Object.keys(this.ranges).forEach(function(guid) {
      var info = this.ranges[guid];
      if (guid === guidFromThreadID && info.style !== "default") {
        info.style = "default";
        info.prettyName = null;
        this.render(guid);
      } else {
        if (guid !== guidFromThreadID && info.style !== "underline") {
          info.style = "underline";
          this.render(guid);
        }
      }
    }, this);
  };
  RangeManager.prototype.render = function(guid) {
    var info = this.ranges[guid];
    if (info == null) {
      rutil.range.fakeRenderRange(null, "black", guid);
      return;
    }
    rutil.range.fakeRenderRange(info.range, info.color, guid, info.prettyName, info.style);
  };
  RangeManager.prototype.renderAll = function() {
    var guids = Object.keys(this.ranges);
    for (var i = 0; i < guids.length; i++) {
      this.render(guids[i]);
    }
  };
  RangeManager.prototype.remove = function(guid) {
    delete this.ranges[guid];
    this.render(guid);
  };
})();
goog.provide("uno.realtime.Commenting");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.events");
goog.require("goog.functions");
goog.require("uno.realtime.Plugin");
goog.require("uno.realtime.util.commenting");
goog.require("uno.realtime.util.rangemanager");
goog.require("uno.util.dom");
goog.require("uno.util.menu");
(function() {
  var log = goog.debug.Logger.getLogger("uno.realtime.Commenting");
  var util = uno.realtime.util;
  var skipSelection = false;
  var Commenting = uno.realtime.Commenting = function(yjsmodule) {
    uno.realtime.Plugin.call(this, yjsmodule);
    goog.events.listen(document, "selectionchange", this.handleNativeSelectionChange, false, this);
    this.rangeman = new util.rangemanager.RangeManager;
  };
  goog.inherits(Commenting, uno.realtime.Plugin);
  var exclusionToken = true;
  var mutualExclusive = function(f) {
    if (exclusionToken) {
      exclusionToken = false;
      try {
        f();
      } catch (e) {
        exclusionToken = true;
        throw new Error(e);
      }
      exclusionToken = true;
    }
  };
  Commenting.prototype.setupObservation = function() {
    var self = this;
    var y = this.yjsmodule.y;
    var share = y.share;
    y.define("userConnections", Y.Map);
    y.define("comments", Y.Map);
    util.commenting.initState(this.yjsmodule.y, this.yjsmodule.config.user.userID, this.editor);
    util.commenting.updateRanges(this.rangeman, this.editor.field);
    util.commenting.changeColumnPaddingIfNeeded(this.rangeman, this.editor.field);
    share.comments.observeDeep(function(events) {
      mutualExclusive(function() {
        self.handleCommentEvent(events);
      });
    });
    share.content.observeDeep(function(event) {
      mutualExclusive(function() {
        util.commenting.updateRanges(self.rangeman, self.editor.field);
        util.commenting.changeColumnPaddingIfNeeded(self.rangeman, self.editor.field);
      });
    });
    share.userConnections.observeDeep(function() {
      mutualExclusive(function() {
        util.commenting.setUsers(self.yjsmodule.y);
      });
    });
    window.addEventListener("resize", function() {
      mutualExclusive(function() {
        util.commenting.updateRanges(self.rangeman, self.editor.field);
        util.commenting.changeColumnPaddingIfNeeded(self.rangeman, self.editor.field);
      });
    });
  };
  Commenting.prototype.handleCommentEvent = function(events) {
    if (util.commenting.setState(this.yjsmodule.y, events, this.rangeman, this.editor)) {
      util.commenting.updateRanges(this.rangeman, this.editor.field);
      util.commenting.changeColumnPaddingIfNeeded(this.rangeman, this.editor.field);
    }
  };
  Commenting.prototype.isSupportedCommand = function(command) {
    return command === "comment";
  };
  Commenting.prototype.handleNativeSelectionChange = function(evt) {
    if (skipSelection) {
      skipSelection = false;
      return;
    }
    var range = this.editor.getRange();
    var state = util.commenting.getState();
    if (!state || !range || !goog.dom.getAncestor(range.getContainer(), uno.util.dom.isEnnote, true)) {
      if (util.commenting.layoutAdder()) {
        util.commenting.changeColumnPaddingIfNeeded(this.rangeman, this.editor.field);
      }
      return;
    }
    util.commenting.layoutAdder(this.queryCommandEnabled() ? range : null);
    var keys = Object.keys(this.rangeman.ranges);
    for (var i = 0; i < keys.length; i++) {
      var key = keys[i];
      var info = this.rangeman.ranges[key];
      if (info && info.range.containsRange(range)) {
        if (info.style !== "default") {
          var threadId = key.substr(8);
          util.commenting.highlight(this.rangeman, this.editor, threadId);
          util.commenting.changeColumnPaddingIfNeeded(this.rangeman, this.editor.field);
        }
        return;
      }
    }
    util.commenting.highlight(this.rangeman, this.editor);
    util.commenting.changeColumnPaddingIfNeeded(this.rangeman, this.editor.field);
  };
  Commenting.prototype.execCommand = function(command, value) {
    var options = value || {};
    var action = options.action || (this.queryCommandEnabled() ? "init" : null);
    var id = options.id;
    var threadId = options.threadId;
    var rangeManager = this.rangeman;
    var editor = this.editor;
    var commentMap = this.yjsmodule.y.share.comments;
    var retVal = false;
    if (action === "init") {
      skipSelection = true;
      retVal = util.commenting.init(this.yjsmodule.y, editor, rangeManager);
    }
    if (action === "insert") {
      retVal = util.commenting.insert(commentMap, options);
    } else {
      if (action === "edit") {
        retVal = util.commenting.edit(commentMap, options);
      } else {
        if (action === "remove") {
          retVal = util.commenting.remove(commentMap, {id:id, rangeManager:rangeManager, editor:editor});
        } else {
          if (action === "resolve") {
            retVal = util.commenting.resolve(commentMap, {threadId:threadId, editor:editor});
          } else {
            if (action === "reopen") {
              retVal = util.commenting.reopen(commentMap, {threadId:threadId, editor:editor});
            } else {
              if (action === "highlight") {
                retVal = util.commenting.highlight(rangeManager, editor, threadId);
              } else {
                if (action === "canceledit") {
                  retVal = util.commenting.setEditing(rangeManager, editor, id, false);
                } else {
                  if (action === "menu") {
                    uno.util.menu.presentCommentMenu({x:options.x, y:options.y}, {edit:function() {
                      util.commenting.setEditing(rangeManager, editor, id, true);
                    }, remove:function() {
                      retVal = util.commenting.remove(commentMap, {id:id, rangeManager:rangeManager, editor:editor});
                    }});
                    retVal = true;
                  } else {
                    if (action === "collapse") {
                      retVal = util.commenting.highlight(rangeManager, editor, null, true);
                    } else {
                      if (action === "openarchive") {
                        this.editor.openFullSize("archive");
                        retVal = true;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    if (retVal && ["collapse", "highlight", "reopen", "remove", "resolve", "insert", "init"].indexOf(action) > -1) {
      util.commenting.updateRanges(rangeManager, editor.field);
      util.commenting.changeColumnPaddingIfNeeded(rangeManager, editor.field);
    }
    return retVal;
  };
  Commenting.prototype.queryCommandEnabled = function() {
    var range = this.editor.getRange();
    var readonly = this.editor.readOnly;
    if (readonly || !range || range.isCollapsed() || !goog.dom.getAncestor(range.getContainer(), uno.util.dom.isEnnote, true)) {
      return false;
    }
    var state = util.commenting.getState() || {};
    if (!state.user) {
      return false;
    }
    var threads = state.threads || [];
    if (threads.find(function(t) {
      return t.active && t.comments.length === 0;
    })) {
      return false;
    }
    return true;
  };
})();
goog.provide("uno.realtime.model.resources");
goog.require("goog.array");
goog.require("uno.realtime.util.common");
(function() {
  var rutil = uno.realtime.util;
  var rmodel = uno.realtime.model;
  rmodel.resources.publish = function(yjsmodule, resourceMap) {
    var yResources = yjsmodule.y.share.resources;
    goog.array.forEach(resourceMap, function(resource) {
      if (!goog.isString(resource.hash)) {
        return;
      }
      var specific = yResources.get(resource.hash);
      if (specific == null) {
        specific = yResources.set(resource.hash, window.Y.Map);
      }
      var relevantData = ["filename", "filesize", "mime", "rect"];
      goog.array.forEach(Object.keys(resource), function(key) {
        if (relevantData.indexOf(key) >= 0) {
          var value = resource[key];
          if (!goog.isString(value)) {
            value = JSON.stringify(value);
          }
          if (value == null) {
            value = null;
          }
          rutil.common.setIfDifferent(specific, key, value);
        }
      });
    });
  };
})();
goog.provide("uno.realtime.Resources");
goog.require("uno.realtime.Plugin");
goog.require("goog.debug.Logger");
goog.require("uno.realtime.model.resources");
(function() {
  var rmodel = uno.realtime.model;
  var log = goog.debug.Logger.getLogger("uno.realtime.Resources");
  var Resources = uno.realtime.Resources = function(yjsmodule) {
    uno.realtime.Plugin.call(this, yjsmodule);
  };
  goog.inherits(Resources, uno.realtime.Plugin);
  var exclusionToken = true;
  var mutualExclusive = function(f) {
    if (exclusionToken) {
      exclusionToken = false;
      try {
        f();
      } catch (e) {
        exclusionToken = true;
        throw new Error(e);
      }
      exclusionToken = true;
    }
  };
  Resources.prototype.setupObservation = function() {
    var self = this;
    this.yjsmodule.y.define("resources", Y.Map);
  };
})();
goog.provide("uno.realtime.commands.Connector");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.realtime.Plugin");
(function() {
  var COMMANDS = {DELETE_NOTE:"deletenote", UPDATE_TOKEN:"updatetoken", CONNECTION:"connection"};
  var log = goog.debug.Logger.getLogger("uno.realtime.commands.Connector");
  var stateManager = null;
  var Connector = uno.realtime.commands.Connector = function(yjsmodule) {
    uno.realtime.Plugin.call(this, yjsmodule);
  };
  goog.inherits(Connector, uno.realtime.Plugin);
  Connector.prototype.setupObservation = function() {
    stateManager = this.yjsmodule.stateManager;
  };
  Connector.prototype.isSupportedCommand = function(command) {
    return Object.values(COMMANDS).indexOf(command) >= 0;
  };
  Connector.prototype.execCommand = function(command, value) {
    if (command === COMMANDS.UPDATE_TOKEN) {
      this.yjsmodule.y.connector.updateAuthToken(value);
      return true;
    } else {
      if (command === COMMANDS.DELETE_NOTE) {
        this.yjsmodule.y.connector.sendDeleteNoteMessage();
        return true;
      }
    }
    return false;
  };
  Connector.prototype.queryCommandValue = function(command) {
    if (command === COMMANDS.CONNECTION) {
      return {connected:stateManager.get("connected")};
    }
    return null;
  };
  Connector.prototype.queryCommandEnabled = goog.functions.TRUE;
})();
goog.provide("uno.realtime.commands.Shutdown");
goog.require("goog.debug.Logger");
goog.require("goog.functions");
goog.require("uno.realtime.Plugin");
goog.require("uno.util.dom");
(function() {
  var log = goog.debug.Logger.getLogger("uno.realtime.commands.Shutdown");
  var rutil = uno.realtime.util;
  var util = uno.util;
  var isShuttingDown = false;
  var isShutdownComplete = false;
  var isSaved = true;
  var isForceShutdown = false;
  var timeoutTimerID = 0;
  var stateManager = null;
  var SHUTDOWN_TIMEOUT = 10000;
  var Shutdown = uno.realtime.commands.Shutdown = function(yjsmodule) {
    uno.realtime.Plugin.call(this, yjsmodule);
  };
  goog.inherits(Shutdown, uno.realtime.Plugin);
  Shutdown.prototype.setupObservation = function() {
    stateManager = this.yjsmodule.stateManager;
    uno.realtime.Plugin.call(this, this.yjsmodule);
  };
  var tryShutdown = function(self) {
    if (isShutdownComplete) {
      return;
    }
    if (!isForceShutdown) {
      if (!isShuttingDown) {
        return;
      }
      if (!stateManager.get("saved")) {
        return;
      }
    }
    self.editor.dispatchEvent({type:"shutdownComplete", code:isForceShutdown ? "timeout" : "success"});
    isShuttingDown = false;
    isShutdownComplete = true;
    clearTimeout(timeoutTimerID);
  };
  Shutdown.prototype.stateManagerChange = function(state, value) {
    if (state === "saved" && value === true) {
      tryShutdown(this);
    }
  };
  Shutdown.prototype.isSupportedCommand = function(command) {
    return command === "shutdown";
  };
  Shutdown.prototype.execCommand = function() {
    log.info("Beginning realtime shutdown protocol! NOTE LOCKED");
    this.editor.execCommand("active", false);
    isShuttingDown = true;
    tryShutdown(this);
    timeoutTimerID = setTimeout(function() {
      isForceShutdown = true;
      tryShutdown(this);
    }.bind(this), SHUTDOWN_TIMEOUT);
    return true;
  };
  Shutdown.prototype.queryCommandEnabled = goog.functions.TRUE;
})();
goog.provide("ENFORMATCONVERTER");
goog.require("goog.functions");
goog.require("goog.dom");
goog.require("uno.PluginManager");
goog.require("uno.util.dom");
goog.require("uno.realtime.util.convert");
goog.require("uno.defs");
goog.require("uno.util.canvas");
goog.require("uno.util.dom");
goog.require("uno.util.font");
goog.require("uno.util.img");
goog.require("uno.util.loc");
goog.require("uno.util.objects");
goog.require("uno.util.preview");
goog.require("uno.util.resource");
goog.require("uno.util.richlink.googledrive");
goog.require("uno.util.touch");
goog.require("uno.util.todo");
goog.require("uno.util.tools");
goog.require("uno.filters.All");
(function() {
  var util = uno.util;
  var rutil = uno.realtime.util;
  var PM = new uno.PluginManager;
  var fakeEditor = {config:{client:null, richlinks:{enabled:false}}, context:{crypt:{uniqueIdCounter:0, incrementUniqueId:function() {
    return ++this.uniqueIdCounter;
  }}, resources:{}, format:uno.defs.format.ENML}, field:{hasAttributes:goog.functions.FALSE, getAttribute:goog.functions.NULL}, hasForeignSource:goog.functions.FALSE};
  (function setup() {
    var allFiltersPM = uno.filters.All();
    allFiltersPM.forEach(function(plugin) {
      PM.add(plugin);
      plugin.registerFieldObject(fakeEditor);
    });
  })();
  ENFORMATCONVERTER.enmlToDom = function(enml) {
    fakeEditor.context.format = uno.defs.format.ENML;
    PM.forEach(function(filter) {
      if (filter.prepareContentsHtml) {
        enml = filter.prepareContentsHtml(enml);
      }
    });
    var frag = util.dom.fragFromString(enml);
    PM.forEach(function(filter) {
      if (filter.prepareContentsDom) {
        filter.prepareContentsDom(frag);
      }
    });
    var ennoteWrapper = goog.dom.createDom("en-note");
    while (frag.firstChild != null) {
      ennoteWrapper.appendChild(frag.firstChild);
    }
    return ennoteWrapper;
  };
  ENFORMATCONVERTER.domToEnml = function(html) {
    var doctype = '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">';
    fakeEditor.context.format = uno.defs.format.ENML;
    PM.forEachRight(function(filter) {
      if (filter.cleanContentsDom) {
        filter.cleanContentsDom(html);
      }
    });
    var enml = util.dom.stringFromFrag(html);
    PM.forEachRight(function(filter) {
      if (filter.cleanContentsHtml) {
        enml = filter.cleanContentsHtml(enml);
      }
    });
    if (enml === "<en-note/>") {
      enml = "<en-note></en-note>";
    }
    return doctype + enml;
  };
  ENFORMATCONVERTER.modelToDOM = function(model) {
    return model.get("en-note").toDom();
  };
  ENFORMATCONVERTER.domToModel = function(dom, model) {
    var fragment = model.set("en-note", window.Y.XmlFragment);
    var elements = [];
    for (var i = 0; i < dom.childNodes.length; i++) {
      elements.push(dom.childNodes[i]);
    }
    fragment.insertDomElements(0, elements);
    fragment.bindToDom(dom);
  };
})();
goog.provide("uno.realtime.YJS");
goog.require("goog.string");
goog.require("goog.functions");
goog.require("uno.PluginManager");
goog.require("uno.realtime.StateManager");
goog.require("uno.realtime.YJSHooks");
goog.require("uno.realtime.Editing");
goog.require("uno.realtime.Selecting");
goog.require("uno.realtime.Commenting");
goog.require("uno.realtime.Resources");
goog.require("uno.realtime.commands.Connector");
goog.require("uno.realtime.commands.Shutdown");
goog.require("ENFORMATCONVERTER");
(function() {
  var CommonEditorErrorDomain = "CommonEditorDomain";
  var ErrorCodes = {UNKNOWN:-1, SETUP_FAILURE:1};
  var YJSConfig = {connector:{name:"websockets-client", room:"en-webrtc-test", socketHandlers:{}, utilities:{}, url:"https://rtes-p.kundures.com", generateUserId:false, maxBufferLength:2000}};
  var YJS = uno.realtime.YJS = function(editor, options) {
    var self = this;
    this.editor = editor;
    this.config = options;
    if (options && options.user && options.user.userID) {
      this.config.user.userID = options.user.userID + "";
    }
    if (window.Y == null) {
      console.error("YJS not available, did you run npm install?");
      return;
    }
    self.PM = new uno.PluginManager;
    self.stateManager = new uno.realtime.StateManager(self, function(state, value) {
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "stateManagerChange", [state, value]);
      });
    });
    self.PM.add(self.stateManager);
    self.PM.add(new uno.realtime.commands.Connector(self));
    self.PM.add(new uno.realtime.YJSHooks(self));
    self.PM.add(new uno.realtime.Resources(self));
    self.PM.add(new uno.realtime.Editing(self));
    self.PM.add(new uno.realtime.Selecting(self));
    if (options.realtime.commenting === true) {
      self.PM.add(new uno.realtime.Commenting(self));
    }
    self.PM.add(new uno.realtime.commands.Shutdown(self));
    if (options.note && options.note.guid) {
      YJSConfig.connector.room = options.note.guid;
    } else {
      var letters = "0123456789ABCDEF";
      var roomname = "no-guid-";
      for (var i = 0; i < 6; i++) {
        roomname += letters[Math.floor(Math.random() * 16)];
      }
      YJSConfig.connector.room = roomname;
    }
    console.log("YJS Using Room:", YJSConfig.connector.room);
    this.serverContentLoaded = function() {
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "serverContentLoaded");
      });
    };
    YJSConfig.connector.socketHandlers.connect = function(success) {
      console.log("SOCKET EVENT:", "connect", success);
      if (success) {
        self.editor.dispatchEvent({type:"realtimeServerVersionUpdated"});
      }
      self.editor.dispatchEvent({type:"realtimeConnectStateChanged", connected:success});
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "socketConnect", [success]);
      });
    };
    YJSConfig.connector.socketHandlers.connectError = function() {
      console.log("SOCKET EVENT:", "connect_error");
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "socketConnectError");
      });
    };
    YJSConfig.connector.socketHandlers.reconnect = function(numAttempts) {
      console.log("SOCKET EVENT:", "reconnect(ed)", numAttempts);
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "socketReconnect", [numAttempts]);
      });
    };
    YJSConfig.connector.socketHandlers.reconnectAttempt = function() {
      console.log("SOCKET EVENT:", "reconnect_attempt");
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "socketReconnectAttempt");
      });
    };
    YJSConfig.connector.socketHandlers.reconnectError = function(err) {
      console.log("SOCKET EVENT:", "reconnect_error", err);
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "socketReconnectError", [err]);
      });
    };
    YJSConfig.connector.socketHandlers.disconnect = function() {
      console.log("SOCKET EVENT:", "disconnect");
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "socketDisconnect");
      });
    };
    YJSConfig.connector.utilities.noteSavedNotification = function() {
      console.log("CE-YJS NOTIFICATION:", "note saved");
      self.editor.dispatchEvent({type:"realtimeNoteSavedNotification"});
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "realtimeNoteSaved");
      });
    };
    YJSConfig.connector.utilities.resetYjsModel = function() {
      console.log("CE-YJS NOTIFICATION:", "reload");
      self.editor.dispatchEvent({type:"reload"});
    };
    YJSConfig.connector.utilities.errorHandler = function(error) {
      self.editor.dispatchEvent({type:"realtimeErrorHandler", error:error});
    };
    YJSConfig.connector.utilities.permissionsHandler = function(readOnly) {
      console.log("CE-YJS Permissions:", readOnly ? "read" : "write");
      self.editor.execCommand("active", !readOnly);
    };
    self.getRealtimeServerVersion = function() {
      if (!self.y) {
        return null;
      }
      return self.y.connector.serverVersion;
    };
    var isNewNote = false;
    if (options.realtime && options.user && options.note) {
      isNewNote = options.note.newNote === true;
      YJSConfig.connector.authToken = options.user.authToken;
      YJSConfig.connector.serviceHost = options.user.serviceHost;
      YJSConfig.connector.shardID = options.user.shardID;
      YJSConfig.connector.url = options.realtime.url || YJSConfig.connector.url;
      YJSConfig.connector.userName = options.user.displayName;
      YJSConfig.connector.newNote = options.note.newNote;
      YJSConfig.connector.dontWaitForServer = isNewNote;
      var demopath = EN.getBuildPath() ? "http://localhost:8888/demo/" : "https://evernote.s3.amazonaws.com/ce/demo/latest/";
      window.YINFO = {guid:options.note.guid, name:options.user.displayName, authToken:options.user.authToken, serviceHost:options.user.serviceHost, shardID:options.user.shardID, url:YJSConfig.connector.url, debugURL:demopath + "index.html?client=" + self.editor.config.client + "&room=" + options.note.guid + "&userID=" + options.user.userID + "&authToken=" + options.user.authToken + "&serviceHost=" + options.user.serviceHost + "&shardID=" + options.user.shardID + "&name=DBG-" + goog.string.urlEncode(options.user.displayName)};
    }
    var yjsErrorHandler = function(error) {
      console.error("There is a critical error has happened in YJS. Reload editor to reset y-model.");
      self.editor.dispatchEvent({type:"reload"});
    };
    console.log("Launching YJS with config", YJSConfig);
    var y = new Y(YJSConfig);
    console.log("YJS LOADED!!");
    window.YINSTANCE = self.y = y;
    y.on("error", yjsErrorHandler);
    if (isNewNote) {
      var model = y.define("content", Y.Map).set("document", Y.XmlFragment);
      model.insertDomElements(0, self.editor.field.childNodes);
      model.bindToDom(self.editor.field);
    }
    y.once("synced", function() {
      self.editor.dispatchEvent({type:"realtimeServerVersionUpdated"});
      self.execCommand = self.PM.execCommand.bind(self.PM);
      self.queryCommandEnabled = self.PM.queryCommandEnabled.bind(self.PM);
      self.queryCommandValue = self.PM.queryCommandValue.bind(self.PM);
      self.isSupportedCommand = self.PM.isSupportedCommand.bind(self.PM);
      self.PM.forEach(function(plugin) {
        self.PM.tryToRun(plugin, "setupObservation");
      });
      self.editor.dispatchEvent({type:"realtimeSetupDone"});
    });
  };
  YJS.prototype.editor = null;
  YJS.prototype.options = null;
  YJS.prototype.y = null;
  YJS.prototype.PM = null;
  YJS.prototype.execCommand = goog.functions.FALSE;
  YJS.prototype.queryCommandEnabled = goog.functions.FALSE;
  YJS.prototype.queryCommandValue = goog.functions.NULL;
  YJS.prototype.isSupportedCommand = goog.functions.FALSE;
})();
goog.provide("uno.api.ce");
goog.provide("EN");
goog.require("goog.debug.Logger");
goog.require("goog.dom");
goog.require("goog.dom.classlist");
goog.require("goog.style");
goog.require("goog.editor.Command");
goog.require("goog.events");
goog.require("goog.object");
goog.require("uno.api.celogger");
goog.require("uno.Auth");
goog.require("uno.Cache");
goog.require("uno.debug");
goog.require("uno.Editor");
goog.require("uno.template.Template");
goog.require("uno.Router");
goog.require("uno.context.Context");
goog.require("uno.context.Info");
goog.require("uno.context.Upsell");
goog.require("uno.PluginManager");
goog.require("uno.polyfill");
goog.require("uno.realtime.YJS");
goog.require("uno.util.dom");
(function() {
  EN.version = "1.38.3824";
  var options;
  var log = goog.debug.Logger.getLogger("uno.api.ce");
  var util = uno.util;
  var ted = null;
  window.DEBUG = false;
  window.onerror = function(error) {
    log.severe("Unhandled error: " + (error.stack || error));
    return false;
  };
  var consoleLogger = new uno.ConsoleLogger({cachingEnabled:true});
  consoleLogger.setCapturing(true);
  var purgeLogsOnSetup = false;
  var Editor = uno.Editor;
  var Template = uno.template.Template;
  var rxRedundantPrefixes = /^(?:rte|content|richlinks)\./;
  var router = new uno.Router({sendMessage:function(name, info) {
    return EN.notification(name, info);
  }, routesToHost:{requestAuth:{identifier:"serviceName"}, showOptions:{identifier:"correlationId"}, getFromCache:{identifier:"correlationId"}, saveInCache:{identifier:"correlationId", oneway:true}}, routesFromHost:{authtoken:{identifier:"service"}, optionselected:{identifier:"showEvent.correlationId"}, cacheddata:{identifier:"cacheRequest.correlationId"}}});
  var cache = new uno.Cache({router:router});
  var auth = new uno.Auth({router:router});
  var PM = new uno.PluginManager;
  EN.logs = consoleLogger;
  EN.getLogs = function() {
    return EN.logs.cache.map(function(record) {
      return record.formattedText;
    }).join("\n");
  };
  EN.setup = function(opt) {
    opt = opt || {};
    options = goog.isObject(opt) ? opt : JSON.parse(opt);
    DEBUG = options.debug === true;
    start("EN.setup");
    EN.cleanupInternal_();
    var id;
    options.logging = options.logging || {};
    options.logging.consoleLogger = consoleLogger;
    configLogging(options);
    cache.diskEnabled = options.rte && options.rte.richLink && options.rte.richLinksCaching;
    goog.object.extend(options, {cache:cache, auth:auth, router:router});
    id = options.id || "en-note";
    if (DEBUG) {
      initDebug();
    } else {
      clearDebug();
    }
    window.ed = new Editor(id, options);
    ted = new Template(id, options);
    ed.listen(Editor.EventType.DELAYEDCHANGE, onEditorDelayedChange);
    ed.listen(Editor.EventType.FOCUS, onEditorFocus);
    ed.listen(Editor.EventType.BLUR, onEditorBlur);
    ed.listen(Editor.EventType.STYLE_CHANGED, onEditorStyleChanged);
    ed.listen(Editor.EventType.PRINT_READY, onPrintReady);
    ed.listen(Editor.EventType.ENCRYPT, onEncrypt);
    ed.listen(Editor.EventType.DECRYPT, onDecrypt);
    ed.listen(Editor.EventType.CONTENT_LOADED, onEditorContentLoaded);
    ed.listen(Editor.EventType.ACTION_DENIED, onActionDenied);
    ed.listen(Editor.EventType.SHUTDOWN_COMPLETE, onShutdownComplete);
    if (DEBUG) {
      ed.listen(Editor.EventType.EDIT_MODE_CHANGED, onEditorEditModeChanged);
    }
    if (options.rte != null) {
      options.rte = options.rte || {};
      options.rte.imageConfig = options.rte.imageConfig || {};
      if (options.rte.imageConfig.imageClickEvents) {
        ed.listen(Editor.EventType.IMAGE_CLICK, onImageClick);
        ed.listen(Editor.EventType.IMAGE_DOUBLECLICK, onImageDoubleClick);
      }
      if (options.rte.imageConfig.annotate) {
        ed.listen(Editor.EventType.IMAGE_ANNOTATE, onImageEvent);
      }
      if (options.rte.imageConfig.preview) {
        ed.listen(Editor.EventType.IMAGE_PREVIEW, onImageEvent);
      }
      if (options.rte.imageConfig.rotate) {
        ed.listen(Editor.EventType.IMAGE_ROTATE, onImageEvent);
      }
      ed.listen(Editor.EventType.LINK_CLICK, onLinkClick);
      ed.listen(Editor.EventType.CRYPT_DOUBLECLICK, onCryptDoubleClick);
      ed.listen(Editor.EventType.RESOURCE_DOUBLECLICK, onResourceDoubleClick);
    }
    options.rte.trackStateChanges = (options.rte.trackStateChanges || []).concat(["bold", "italic", "underline", "highlight", "strikethrough", "subscript", "superscript"]);
    options.rte.trackValueChanges = (options.rte.trackValueChanges || []).concat(["justifyleft", "justifyright", "justifycenter", "fontsize", "fontname", "forecolor"]);
    goog.array.removeDuplicates(options.rte.trackStateChanges);
    goog.array.removeDuplicates(options.rte.trackValueChanges);
    ed.suppressFocusDuring(ed.setup);
    var rteElement = ed.getElement();
    var templateElement = ted.getElement();
    if (options.template != null) {
      options.template = options.template || {};
      if (!options.template.html && !options.template.enml && options.rte) {
        options.template.html = options.html || options.rte.html || "";
        options.template.enml = options.enml || options.rte.enml || "";
      }
      ed.clearListeners();
      ted.setup(options);
      if (rteElement) {
        rteElement.style.display = "none";
      }
      if (templateElement) {
        templateElement.style.display = "";
      }
    } else {
      if (rteElement) {
        rteElement.style.display = "";
      }
      if (templateElement) {
        templateElement.style.display = "none";
      }
    }
    start("Setup Context");
    PM.add(new uno.context.Context(options.context || {}));
    stop("Setup Context");
    start("Setup Context Upsell");
    PM.add(new uno.context.Upsell(options["context-upsell"] || {}));
    stop("Setup Context Upsell");
    start("Setup Context Info");
    PM.add(new uno.context.Info(options["context-info"] || {}));
    stop("Setup Context Info");
    if (options.realtime != null && !!options.realtime.enabled) {
      EN.setupRealtime(options);
    }
    PM.add(ted);
    PM.add(ed);
    EN.notification("setupDone", {module:"document"});
    if (DEBUG) {
      updateDebug();
    }
    stop("EN.setup");
    return true;
  };
  EN.setupRealtime = function(opt) {
    var ed = window.ed;
    if (!options || !ed || !ed.isSetup) {
      return;
    }
    EN.cleanupRealtime();
    ed.listen("realtimeSetupDone", onRealtimeSetupDone);
    ed.listen("realtimeConnectStateChanged", onRealtimeConnectStateChanged);
    ed.listen("realtimeServerVersionUpdated", onRealtimeServerVersionUpdated);
    ed.listen("realtimeNoteSavedNotification", onRealtimeNoteSavedNotification);
    ed.listen("realtimeErrorHandler", onRealtimeErrorHandler);
    ed.listen("reload", onReload);
    ed.listen("resourceNeedsUpdate", onResourceNeedsUpdate);
    opt = opt || {};
    options = goog.isObject(opt) ? opt : JSON.parse(opt);
    EN.realtimeModule = new uno.realtime.YJS(ed, options);
    window.rte = EN.realtimeModule;
    PM.add(EN.realtimeModule);
  };
  EN.cleanupRealtime = function() {
    var ed = window.ed;
    PM.filterRemove(function(module) {
      return module !== EN.realtimeModule;
    });
    ed.unlisten("realtimeSetupDone");
    ed.unlisten("realtimeConnectStateChanged");
    ed.unlisten("realtimeServerVersionUpdated");
    ed.unlisten("realtimeErrorHandler");
    ed.unlisten("reload");
    ed.unlisten("resourceNeedsUpdate");
    EN.realtimeModule = null;
    window.rte = null;
  };
  EN.cleanup = function() {
    start("EN.cleanup");
    var result = EN.cleanupInternal_();
    EN.notification("cleanupDone");
    stop("EN.cleanup");
    return result;
  };
  EN.cleanupInternal_ = function() {
    if (window.ed && goog.isFunction(window.ed.cleanup)) {
      window.ed.cleanup();
    }
    if (ted && goog.isFunction(ted.cleanup)) {
      ted.cleanup();
    }
    if (PM) {
      PM.clear();
    }
    util.dom.scrollLeft(document.body, 0);
    util.dom.scrollTop(document.body, 0);
    return true;
  };
  function setLogLevel(level) {
    var rootLogger = goog.debug.Logger.getLogger(goog.debug.Logger.ROOT_LOGGER_NAME);
    var googLevel = goog.debug.Logger.Level.getPredefinedLevel(level || "ALL");
    rootLogger.setLevel(googLevel);
  }
  EN.setLogLevel = setLogLevel;
  EN.getLogLevel = function() {
    var rootLogger = goog.debug.Logger.getLogger(goog.debug.Logger.ROOT_LOGGER_NAME);
    return rootLogger.getLevel().name;
  };
  function configLogging(opt) {
    opt.logging = opt.logging || {};
    opt.logging.level = opt.logging.level || "CONFIG";
    setLogLevel(opt.logging.level);
    consoleLogger.configure({cachingEnabled:opt.logging.cachingEnabled != null ? opt.logging.cachingEnabled : DEBUG, maxEntries:typeof opt.logging.maxEntries !== "undefined" ? opt.logging.maxEntries : 1000});
    purgeLogsOnSetup = opt.logging.purgeLogsOnSetup != null ? opt.logging.purgeLogsOnSetup : true;
  }
  EN.execCommand = function(command, value, opt) {
    var normalizedCommand = filterCommandPrefix(command);
    var parsedValue = valueToObject(value);
    var parsedOpt = valueToObject(opt);
    if (router.fromHost(normalizedCommand, parsedValue)) {
      return true;
    }
    return PM.execCommand(normalizedCommand, parsedValue, parsedOpt, true);
  };
  EN.queryCommandEnabled = function(command, opt) {
    var disabledByRealtime = ["crypt"];
    if (options != null && options.realtime && disabledByRealtime.indexOf(command) >= 0) {
      log.info("Command disabled by realtime: " + command);
      return false;
    }
    return PM.queryCommandEnabled(filterCommandPrefix(command), opt, true);
  };
  EN.queryCommandValue = function(command, opt) {
    var normalizedCommand = filterCommandPrefix(command);
    var parsedOptions = valueToObject(opt);
    var result = PM.queryCommandValue(normalizedCommand, parsedOptions, true);
    if (DEBUG) {
      showDebugDirty();
    }
    return result;
  };
  EN.queryCommandState = function(command, opt) {
    var normalizedCommand = filterCommandPrefix(command);
    var result = PM.queryCommandValue(normalizedCommand, opt || null);
    if (result === "true") {
      result = true;
    }
    if (result === "false") {
      result = false;
    }
    if (command === "justifyleft") {
      result = result === "left";
    } else {
      if (command === "justifycenter") {
        result = result === "center";
      } else {
        if (command === "justifyright") {
          result = result === "right";
        } else {
          if (command === "justifyfull") {
            result = result === "justify";
          } else {
            if (command === "insertorderedlist") {
              result = result === "ol";
            } else {
              if (command === "insertunorderedlist") {
                result = result === "ul";
              }
            }
          }
        }
      }
    }
    return !!result;
  };
  EN.fireUpAndroid = function() {
    if (document && document.body) {
      if (!window.noteEditor || !noteEditor.onWebViewLoaded) {
        log.severe("Native did not set up `noteEditor` correctly");
      } else {
        noteEditor.onWebViewLoaded();
      }
    } else {
      if (DEBUG) {
        log.info("Will wait another while until document.body is ready");
      }
      window.setTimeout(EN.fireUpAndroid, 100);
    }
  };
  EN.enablePrint = function(localization, opt) {
    ed.execCommand("printpreview", localization, opt);
  };
  EN.disablePrint = function() {
    ed.execCommand("printpreview", null, {disable:true});
  };
  EN.getVersion = function() {
    return EN.version;
  };
  EN.getBuildPath = function() {
    var scripts = document.querySelectorAll('script[src*="/deps.js"]');
    var depsScript = Array.from(scripts).find(function(s) {
      return /goog\/deps.js/.test(s.getAttribute("src")) === false;
    });
    return depsScript ? depsScript.getAttribute("src").replace(/\/deps.js$/, "") + "/" : "";
  };
  EN.notification = function(name, info) {
    setTimeout(EN.notify.bind(EN, name, info));
  };
  EN.notify = function(name, info) {
    info = info || {};
    info.version = "1.0";
    if (window.Evernote && Evernote.handleJavascriptEvent) {
      Evernote.handleJavascriptEvent(name, JSON.stringify({name:name, info:info}));
    } else {
      if (window.evernoteClient && evernoteClient.postNotification) {
        evernoteClient.postNotification(name, JSON.stringify(info));
      } else {
        if (window.noteEditor && window.noteEditor.handleJavascriptEvent) {
          window.noteEditor.handleJavascriptEvent(name, JSON.stringify(info) || null);
        } else {
          if (window.evernoteClient && evernoteClient.handleNotificationInfo) {
            evernoteClient.handleNotificationInfo(name, info);
          }
        }
      }
    }
  };
  EN.convertEvernoteLinkToPublicLink = function(uri) {
    if (window.androidUtils && androidUtils.convertEvernoteLinkToPublicLink) {
      return androidUtils.convertEvernoteLinkToPublicLink(uri);
    }
    return uri;
  };
  EN.setupCopyHandler = goog.nullFunction;
  function valueToObject(value) {
    if (typeof value === "string" && value.length > 0 && (value[0] === "{" || value[0] === "[")) {
      try {
        return JSON.parse(value);
      } catch (err$14) {
        log.fine(err$14.stack || err$14);
      }
    }
    return value;
  }
  function filterCommandPrefix(command) {
    return command.replace(rxRedundantPrefixes, "");
  }
  function onEditorDelayedChange() {
    EN.notification("contentChanged", {module:"content"});
    if (DEBUG) {
      showDebugDirty();
    }
  }
  function onEditorFocus() {
    EN.notification("focusChanged", {focus:true, module:"content", showInput:ed.showVirtualKeyboardOnFocus});
    if (DEBUG) {
      updateDebug();
    }
  }
  function onEditorBlur() {
    EN.notification("focusChanged", {focus:false, module:"content"});
    if (DEBUG) {
      updateDebug();
    }
  }
  function onEditorStyleChanged(e) {
    e.style.module = "content";
    EN.notification("styleChanged", e.style);
  }
  function onPrintReady() {
    EN.notification("printReady", {module:"print"});
  }
  function onEncrypt(e) {
    EN.notification("encrypt", e.cryptInfo);
  }
  function onDecrypt(e) {
    EN.notification("decrypt", e.cryptInfo);
  }
  function onEditorContentLoaded() {
    EN.notification("contentLoaded", {module:"content"});
  }
  function onEditorEditModeChanged() {
    if (DEBUG) {
      updateDebug();
    }
  }
  function onActionDenied(e) {
    EN.notification("actionDenied", e.reason);
  }
  function onImageClick(e) {
    EN.notification("clicked", {name:e.name, src:e.src, tagname:e.tagname, reference:e.reference});
  }
  function onImageDoubleClick(e) {
    EN.notification("doubleClicked", {name:e.name, src:e.src, tagname:e.tagname, reference:e.reference});
  }
  function onImageEvent(e) {
    EN.notification(e.type, {module:e.module, src:e.src, tagname:e.tagname});
  }
  function onLinkClick(e) {
    EN.notification("openLink", e.data);
  }
  function onRealtimeSetupDone(e) {
    EN.notification("realtimeSetupDone");
  }
  function onRealtimeConnectStateChanged(e) {
    EN.notification("realtimeConnectStateChanged", {connected:e.connected});
  }
  function onRealtimeServerVersionUpdated() {
    updateDebug();
  }
  function onRealtimeNoteSavedNotification(e) {
    EN.notification("realtimeNoteSavedNotification");
  }
  function onRealtimeErrorHandler(e) {
    EN.notification("realtimeErrorHandler", e.error);
  }
  function onReload(e) {
    EN.notification("reload");
  }
  function onShutdownComplete(e) {
    EN.notification("shutdownComplete", {code:e.code});
  }
  function onCryptDoubleClick(e) {
    EN.notification("doubleClicked", {id:e.id, src:e.src});
  }
  function onResourceNeedsUpdate(e) {
    EN.notification("resourceNeedsUpdate", {props:e.props});
  }
  function onResourceDoubleClick(e) {
    EN.notification("doubleClicked", {src:e.src});
  }
  function updateStyleChanges(styleOverrides) {
    var rte = options.rte;
    var style = ed.context.style;
    var hasChanges = false;
    styleOverrides = styleOverrides || {state:{}, value:{}, enabled:{}};
    if (rte && goog.isArray(rte.trackStateChanges)) {
      rte.trackStateChanges.map(filterCommandPrefix).forEach(function(command) {
        var result = typeof styleOverrides.state[command] !== "undefined" ? styleOverrides.state[command] : queryCommandStateInternal(command);
        if (style.state[command] !== result) {
          style.state[command] = result;
          hasChanges = true;
        }
      });
    }
    if (rte && goog.isArray(rte.trackValueChanges)) {
      rte.trackValueChanges.map(filterCommandPrefix).forEach(function(command) {
        var result = typeof styleOverrides.value[command] !== "undefined" ? styleOverrides.value[command] : ed.queryCommandValue(command);
        if (style.value[command] !== result) {
          style.value[command] = result;
          hasChanges = true;
        }
      });
    }
    if (rte && goog.isArray(rte.trackEnabledChanges)) {
      rte.trackEnabledChanges.map(filterCommandPrefix).forEach(function(command) {
        var result = typeof styleOverrides.enabled[command] !== "undefined" ? styleOverrides.enabled[command] : ed.queryCommandEnabled(command);
        if (style.enabled[command] !== result) {
          style.enabled[command] = result;
          hasChanges = true;
        }
      });
    }
    if (hasChanges) {
      style.module = "content";
      EN.notification("styleChanged", style);
    }
  }
  function initDebug() {
    if (document.querySelector("en-debug")) {
      updateDebug();
    } else {
      goog.dom.appendChild(document.body, goog.dom.createDom("en-debug", null, "CE " + EN.version));
      EN.getVersionString = getVersionString;
    }
  }
  function clearDebug() {
    goog.dom.removeNode(document.querySelector("en-debug"));
    delete EN.getVersionString;
  }
  function getVersionString() {
    var version = "";
    if (ed.strictMode) {
      version = "CE " + EN.version + " (strict)";
    } else {
      version = "CE " + EN.version;
    }
    if (EN.realtimeModule && EN.realtimeModule.getRealtimeServerVersion()) {
      version = version + " RT " + EN.realtimeModule.getRealtimeServerVersion();
    }
    return version;
  }
  function updateDebug() {
    var endebug = document.querySelector("en-debug");
    if (!endebug || !window.ed) {
      return;
    }
    if (endebug.textContent !== getVersionString()) {
      endebug.textContent = getVersionString();
    }
    if (ed.inEditMode()) {
      goog.dom.classlist.add(endebug, "editmode");
    } else {
      goog.dom.classlist.remove(endebug, "editmode");
    }
    if (ed.isFocused()) {
      goog.dom.classlist.add(endebug, "focused");
    } else {
      goog.dom.classlist.remove(endebug, "focused");
    }
  }
  function showDebugDirty() {
    var endebug = document.querySelector("en-debug");
    if (endebug && window.ed) {
      if (ed.dirty) {
        goog.dom.classlist.add(endebug, "dirty");
      } else {
        goog.dom.classlist.remove(endebug, "dirty");
      }
      if (endebug.textContent !== getVersionString()) {
        endebug.textContent = getVersionString();
      }
    }
  }
  uno.api.celogger.wrap(EN);
  (function() {
    var setup = EN.setup;
    EN.setup = function(opt) {
      if (purgeLogsOnSetup) {
        consoleLogger.clear();
      }
      return setup(opt);
    };
  })();
  window.enLoadState = "didLoad";
  goog.events.listenOnce(document, "DOMContentLoaded", function(e) {
    EN.notification("ready");
  });
})();

