/* Minification failed. Returning unminified contents.
(5181,18-19): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: i
(5181,45-46): run-time error JS1294: Strict-mode does not allow ++ or -- on certain objects: i
 */
(function ($, Cobalt, undefined) {
    'use strict';

    Cobalt.Throttle = {
        isInit: false,
        initialize: function() {
            if (!Cobalt.Throttle.isInit) {
                Cobalt.Throttle.isInit = true;
                window.throttle = throttleFunc;
            } else {
                console.debug('Cobalt.Throttle is being initialized again.')
            }
            return false;
        }
    }

})(jQuery, Cobalt);



function throttleFunc(fn, threshold, scope) {
    threshold || (threshold = 250);
    var last,
        deferTimer;
    return function () {
        var context = scope || this;

        var now = +new Date,
            args = arguments;
        if (last && now < last + threshold) {
            clearTimeout(deferTimer);
            deferTimer = setTimeout(function () {
                last = now;
                fn.apply(context, args);
            }, threshold + last - now);
        } else {
            last = now;
            fn.apply(context, args);
        }
    };
}
;
(function (global) {
    'use strict';

    var scripts = document.getElementsByTagName('script');
    var path = '';

    for (var s in scripts) {
        if (!scripts.hasOwnProperty(s) || isNaN(parseInt(s))) {
            continue;
        }

        var script = scripts[s];
        var matches = script.src.match(/(?:tt\.js|curse(?:\.|)tip\.js)(?:(?:\?|)(.*))/i);

        if (matches && matches.length) {
            path = script.src;

            var args = matches[1].split(/\&/);

            for (var i in args) {
                if (args.hasOwnProperty(i)) {
                    var arg = args[i].split(/=/);

                    if (arg[0] = 'var' && arg[1]) {
                        window[arg[1]] = this;
                    }
                }
            }

            break;
        }
    }

    var px = function (num) {
        return num + 'px';
    };

    var Position = function (_x, _y) {
        this.x = _x || 0;
        this.y = _y || 0;
    };

    var CurseTip = function () {
        CurseTip.prototype.initialize.apply(this, arguments);
    };

    CurseTip.Ready = false;

    CurseTip.bindEvent = function (element, _event, handler) {
        var _this = this;

        if (_event === 'load') {
            var _handler = handler;

            if (element.addEventListener) {
                _event = 'DOMContentLoaded';

                handler = function () {
                    _handler.call(_this);
                    _this.Ready = true;
                };
            } else if (element.attachEvent) {
                _event = 'onreadystatechange';
                element = document;

                handler = function () {
                    if (document.readyState === 'complete' && !_this.Ready) {
                        _handler.call(_this);
                        _this.Ready = true;
                    }
                };
            } else {
                _event = 'onload';

                handler = function () {
                    _handler.call(_this);
                    _this.Ready = true;
                };
            }
        } else if (!element.addEventListener && !element.attachEvent) {
            _event = 'on' + _event;
        }

        if (element.addEventListener) {
            element.addEventListener(_event, function (event) { handler.call(_this, event); });
        } else if (element.attachEvent) {
            element.attachEvent(_event, function (event) { handler.call(_this, event); });
        } else {
            element[_event] = function (event) { handler.call(_this, event); };
        }

        return this;
    };

    CurseTip.unbindEvent = function (element, _event, handler) {
        var _this = this,
            eventHandler;

        if (_event === 'load') {
            var _handler = handler;

            if (element.removeEventListener) {
                _event = 'DOMContentLoaded';

                handler = function () {
                    _handler.call(_this);
                    _this.Ready = true;
                };
            } else if (element.detachEvent) {
                _event = 'onreadystatechange';
                element = document;

                handler = function () {
                    if (document.readyState === 'complete' && !_this.Ready) {
                        _handler.call(_this);
                        _this.Ready = true;
                    }
                };
            } else {
                _event = 'onload';

                handler = function () {
                    _handler.call(_this);
                    _this.Ready = true;
                }
            }
        } else if (!element.removeEventListener && !element.detachEvent) {
            _event = 'on' + _event;
        }

        if (element.removeEventListener) {
            element.removeEventListener(_event, function (event) { handler.call(_this, event); });
        } else if (element.detachEvent) {
            element.detachEvent(_event, function (event) { handler.call(_this, event); });
        } else {
            element[_event] = null;
        }

        return this;
    };

    CurseTip.prototype = {
        Path: path,
        Cache: {},
        Options: {
            AdvancedTooltips: false,
            HashAliases: {},
            LoadingText: 'Loading&hellip;',
            Namespace: 'db-tooltip',
            Offset: new Position(10, 10),
            Paths: [],
            ExtraRegexes: [],
            Url: null,
            WatchComplete: null
        },
        MousePosition: new Position(0, 0),
        EventHandler: null,
        CurrentElement: null,
        CurrentTitle: null,
        Timeout: null,
        LastPosition: new Position(),
        FirstParty: false,
        RegEx: null,
        MouseOverDocument: false,

        Disabled: false,
        IsDocumentTouchListenerEnabled: false,

        initialize: function () {
            var _this = this;
            // Handle Args
            switch (arguments.length) {
                case 0:
                    return false;
                    break;
                case 1:
                    if (typeof arguments[0] === 'object') {
                        this.setOptions(arguments[0]);
                    } else {
                        this.setOptions({ Url: arguments[0] });
                    }
                    break;
                case 2:
                    this.setOptions({ Url: arguments[0], Namespace: arguments[1] });
                    break;
            }

            if (this.Options.Url === undefined) {
                return false;
            }

            // Determine Event Handler (If Any)
            if (window.addEventListener) {
                this.EventHandler = 'addEventListener';
            }

            var re = /^(?:.*\/\/)?((.*)\.(com|net|org|local|dev))$/;

            // Check if this is our site or not (extra checks to do when binding hovers if so)
            try {
                this.FirstParty = (this.Options.Url.match(re)[2] === document.location.host.match(re)[2]);
            } catch (e) { }

            if (!this.FirstParty) {
                var css = document.createElement('link');

                css.type = 'text/css';
                css.rel = 'stylesheet';
                css.href = this.Path.substr(0, this.Path.indexOf('/js/')) + '/content/syndication/tt.css';

                document.getElementsByTagName('head')[0].appendChild(css);
            }

            var paths = this.Options.Paths;
            paths = paths.length > 0 ? paths.join('|') : '';
            paths = paths.replace(/\//, '\\/');

            // Deconstruct URL for RegExp
            //this.RegEx = new RegExp(this.Options.Url.replace(re, '$2.(?:com|net|org|local|dev)/' + (this.Options.Paths.length > 0 ? '(' + this.Options.Paths.join('|') + ')/([\\d]+(?:[\\w-]+)?)(?:\\?(simple|advanced))?(?:#(\\d+)-(\\d+))?' : '')));
            this.RegEx = new RegExp(this.Options.Url.replace(re, '$2.(?:com|net|org|local|dev)/' + (this.Options.Paths.length > 0 ? '(' + this.Options.Paths.join('|') + ')/[0-9p]+\-tooltip' : '')));

            if (!CurseTip.Ready) {
                CurseTip.bindEvent.call(this, window, 'load', this.watchElligibleElements);
            } else {
                this.watchElligibleElements();
            }

            window.CurseTips = window.CurseTips || {};

            while (window.CurseTips[this.Options.Namespace]) {
                this.Options.Namespace += '-' + new Date().getTime();
            }

            window.CurseTips[this.Options.Namespace] = this;

            try {
                Cobalt.runOnHtmlInsert(function ($parent) {
                    _this.watchElements($parent.find('a[href], *[data-tooltip-href]'));
                });
            } catch (e) { }
        },

        disable: function () {
            this.Disabled = true;
        },

        enable: function () {
            this.Disabled = false;
        },

        toggle: function () {
            this.Disabled = !this.Disabled;
        },

        setOptions: function (options) {
            var _options = {};

            for (var opt in this.Options) {
                if (this.Options.hasOwnProperty(opt)) {
                    _options[opt] = this.Options[opt];
                }
            }

            for (var opt in options) {
                if (options.hasOwnProperty(opt)) {
                    _options[opt] = options[opt];
                }
            }

            this.Options = _options;
        },

        watchElligibleElements: function () {
            this._watchElements(this.getElligibleElements());
        },

        watchElements: function (elements) {
            if (elements.nodeName && !elements.length) {
                elements = [elements];
            }

            elements = this._processElements(elements);

            if (elements.length) {
                this._watchElements(elements);
            }
        },

        _watchElements: function (elements) {
            for (var i in elements) {
                if (elements.hasOwnProperty(i)) {
                    var element = elements[i];

                    if (!element.nodeName) {
                        continue;
                    }

                    CurseTip.bindEvent.call(this, element, 'mouseover', this.createTooltip);
                    CurseTip.bindEvent.call(this, element, 'mouseout', function (event) {
                        this.handleTooltipData();
                        CurseTip.unbindEvent.call(this, event.currentTarget, 'mousemove', this.moveTooltip);
                    });

                    // Fixes for hanging tooltips
                    CurseTip.bindEvent.call(this, document, 'mouseover', function () {
                        if (!this.MouseOverDocument) {
                            this.MouseOverDocument = true;
                        }

                        return false;
                    });
                    CurseTip.bindEvent.call(this, document, 'mouseout', function () {
                        if (this.MouseOverDocument) {
                            this.handleTooltipData();
                            this.MouseOverDocument = false;
                        }

                        return;
                    });
                }
            }

            if (typeof this.Options.WatchComplete === "function") {
                this.Options.WatchComplete(elements);
            }

            if (!this.IsDocumentTouchListenerEnabled) {
                CurseTip.bindEvent.call(this, document, 'touchend', function () {
                    this.handleTooltipData();
                });

                this.IsDocumentTouchListenerEnabled = true;
            }
        },

        _getURLParams: function (url) {
            try {
                var qsa = url.split('?')[1].match(/(.*?)(#|$)/)[1].split('&');
            } catch (e) {
                return {};
            }

            var params = {};

            for (var i in url.split('?')[1].split('&')) {
                if (qsa.hasOwnProperty(i)) {
                    var tmp = qsa[i].split('=');
                    params[tmp[0]] = tmp[1];
                }
            }

            return params;
        },

        _isValidToolipHref: function (url) {
            var urlBase = url.split(/(\?|#)/)[0];
            var locationBase = document.location.href.split(/(\?|#)/)[0];

            if (urlBase === locationBase) {
                var urlParams = this._getURLParams(url);
                var locationParams = this._getURLParams(document.location.href);

                for (var i in this.Options.Arguments) {
                    if (this.Options.Arguments.hasOwnProperty(i)) {
                        var arg = this.Options.Arguments[i];

                        if (urlParams[arg] !== locationParams[arg]) {
                            return true;
                        }
                    }
                }

                return false;
            } else {
                return true;
            }
        },

        _processElements: function (elements) {
            var finalElements = [];

            for (var j in elements) {
                if (elements.hasOwnProperty(j) && !isNaN(j)) {
                    var element = elements[j],
                        href;

                    if (!element.nodeName) {
                        continue;
                    }

                    try {
                        var href = element.getAttribute('data-tooltip-href') || element.href;

                        if (!this._isValidToolipHref(href)) {
                            continue;
                        }
                    } catch (e) { }

                    if (!href) {
                        continue;
                    }

                    try {
                        if (element.getAttribute('data-disable-tip') === 'true') {
                            continue;
                        }
                    } catch (e) { }

                    if (href[0] === '/' && href[1] !== '/') {
                        href = '//' + document.location.host + href;
                    }

                    href = href.replace(/\/(#|\?|$)/, '$1').replace(/#$/, '');

                    // Search for hash aliases
                    for (var alias in this.Options.HashAliases) {
                        if (this.Options.HashAliases.hasOwnProperty(alias)) {
                            var _href = href.split('#');

                            if (!_href[1]) {
                                continue;
                            }

                            if (_href[1] === alias) {
                                _href[0] += (_href[0].search(/\?/) >= 0 ? '&' : '?') + this.Options.HashAliases[alias];
                                href = _href[0];
                                element.setAttribute('data-tooltip-href', href);
                            }
                        }
                    }

                    if (this.FirstParty) {
                        if (href.search(new RegExp(document.location.host + document.location.pathname + '$')) > -1) {
                            continue;
                        }
                    }

                    if (href.substr(0, 11) === 'javascript:' || href.length === 0 || href === '#') {
                        continue;
                    }

                    var matches = href.match(this.RegEx);

                    if (matches) {
                        if (href.substr(0, href.search(this.RegEx)).search(/\/\//) === -1) {
                            href = '//' + href;
                        }

                        element.setAttribute('data-tooltip-href', href);

                        if (matches[3]) {
                            element.setAttribute('data-tooltip-mode', matches[3]);
                        }

                        if (matches[4] && matches[5]) {
                            element.setAttribute('data-tooltip-ver1', matches[4]);
                            element.setAttribute('data-tooltip-ver2', matches[5]);
                        }

                        finalElements.push(element);
                    } else {
                        var found = false;
                        for (var reg in this.Options.ExtraRegexes) {
                            if (this.Options.ExtraRegexes.hasOwnProperty(reg)) {
                                var match = href.match(this.Options.ExtraRegexes[reg]);
                                if (!found && match) {
                                    element.setAttribute("data-tooltip-custom", "true");
                                    found = true;
                                    finalElements.push(element);
                                }
                            }
                        }
                    }

                }
            }

            return finalElements;
        },

        getElligibleElements: function () {
            var finalElements = [];

            if (document.querySelectorAll) {
                var elements = document.querySelectorAll('a[data-tooltip-href]');
            } else {
                // Warning: This is SUPER inefficient, but will only be used on SUPER outdated browsers.
                // document.querySelectorAll() is supported by the browsers/versions we support: http://caniuse.com/#search=queryselector
                var _elements = document.getElementsByTagName('body')[0].getElementsByTagName('*'),
                    elements = [];

                for (var i in _elements) {
                    if (_elements.hasOwnProperty(i)) {
                        var element = _elements[i];

                        if (element.getAttribute('data-tooltip-href')) {
                            elements.push(element);
                        }
                    }
                }
            }

            return this._processElements(elements);
        },

        createTooltip: function (event) {
            if (this.Disabled || !event.currentTarget.getAttribute('data-tooltip-href') || $(document).width() <= 640) {
                return false;
            }

            var container,
                target = event.currentTarget,
                origHref = target.getAttribute('data-tooltip-href'),
                isCustom = target.getAttribute('data-tooltip-custom'),
                href = origHref,
                parts = null,
                id = null;

            if (!isCustom) {
                href = origHref.split(/\//),
                parts = href.pop().split('-');
                id = parts[0];
            }

            var args = [],
                hash = null;

            this.MousePosition.x = event.clientX;
            this.MousePosition.y = event.clientY;

            if (!isCustom) {
                if (parts && parts.length) {
                    for (var i = 2; i < parts.length; i++) {
                        if (!parts[i]) {
                            continue;
                        }

                        switch (parts[i][0]) {
                            case '?':
                                args = parts[i].substr(1).split(/&/);
                                break;
                            case '#':
                                hash = parts[i];
                                break;
                        }
                    }
                }

                if (!id) {
                    return false;
                }

                href.push(id);
                href = href.join('/');

                if ((this.Options.AdvancedTooltips && target.getAttribute('data-tooltip-mode') !== 'simple') || target.getAttribute('data-tooltip-mode') === 'advanced') {
                    args.push('advanced=1');
                }

                args.push('callback=window.CurseTips[\'' + this.Options.Namespace + '\'].handleTooltipData');
            }

            if (container = document.getElementById('db-tooltip-container')) {
                container.innerHTML = "";
            } else {
                container = document.createElement('div');
                container.id = 'db-tooltip-container';
                document.getElementsByTagName('body')[0].appendChild(container);
            }

            container.className = this.Options.Namespace;

            if (target.getAttribute('data-tooltip-ver1') && target.getAttribute('data-tooltip-ver2')) {
                if (!isCustom) {
                    href += '/dual-tooltip/' + target.getAttribute('data-tooltip-ver1') + '/' + target.getAttribute('data-tooltip-ver2');
                }
                container.className += ' diff';
            } else {
                if (!isCustom) {
                    href += '/tooltip';
                }
            }
            if (!isCustom) {
                href += '?' + args.join('&');
                href = href.replace(/^http(s)?:/, '');
            }

            container.style.position = 'fixed';
            container.style.zIndex = 9999;
            container.style.whiteSpace = 'nowrap';

            var h3 = document.createElement('h3'),
                body = document.createElement('div'),
                tipUrl = document.createElement('div');

            h3.style.display = 'none';

            body.className = 'body';

            tipUrl.className = 'url';

            if (this.Options.ShowURL) {
                tipUrl.innerText = origHref.replace(/^http(s)?:\/\//, '');
            } else {
                tipUrl.style.display = 'none';
            }

            container.appendChild(h3);
            container.appendChild(body);
            container.appendChild(tipUrl);

            CurseTip.bindEvent.call(this, target, 'mousemove', this.moveTooltip);

            if (this.Cache[document.location.protocol + href]) {
                this.handleTooltipData(this.Cache[document.location.protocol + href]);
            } else {
                var script = document.createElement('script');
                script.src = href;
                script.setAttribute('data-tooltip-href', origHref);

                document.getElementsByTagName('head')[0].appendChild(script);
                body.innerHTML = this.Options.LoadingText;
                container.style.display = 'block';
            }
        },

        handleTooltipData: function (data) {
            var container = document.getElementById('db-tooltip-container');

            if (!container) {
                return false;
            }

            if (!data) {
                container.style.display = 'none';
                return false;
            }

            this.Cache[data.Url] = data;

            if (container.className === this.Options.Namespace + ' diff') {
                var tmp = document.createElement('div');
                tmp.innerHTML = data.Tooltip;

                var blocks = tmp.getElementsByClassName('db-tooltip');

                if (blocks.length > 2) {
                    var differ = new HTMLDiff(blocks[1], blocks[2]);
                    differ.diff();
                    data.Tooltip = tmp.innerHTML;
                }
            }
            container.getElementsByClassName('body')[0].innerHTML = data.Tooltip;
            container.style.display = 'block';

            var desc = container.getElementsByClassName('db-description');

            for (var i in desc) {
                if (desc.hasOwnProperty(i) && desc[i].style !== undefined) {
                    desc[i].style.whiteSpace = 'normal';
                }
            }

            this.moveTooltip();
        },

        moveTooltip: function (event) {
            if (event) {
                this.MousePosition.x = event.clientX;
                this.MousePosition.y = event.clientY;
            } else {
                event = { clientX: this.MousePosition.x, clientY: this.MousePosition.y };
            }

            if (!this.Options.Offset.x || !this.Options.Offset.y) {
                this.Options.Offset = new Position(10, 10);
            }

            var container = document.getElementById('db-tooltip-container'),
                height = container.offsetHeight,
                width = container.offsetWidth,
                left = event.clientX + this.Options.Offset.x,
                bottom = (window.innerHeight - event.clientY) + this.Options.Offset.y;

            if (event.clientY - height - this.Options.Offset.y < 0) {
                if (event.clientY + height + this.Options.Offset.y <= window.innerHeight) {
                    bottom -= height + (this.Options.Offset.y * 2);
                } else {
                    bottom -= (height / 2) - this.Options.Offset.y;
                }
            }

            if (window.innerWidth - event.clientX - width - this.Options.Offset.x < this.Options.Offset.x) {
                left -= width + (this.Options.Offset.x * 2);
            }

            container.style.left = px(left);
            container.style.bottom = px(bottom);
        }
    };

    CurseTip.bindEvent(window, 'load', function () { this.Ready = true; });

    global.CurseTip = CurseTip;
}(window || this));;
(function () {

    window.HTMLDiff = (function () {

        function HTMLDiff(a, b) {
            this.a = a;
            this.b = b;
        }

        HTMLDiff.prototype.diff = function () {
            var diff;
            diff = this.diff_list(this.tokenize(this.a), this.tokenize(this.b));
            this.update(this.a, diff.filter(function (_arg) {
                var status, text;
                status = _arg[0], text = _arg[1];
                return status !== '+';
            }));
            return this.update(this.b, diff.filter(function (_arg) {
                var status, text;
                status = _arg[0], text = _arg[1];
                return status !== '-';
            }));
        };

        HTMLDiff.prototype.parseTextNodes = function (node, callback) {
            var handleNode;
            handleNode = function (node) {
                if (node == null) { return false; }
                var n, new_node, new_nodes, old_node, _i, _j, _len, _len2, _ref;
                if (node.nodeType === 3) {
                    if (!/^\s*$/.test(node.nodeValue)) return callback(node);
                } else {
                    _ref = (function () {
                        var _j, _len, _ref, _results;
                        _ref = node.childNodes;
                        _results = [];
                        for (_j = 0, _len = _ref.length; _j < _len; _j++) {
                            n = _ref[_j];
                            _results.push(n);
                        }
                        return _results;
                    })();
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        old_node = _ref[_i];
                        new_nodes = handleNode(old_node);
                        if (new_nodes) {
                            for (_j = 0, _len2 = new_nodes.length; _j < _len2; _j++) {
                                new_node = new_nodes[_j];
                                node.insertBefore(new_node, old_node);
                            }
                            node.removeChild(old_node);
                        }
                    }
                    return false;
                }
            };
            return handleNode(node);
        };

        HTMLDiff.prototype.tokenize = function (root) {
            var tokens;
            tokens = [];
            this.parseTextNodes(root, function (node) {
                tokens = tokens.concat(node.nodeValue.split(' '));
                return false;
            });
            return tokens;
        };

        HTMLDiff.prototype.update = function (root, diff) {
            var pos;
            pos = 0;
            return this.parseTextNodes(root, function (node) {
                var end, ins_node, new_node, new_nodes, output, part, start, status, text, _i, _len, _ref;
                start = pos;
                end = pos + (node.nodeValue.split(' ')).length;
                pos = end;
                output = (function () {
                    var _i, _len, _ref, _ref2, _results;
                    _ref = diff.slice(start, end);
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                        _ref2 = _ref[_i], status = _ref2[0], text = _ref2[1];
                        if (status === '=') {
                            _results.push(text);
                        } else {
                            _results.push('<ins>' + text + '</ins>');
                        }
                    }
                    return _results;
                })();
                output = output.join(' ').replace(/<\/ins> <ins>/g, ' ').replace(/<ins> /g, ' <ins>').replace(/[ ]<\/ins>/g, '</ins> ').replace(/<ins><\/ins>/g, '');
                new_nodes = [];
                new_node = document.createTextNode("");
                new_nodes.push(new_node);
                _ref = output.split(/(<\/?ins>)/);
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                    part = _ref[_i];
                    switch (part) {
                        case '<ins>':
                            ins_node = document.createElement('ins');
                            new_nodes.push(ins_node);
                            new_node = document.createTextNode("");
                            ins_node.appendChild(new_node);
                            break;
                        case '</ins>':
                            new_node = document.createTextNode("");
                            new_nodes.push(new_node);
                            break;
                        default:
                            new_node.nodeValue = part;
                    }
                }
                return new_nodes.filter(function (node) {
                    return !(node.nodeType === 3 && node.nodeValue === '');
                });
            });
        };

        HTMLDiff.prototype.diff_list = function (before, after) {
            var i, j, k, lastRow, ohash, subLength, subStartAfter, subStartBefore, thisRow, val, _i, _len, _len2, _len3, _ref, _ref2;
            ohash = {};
            for (i = 0, _len = before.length; i < _len; i++) {
                val = before[i];
                if (!(val in ohash)) ohash[val] = [];
                ohash[val].push(i);
            }
            lastRow = (function () {
                var _ref, _results;
                _results = [];
                for (i = 0, _ref = before.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
                    _results.push(0);
                }
                return _results;
            })();
            subStartBefore = subStartAfter = subLength = 0;
            for (j = 0, _len2 = after.length; j < _len2; j++) {
                val = after[j];
                thisRow = (function () {
                    var _ref, _results;
                    _results = [];
                    for (i = 0, _ref = before.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
                        _results.push(0);
                    }
                    return _results;
                })();
                _ref2 = (_ref = ohash[val]) != null ? _ref : [];
                for (_i = 0, _len3 = _ref2.length; _i < _len3; _i++) {
                    k = _ref2[_i];
                    thisRow[k] = (k && lastRow[k - 1] ? 1 : 0) + 1;
                    if (thisRow[k] > subLength) {
                        subLength = thisRow[k];
                        subStartBefore = k - subLength + 1;
                        subStartAfter = j - subLength + 1;
                    }
                }
                lastRow = thisRow;
            }
            if (subLength === 0) {
                return [].concat((function () {
                    var _j, _len4, _results;
                    _results = [];
                    for (_j = 0, _len4 = before.length; _j < _len4; _j++) {
                        val = before[_j];
                        _results.push(['-', val]);
                    }
                    return _results;
                })(), (function () {
                    var _j, _len4, _results;
                    _results = [];
                    for (_j = 0, _len4 = after.length; _j < _len4; _j++) {
                        val = after[_j];
                        _results.push(['+', val]);
                    }
                    return _results;
                })());
            } else {
                return [].concat(this.diff_list(before.slice(0, subStartBefore), after.slice(0, subStartAfter)), (function () {
                    var _j, _len4, _ref3, _results;
                    _ref3 = after.slice(subStartAfter, (subStartAfter + subLength));
                    _results = [];
                    for (_j = 0, _len4 = _ref3.length; _j < _len4; _j++) {
                        val = _ref3[_j];
                        _results.push(['=', val]);
                    }
                    return _results;
                })(), this.diff_list(before.slice(subStartBefore + subLength), after.slice(subStartAfter + subLength)));
            }
        };

        return HTMLDiff;

    })();

}).call(this);;
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vex = f()}})(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){
/*
 * classList.js: Cross-browser full element.classList implementation.
 * 2014-07-23
 *
 * By Eli Grey, http://eligrey.com
 * Public Domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */

/*global self, document, DOMException */

/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/

/* Copied from MDN:
 * https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
 */

if ("document" in window.self) {

  // Full polyfill for browsers with no classList support
  // Including IE < Edge missing SVGElement.classList
  if (!("classList" in document.createElement("_"))
    || document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg","g"))) {

  (function (view) {

    "use strict";

    if (!('Element' in view)) return;

    var
        classListProp = "classList"
      , protoProp = "prototype"
      , elemCtrProto = view.Element[protoProp]
      , objCtr = Object
      , strTrim = String[protoProp].trim || function () {
        return this.replace(/^\s+|\s+$/g, "");
      }
      , arrIndexOf = Array[protoProp].indexOf || function (item) {
        var
            i = 0
          , len = this.length
        ;
        for (; i < len; i++) {
          if (i in this && this[i] === item) {
            return i;
          }
        }
        return -1;
      }
      // Vendors: please allow content code to instantiate DOMExceptions
      , DOMEx = function (type, message) {
        this.name = type;
        this.code = DOMException[type];
        this.message = message;
      }
      , checkTokenAndGetIndex = function (classList, token) {
        if (token === "") {
          throw new DOMEx(
              "SYNTAX_ERR"
            , "An invalid or illegal string was specified"
          );
        }
        if (/\s/.test(token)) {
          throw new DOMEx(
              "INVALID_CHARACTER_ERR"
            , "String contains an invalid character"
          );
        }
        return arrIndexOf.call(classList, token);
      }
      , ClassList = function (elem) {
        var
            trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
          , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
          , i = 0
          , len = classes.length
        ;
        for (; i < len; i++) {
          this.push(classes[i]);
        }
        this._updateClassName = function () {
          elem.setAttribute("class", this.toString());
        };
      }
      , classListProto = ClassList[protoProp] = []
      , classListGetter = function () {
        return new ClassList(this);
      }
    ;
    // Most DOMException implementations don't allow calling DOMException's toString()
    // on non-DOMExceptions. Error's toString() is sufficient here.
    DOMEx[protoProp] = Error[protoProp];
    classListProto.item = function (i) {
      return this[i] || null;
    };
    classListProto.contains = function (token) {
      token += "";
      return checkTokenAndGetIndex(this, token) !== -1;
    };
    classListProto.add = function () {
      var
          tokens = arguments
        , i = 0
        , l = tokens.length
        , token
        , updated = false
      ;
      do {
        token = tokens[i] + "";
        if (checkTokenAndGetIndex(this, token) === -1) {
          this.push(token);
          updated = true;
        }
      }
      while (++i < l);

      if (updated) {
        this._updateClassName();
      }
    };
    classListProto.remove = function () {
      var
          tokens = arguments
        , i = 0
        , l = tokens.length
        , token
        , updated = false
        , index
      ;
      do {
        token = tokens[i] + "";
        index = checkTokenAndGetIndex(this, token);
        while (index !== -1) {
          this.splice(index, 1);
          updated = true;
          index = checkTokenAndGetIndex(this, token);
        }
      }
      while (++i < l);

      if (updated) {
        this._updateClassName();
      }
    };
    classListProto.toggle = function (token, force) {
      token += "";

      var
          result = this.contains(token)
        , method = result ?
          force !== true && "remove"
        :
          force !== false && "add"
      ;

      if (method) {
        this[method](token);
      }

      if (force === true || force === false) {
        return force;
      } else {
        return !result;
      }
    };
    classListProto.toString = function () {
      return this.join(" ");
    };

    if (objCtr.defineProperty) {
      var classListPropDesc = {
          get: classListGetter
        , enumerable: true
        , configurable: true
      };
      try {
        objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
      } catch (ex) { // IE 8 doesn't support enumerable:true
        if (ex.number === -0x7FF5EC54) {
          classListPropDesc.enumerable = false;
          objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
        }
      }
    } else if (objCtr[protoProp].__defineGetter__) {
      elemCtrProto.__defineGetter__(classListProp, classListGetter);
    }

    }(window.self));

    } else {
    // There is full or partial native classList support, so just check if we need
    // to normalize the add/remove and toggle APIs.

    (function () {
      "use strict";

      var testElement = document.createElement("_");

      testElement.classList.add("c1", "c2");

      // Polyfill for IE 10/11 and Firefox <26, where classList.add and
      // classList.remove exist but support only one argument at a time.
      if (!testElement.classList.contains("c2")) {
        var createMethod = function(method) {
          var original = DOMTokenList.prototype[method];

          DOMTokenList.prototype[method] = function(token) {
            var i, len = arguments.length;

            for (i = 0; i < len; i++) {
              token = arguments[i];
              original.call(this, token);
            }
          };
        };
        createMethod('add');
        createMethod('remove');
      }

      testElement.classList.toggle("c3", false);

      // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
      // support the second argument.
      if (testElement.classList.contains("c3")) {
        var _toggle = DOMTokenList.prototype.toggle;

        DOMTokenList.prototype.toggle = function(token, force) {
          if (1 in arguments && !this.contains(token) === !force) {
            return force;
          } else {
            return _toggle.call(this, token);
          }
        };

      }

      testElement = null;
    }());
  }
}

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

/**
 * Expose `parse`.
 */

module.exports = parse;

/**
 * Tests for browser support.
 */

var innerHTMLBug = false;
var bugTestDiv;
if (typeof document !== 'undefined') {
  bugTestDiv = document.createElement('div');
  // Setup
  bugTestDiv.innerHTML = '  <link/><table></table><a href="/a">a</a><input type="checkbox"/>';
  // Make sure that link elements get serialized correctly by innerHTML
  // This requires a wrapper element in IE
  innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
  bugTestDiv = undefined;
}

/**
 * Wrap map from jquery.
 */

var map = {
  legend: [1, '<fieldset>', '</fieldset>'],
  tr: [2, '<table><tbody>', '</tbody></table>'],
  col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
  // for script/link/style tags to work in IE6-8, you have to wrap
  // in a div with a non-whitespace character in front, ha!
  _default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
};

map.td =
map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];

map.option =
map.optgroup = [1, '<select multiple="multiple">', '</select>'];

map.thead =
map.tbody =
map.colgroup =
map.caption =
map.tfoot = [1, '<table>', '</table>'];

map.polyline =
map.ellipse =
map.polygon =
map.circle =
map.text =
map.line =
map.path =
map.rect =
map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">','</svg>'];

/**
 * Parse `html` and return a DOM Node instance, which could be a TextNode,
 * HTML DOM Node of some kind (<div> for example), or a DocumentFragment
 * instance, depending on the contents of the `html` string.
 *
 * @param {String} html - HTML string to "domify"
 * @param {Document} doc - The `document` instance to create the Node for
 * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
 * @api private
 */

function parse(html, doc) {
  if ('string' != typeof html) throw new TypeError('String expected');

  // default to the global `document` object
  if (!doc) doc = document;

  // tag name
  var m = /<([\w:]+)/.exec(html);
  if (!m) return doc.createTextNode(html);

  html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace

  var tag = m[1];

  // body support
  if (tag == 'body') {
    var el = doc.createElement('html');
    el.innerHTML = html;
    return el.removeChild(el.lastChild);
  }

  // wrap map
  var wrap = map[tag] || map._default;
  var depth = wrap[0];
  var prefix = wrap[1];
  var suffix = wrap[2];
  var el = doc.createElement('div');
  el.innerHTML = prefix + html + suffix;
  while (depth--) el = el.lastChild;

  // one element
  if (el.firstChild == el.lastChild) {
    return el.removeChild(el.firstChild);
  }

  // several elements
  var fragment = doc.createDocumentFragment();
  while (el.firstChild) {
    fragment.appendChild(el.removeChild(el.firstChild));
  }

  return fragment;
}

},{}],3:[function(require,module,exports){
/**
 * Code refactored from Mozilla Developer Network:
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
 */

'use strict';

function assign(target, firstSource) {
  if (target === undefined || target === null) {
    throw new TypeError('Cannot convert first argument to object');
  }

  var to = Object(target);
  for (var i = 1; i < arguments.length; i++) {
    var nextSource = arguments[i];
    if (nextSource === undefined || nextSource === null) {
      continue;
    }

    var keysArray = Object.keys(Object(nextSource));
    for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
      var nextKey = keysArray[nextIndex];
      var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
      if (desc !== undefined && desc.enumerable) {
        to[nextKey] = nextSource[nextKey];
      }
    }
  }
  return to;
}

function polyfill() {
  if (!Object.assign) {
    Object.defineProperty(Object, 'assign', {
      enumerable: false,
      configurable: true,
      writable: true,
      value: assign
    });
  }
}

module.exports = {
  assign: assign,
  polyfill: polyfill
};

},{}],4:[function(require,module,exports){
// get successful control from form and assemble into object
// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

// types which indicate a submit action and are not successful controls
// these will be ignored
var k_r_submitter = /^(?:submit|button|image|reset|file)$/i;

// node names which could be successful controls
var k_r_success_contrls = /^(?:input|select|textarea|keygen)/i;

// Matches bracket notation.
var brackets = /(\[[^\[\]]*\])/g;

// serializes form fields
// @param form MUST be an HTMLForm element
// @param options is an optional argument to configure the serialization. Default output
// with no options specified is a url encoded string
//    - hash: [true | false] Configure the output type. If true, the output will
//    be a js object.
//    - serializer: [function] Optional serializer function to override the default one.
//    The function takes 3 arguments (result, key, value) and should return new result
//    hash and url encoded str serializers are provided with this module
//    - disabled: [true | false]. If true serialize disabled fields.
//    - empty: [true | false]. If true serialize empty fields
function serialize(form, options) {
    if (typeof options != 'object') {
        options = { hash: !!options };
    }
    else if (options.hash === undefined) {
        options.hash = true;
    }

    var result = (options.hash) ? {} : '';
    var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize);

    var elements = form && form.elements ? form.elements : [];

    //Object store each radio and set if it's empty or not
    var radio_store = Object.create(null);

    for (var i=0 ; i<elements.length ; ++i) {
        var element = elements[i];

        // ingore disabled fields
        if ((!options.disabled && element.disabled) || !element.name) {
            continue;
        }
        // ignore anyhting that is not considered a success field
        if (!k_r_success_contrls.test(element.nodeName) ||
            k_r_submitter.test(element.type)) {
            continue;
        }

        var key = element.name;
        var val = element.value;

        // we can't just use element.value for checkboxes cause some browsers lie to us
        // they say "on" for value when the box isn't checked
        if ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {
            val = undefined;
        }

        // If we want empty elements
        if (options.empty) {
            // for checkbox
            if (element.type === 'checkbox' && !element.checked) {
                val = '';
            }

            // for radio
            if (element.type === 'radio') {
                if (!radio_store[element.name] && !element.checked) {
                    radio_store[element.name] = false;
                }
                else if (element.checked) {
                    radio_store[element.name] = true;
                }
            }

            // if options empty is true, continue only if its radio
            if (!val && element.type == 'radio') {
                continue;
            }
        }
        else {
            // value-less fields are ignored unless options.empty is true
            if (!val) {
                continue;
            }
        }

        // multi select boxes
        if (element.type === 'select-multiple') {
            val = [];

            var selectOptions = element.options;
            var isSelectedOptions = false;
            for (var j=0 ; j<selectOptions.length ; ++j) {
                var option = selectOptions[j];
                var allowedEmpty = options.empty && !option.value;
                var hasValue = (option.value || allowedEmpty);
                if (option.selected && hasValue) {
                    isSelectedOptions = true;

                    // If using a hash serializer be sure to add the
                    // correct notation for an array in the multi-select
                    // context. Here the name attribute on the select element
                    // might be missing the trailing bracket pair. Both names
                    // "foo" and "foo[]" should be arrays.
                    if (options.hash && key.slice(key.length - 2) !== '[]') {
                        result = serializer(result, key + '[]', option.value);
                    }
                    else {
                        result = serializer(result, key, option.value);
                    }
                }
            }

            // Serialize if no selected options and options.empty is true
            if (!isSelectedOptions && options.empty) {
                result = serializer(result, key, '');
            }

            continue;
        }

        result = serializer(result, key, val);
    }

    // Check for all empty radio buttons and serialize them with key=""
    if (options.empty) {
        for (var key in radio_store) {
            if (!radio_store[key]) {
                result = serializer(result, key, '');
            }
        }
    }

    return result;
}

function parse_keys(string) {
    var keys = [];
    var prefix = /^([^\[\]]*)/;
    var children = new RegExp(brackets);
    var match = prefix.exec(string);

    if (match[1]) {
        keys.push(match[1]);
    }

    while ((match = children.exec(string)) !== null) {
        keys.push(match[1]);
    }

    return keys;
}

function hash_assign(result, keys, value) {
    if (keys.length === 0) {
        result = value;
        return result;
    }

    var key = keys.shift();
    var between = key.match(/^\[(.+?)\]$/);

    if (key === '[]') {
        result = result || [];

        if (Array.isArray(result)) {
            result.push(hash_assign(null, keys, value));
        }
        else {
            // This might be the result of bad name attributes like "[][foo]",
            // in this case the original `result` object will already be
            // assigned to an object literal. Rather than coerce the object to
            // an array, or cause an exception the attribute "_values" is
            // assigned as an array.
            result._values = result._values || [];
            result._values.push(hash_assign(null, keys, value));
        }

        return result;
    }

    // Key is an attribute name and can be assigned directly.
    if (!between) {
        result[key] = hash_assign(result[key], keys, value);
    }
    else {
        var string = between[1];
        // +var converts the variable into a number
        // better than parseInt because it doesn't truncate away trailing
        // letters and actually fails if whole thing is not a number
        var index = +string;

        // If the characters between the brackets is not a number it is an
        // attribute name and can be assigned directly.
        if (isNaN(index)) {
            result = result || {};
            result[string] = hash_assign(result[string], keys, value);
        }
        else {
            result = result || [];
            result[index] = hash_assign(result[index], keys, value);
        }
    }

    return result;
}

// Object/hash encoding serializer.
function hash_serializer(result, key, value) {
    var matches = key.match(brackets);

    // Has brackets? Use the recursive assignment function to walk the keys,
    // construct any missing objects in the result tree and make the assignment
    // at the end of the chain.
    if (matches) {
        var keys = parse_keys(key);
        hash_assign(result, keys, value);
    }
    else {
        // Non bracket notation can make assignments directly.
        var existing = result[key];

        // If the value has been assigned already (for instance when a radio and
        // a checkbox have the same name attribute) convert the previous value
        // into an array before pushing into it.
        //
        // NOTE: If this requirement were removed all hash creation and
        // assignment could go through `hash_assign`.
        if (existing) {
            if (!Array.isArray(existing)) {
                result[key] = [ existing ];
            }

            result[key].push(value);
        }
        else {
            result[key] = value;
        }
    }

    return result;
}

// urlform encoding serializer
function str_serialize(result, key, value) {
    // encode newlines as \r\n cause the html spec says so
    value = value.replace(/(\r)?\n/g, '\r\n');
    value = encodeURIComponent(value);

    // spaces should be '+' rather than '%20'.
    value = value.replace(/%20/g, '+');
    return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
}

module.exports = serialize;

},{}],5:[function(require,module,exports){
(function (global){
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vexDialog = f()}})(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){

/**
 * Expose `parse`.
 */

module.exports = parse;

/**
 * Tests for browser support.
 */

var innerHTMLBug = false;
var bugTestDiv;
if (typeof document !== 'undefined') {
  bugTestDiv = document.createElement('div');
  // Setup
  bugTestDiv.innerHTML = '  <link/><table></table><a href="/a">a</a><input type="checkbox"/>';
  // Make sure that link elements get serialized correctly by innerHTML
  // This requires a wrapper element in IE
  innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
  bugTestDiv = undefined;
}

/**
 * Wrap map from jquery.
 */

var map = {
  legend: [1, '<fieldset>', '</fieldset>'],
  tr: [2, '<table><tbody>', '</tbody></table>'],
  col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
  // for script/link/style tags to work in IE6-8, you have to wrap
  // in a div with a non-whitespace character in front, ha!
  _default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
};

map.td =
map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];

map.option =
map.optgroup = [1, '<select multiple="multiple">', '</select>'];

map.thead =
map.tbody =
map.colgroup =
map.caption =
map.tfoot = [1, '<table>', '</table>'];

map.polyline =
map.ellipse =
map.polygon =
map.circle =
map.text =
map.line =
map.path =
map.rect =
map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">','</svg>'];

/**
 * Parse `html` and return a DOM Node instance, which could be a TextNode,
 * HTML DOM Node of some kind (<div> for example), or a DocumentFragment
 * instance, depending on the contents of the `html` string.
 *
 * @param {String} html - HTML string to "domify"
 * @param {Document} doc - The `document` instance to create the Node for
 * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
 * @api private
 */

function parse(html, doc) {
  if ('string' != typeof html) throw new TypeError('String expected');

  // default to the global `document` object
  if (!doc) doc = document;

  // tag name
  var m = /<([\w:]+)/.exec(html);
  if (!m) return doc.createTextNode(html);

  html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace

  var tag = m[1];

  // body support
  if (tag == 'body') {
    var el = doc.createElement('html');
    el.innerHTML = html;
    return el.removeChild(el.lastChild);
  }

  // wrap map
  var wrap = map[tag] || map._default;
  var depth = wrap[0];
  var prefix = wrap[1];
  var suffix = wrap[2];
  var el = doc.createElement('div');
  el.innerHTML = prefix + html + suffix;
  while (depth--) el = el.lastChild;

  // one element
  if (el.firstChild == el.lastChild) {
    return el.removeChild(el.firstChild);
  }

  // several elements
  var fragment = doc.createDocumentFragment();
  while (el.firstChild) {
    fragment.appendChild(el.removeChild(el.firstChild));
  }

  return fragment;
}

},{}],2:[function(require,module,exports){
// get successful control from form and assemble into object
// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

// types which indicate a submit action and are not successful controls
// these will be ignored
var k_r_submitter = /^(?:submit|button|image|reset|file)$/i;

// node names which could be successful controls
var k_r_success_contrls = /^(?:input|select|textarea|keygen)/i;

// Matches bracket notation.
var brackets = /(\[[^\[\]]*\])/g;

// serializes form fields
// @param form MUST be an HTMLForm element
// @param options is an optional argument to configure the serialization. Default output
// with no options specified is a url encoded string
//    - hash: [true | false] Configure the output type. If true, the output will
//    be a js object.
//    - serializer: [function] Optional serializer function to override the default one.
//    The function takes 3 arguments (result, key, value) and should return new result
//    hash and url encoded str serializers are provided with this module
//    - disabled: [true | false]. If true serialize disabled fields.
//    - empty: [true | false]. If true serialize empty fields
function serialize(form, options) {
    if (typeof options != 'object') {
        options = { hash: !!options };
    }
    else if (options.hash === undefined) {
        options.hash = true;
    }

    var result = (options.hash) ? {} : '';
    var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize);

    var elements = form && form.elements ? form.elements : [];

    //Object store each radio and set if it's empty or not
    var radio_store = Object.create(null);

    for (var i=0 ; i<elements.length ; ++i) {
        var element = elements[i];

        // ingore disabled fields
        if ((!options.disabled && element.disabled) || !element.name) {
            continue;
        }
        // ignore anyhting that is not considered a success field
        if (!k_r_success_contrls.test(element.nodeName) ||
            k_r_submitter.test(element.type)) {
            continue;
        }

        var key = element.name;
        var val = element.value;

        // we can't just use element.value for checkboxes cause some browsers lie to us
        // they say "on" for value when the box isn't checked
        if ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {
            val = undefined;
        }

        // If we want empty elements
        if (options.empty) {
            // for checkbox
            if (element.type === 'checkbox' && !element.checked) {
                val = '';
            }

            // for radio
            if (element.type === 'radio') {
                if (!radio_store[element.name] && !element.checked) {
                    radio_store[element.name] = false;
                }
                else if (element.checked) {
                    radio_store[element.name] = true;
                }
            }

            // if options empty is true, continue only if its radio
            if (!val && element.type == 'radio') {
                continue;
            }
        }
        else {
            // value-less fields are ignored unless options.empty is true
            if (!val) {
                continue;
            }
        }

        // multi select boxes
        if (element.type === 'select-multiple') {
            val = [];

            var selectOptions = element.options;
            var isSelectedOptions = false;
            for (var j=0 ; j<selectOptions.length ; ++j) {
                var option = selectOptions[j];
                var allowedEmpty = options.empty && !option.value;
                var hasValue = (option.value || allowedEmpty);
                if (option.selected && hasValue) {
                    isSelectedOptions = true;

                    // If using a hash serializer be sure to add the
                    // correct notation for an array in the multi-select
                    // context. Here the name attribute on the select element
                    // might be missing the trailing bracket pair. Both names
                    // "foo" and "foo[]" should be arrays.
                    if (options.hash && key.slice(key.length - 2) !== '[]') {
                        result = serializer(result, key + '[]', option.value);
                    }
                    else {
                        result = serializer(result, key, option.value);
                    }
                }
            }

            // Serialize if no selected options and options.empty is true
            if (!isSelectedOptions && options.empty) {
                result = serializer(result, key, '');
            }

            continue;
        }

        result = serializer(result, key, val);
    }

    // Check for all empty radio buttons and serialize them with key=""
    if (options.empty) {
        for (var key in radio_store) {
            if (!radio_store[key]) {
                result = serializer(result, key, '');
            }
        }
    }

    return result;
}

function parse_keys(string) {
    var keys = [];
    var prefix = /^([^\[\]]*)/;
    var children = new RegExp(brackets);
    var match = prefix.exec(string);

    if (match[1]) {
        keys.push(match[1]);
    }

    while ((match = children.exec(string)) !== null) {
        keys.push(match[1]);
    }

    return keys;
}

function hash_assign(result, keys, value) {
    if (keys.length === 0) {
        result = value;
        return result;
    }

    var key = keys.shift();
    var between = key.match(/^\[(.+?)\]$/);

    if (key === '[]') {
        result = result || [];

        if (Array.isArray(result)) {
            result.push(hash_assign(null, keys, value));
        }
        else {
            // This might be the result of bad name attributes like "[][foo]",
            // in this case the original `result` object will already be
            // assigned to an object literal. Rather than coerce the object to
            // an array, or cause an exception the attribute "_values" is
            // assigned as an array.
            result._values = result._values || [];
            result._values.push(hash_assign(null, keys, value));
        }

        return result;
    }

    // Key is an attribute name and can be assigned directly.
    if (!between) {
        result[key] = hash_assign(result[key], keys, value);
    }
    else {
        var string = between[1];
        // +var converts the variable into a number
        // better than parseInt because it doesn't truncate away trailing
        // letters and actually fails if whole thing is not a number
        var index = +string;

        // If the characters between the brackets is not a number it is an
        // attribute name and can be assigned directly.
        if (isNaN(index)) {
            result = result || {};
            result[string] = hash_assign(result[string], keys, value);
        }
        else {
            result = result || [];
            result[index] = hash_assign(result[index], keys, value);
        }
    }

    return result;
}

// Object/hash encoding serializer.
function hash_serializer(result, key, value) {
    var matches = key.match(brackets);

    // Has brackets? Use the recursive assignment function to walk the keys,
    // construct any missing objects in the result tree and make the assignment
    // at the end of the chain.
    if (matches) {
        var keys = parse_keys(key);
        hash_assign(result, keys, value);
    }
    else {
        // Non bracket notation can make assignments directly.
        var existing = result[key];

        // If the value has been assigned already (for instance when a radio and
        // a checkbox have the same name attribute) convert the previous value
        // into an array before pushing into it.
        //
        // NOTE: If this requirement were removed all hash creation and
        // assignment could go through `hash_assign`.
        if (existing) {
            if (!Array.isArray(existing)) {
                result[key] = [ existing ];
            }

            result[key].push(value);
        }
        else {
            result[key] = value;
        }
    }

    return result;
}

// urlform encoding serializer
function str_serialize(result, key, value) {
    // encode newlines as \r\n cause the html spec says so
    value = value.replace(/(\r)?\n/g, '\r\n');
    value = encodeURIComponent(value);

    // spaces should be '+' rather than '%20'.
    value = value.replace(/%20/g, '+');
    return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
}

module.exports = serialize;

},{}],3:[function(require,module,exports){
var domify = require('domify')
var serialize = require('form-serialize')

// Build DOM elements for the structure of the dialog
var buildDialogForm = function buildDialogForm (options) {
  var form = document.createElement('form')
  form.classList.add('vex-dialog-form')

  var message = document.createElement('div')
  message.classList.add('vex-dialog-message')
  message.appendChild(options.message instanceof window.Node ? options.message : domify(options.message))

  var input = document.createElement('div')
  input.classList.add('vex-dialog-input')
  input.appendChild(options.input instanceof window.Node ? options.input : domify(options.input))

  form.appendChild(message)
  form.appendChild(input)

  return form
}

// Take an array of buttons (see the default buttons below) and turn them into DOM elements
var buttonsToDOM = function buttonsToDOM (buttons) {
  var domButtons = document.createElement('div')
  domButtons.classList.add('vex-dialog-buttons')

  for (var i = 0; i < buttons.length; i++) {
    var button = buttons[i]
    var domButton = document.createElement('button')
    domButton.type = button.type
    domButton.textContent = button.text
    domButton.classList.add(button.className)
    domButton.classList.add('vex-dialog-button')
    if (i === 0) {
      domButton.classList.add('vex-first')
    } else if (i === buttons.length - 1) {
      domButton.classList.add('vex-last')
    }
    // Attach click listener to button with closure
    (function (button) {
      domButton.addEventListener('click', function (e) {
        if (button.click) {
          button.click.call(this, e)
        }
      }.bind(this))
    }.bind(this)(button))

    domButtons.appendChild(domButton)
  }

  return domButtons
}

var plugin = function plugin (vex) {
  // Define the API first
  var dialog = {
    // Plugin name
    name: 'dialog',

    // Open
    open: function open (opts) {
      var options = Object.assign({}, this.defaultOptions, opts)

      // `message` is unsafe internally, so translate
      // safe default: HTML-escape the message before passing it through
      if (options.unsafeMessage && !options.message) {
        options.message = options.unsafeMessage
      } else if (options.message) {
        options.message = vex._escapeHtml(options.message)
      }

      // Build the form from the options
      var form = options.unsafeContent = buildDialogForm(options)

      // Open the dialog
      var dialogInstance = vex.open(options)

      // Quick comment - these options and appending buttons and everything
      // would preferably be done _before_ opening the dialog. However, since
      // they rely on the context of the vex instance, we have to do them
      // after. A potential future fix would be to differentiate between
      // a "created" vex instance and an "opened" vex instance, so any actions
      // that rely on the specific context of the instance can do their stuff
      // before opening the dialog on the page.

      // Override the before close callback to also pass the value of the form
      var beforeClose = options.beforeClose && options.beforeClose.bind(dialogInstance)
      dialogInstance.options.beforeClose = function dialogBeforeClose () {
        // Only call the callback once - when the validation in beforeClose, if present, is true
        var shouldClose = beforeClose ? beforeClose() : true
        if (shouldClose) {
          options.callback(this.value || false)
        }
        // Return the result of beforeClose() to vex
        return shouldClose
      }.bind(dialogInstance)

      // Append buttons to form with correct context
      form.appendChild(buttonsToDOM.call(dialogInstance, options.buttons))

      // Attach form to instance
      dialogInstance.form = form

      // Add submit listener to form
      form.addEventListener('submit', options.onSubmit.bind(dialogInstance))

      // Optionally focus the first input in the form
      if (options.focusFirstInput) {
        var el = dialogInstance.contentEl.querySelector('button, input, textarea')
        if (el) {
          el.focus()
        }
      }

      // For chaining
      return dialogInstance
    },

    // Alert
    alert: function (options) {
      // Allow string as message
      if (typeof options === 'string') {
        options = {
          message: options
        }
      }
      options = Object.assign({}, this.defaultOptions, this.defaultAlertOptions, options)
      return this.open(options)
    },

    // Confirm
    confirm: function (options) {
      if (typeof options !== 'object' || typeof options.callback !== 'function') {
        throw new Error('dialog.confirm(options) requires options.callback.')
      }
      options = Object.assign({}, this.defaultOptions, this.defaultConfirmOptions, options)
      return this.open(options)
    },

    // Prompt
    prompt: function (options) {
      if (typeof options !== 'object' || typeof options.callback !== 'function') {
        throw new Error('dialog.prompt(options) requires options.callback.')
      }
      var defaults = Object.assign({}, this.defaultOptions, this.defaultPromptOptions)
      var dynamicDefaults = {
        unsafeMessage: '<label for="vex">' + vex._escapeHtml(options.label || defaults.label) + '</label>',
        input: '<input name="vex" type="text" class="vex-dialog-prompt-input" placeholder="' + vex._escapeHtml(options.placeholder || defaults.placeholder) + '" value="' + vex._escapeHtml(options.value || defaults.value) + '" />'
      }
      options = Object.assign(defaults, dynamicDefaults, options)
      // Pluck the value of the "vex" input field as the return value for prompt's callback
      // More closely mimics "window.prompt" in that a single string is returned
      var callback = options.callback
      options.callback = function promptCallback (value) {
        value = value[Object.keys(value)[0]]
        callback(value)
      }
      return this.open(options)
    }
  }

  // Now define any additional data that's not the direct dialog API
  dialog.buttons = {
    YES: {
      text: 'OK',
      type: 'submit',
      className: 'vex-dialog-button-primary',
      click: function yesClick () {
        this.value = true
      }
    },

    NO: {
      text: 'Cancel',
      type: 'button',
      className: 'vex-dialog-button-secondary',
      click: function noClick () {
        this.value = false
        this.close()
      }
    }
  }

  dialog.defaultOptions = {
    callback: function () {},
    afterOpen: function () {},
    message: '',
    input: '',
    buttons: [
      dialog.buttons.YES,
      dialog.buttons.NO
    ],
    showCloseButton: false,
    onSubmit: function onDialogSubmit (e) {
      e.preventDefault()
      if (this.options.input) {
        this.value = serialize(this.form, { hash: true })
      }
      return this.close()
    },
    focusFirstInput: true
  }

  dialog.defaultAlertOptions = {
    buttons: [
      dialog.buttons.YES
    ]
  }

  dialog.defaultPromptOptions = {
    label: 'Prompt:',
    placeholder: '',
    value: ''
  }

  dialog.defaultConfirmOptions = {}

  return dialog
}

module.exports = plugin

},{"domify":1,"form-serialize":2}]},{},[3])(3)
});
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"domify":2,"form-serialize":4}],6:[function(require,module,exports){
var vex = require('./vex')
vex.registerPlugin(require('vex-dialog'))
module.exports = vex

},{"./vex":7,"vex-dialog":5}],7:[function(require,module,exports){
// classList polyfill for old browsers
require('classlist-polyfill')
// Object.assign polyfill
require('es6-object-assign').polyfill()

// String to DOM function
var domify = require('domify')

// Use the DOM's HTML parsing to escape any dangerous strings
var escapeHtml = function escapeHtml (str) {
  if (typeof str !== 'undefined') {
    var div = document.createElement('div')
    div.appendChild(document.createTextNode(str))
    return div.innerHTML
  } else {
    return ''
  }
}

// Utility function to add space-delimited class strings to a DOM element's classList
var addClasses = function addClasses (el, classStr) {
  if (typeof classStr !== 'string' || classStr.length === 0) {
    return
  }
  var classes = classStr.split(' ')
  for (var i = 0; i < classes.length; i++) {
    var className = classes[i]
    if (className.length) {
      el.classList.add(className)
    }
  }
}

// Detect CSS Animation End Support
// https://github.com/limonte/sweetalert2/blob/99bd539f85e15ac170f69d35001d12e092ef0054/src/utils/dom.js#L194
var animationEndEvent = (function detectAnimationEndEvent () {
  var el = document.createElement('div')
  var eventNames = {
    'WebkitAnimation': 'webkitAnimationEnd',
    'MozAnimation': 'animationend',
    'OAnimation': 'oanimationend',
    'msAnimation': 'MSAnimationEnd',
    'animation': 'animationend'
  }
  for (var i in eventNames) {
    if (el.style[i] !== undefined) {
      return eventNames[i]
    }
  }
  return false
})()

// vex base CSS classes
var baseClassNames = {
  vex: 'vex',
  content: 'vex-content',
  overlay: 'vex-overlay',
  close: 'vex-close',
  closing: 'vex-closing',
  open: 'vex-open'
}

// Private lookup table of all open vex objects, keyed by id
var vexes = {}
var globalId = 1

// Private boolean to assist the escapeButtonCloses option
var isEscapeActive = false

// vex itself is an object that exposes a simple API to open and close vex objects in various ways
var vex = {
  open: function open (opts) {
    // Check for usage of deprecated options, and log a warning
    var warnDeprecated = function warnDeprecated (prop) {
      console.warn('The "' + prop + '" property is deprecated in vex 3. Use CSS classes and the appropriate "ClassName" options, instead.')
      console.warn('See http://github.hubspot.com/vex/api/advanced/#options')
    }
    if (opts.css) {
      warnDeprecated('css')
    }
    if (opts.overlayCSS) {
      warnDeprecated('overlayCSS')
    }
    if (opts.contentCSS) {
      warnDeprecated('contentCSS')
    }
    if (opts.closeCSS) {
      warnDeprecated('closeCSS')
    }

    // The dialog instance
    var vexInstance = {}

    // Set id
    vexInstance.id = globalId++

    // Store internally
    vexes[vexInstance.id] = vexInstance

    // Set state
    vexInstance.isOpen = true

    // Close function on the vex instance
    // This is how all API functions should close individual vexes
    vexInstance.close = function instanceClose () {
      // Check state
      if (!this.isOpen) {
        return true
      }

      var options = this.options

      // escapeButtonCloses is checked first
      if (isEscapeActive && !options.escapeButtonCloses) {
        return false
      }

      // Allow the user to validate any info or abort the close with the beforeClose callback
      var shouldClose = (function shouldClose () {
        // Call before close callback
        if (options.beforeClose) {
          return options.beforeClose.call(this)
        }
        // Otherwise indicate that it's ok to continue with close
        return true
      }.bind(this)())

      // If beforeClose() fails, abort the close
      if (shouldClose === false) {
        return false
      }

      // Update state
      this.isOpen = false

      // Detect if the content el has any CSS animations defined
      var style = window.getComputedStyle(this.contentEl)
      function hasAnimationPre (prefix) {
        return style.getPropertyValue(prefix + 'animation-name') !== 'none' && style.getPropertyValue(prefix + 'animation-duration') !== '0s'
      }
      var hasAnimation = hasAnimationPre('') || hasAnimationPre('-webkit-') || hasAnimationPre('-moz-') || hasAnimationPre('-o-')

      // Define the function that will actually close the instance
      var close = function close () {
        if (!this.rootEl.parentNode) {
          return
        }
        // Run once
        this.rootEl.removeEventListener(animationEndEvent, close)
        // Remove from lookup table (prevent memory leaks)
        delete vexes[this.id]
        // Remove the dialog from the DOM
        this.rootEl.parentNode.removeChild(this.rootEl)
        // Call after close callback
        if (options.afterClose) {
          options.afterClose.call(this)
        }
        // Remove styling from the body, if no more vexes are open
        if (Object.keys(vexes).length === 0) {
          document.body.classList.remove(baseClassNames.open)
        }
      }.bind(this)

      // Close the vex
      if (animationEndEvent && hasAnimation) {
        // Setup the end event listener, to remove the el from the DOM
        this.rootEl.addEventListener(animationEndEvent, close)
        // Add the closing class to the dialog, showing the close animation
        this.rootEl.classList.add(baseClassNames.closing)
      } else {
        close()
      }

      return true
    }

    // Allow strings as content
    if (typeof opts === 'string') {
      opts = {
        content: opts
      }
    }

    // `content` is unsafe internally, so translate
    // safe default: HTML-escape the content before passing it through
    if (opts.unsafeContent && !opts.content) {
      opts.content = opts.unsafeContent
    } else if (opts.content) {
      opts.content = escapeHtml(opts.content)
    }

    // Store options on instance for future reference
    var options = vexInstance.options = Object.assign({}, vex.defaultOptions, opts)

    // vex root
    var rootEl = vexInstance.rootEl = document.createElement('div')
    rootEl.classList.add(baseClassNames.vex)
    addClasses(rootEl, options.className)

    // Overlay
    var overlayEl = vexInstance.overlayEl = document.createElement('div')
    overlayEl.classList.add(baseClassNames.overlay)
    addClasses(overlayEl, options.overlayClassName)
    if (options.overlayClosesOnClick) {
      overlayEl.addEventListener('click', function overlayClickListener (e) {
        if (e.target === overlayEl) {
          vexInstance.close()
        }
      })
    }
    rootEl.appendChild(overlayEl)

    // Content
    var contentEl = vexInstance.contentEl = document.createElement('div')
    contentEl.classList.add(baseClassNames.content)
    addClasses(contentEl, options.contentClassName)
    contentEl.appendChild(options.content instanceof window.Node ? options.content : domify(options.content))
    rootEl.appendChild(contentEl)

    // Close button
    if (options.showCloseButton) {
      var closeEl = vexInstance.closeEl = document.createElement('div')
      closeEl.classList.add(baseClassNames.close)
      addClasses(closeEl, options.closeClassName)
      closeEl.addEventListener('click', vexInstance.close.bind(vexInstance))
      contentEl.appendChild(closeEl)
    }

    // Add to DOM
    document.querySelector(options.appendLocation).appendChild(rootEl)

    // Call after open callback
    if (options.afterOpen) {
      options.afterOpen.call(vexInstance)
    }

    // Apply styling to the body
    document.body.classList.add(baseClassNames.open)

    // Return the created vex instance
    return vexInstance
  },

  // A top-level vex.close function to close dialogs by reference or id
  close: function close (vexOrId) {
    var id
    if (vexOrId.id) {
      id = vexOrId.id
    } else if (typeof vexOrId === 'string') {
      id = vexOrId
    } else {
      throw new TypeError('close requires a vex object or id string')
    }
    if (!vexes[id]) {
      return false
    }
    return vexes[id].close()
  },

  // Close the most recently created/opened vex
  closeTop: function closeTop () {
    var ids = Object.keys(vexes)
    if (!ids.length) {
      return false
    }
    return vexes[ids[ids.length - 1]].close()
  },

  // Close every vex!
  closeAll: function closeAll () {
    for (var id in vexes) {
      this.close(id)
    }
    return true
  },

  // A getter for the internal lookup table
  getAll: function getAll () {
    return vexes
  },

  // A getter for the internal lookup table
  getById: function getById (id) {
    return vexes[id]
  }
}

// Close top vex on escape
window.addEventListener('keyup', function vexKeyupListener (e) {
  if (e.keyCode === 27) {
    isEscapeActive = true
    vex.closeTop()
    isEscapeActive = false
  }
})
// Close all vexes on history pop state (useful in single page apps)
window.addEventListener('popstate', vex.closeAll)

vex.defaultOptions = {
  content: '',
  showCloseButton: true,
  escapeButtonCloses: true,
  overlayClosesOnClick: true,
  appendLocation: 'body',
  className: '',
  overlayClassName: '',
  contentClassName: '',
  closeClassName: ''
}

// TODO Loading symbols?

// Include escapeHtml function on the library object
Object.defineProperty(vex, '_escapeHtml', {
  configurable: false,
  enumerable: false,
  writable: false,
  value: escapeHtml
})

// Plugin system!
vex.registerPlugin = function registerPlugin (pluginFn, name) {
  var plugin = pluginFn(vex)
  var pluginName = name || plugin.name
  if (vex[pluginName]) {
    throw new Error('Plugin ' + name + ' is already registered.')
  }
  vex[pluginName] = plugin
}

module.exports = vex

},{"classlist-polyfill":1,"domify":2,"es6-object-assign":3}]},{},[6])(6)
});;
/**
 shave - Shave is a javascript plugin that truncates multi-line text within a html element based on set max height
 @version v2.5.9
 @link https://github.com/yowainwright/shave#readme
 @author Jeff Wainwright <yowainwright@gmail.com> (jeffry.in)
 @license MIT
 **/
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
            (global = global || self, global.shave = factory());
}(this, (function () { 'use strict';

    function shave(target, maxHeight) {
        var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        if (typeof maxHeight === 'undefined' || isNaN(maxHeight)) throw Error('maxHeight is required');
        var els = typeof target === 'string' ? document.querySelectorAll(target) : target;
        if (!els) return;
        var character = opts.character || '&mldr;';
        var classname = opts.classname || 'js-shave';
        var spaces = typeof opts.spaces === 'boolean' ? opts.spaces : true;
        var charHtml = "<span class=\"js-shave-char\">".concat(character, "</span>");
        if (!('length' in els)) els = [els];

        for (var i = 0; i < els.length; i += 1) {
            var el = els[i];
            var styles = el.style;
            var span = el.querySelector(".".concat(classname));
            var textProp = el.textContent === undefined ? 'innerText' : 'textContent'; // If element text has already been shaved

            if (span) {
                // Remove the ellipsis to recapture the original text
                el.removeChild(el.querySelector('.js-shave-char'));
                el[textProp] = el[textProp]; // eslint-disable-line
                // nuke span, recombine text
            }

            var fullText = el[textProp];
            var words = spaces ? fullText.split(' ') : fullText; // If 0 or 1 words, we're done

            if (words.length < 2) continue; // Temporarily remove any CSS height for text height calculation

            var heightStyle = styles.height;
            styles.height = 'auto';
            var maxHeightStyle = styles.maxHeight;
            styles.maxHeight = 'none'; // If already short enough, we're done

            if (el.offsetHeight <= maxHeight) {
                styles.height = heightStyle;
                styles.maxHeight = maxHeightStyle;
                continue;
            } // Binary search for number of words which can fit in allotted height


            var max = words.length - 1;
            var min = 0;
            var pivot = void 0;

            while (min < max) {
                pivot = min + max + 1 >> 1; // eslint-disable-line no-bitwise

                el[textProp] = spaces ? words.slice(0, pivot).join(' ') : words.slice(0, pivot);
                el.insertAdjacentHTML('beforeend', charHtml);
                if (el.offsetHeight > maxHeight) max = pivot - 1;else min = pivot;
            }

            el[textProp] = spaces ? words.slice(0, max).join(' ') : words.slice(0, max);
            el.insertAdjacentHTML('beforeend', charHtml);
            var diff = spaces ? " ".concat(words.slice(max).join(' ')) : words.slice(max);
            var shavedText = document.createTextNode(diff);
            var elWithShavedText = document.createElement('span');
            elWithShavedText.classList.add(classname);
            elWithShavedText.style.display = 'none';
            elWithShavedText.appendChild(shavedText);
            el.insertAdjacentElement('beforeend', elWithShavedText);
            styles.height = heightStyle;
            styles.maxHeight = maxHeightStyle;
        }
    }

    return shave;

})));;
(function ($, Cobalt, global, undefined) {
	"use strict";

	var Waterdeep = {
        priority: 2,
        subLevelCookieName: "sublevel",

		initialize: function () {
            Waterdeep.ensureSubLevelCookie();
		},
		fancyCheckbox: function($fakeCheckContainer, $realCheckContainer, cb) {
			$fakeCheckContainer = $fakeCheckContainer || $('.fc-fake');
			$realCheckContainer = $realCheckContainer || $('.fc-real');

			if ($fakeCheckContainer.length == 0 || $realCheckContainer.length == 0) {
				return;
			}

		    $realCheckContainer.children("input[type='checkbox']").each(function(idx, el) {
		        if ($(this).prop("checked")) {
		            var id = el.id;
                    $(".fc-fake-item[data-fc-real-item-id='" + id + "']").addClass("fc-selected");
		        }
		    });

			$fakeCheckContainer.children().each(function(idx, el) {
				var $el = $(el);
				var realId = $el.attr('data-fc-real-item-id');

				$el.click(function(e) {
					var $checkbox = $realCheckContainer.find('#' + realId);
					$checkbox.prop('checked', !$checkbox.prop('checked')).change();
					$el.toggleClass('fc-selected');
					if (typeof cb === 'function') {
				    	cb($el);
					}
				});
			});
        },
        ensureSubLevelCookie: function () {
            if (!Cobalt.User.IsAuthenticated) {
                $.cookie(Waterdeep.subLevelCookieName, 'ANON');
                return;
            }
            if (!$.cookie(Waterdeep.subLevelCookieName)) {
                $.ajax({
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: '/api/subscriptionlevel',
                    dataType: "json",
                    xhrFields: {
                        withCredentials: true
                    },
                    success: function (data) {
                        if (data) {
                            Waterdeep.setSubLevelCookie(data);
                        }
                    },
                    error: function (xhr) {
                        console.error(xhr.responseText);
                    }
                });
            }
        },
        setSubLevelCookie: function (val) {
            $.cookie(Waterdeep.subLevelCookieName, val);
        },
        clearSubLevelCookie: function () {
            $.removeCookie(Waterdeep.subLevelCookieName, { path: '/' });
        }
	};

	global.Waterdeep = Waterdeep;
	Waterdeep.User = Cobalt.User;
})(jQuery, Cobalt, window || this);;
(function ($, Cobalt, Waterdeep, global, undefined) {
	"use strict";

	Waterdeep.Localization = new Cobalt.Localization(true);
	global.L = Waterdeep.Localization;

})(jQuery, Cobalt, Waterdeep, window || this);
;
(function ($, Cobalt, Waterdeep, undefined) {
	"use strict";

	Waterdeep.Routes = new Cobalt.Routes();
})(jQuery, Cobalt, Waterdeep);
;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.ShowMore = {
        isInitialize : false,
        initialize: function initializeShowMore() {
            $('.info').on('click', Waterdeep.ShowMore.toggleMoreInfo).on('hover', Waterdeep.ShowMore.handleHoverChange);
            $('.list-row').on('click', Waterdeep.ShowMore.getMoreInfo).on('hover', Waterdeep.ShowMore.handleHoverChange);

            $('div.more, .close').on('click', Waterdeep.ShowMore.toggleLinks);
            $('.advanced-filters').on('click', Waterdeep.ShowMore.toggleAdvancedFilters);
            $('.fav-indicator').on('click', Waterdeep.ShowMore.toggleFavorite);
        },

        initializeWithUrl: function initializeShowMoreWithUrl() {
            $('.info').on('click', Waterdeep.ShowMore.toggleMoreInfoWithUrl).on('hover', Waterdeep.ShowMore.handleHoverChange);
            $('.list-row').on('click', Waterdeep.ShowMore.getMoreInfoWithUrl).on('hover', Waterdeep.ShowMore.handleHoverChange);

            $('div.more, .close').on('click', Waterdeep.ShowMore.toggleLinks);
            $('.advanced-filters').on('click', Waterdeep.ShowMore.toggleAdvancedFilters);
            $('.fav-indicator').on('click', Waterdeep.ShowMore.toggleFavorite);
        },

        //refactored toggleMoreInfo
        //TODO: Use new function on all entities eventually
        getMoreInfo: function getMoreInfo(e, listItem) {
            if (e.target.className == "link") {
                e.preventDefault();
                window.location.href = e.target.href;
                return;
            }

            listItem = listItem || $(this);
            var type = listItem.data('type');
            var slug = listItem.data('slug');
            var isLoading = listItem.data('isloading');
            var isLoaded = listItem.data('isloaded');
            var moreInfo = listItem.next('.more-info');

            if (!isLoaded && !isLoading) {
                listItem.data('isloading', 'true');

                $.ajax({
                    url: '/' + type + '/' + slug + '/more-info',
                    method: 'GET',
                    success: function(res) {
                        listItem.after(res);
                        listItem.data('isloaded', 'true');
                        listItem.data('isloading', 'true');
                        listItem.addClass('open');
                        moreInfo.toggle();
                        Waterdeep.ShowMore.toggleIndicator(listItem);
                        return false;
                    }
                });
            } else if (isLoaded) {
                listItem.toggleClass('open');
                moreInfo.toggle();
                Waterdeep.ShowMore.toggleIndicator(listItem);
                return false;
            } else {
                return false;
            }
        },

        getMoreInfoWithUrl: function getMoreInfo(e, listItem) {
            if (e.target.className == "link") {
                e.preventDefault();
                window.location.href = e.target.href;
                return;
            }

            listItem = listItem || $(this);
            var url = listItem.data('url');
            var isLoading = listItem.data('isloading');
            var isLoaded = listItem.data('isloaded');
            var moreInfo = listItem.next('.more-info');

            if (!isLoaded && !isLoading) {
                listItem.data('isloading', 'true');

                $.ajax({
                    url: url,
                    method: 'GET',
                    success: function (res) {
                        listItem.after(res);
                        listItem.data('isloaded', 'true');
                        listItem.data('isloading', 'true');
                        listItem.addClass('open');
                        moreInfo.toggle();
                        Waterdeep.ShowMore.toggleIndicator(listItem);
                        return false;
                    }
                });
            } else if (isLoaded) {
                listItem.toggleClass('open');
                moreInfo.toggle();
                Waterdeep.ShowMore.toggleIndicator(listItem);
                return false;
            } else {
                return false;
            }
        },

        //refactored toggleIndicator
        toggleIndicator: function(el) {
            var listItem = el;
            var indicator = listItem.find(".list-row-indicator");

            indicator.toggleClass("open closed");
        },

        //use getMoreInfo!
        //TODO remove after list-row refactor is complete
        toggleMoreInfo: function toggleMoreInfo(e) {
            var info = $(this);

            if (e.target.className == "link") {
                e.preventDefault();
                window.location.href = e.target.href;
                return;
            }

            if (e.target.className == "image") {
                info.find('[data-lightbox').click();
            }


            var clickedMoreInfo = info.next('.more-info');
            var type = info.data('type');
            var slug = info.data('slug');
            var isLoading = info.data('isloading');
            var isLoaded = info.data('isloaded');

            if (!isLoaded && !isLoading) {
                info.data('isloading', 'true');

                $.ajax({
                    url: '/' + type + '/' + slug + '/more-info',
                    method: 'GET',
                    success: function (res) {
                        info.after(res);
                        info.data('isloaded', 'true');
                        info.data('isloading', 'false');
                        clickedMoreInfo.toggle();
                        Waterdeep.ShowMore.toggleOpenIndicator(info);
                        return false;
                    }
                });
            } else if (isLoaded) {
                clickedMoreInfo.toggle();
                Waterdeep.ShowMore.toggleOpenIndicator(info);
                return false;
            } else {
                return false;
            }
        },

        toggleMoreInfoWithUrl: function toggleMoreInfo(e) {
            var info = $(this);

            if (e.target.className == "link") {
                e.preventDefault();
                window.location.href = e.target.href;
                return;
            }

            if (e.target.className == "image") {
                info.find('[data-lightbox').click();
            }


            var clickedMoreInfo = info.next('.more-info');
            var url = info.data('url');
            var isLoading = info.data('isloading');
            var isLoaded = info.data('isloaded');

            if (!isLoaded && !isLoading) {
                info.data('isloading', 'true');

                $.ajax({
                    url: url,
                    method: 'GET',
                    success: function (res) {
                        info.after(res);
                        info.data('isloaded', 'true');
                        info.data('isloading', 'false');
                        clickedMoreInfo.toggle();
                        Waterdeep.ShowMore.toggleOpenIndicator(info);
                        return false;
                    }
                });
            } else if (isLoaded) {
                clickedMoreInfo.toggle();
                Waterdeep.ShowMore.toggleOpenIndicator(info);
                return false;
            } else {
                return false;
            }
        },

        //TODO refactor for list-row refactor, remove silas
        //use toggleIndicator instead
        toggleOpenIndicator: function toggleOpenIndicator(el) {
            var info = el;
            var indicator = info.children().last().children().first();
            var isOpen = info.attr('data-isopen') || 'false';
            
            if (isOpen === 'true') {
                indicator.addClass('plus').removeClass('minus');
                info.removeClass('silas-fleetfoot').attr('data-isopen', 'false');
            } else {
                indicator.addClass('minus').removeClass('plus');
                info.addClass('silas-fleetfoot').attr('data-isopen', 'true');
            }

            return el;
        },

        //TODO change class from stevanus
        toggleLinks: function toggleLinks() {
            var that = $(this);
            var links = that.hasClass('more') ? that.next('.links') : that.parent();
            links.toggleClass('stevanus-aurelius');
        },

        //TODO remove samiphi for list-row refactor
        handleHoverChange: function handleHoverChange(e) {
            var type = e.type;
            type == 'mouseenter' ? $(this).addClass('samiphi-wobblecog hover') : $(this).removeClass('samiphi-wobblecog hover'); //sets class to apply hover image
        },

        //TODO change class from stevanus
        toggleAdvancedFilters: function toggleAdvancedFilters(e) {
            e.preventDefault();

            var advancedFiltersButton = $('.advanced-filters');
            var buttonTextEl = advancedFiltersButton.children('span');
            var advancedFilters = $('.adv-filter:not(.search-filter)');

            advancedFilters.toggleClass('stevanus-aurelius');
            advancedFiltersButton.toggleClass('adv-filters-open');
            buttonTextEl.text() == 'Show Advanced Filters' ? buttonTextEl.text('Hide Advanced Filters') : buttonTextEl.text('Show Advanced Filters');
            $('.spell-header, .monster-header, .item-header').toggleClass('filters-open');

            window.scrollTo(0, 0);
        },

        handleExpansion: function(e, $indicator, $el) {
            $indicator.toggleClass("open");
            $el.toggleClass("hide");
        }

        //commented out until favorites get turned on

        // toggleFavorite: function toggleFavorite(e) {
        //     e.preventDefault();
        //     e.stopPropagation();
        //
        //     var el = $(this);
        //     el.children('.i-favorite').toggleClass('joe-blow')
        // }
    };

})(jQuery, Cobalt, Waterdeep);







;
(function ($, Cobalt, Waterdeep, undefined) {
	"use strict";
	var subTypeJson;

	Waterdeep.ShowBase = {
	    initialize: function initializeShowBase(subTypeJSON) {
	        subTypeJson = subTypeJSON;

            // Run once initially. 
	        Waterdeep.ShowBase.showWeaponInfo();
	        Waterdeep.ShowBase.showArmorInfo();

            // Run on HTML load. Need this for form within modal
	        Cobalt.runOnHtmlInsert((function ()
	        {
	            var $itemModifierModalForm = $('.t-save-deck-modal .form-item-modifier');

                // Don't run unless desired form has loaded on page.
	            if ($itemModifierModalForm.length > 0)
	                Waterdeep.ShowBase.refreshSubTypes(true);    
	        }))

            // Bind functions to select changes.
	        $('#form-field-base-weapon select').on('change', Waterdeep.ShowBase.showWeaponInfo);
	        $('#form-field-base-armor select').on('change', Waterdeep.ShowBase.showArmorInfo);

	        $('#field-item-modifier-type').on('change', function () { Waterdeep.ShowBase.refreshSubTypes(false) });
        
	        $(document).on('change', '.t-save-deck-modal #field-item-modifier-type', function () { Waterdeep.ShowBase.refreshSubTypes(true) });
		},

	    showWeaponInfo: function showWeaponInfo() {
	        var $weaponSelect = $('#form-field-base-weapon select');	        
		    var weaponVal = $weaponSelect.val();

		    if (weaponVal) {
		        $.get('/weapons/' + weaponVal + "/partial", function (res) {
		            $('.base-info').html("");
		            $('.base-info').html(res);
		            return false;
		        });
		    }

		    else {
		        $('.base-info').html("");
		        return false;
		    }
	    },

	    showArmorInfo: function showArmorInfo() {
	        var $armorSelect = $('#form-field-base-armor select');
	        var armorVal = $armorSelect.val();

	        if (armorVal) {
	            $.get('/armor/' + armorVal + "/partial", function (res) {
	                $('.base-info').html("");
	                $('.base-info').html(res);
	                return false;
	            });
	        }

	        else {
	            $('.base-info').html("");
	            return false;
	        }
	    },

	    refreshSubTypes: function refreshSubTypes(inModal) {

	        var $typeField, $subTypeField;
	        var subTypes = subTypeJson;

	        if (inModal == true) {
	            $typeField = $('.t-save-deck-modal #field-item-modifier-type');
	            $subTypeField = $('.t-save-deck-modal #field-item-modifier-sub-type');
	        }
	        else {
	            $typeField = $('#field-item-modifier-type');
	            $subTypeField = $('#field-item-modifier-sub-type');
	        }

	        var typeVal = $typeField.val();
	        var subTypeVal = $subTypeField.val();

	        var subTypeChange = function (id) {
	            var validOption = false;
	            $subTypeField.html("");
	            $.each(subTypes, function (key, value) {
	                if (value.type.toString() == id)
	                {
	                    $subTypeField.append($("<option></option>")
                                       .attr("value", value.id)
                                       .text(value.name));
	                }
	            });

	            $subTypeField.val(subTypeVal).trigger('change'); // Trigger change for Select2
	        };

	        subTypeChange(typeVal);
	    }
	}



})(jQuery, Cobalt, Waterdeep);;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.Filters = {
        initialize: function initializeFilters() {
            var urlParams = getUrlParams();
            var sortableColSelector = '.adohand > div:not(.blank, .attack, .damage, .environment, .tags, .notes)';

            $('.main-list > li').click(Waterdeep.Filters.handleFilterItemSelection);
            $('.special-select-item').click(Waterdeep.Filters.handleComponentSelection);
            $('.magic-bonus').click(Waterdeep.Filters.handleMagicBonusSelection); // ToDo: both this and component needs to be combined
            $('.all-items').click(Waterdeep.Filters.handleSubmit);
            $('[id$="-filter-button"]').click(Waterdeep.Filters.handleSubmit);
            $('input[id*="filter-"]').keypress(Waterdeep.Filters.handleFormSubmitOnEnter);
            $('.show-more').click(Waterdeep.Filters.showMoreItemsMainFilter);

            $(sortableColSelector).on('click', Waterdeep.Filters.handleColumnSort); //old listing structure
            $('.list-column-header-item.sortable').click(Waterdeep.Filters.handleColumnSort);
            

            Waterdeep.Filters.handleOnLoadFilterItemSelection(urlParams);

            Waterdeep.Filters.handleOnLoadComponentSelection(urlParams);
            Waterdeep.Filters.handleOnLoadMagicBonusSelection(urlParams);// ToDo: both this and component needs to be combined

            Waterdeep.Filters.setup100PercentOnSelect2();

            Waterdeep.Filters.handleFilterCounter(urlParams);

            Waterdeep.Filters.setSortCol(urlParams);
        },
        setup100PercentOnSelect2: function setup100PercentOnSelect2()
        {
            //ToDo: look into if we can set the default for select2 to 100% because this is more work that we dont really need to do.
            var options = [];
            $('.is-select2-select').each(function (index) {
                options[this.id] = {
                    width: "100%"
                };
            });
            Cobalt.Forms.Select2Options = options;
        },
        handleFilterItemSelection: function handleFilterItemSelection() {
            var li = $(this);
            var checkbox = li.children('input');
            var isChecked = checkbox.prop('checked');
            var icon = checkbox.next('span');
            var aLi = $('.all-items');
            var aCheckbox = aLi.children('input');
            var aIcon = aCheckbox.next('span');
            var form = li.closest('form');

            if (li.hasClass('all-items')) {
                var others = li.siblings('.item');
                $.each(others, function (idx) {
                    var item = $(others[idx]);
                    var iCheckbox = item.children('input');
                    var iIcon = iCheckbox.next('span');

                    iIcon.removeClass('escobert-the-red');
                    iCheckbox.prop('checked', false);
                });
                aIcon.addClass('escobert-the-red');
                aCheckbox.prop('checked', true);
                return;
            } else {
                aIcon.removeClass('escobert-the-red');
                aCheckbox.prop('checked', false);
            }

            icon.toggleClass('escobert-the-red'); //change to "checked" image
            checkbox.prop('checked', !isChecked); //change to "checked" state
            form.submit();
        },

        handleOnLoadFilterItemSelection: function handleOnLoadFilterItemSelection(urlParams) {
            var params = urlParams.filter(function (param) {
                if ($('body').hasClass('body-rpgspell')) {
                    return (param[0] == 'filter-class');
                } else
                if ($('body').hasClass('body-rpgmonster')) {
                    return (param[0] == 'filter-type');
                }
                else
                if ($('body').hasClass('body-rpgmagicitem')) {
                    return (param[0] == 'filter-type');
                }
            });
            var checkedItems = params.map(function (param) {
                return (param[0] + '-' + param[1]);
            });
            if (checkedItems.length == 0 || checkedItems[0] == 'filter-class-0' || checkedItems[0] == 'filter-type-0') {
                $('span.all-icon').addClass('escobert-the-red');
            }
            checkedItems.each(function (klass) {
                var labelEl = $('[for=' + klass + ']');
                labelEl.prev('span').addClass('escobert-the-red');
                labelEl.prevAll('input').prop('checked', true);
            });
        },

        handleComponentSelection: function handleComponentSelection() {
            var el = $(this);
            var option = $('#' + el.data('target-input-id'));
            if (el.hasClass('t')) { //t = true/selected
                el.removeClass('t').addClass('f');
                option.val('f');
            } else if (el.hasClass('f')) { //f = false/excluded
                el.removeClass('f');
                option.val('');
            } else { // null/unselected
                el.addClass('t');
                option.val('t');
            }
        },
        handleMagicBonusSelection: function handleMagicBonusSelection() {
            var fakeBox = $(this);
            var componentName = fakeBox.attr('class').replace('magic-bonus ', '').replace(' grissel-pete-who-even-is-this-guy', '');
            var checkbox = $('#filter-magic-bonus-' + componentName);
            var isChecked = checkbox.prop('checked');

            fakeBox.toggleClass('grissel-pete-who-even-is-this-guy');
            checkbox.prop('checked', !isChecked);
        },

        handleOnLoadComponentSelection: function handleOnLoadComponentSelection(urlParams) {
            var params = urlParams.filter(function (param) {
                return (param[0] == 'filter-verbal' || param[0] == 'filter-somatic' || param[0] == 'filter-material');
            });
            var parsedParams = params.map(function(param) {
                console.log(param)
                return [param[0], param[1]];
            });
            parsedParams.each(function (component) {
                $('.special-select').find('[data-target-input-id="' + component[0] + '"]').addClass(component[1]);
            });
        },
        handleOnLoadMagicBonusSelection: function handleOnLoadMagicBonusSelection(urlParams) {
            var params = urlParams.filter(function (param) {
                return (param[0] == 'filter-magic-bonus');
            });
            var checkedComponents = params.map(function (param) {
                return ('magic-bonus-' + param[1]);
            });
            checkedComponents.each(function (component) {
                $('#' + component).addClass('grissel-pete-who-even-is-this-guy');
            });
        },

        handleSubmit: function handleSubmit() {
            var form = $(this).first().closest('form');
            form.submit();
        },

        handleFormSubmitOnEnter: function handleFormSubmitOnEnter(ev) {
            ev.keyCode == 13 ? $(this).first().closest('form').submit() : false;
        },

        handleColumnSort: function handleColumnSort() {
            var el = $(this);
            var sortBy = el.data('sort-by');
            var currentUrl = window.location.origin + window.location.pathname;
            var currentParams = getUrlParams();
            var sortParam;
            var newUrl;

            if (currentParams.length) {
                currentParams.each(function (el, idx, arr) {
                    if (el[0] === 'sort') {
                        if (el[1] === sortBy || el[1] === ('-' + sortBy)) {
                            if (el[1] === sortBy) {
                                sortBy = '-' + sortBy;
                            }

                            if (arr.length === 1) {
                                newUrl = currentUrl + '?sort=' + sortBy;
                            } else {
                                currentParams.pop();
                                newUrl = currentUrl + '?' + currentParams.join('&') + '&sort=' + sortBy;
                            }
                        } else {
                            if (arr.length === 1) {
                                newUrl = currentUrl + '?sort=' + sortBy;
                            } else {
                                currentParams.pop();
                                newUrl = currentUrl + '?' + currentParams.join('&') + '&sort=' + sortBy;
                            }
                        }
                    }
                    
                    if (idx !== arr.length) {
                        arr[idx] = arr[idx].join('=');
                    }
                });

                if (!newUrl) { //filters active, but no sort
                    var parsedParams = '?' + currentParams.join('&');
                    newUrl = currentUrl + parsedParams + '&sort=' + sortBy;
                }
            } else {
                sortParam = '?sort=' + sortBy;
                newUrl = currentUrl + sortParam;
            }

            window.location.href = newUrl;
        },

        setSortCol: function setSortCol(params) {
            var sortedCol = null;
            var cols = $("div[data-sort-by]");

            params.each(function (el, idx, arr) {
                if (el[0] === "sort") {
                    sortedCol = el[1];
                }
            });

            if (sortedCol) {
                cols.each(function (idx, el, arr) {
                    var currCol = $(el);
                    var currSlug = currCol.data("sort-by")

                    if (currSlug === sortedCol) {
                        currCol.addClass("sort-up");
                    } else if ('-' + currSlug === sortedCol) {
                        currCol.addClass("sort-down");
                    }
                });
            } else {
                return false;
            }
        },

        handleFilterCounter: function handleFilterCounter(params) {
            var count = 0;

            params.each(function (el, idx, arr) {
                if (el[0] !== 'sort' && el[1] !== '' && el[0] !== "filter-search" && el[0] !== "page") {
                    if ($('body').hasClass('body-rpgspell') && el[0] !== "filter-class" && el[0] !== "filter-level" && el[0] !== "filter-tags" && el[0] !== "filter-casting-time") {
                        count++;
                    } else if ($('body').hasClass('body-rpgmagicitem') && el[0] !== "filter-type" && el[0] !== "filter-rarity" && el[0] !== "filter-requires-attunement" && el[0] !== "filter-tags" && el[0] !== "filter-magic-bonus") {
                        count++;
                    } else if ($('body').hasClass('body-rpgmonster') && el[0] !== "filter-type" && el[0] !== "filter-rarity" && el[0] !== "filter-cr-min" && el[0] !== "filter-cr-max" && el[0] !== "filter-size" && el[0] !== "filter-environment") {
                        count++;
                    } else if ($('body').hasClass('body-rpgbackground') && el[0] !== "filter-type" && el[0] !== "filter-source-category" && el[0] !== "filter-source" && el[0] !== "filter-skills" && el[0] !== "filter-tags") {
                        count++;
                    } else if ($('body').hasClass('body-rpgfeat') && el[0] !== "filter-type" && el[0] !== "filter-source-category" && el[0] !== "filter-source" && el[0] !== "filter-prereq-subtype" && el[0] !== "filter-tags") {
                        count++;
                    }
                }
            });

            document.getElementById('filter-counter').setAttribute('data-count', count);
        },

        showMoreItemsMainFilter: function showMoreItemsMainFilter() {
            var button = $(this);
            var itemList = button.parent().prev().children();

            itemList.each(function (idx, el) {
                var $el = $(el);

                if (!$el.hasClass('all-items')) {
                    $el.toggle();
                }
            });

            button.toggleClass('activated');
        }
    };

})(jQuery, Cobalt, Waterdeep);

function getUrlParams() {
    /* Load up URL params */
    var urlParams = [];
    (function () {
        var match,
        pl = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query = window.location.search.substring(1);

        while (match = search.exec(query))
            urlParams.push([decode(match[1]), decode(match[2])]);
    })();

    return urlParams;
}

Array.prototype.each = function (cb) {
    for (var i = 0; i < this.length; i++) {
        cb(this[i], i, this);
    }
};

var debounce = function(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this,
            args = arguments;
        var later = function() {
            timeout = null;
            if ( !immediate ) {
                func.apply(context, args);
            }
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait || 200);
        if ( callNow ) { 
            func.apply(context, args);
        }
    };
};;
var __tip = new CurseTip({
    Url: window.location.origin,
    Namespace: 'waterdeep-tooltip',
    Paths: ['spells', 'magic-items', 'monsters', 'characters', 'conditions', 'senses', 'skills', 'actions', 'weapon-properties', 'adventuring-gear', 'armor', 'weapons', 'dicerolls', 'vehicles', 'rules' ],
    LoadingText: '<div class="tooltip tooltip-loading"></div>',
    WatchComplete: function (elements) {
        for (var i in elements) {
            if (elements[i].dataset && elements[i].dataset.tooltipHref) {
                elements[i].dataset.tooltipHref += (elements[i].dataset.tooltipHref.indexOf('?') >= 0 ? '&' : '?') + 'disable-webm=1';
            }
        }
    }
});

if (typeof Waterdeep !== 'undefined') {
    Waterdeep.CurseTip = __tip;
};
(function ($, Cobalt, Waterdeep, undefined) {
	"use strict";

	var subTypeJson;

	Waterdeep.Subtypes = {
		initialize: function initializeFilters(subTypeJSON) {
		    subTypeJson = subTypeJSON;
		    Waterdeep.Subtypes.refreshSubtypes();
			$('*[data-select="types"] select').on('change', Waterdeep.Subtypes.refreshSubtypes);
		},
		refreshSubtypes: function refreshSubtypes() {
		    var $typeField = $('*[data-select="types"] select');
		    var $subTypeField = $('*[data-select="subtypes"] select');
		    var subTypes = subTypeJson;

		    var typeVal = $typeField.val();
		    var subTypeVal = $subTypeField.val();

		    var subTypeChange = function (id) {
		        var validOption = false;
		        $subTypeField.html("");
		        $subTypeField.append($("<option></option>")
                                       .attr("value", "")
                                       .text("—"));
		        $.each(subTypes[0], function (key, value) {
		            if (value.type.toString() == id) {
		                $subTypeField.append($("<option></option>")
                                       .attr("value", value.id)
                                       .text(value.name));
		            }
		        });

		        $subTypeField.val(subTypeVal).trigger('change'); // Trigger change for Select2
		    };

		    subTypeChange(typeVal);
		},
	};

})(jQuery, Cobalt, Waterdeep);;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.Marketplace = {
        mobileBreakpoint: 768,

        initialize: function () {
            Waterdeep.Marketplace.createCartButtonHandlers();

            $(document).on("change", ".j-payment-radio", function () {
                Waterdeep.Marketplace.handlePaymentRadioChange(this);
            });

            $(document).on("click", "#payment-same-address", function () {
                Waterdeep.Marketplace.handleAddressVisibility();
            });

            $("form#checkout").on("submit", Waterdeep.Marketplace.syncAddressesIfNecessary);

            $("#coupon-code-form button").on("click", Waterdeep.Marketplace.applyCouponCode);

            $("#coupon-code-remove").on("click", Waterdeep.Marketplace.bindAjaxPost);
        },

        bindAjaxPost: function (e) {
            e.preventDefault();
            var $this = $(this);

            if ($this.hasClass('disabled') || $this.hasClass('loading')) {
                return;
            }

            var confirmMessage = $this.attr('data-confirm-message');

            if (!confirmMessage && $this.hasClass('confirm'))
                confirmMessage = 'Are you sure?';

            if (confirmMessage !== undefined && !confirm(confirmMessage))
                return;

            if (!$this.hasClass('silent')) {
                $this.addClass('loading');
            }

            var token = $.cookie("RequestVerificationToken");
            if (token) {
                Cobalt.Forms.AjaxPostSubmit($this, token);
            } else {
                $.ajax({
                    url: "/refresh-request-verification-token",
                    type: 'POST',
                    dataType: 'json',
                    success: function (data) {
                        token = $.cookie("RequestVerificationToken");
                        Cobalt.Forms.AjaxPostSubmit($this, token);
                    }
                });
            }
        },

        createCartButtonHandlers: function () {
            $(".button-add-to-cart").on("click", Waterdeep.Marketplace.bindAjaxPost);
            $(".ddb-market-cart .remove-from-cart").on("click", Waterdeep.Marketplace.bindAjaxPost);

            $(".button-add-to-cart").on("click", Waterdeep.Marketplace.addToCart);
            $(".ddb-market-cart .remove-from-cart").on("click", Waterdeep.Marketplace.removeFromCart);

            $(".button-add-to-cart-modal").on("click", Waterdeep.Marketplace.bindAjaxPostAddToCart);
        },

        handlePaymentRadioChange: function ($radio) {
            if ($radio.value === "paypal") {
                $("#payment-paypal").show();
                $("#payment-credit").hide();
                $(".ddb-market-checkout-form-address-same").hide();
            } else {
                $("#payment-credit").show();
                $("#payment-paypal").hide();
                $(".ddb-market-checkout-form-address-same").show();
            }
            Waterdeep.Marketplace.handleAddressVisibility();
        },
        handleAddressVisibility: function () {
            var isPayPal = $("#payment-radio-paypal")[0].checked;
            var sameAddress = $("#payment-same-address")[0].checked;

            if (isPayPal || sameAddress) {
                $("#billing-address").hide();
            } else {
                $("#billing-address").show();
            }
        },
        syncAddressesIfNecessary: function () {
            var field = $("#payment-same-address")[0];
            if (!field) { return; }
            var sameAddress = field.checked;
            if (sameAddress) {
                $("#field-billing-first-name").val($("#field-shipping-first-name").val());
                $("#field-billing-last-name").val($("#field-shipping-last-name").val());
                $("#field-billing-street-address-1").val($("#field-shipping-street-address-1").val());
                $("#field-billing-street-address-2").val($("#field-shipping-street-address-2").val());
                $("#field-billing-locality").val($("#field-shipping-locality").val());
                $("#field-billing-state").val($("#field-shipping-state").val());
                $("#field-billing-postal-code").val($("#field-shipping-postal-code").val());
                $("#field-billing-country").val($("#field-shipping-country").val());
            }
        },
        addToCart: function () {
            var $btn = $(this);
            $btn.unbind("click");
            var postUrl = $btn.getAttribute("href");

            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: postUrl,
                dataType: "json",
                xhrFields: {
                    withCredentials: true
                },
                success: function (data) {
                    if (data.Success) {
                        $btn.addClass("button-in-cart");
                        $btn.removeClass('button-add-to-cart');
                        $btn.text("In Cart");
                        Waterdeep.Marketplace.updateCartInfo(data);
                    }
                    else {
                        alert(data.Message);
                    }
                },
                error: function (xhr) {
                    alert(xhr.responseText);
                }
            });

        },
        bindAjaxPostAddToCart: function (e) {
            e.preventDefault();
            var $this = $(this);

            if ($this.hasClass('disabled') || $this.hasClass('loading')) {
                return;
            }

            var confirmMessage = $this.attr('data-confirm-message');

            if (!confirmMessage && $this.hasClass('confirm'))
                confirmMessage = 'Are you sure?';

            if (confirmMessage !== undefined && !confirm(confirmMessage))
                return;

            if (!$this.hasClass('silent')) {
                $this.addClass('loading');
            }

            Cobalt.Utils.getRequestVerificationToken().done(function (token) {
                Cobalt.Forms.AjaxPostSubmit($this, token).done(function () {
                    if ($(window).width() < Waterdeep.Marketplace.mobileBreakpoint) {
                        Waterdeep.MarketplaceCartModal.displayCartModal();
                    }
                    else {
                        self.location.reload();
                    }
                });
            });
        },
        removeFromCart: function () {
            var $btn = $(this);
            $btn.unbind("click");
            var postUrl = $btn.getAttribute("href");

            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: postUrl,
                dataType: "json",
                xhrFields: {
                    withCredentials: true
                },
                success: function (data) {

                    if (data.Success) {
                        $btn.closest("tr").remove();
                        Waterdeep.Marketplace.updateCartInfo(data);
                    }
                    else {
                        alert(data.Message);
                    }
                },
                error: function (xhr) {
                    alert(xhr.responseText);
                }
            });
        },
        updateCartInfo: function (data) {
            var subtotal = data.Subtotal.toFixed(2);
            var total = data.Total.toFixed(2);

            $(".my-cart .label").text("My Cart (" + data.CartSize + ")");
            $("#subtotal").text('$' + subtotal);
            $(".cart-total-price").text('$' + total);
            $(".ddb-market-cart-totals-item-checkout-order-total .ddb-market-cart-totals-item-cost").text('$' + total);

            var $minimum = $(".ddb-market-cart-totals-item-minimum");
            data.IsMinimumCharge ? $minimum.removeClass("hide") : $minimum.addClasss("hide");
        },
        applyCouponCode: function () {
            $("#coupon-code-form").ajaxSubmit({
                type: 'post',
                success: function (data) {
                    if (data.Success) {
                        if (data.Coupons) {

                            var old = $('.ddb-market-cart-totals-item-coupon');
                            old.remove();

                            var subTotalLi = $('#cart-totals li.j-subtotal');
                            for (var i = 0; i < data.Coupons.length; i++) {
                                var coupon = data.Coupons[i];
                                var couponLi = $('<li class="ddb-market-cart-totals-item ddb-market-cart-totals-item-coupon">')
                                    .append($('<a class="ajax-post ddb-market-cart-totals-item-coupon-code-remove" id="coupon-code-remove" href="' + coupon.RemoveUrl + '"></a>'))
                                    .append($('<span class="ddb-market-cart-totals-item-label">').text('Coupon: ' + coupon.Code))
                                    .append($('<span class="ddb-market-cart-totals-item-cost" id="discount">').text('-' + coupon.DiscountAmount))
                                subTotalLi.after(couponLi);
                            }
                        }
                        Waterdeep.Marketplace.updateCartInfo(data);

                        // push the coupon redemption to the data layer
                        pushCheckoutOptionToDataLayer('1', coupon.Code);

                        $('#coupon-code').val('');
                        $('#coupon-code-msg').text('');
                    } else {
                        $('#coupon-code-msg').addClass('error').text(data.Message);
                    }
                }
            });
            return false;
        }
    };

})(jQuery, Cobalt, Waterdeep);;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";
    
    Waterdeep.MarketplaceCartModal = {
        cartUrl: '/marketplace/cart',
        hideClass: 'marketplace-content-hide',
        noScrollClass: 'marketplace-no-scroll',
        windowResizeDebounce: null,
    
        initialize: function () {
            Waterdeep.MarketplaceCartModal.initializeButtons();
        },
            
        initializeButtons: function() {
            const modalContainer = document.querySelector('.j-cart-modal-container');

            modalContainer.addEventListener('click', (event => {
                if (event.target !== modalContainer) return;
                Waterdeep.MarketplaceCartModal.refreshPage();
            }));

            const continueShoppingButton = document.querySelector('.cart-modal__continue-shopping');
            if (continueShoppingButton !== null) {
                continueShoppingButton.addEventListener('click', Waterdeep.MarketplaceCartModal.refreshPage);
            }

            const goToCartButton = document.querySelector('.cart-modal__button-cart');
            if (goToCartButton !== null) {
                goToCartButton.addEventListener('click', Waterdeep.MarketplaceCartModal.goToCart);
            }
        },
    
        displayCartModal: function () {
            const modal = document.querySelector('.j-cart-modal-container');
            const hidden = modal.classList.toggle(Waterdeep.MarketplaceCartModal.hideClass);

            const body = document.querySelector('.body-marketplace, .body-newmarketplace');
            if (body !== null) {
                body.classList.toggle(Waterdeep.MarketplaceCartModal.noScrollClass, !hidden);
            }
        },

        refreshPage: function () {
            self.location.reload();
        },

        goToCart: function () {
            window.location.href = Waterdeep.MarketplaceCartModal.cartUrl;
        },
    };

})(jQuery, Cobalt, Waterdeep);
;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";
    
    Waterdeep.MarketplaceFilter = {
        filterShowOwnedCookieName: 'marketplace_filter_show_owned',
        hideClass: 'marketplace-content-hide',
        noScrollClass: 'marketplace-no-scroll',
        windowResizeDebounce: null,
    
        initialize: function () {
            if (document.querySelector('.j-filter-modal-container') !== null) {
                Waterdeep.MarketplaceFilter.initializeItemsListingFilters();   
            }
            
            if (document.querySelector('.j-additional-purchase-options-category-selector') !== null) {
                Waterdeep.MarketplaceFilter.initializeAdditionalItemsFilters();
            }
            
            Waterdeep.MarketplaceFilter.initializeDescriptionTextTruncation();
        },
        
        initializeDescriptionTextTruncation: function() {
            Waterdeep.MarketplaceFilter.truncateDescriptionText();

            window.addEventListener('orientationchange', Waterdeep.MarketplaceFilter.truncateDescriptionText);
            window.addEventListener('resize', () => {
                if (Waterdeep.MarketplaceFilter.windowResizeDebounce != null) {
                    window.clearTimeout(Waterdeep.MarketplaceFilter.windowResizeDebounce);
                }
                
                Waterdeep.MarketplaceFilter.windowResizeDebounce = window.setTimeout(
                    Waterdeep.MarketplaceFilter.truncateDescriptionText, 200);
            });
        },
        
        truncateDescriptionText: function() {
            const listItemDescriptions = document.querySelectorAll(
                '.j-marketplace-listing-list-item__description');
            listItemDescriptions.forEach(d => {
                shave(d.children[0], d.clientHeight);
            });
        },
        
        initializeAdditionalItemsFilters: function() {
            document.querySelector('.j-additional-purchase-options-category-selector')
                .addEventListener('change', Waterdeep.MarketplaceFilter.updateAdditionalItemsFilter);
        },

        updateAdditionalItemsFilter: function() {
            const selectedValue = this.value;
            const categoryGroups = document.querySelectorAll('.additional-purchase-options__category[data-category]');
            
            if (selectedValue) {
                categoryGroups.forEach(c => {
                    const dataCategory = c.getAttribute('data-category');
                    c.classList.toggle(Waterdeep.MarketplaceFilter.hideClass, dataCategory !== selectedValue);
                });   
            } else {
                categoryGroups.forEach(c => {
                    c.classList.remove(Waterdeep.MarketplaceFilter.hideClass);
                });
            }
        },
    
        initializeItemsListingFilters: function() { 
            // Set show owned filter to default to false
            if (!$.cookie(Waterdeep.MarketplaceFilter.filterShowOwnedCookieName)) {
                Waterdeep.MarketplaceFilter.setFilterByOwnedCookie(false);
            }
    
            const showOwnedFilter = Waterdeep.MarketplaceFilter.getFilterByOwnedCookie();
    
            // Set filter checkbox based on cookie
            const showOwnedCheckbox = document.querySelector('.j-owned-item-filter-checkbox');
            showOwnedCheckbox.checked = showOwnedFilter;
    
            // initially hide or show owned items
            Waterdeep.MarketplaceFilter.toggleHidingOwnedItems(showOwnedFilter);
    
            const modalContainer = document.querySelector('.j-filter-modal-container');
            modalContainer.addEventListener('click', (event => {
                if (event.target !== modalContainer) return;
                Waterdeep.MarketplaceFilter.displayFiltersModal()
            }));

            const filterButton = document.querySelector('.j-marketplace-action-item--filters');
            if (filterButton !== null) {
                filterButton.addEventListener('click', Waterdeep.MarketplaceFilter.displayFiltersModal)
            }

            document.querySelector('.j-filter-modal__close-button')
                .addEventListener('click', Waterdeep.MarketplaceFilter.displayFiltersModal);
            document.querySelector('.j-owned-item-filter-checkbox')
                .addEventListener('change', Waterdeep.MarketplaceFilter.toggleOwnedFilter);
        },
    
        displayFiltersModal: function() {
            const modal = document.querySelector('.j-filter-modal-container');
            const hidden = modal.classList.toggle(Waterdeep.MarketplaceFilter.hideClass);

            const body = document.querySelector('.body-marketplace, .body-newmarketplace');
            if (body !== null) {
                body.classList.toggle(Waterdeep.MarketplaceFilter.noScrollClass, !hidden);
            }
        },
    
        toggleOwnedFilter: function() {
            const hidingOwned = this.checked;
    
            Waterdeep.MarketplaceFilter.setFilterByOwnedCookie(hidingOwned);
            Waterdeep.MarketplaceFilter.toggleHidingOwnedItems(hidingOwned);
        },
    
        toggleHidingOwnedItems: function(showingOwned) {
            const ownedItems = document.querySelectorAll('.j-owned');
            ownedItems.forEach(i => {
                i.parentElement.classList.toggle(Waterdeep.MarketplaceFilter.hideClass, !showingOwned);
            });
            
            // Display empty owned state if filter is on and all items are owned
            const otherItems = document.querySelectorAll(`.j-marketplace-listing-featured-list-item:not(.j-owned), .j-marketplace-listing-list-item:not(.j-owned)`);
            if (otherItems.length === 0) {
                Waterdeep.MarketplaceFilter.toggleEmptyOwnedStateView(showingOwned);
            }
            
            // Attempt to display the filters notification message if it's available
            const filtersNotification = document.querySelector('.j-marketplace-filters-notification');
            if (filtersNotification !== null) {
                filtersNotification.classList.toggle(Waterdeep.MarketplaceFilter.hideClass, showingOwned);
            }
            
            // Display all content now that things have been hidden or shown
            const marketplaceContent = document.querySelector('.j-marketplace-content')
            if (marketplaceContent !== null) {
                marketplaceContent.style.visibility = 'visible';
            }
        },
        
        toggleEmptyOwnedStateView: function(showingOwned) {
            const emptyStateView = document.querySelector('.j-marketplace-empty-filtered-state');
            if (emptyStateView !== null) {
                emptyStateView.classList.toggle(Waterdeep.MarketplaceFilter.hideClass, showingOwned);
            }
            
            // in this same case, hide the search bar if applicable
            const searchBar = document.querySelector('.j-collapsible__search');
            if (searchBar !== null) {
                searchBar.classList.toggle(Waterdeep.MarketplaceFilter.hideClass, !showingOwned);
            }
        },
    
        setFilterByOwnedCookie: function(filterOn) {
            $.cookie(Waterdeep.MarketplaceFilter.filterShowOwnedCookieName, filterOn);
        },
    
        getFilterByOwnedCookie: function() {
            return $.cookie(Waterdeep.MarketplaceFilter.filterShowOwnedCookieName) === 'true';
        },
    };

})(jQuery, Cobalt, Waterdeep);
;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.MarketplaceNavigation = {
        windowResizeDebounce: null,
        noScrollClass: 'marketplace-no-scroll',
        
        initialize: () => {
            if (document.querySelector('.j-marketplace-navigation__mobile-target') !== null) {
                Waterdeep.MarketplaceNavigation.attachNavigationOnClickHandler();

                window.addEventListener('resize', () => {
                    if (Waterdeep.MarketplaceNavigation.windowResizeDebounce != null) {
                        window.clearTimeout(Waterdeep.MarketplaceNavigation.windowResizeDebounce);
                    }

                    Waterdeep.MarketplaceNavigation.windowResizeDebounce = window.setTimeout(
                        Waterdeep.MarketplaceNavigation.attachNavigationOnClickHandler, 200);
                });
            }
        },
        
        attachNavigationOnClickHandler: () => {
            Waterdeep.MarketplaceNavigation.toggleBodyNoScroll(false);
            
            if (window.innerWidth >= 1024) return;
            
            const target = document.querySelector('.j-marketplace-navigation__mobile-target');
            target.removeEventListener('click', Waterdeep.MarketplaceNavigation.toggleExpanded);
            target.addEventListener('click', Waterdeep.MarketplaceNavigation.toggleExpanded);
        },
        
        toggleExpanded: () => {
            const nav = document.querySelector('.j-marketplace-navigation');
            const expanded = nav.classList.toggle('expanded')

            Waterdeep.MarketplaceNavigation.toggleBodyNoScroll(expanded);
        },
        
        toggleBodyNoScroll: (noScroll) => {
            const body = document.querySelector('.body-marketplace, .body-newmarketplace');
            if (body !== null) {
                body.classList.toggle(Waterdeep.MarketplaceNavigation.noScrollClass, noScroll);
            }
        }
    };

})(jQuery, Cobalt, Waterdeep);;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.MarketplaceReadMore = {
        hideClass: 'marketplace-content-hide',
        
        initialize: function() {
            const readMore = document.querySelector(".j-read-more");
            const descriptionContainer = document.querySelector(".j-description-container");
            const description = document.querySelector(".j-description");

            if (readMore !== null) {
                readMore.addEventListener("click", () => {
                    if (descriptionContainer !== null) {
                        descriptionContainer.classList.add("expanded");
                    }
                });
            }

            if (descriptionContainer !== null && description !== null) {
                if (description.clientHeight > descriptionContainer.clientHeight) {
                    const overlay = document.querySelector(".j-description-overlay");
                    if (overlay !== null) {
                        overlay.classList.remove(Waterdeep.MarketplaceReadMore.hideClass);
                    }

                    const readMore = document.querySelector(".j-read-more");
                    if (readMore !== null) {
                        readMore.classList.remove(Waterdeep.MarketplaceReadMore.hideClass);
                    }
                }
            }
        }
    };

})(jQuery, Cobalt, Waterdeep);
;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.CompendiumPage = {
        elToParse: ".p-article-content",
        elToIgnore: null,
        menuItemsLookup: {},
        menuItemPositions: [],
        $menuItems: $([]),
        makeHash: function(str) {
            return str.replace(/[^\w\d]+/g, '');
        },
        openMenuItems: function($menuItems) {
            $menuItems.addClass('quick-menu-item-opened').removeClass('quick-menu-item-closed');
        },
        closeMenuItems: function($menuItems) {
            $menuItems.removeClass('quick-menu-item-opened').addClass('quick-menu-item-closed');
        },
        activateMenuItemById: function(id) {
            var $menuItem = Waterdeep.CompendiumPage.menuItemsLookup[id];
            if ($menuItem) {
                $menuItem.parents('.quick-menu-item').each(function(idx, parent) {
                    var $parent = $(parent);

                    Waterdeep.CompendiumPage.closeMenuItems($parent.siblings());
                    Waterdeep.CompendiumPage.openMenuItems($parent);
                });

                Waterdeep.CompendiumPage.closeMenuItems($menuItem.siblings());
                Waterdeep.CompendiumPage.openMenuItems($menuItem);

                Waterdeep.CompendiumPage.$menuItems.removeClass('quick-menu-item-active');
                $menuItem.addClass('quick-menu-item-active');
            }
        },
        findActiveMenuItem: function findActiveMenuItem() {
            var scrollY = window.scrollY;
            var closestMenuItemPositions = Waterdeep.CompendiumPage.menuItemPositions.slice().sort(function(a, b) {
                var aScrollYDiff = Math.abs(a.offset - scrollY);
                var bScrollYDiff = Math.abs(b.offset - scrollY);
                if (aScrollYDiff < bScrollYDiff) {
                    return -1;
                }
                if (aScrollYDiff > bScrollYDiff) {
                    return 1;
                }
                return  0;
            });

            if (closestMenuItemPositions.length) {
                Waterdeep.CompendiumPage.activateMenuItemById(closestMenuItemPositions[0].id);
            }
        },
        handleScroll: function handleScroll() {
            Waterdeep.CompendiumPage.findActiveMenuItem();
        },
        handleResize: function handleResize() {
            Waterdeep.CompendiumPage.updateMenuItemPositions();
            Waterdeep.CompendiumPage.findActiveMenuItem();
        },
        updateMenuItemPositions: function updateMenuItemPositions() {
            Waterdeep.CompendiumPage.menuItemPositions = [];
            $.each(Waterdeep.CompendiumPage.menuItemsLookup, function(id, $menuItem) {
                var $el = $('#' + id);
                if (!$el.length) {
                    return;
                }
                Waterdeep.CompendiumPage.menuItemPositions.push({
                    id: id,
                    offset: $el.offset().top,
                    $menuItem: $menuItem,
                    $el: $el,
                });
            });

            Waterdeep.CompendiumPage.menuItemPositions.sort(function(a, b) {
                if (a.offset < b.offset) {
                    return -1;
                }
                if (a.offset > b.offset) {
                    return 1;
                }
                return  0;
            });
        },
        renderQuickMenu: function(menuItems) {
            if (!menuItems.length) {
                return null;
            }

            var firstMenuItem = menuItems[0];
            var $menu = $('<ul class="quick-menu quick-menu-tier-' + firstMenuItem.no + '"/>');
            $.each(menuItems, function(idx, menuItem) {
                var $menuItem = $('<li class="quick-menu-item" />');
                var $menuItemLabel = $('<div class="quick-menu-item-label" />');

                var $menuItemLink = $('<a class="quick-menu-item-link" href="#' + menuItem.linkHash + '">' + menuItem.text + '</a>');
                $menuItemLabel.append($menuItemLink);

                if (menuItem.no !== 1 && menuItem.children.length) {
                    $menuItem.addClass('quick-menu-item-closed');
                    $menuItemLabel.append('<div class="quick-menu-item-trigger" />');
                }

                $menuItem.append($menuItemLabel);
                $menuItem.append(Waterdeep.CompendiumPage.renderQuickMenu(menuItem.children));
                $menu.append($menuItem);

                Waterdeep.CompendiumPage.menuItemsLookup[menuItem.linkHash] = $menuItem;
                Waterdeep.CompendiumPage.$menuItems = Waterdeep.CompendiumPage.$menuItems.add($menuItem);
            });

            var $menuItems = $menu.find('> .quick-menu-item');

            $menuItems.each(function(idx, menuItem) {
                var $menuItem = $(menuItem);
                var $menuItemLabel = $menuItem.find('> .quick-menu-item-label');
                var $menuItemTrigger = $menuItemLabel.find('.quick-menu-item-trigger');

                $menuItemLabel.on('click', function(evt) {
                    Waterdeep.CompendiumPage.closeMenuItems($menuItems);
                    Waterdeep.CompendiumPage.openMenuItems($menuItem);
                });

                $menuItemTrigger.on('click', function(evt) {
                    evt.preventDefault();
                    evt.stopPropagation();

                    var isOpen = $menuItem.hasClass('quick-menu-item-opened');

                    Waterdeep.CompendiumPage.closeMenuItems($menuItems);

                    if (isOpen) {
                        Waterdeep.CompendiumPage.closeMenuItems($menuItem);
                    } else {
                        Waterdeep.CompendiumPage.openMenuItems($menuItem);
                    }
                });
            });

            return $menu;
        },
        renderSelect: function(menuItems) {
            if (!menuItems.length) {
                return null;
            }

            var $select = $('<select class="nav-select" />').on('change', function(evt) {
                var destination = evt.target.value;
                if (destination) {
                    location.href = destination;
                }
            });

            $select.append('<option value="">Jump to...</option>');

            for (var i=0; i < menuItems.length; i++) {
                var menuItem = menuItems[i];
                if (menuItem.no == 1 && menuItem.children.length > 0) {
                    for (var j = 0; j < menuItem.children.length; j++) {
                        //if (menuItem.children[j].no == 2) {
                        var $option = $('<option />').text(menuItem.children[j].text).val('#' + menuItem.children[j].linkHash);
                        $select.append($option);
                        //}
                    }
                }
            }

            return $select;
        },
        menuListParser: function(nodes, startIdx) {
            var list = [];
            var curNodeIdx = startIdx;

            while (nodes.length > curNodeIdx) {
                // setup initial details for node
                var node = nodes[curNodeIdx];
                var $node = $(node);
                var nodeTag = node.tagName.toLowerCase();

                // attempt to get heading text without tags
                var headingTextNoTags = $node.contents().filter(function () {
                    return this.nodeType == Node.TEXT_NODE;
                }).text();

                // if we didn't get text, revert to old way
                if (headingTextNoTags.trim() == "") {
                    headingTextNoTags = !$node.data("text") ? $node.text().trim() : $node.data("text");
                }

                var headingText = !$node.data("text") ? headingTextNoTags.trim() : $node.data("text");
                //var headingText = $node.data("text");
                var headingNo = parseInt(nodeTag.substr(1));
                var linkHash = $node.attr('id');
                //var linkHash = Waterdeep.CompendiumPage.makeHash(headingText);
                var nextNode = nodes[curNodeIdx + 1];
                var menuItemInfo = {
                    no: headingNo,
                    text: headingText,
                    children: [],
                    idx: curNodeIdx,
                    linkHash: linkHash,
                };

                // if there is something in the list and the sibling list number is greater than current node number,
                // we need to close out this list and go lower. this is meant to handle the transition from h3 -> h1
                if (list.length && list[0].no > headingNo) {
                    return {
                        list: list,
                        curNodeIdx: curNodeIdx,
                    };
                }

                // if there isn't a next node, we need to push in current item and return the current list
                if (!nextNode) {
                    curNodeIdx++;
                    list.push(menuItemInfo);
                    return {
                        list: list,
                        curNodeIdx: curNodeIdx,
                    };
                }

                var nextNodeTag = nextNode.tagName.toLowerCase();
                var nextHeadingText = nextNode.innerHTML.trim();
                var nextHeadingNo = parseInt(nextNodeTag.substr(1));

                if (nextHeadingNo > headingNo) {
                    // The next node tells us we are diving deeper into the branch h1 -> h2.  Once the children come back,
                    // set what it found into the menu item's children and then we need to set the current node index equal
                    // to where the childnodes left off
                    var childNodes = Waterdeep.CompendiumPage.menuListParser(nodes, curNodeIdx + 1);
                    menuItemInfo.children = childNodes.list;
                    list.push(menuItemInfo);
                    curNodeIdx = childNodes.curNodeIdx;
                    continue;
                } else if (nextHeadingNo < headingNo) {
                    // we are closing out the current menu and returning items since the next heading says we are going
                    // back up the branch (cur) h2 -> (next) h1
                    list.push(menuItemInfo);
                    curNodeIdx++;
                    return {
                        list: list,
                        curNodeIdx: curNodeIdx,
                    };
                } else if (nextHeadingNo == headingNo) {
                    // the next item is a "sibling" heading h2 -> h2, so lets just add this entry with no children into the list
                    list.push(menuItemInfo);
                }

                curNodeIdx++;
            }

            // when we get to the end and break out of the while loop, we need to return the last item to the last h1 item
            return {
                list: list,
                curNodeIdx: curNodeIdx,
            };
        },
        mobilizeTables: function($tables, shouldFlip) {
            if (shouldFlip) {
                $tables.not('.mobilize-exclude').each(function(tableIdx, table) {
                    var $table = $(table);
                    var $headings = $table.find('thead th, thead td');
                    var $rows = $table.find('tbody tr');
                    var textHeadings = $headings.map(function(idx, el) {
                        return $(el).text();
                    });

                    $rows.each(function(rowIdx, row) {
                        $(row).find('td').each(function(cellIdx, td) {
                            $(td).wrapInner('<div class="compendium-mobile-td-value" />');
                            $('<div class="compendium-mobile-td-label">' + textHeadings[cellIdx] + '</div>').prependTo(td);
                        });
                    });

                    $table.addClass('compendium-mobile-table');
                });
            } else {
                $tables.not('.mobilize-exclude')
                    .filter(function () {
                        return !$(this).parent('.table-overflow-wrapper')[0];
                    })
                    .each(function (tableIDx, table) {                    
                        var $table = $(table);                       
                        $table.wrap('<div class="table-overflow-wrapper"></div>');
                });
            }
        },
        renderSidebarMenu: function($context, $menuTarget, $menuMobileTarget, isSticky, initId) {
            //Set up menus
            var nodes = $context.find(Waterdeep.CompendiumPage.elToParse).find('h1, h2, h3, h4, h5').not(Waterdeep.CompendiumPage.elToIgnore + ', .quick-menu-exclude').get();
            var menuLists = Waterdeep.CompendiumPage.menuListParser(nodes, 0);
            var generatedMenu = Waterdeep.CompendiumPage.renderQuickMenu(menuLists.list);
            var generatedSelectMenu = Waterdeep.CompendiumPage.renderSelect(menuLists.list);
            var $container = $('<div class="sidebar-menu" />');

            $container.append('<div class="sidebar-menu-top"><a href="#top" class="sidebar-menu-top-link">Back to Top</a></div>');
            $container.append(generatedMenu);

            $menuTarget.prepend($container);
            $menuMobileTarget.prepend(generatedSelectMenu);

            Waterdeep.CompendiumPage.updateMenuItemPositions();

            if (isSticky && Cobalt && Cobalt.StickyElement) {
                Cobalt.StickyElement.initialize($container);
                $(window).on('scroll', throttle(Waterdeep.CompendiumPage.handleScroll, 100));
                $(window).on('resize', throttle(Waterdeep.CompendiumPage.handleResize, 200));
            }

            if (initId) {
                Waterdeep.CompendiumPage.activateMenuItemById(initId);
            }
        },
        renderBackButton: function($target) {
            var $breadcrumbs = $('#site-main').find('.b-breadcrumb').first().find('.b-breadcrumb-item a');
            var backCrumbIdx = 3;

            if ((backCrumbIdx + 1) >= $breadcrumbs.length) {
                return;
            }

            var $backCrumb = $breadcrumbs.eq(backCrumbIdx);
            var backCrumbUrl = $backCrumb.attr('href');
            var backCrumbText = $backCrumb.text();

            //TODO remove view-rules once beta stuff goes away and remove "stevanus-aurelius" once it is refactored out
            var $quickActions = $('<div class="compendium-quick-actions"><div class="more-links"><div class="more-links__links stevanus-aurelius"><a class="button-alt compendium-quick-action view-rules" href="' + backCrumbUrl + '"><span>Back to ' + backCrumbText + '</span></a></div></div></div>');
            $quickActions.prependTo($target);

            //TODO refactor Waterdeep.ShowMore.js to allow it to be reran, reimplementing for time :(
            $quickActions.find('div.more, .close').on('click', function toggleLinks() {
                var that = $(this);
                var links = that.hasClass('more') ? that.next('.links') : that.parent();
                links.toggleClass('stevanus-aurelius');
            });

        },
        assignAutomagicNodeIds: function assignAutomagicNodeIds($elements) {
            $elements.each(function() {
                var $this = $(this);
                $this.attr('id', Waterdeep.CompendiumPage.makeHash($this.text().trim()));
            });
        },

        //TODO remove this function
        tocInit: function($tocLists) {
            if (!window.Macy) {
                return;
            }

            $tocLists.each(function(idx, tocList) {
                var $tocList = $(tocList);
                var elementKey = 'toc-list-' + idx;
                $tocList.attr('id', elementKey);

                Macy.init({
                    container: '#' + elementKey,
                    columns: 4,
                    margin: 20,
                    breakAt: {
                        1025: 3,
                        769: 2,
                        768: 1,
                    }
                });
            });
        },
        initialize: function(isSticky, elToParse, elToIgnore) {
            var $context = $('#content');
            if (elToParse && elToParse !== null) {
                Waterdeep.CompendiumPage.elToParse = elToParse;
            }
            if (elToIgnore && elToIgnore !== null) {
                Waterdeep.CompendiumPage.elToIgnore = elToIgnore;
            }

            //Waterdeep.CompendiumPage.assignAutomagicNodeIds(
            //    $context.find(Waterdeep.CompendiumPage.elToParse).find('h1, h2, h3, h4, h5')
            //);

            Waterdeep.CompendiumPage.renderSidebarMenu(
                $context,
                $context.find('.secondary-content'),
                $context.find(Waterdeep.CompendiumPage.elToParse),
                isSticky,
                window.location.hash.slice(1)
            );

            Waterdeep.CompendiumPage.mobilizeTables($context.find('table'));

            //Waterdeep.CompendiumPage.tocInit($('.compendium-toc-list'));

            Waterdeep.CompendiumPage.renderBackButton($context.find(".primary-content"));
        }
    };

})(jQuery, Cobalt, Waterdeep);;
(function ($, Cobalt, Waterdeep, undefined) {
    'use strict';

    Waterdeep.ElasticSearch = {
        BaseSearchUrl: '/search',

        initialize: function($input) {
            $.widget('custom.ddbSearchAutoComplete', $.ui.autocomplete, {
                _renderItem: function(ul, item) {
                    var searchUrl = Waterdeep.ElasticSearch.BaseSearchUrl + '?q=' + item.value;

                    var tag = $('<a></a>')
                        .addClass('ddb-search-item--link')
                        .text(item.label)
                        .attr('href', searchUrl);


                    tag.on('click', function(event) {
                        // allows the user to open the link in a new tab/window by preventing JQUI.autocomplete from hijacking the click event.
                        event.stopImmediatePropagation();
                    });

                    return $('<li></li>')
                        .addClass('ddb-search-item--wrapper')
                        .data('item.autocomplete', item)
                        .append(tag)
                        .appendTo(ul);
                }
            });

            $input.ddbSearchAutoComplete({
                source: function (request, response) {
                    $.ajax({
                        url: '/es/term?query=' + request.term,
                        dataType: 'json',
                        success: function (data) {
                            response($.map(data.list, function (item) {
                                    return {
                                        value: item,
                                        label: item,
                                    }
                                }, function() {
                                    console.error(arguments)
                                }
                            ));
                        },
                        error: function(XMLHttpRequest, textStatus, errorThrown) {
                            console.error(errorThrown);
                        },
                    });
                },
                minLength: 0,
                appendTo: $input.siblings('.autocomplete-target'),
                open: function() {
                    $input.siblings('.autocomplete-target').removeClass('hide');
                    $('.ui-menu').addClass('ddb-search-autocomplete').css({
                        width: 'unset',
                        left: '-1px',
                        right: '-1px',
                        top: '68px',
                        zIndex: '9999'
                    });
                },
                close: function() {
                    $input.siblings('.autocomplete-target').addClass('hide');
                }
            });

            Waterdeep.ElasticSearch.fillInputFromQuery($input);
        },

        getSearchTermFromInput: function($input) {
            return $input.find('.es-form-field-query').val();
        },

        getSearchTermFromQueryString: function(location) {
            var term;

            if (location.href.indexOf('q=') >= 0) {
                term = getQueryParam(window.location, 'q');
            }

            return term ? term : '';
        },

        navigateToSearchWithQuery: function(e) {
            var base = Waterdeep.ElasticSearch.BaseSearchUrl;
            var searchTerm = Waterdeep.ElasticSearch.getSearchTermFromInput($(this));
            var searchQuery = base;

            if (searchTerm) {
                searchQuery += '?q=' + searchTerm;
            }

            e.preventDefault();
            window.location.href = searchQuery;
        },

        fillInputFromQuery: function($input) {
            var searchTerm = Waterdeep.ElasticSearch.getSearchTermFromQueryString(window.location);
            $input.val(window.decodeURIComponent(searchTerm))
        }
    };

    function getQueryParam(location, name) {
        var q = location.search.match(new RegExp('[?&]' + name + '=([^&#]*)'));
        return q && q[1];
    }

})(jQuery, Cobalt, Waterdeep);
;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";
    Waterdeep.GenericEntities = {
        initialize: function () {
            Cobalt.runOnHtmlInsert((function () {
                var entitiesJson = Waterdeep.GenericEntities.initialData;
                var $itemModalForm = $('.t-save-deck-modal');

                // Don't run unless desired form has loaded on page.
                if ($itemModalForm.length > 0) {
                    var $entityTypeField = $('.t-save-deck-modal #field-entity-type');
                    var $entityField = $('.t-save-deck-modal #field-entity');

                    Waterdeep.GenericEntities.refreshType(entitiesJson, $entityTypeField, $entityField);
                
                    $entityTypeField.on('change',
                        function() {
                            Waterdeep.GenericEntities.refreshType(entitiesJson, $entityTypeField, $entityField);
                        });                   
                } else {
                    var $entityTypeField = $('#field-entity-type');
                    var $entityField = $('#field-entity');

                    Waterdeep.GenericEntities.refreshType(entitiesJson, $entityTypeField, $entityField);

                    $entityTypeField.on('change', function () { Waterdeep.GenericEntities.refreshType(entitiesJson, $entityTypeField, $entityField) });
                }
            }));
        },

        refreshType: function (json, $typeField, $itemField) {            
            var typeVal = $typeField.val();
            var itemVal = $itemField.val();

            function onTypeChange(id) {
                $itemField.html("");
                $.each(json[0], function (key, value) {
                    if (value.type && value.type.toString() === id) {
                        $itemField.append($("<option></option>")
                            .attr("value", id + ":" + value.id)
                            .text(value.name));
                    } 
                });

                $itemField.val(itemVal).trigger('change'); // Trigger change for Select2
            };

            onTypeChange(typeVal);
        },
    }



})(jQuery, Cobalt, Waterdeep);;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.Notifications = {
        initialize: function(options) {

            vex.defaultOptions = {
                content: options.content || '',
                unsafeContent: options.unsafeContent || '',
                showCloseButton: !!options.showCloseButton,
                escapeButtonCloses: true,
                overlayClosesOnClick: true,
                appendLocation: options.appendLocation || '#content',
                className: options.className || 'vex-theme-default',
                overlayClassName: options.overlayClassName || '',
                contentClassName: options.contentClassName || '',
                closeClassName: options.closeClassName || '',
            };
        },

        open: vex.dialog.open,
        alert: function(messageOrOptions) {
            return vex.dialog.alert(messageOrOptions);
        },
        confirm: vex.dialog.confirm,
        prompt: vex.dialog.prompt

    };

})(jQuery, Cobalt, Waterdeep);
;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

    Waterdeep.FormValidation = {
        initialize: function(triggeringFields, fieldsToDisable, triggerFuncs) {
            if (!triggeringFields || !fieldsToDisable || !triggerFuncs) {
                console.error("Form Validation requires an array of triggering fields, and array of fields to disable, and an array of trigger functions.");
                return;
            }

            Waterdeep.FormValidation.disableFields(fieldsToDisable);

            $(triggeringFields.join(', ')).change(function (e) { //watch each element for change
                Waterdeep.FormValidation.processTriggerFuncs(triggerFuncs, e)
            });
        },

        disableFields: function (fieldsToDisable) {
            fieldsToDisable.forEach(function (field, idx, list) {
                $(field).addClass('disabled');
            });
        },

        processTriggerFuncs: function(triggerFuncs, e) {
            triggerFuncs.forEach(function (func, idx, list) { //go through list of triggers, and run each function over the event obj
                func(e);
            });
        },

        checkSelectValue: function(targetId, validOption, $dependentField, event) {
            if (event.target.id === targetId) {
                var selectedOption = event.target.selectedOptions[0].label;
                var shouldEnable = false;

                if (Array.isArray(validOption)) {

                    for (var i = 0; i < validOption.length; i++) {
                        if (validOption[i] === selectedOption) {
                            shouldEnable = true;
                            break;
                        } else {
                            continue;
                        }
                    }
                } else {
                    shouldEnable = selectedOption === validOption;
                }

                if (validOption === '_Any') {
                    shouldEnable = event.target.selectedOptions[0].value.length > 0;
                }

                if (shouldEnable) {
                    $dependentField.removeClass('disabled');
                } else if (!$dependentField.hasClass('disabled')) {
                    $dependentField.addClass('disabled');
                }
            }
        },

        checkBooleanValue: function(targetId, shouldBeTrueOrFalse, $dependentField, event) {
            if (event.target.id === targetId) {
                var isTrue = event.target.checked;
                var shouldEnable = isTrue === shouldBeTrueOrFalse;

                if (shouldEnable) {
                    $dependentField.removeClass('disabled');
                } else if (!$dependentField.hasClass('disabled')) {
                    $dependentField.addClass('disabled');
                }
            }
        },

        checkTextValue: function(targetId, expectedValue, $dependentField, event) {
            if (event.target.id === targetId) {
                var enteredValue = event.target.value;
                var shouldEnable = enteredValue === expectedValue;

                if (expectedValue === '_Any') {
                    shouldEnable = enteredValue.length > 0;
                }

                if (shouldEnable) {
                    $dependentField.removeClass('disabled');
                } else if (!$dependentField.hasClass('disabled')) {
                    $dependentField.addClass('disabled');
                }
            }
        }
    };

})(jQuery, Cobalt, Waterdeep);
;
(function ($, Cobalt, Waterdeep, undefined) {
    "use strict";

	Waterdeep.Social = {
	    initialize: function () {

	        $('button.facebook-share-result').click(Waterdeep.Social.facebookShare);
	        $('button.twitter-share-result').click(Waterdeep.Social.twitterShare);
	        $('button.reddit-share-result').click(Waterdeep.Social.redditShare);

	    },

	    facebookShare: function () {
	        var url = "https://www.facebook.com/dialog/feed?";
	        var $fbShareButton = $(this);

	        url += "display=popup&";
	        url += "app_id=" + $fbShareButton.attr('data-fb-appid') + "&";
	        url += "redirect_uri=" + $fbShareButton.attr('data-fb-redirect_uri') + "&"
	        url += "link=" + $fbShareButton.attr('data-fb-link') + "&";
	        url += "picture=" + $fbShareButton.attr('data-fb-picture') + "&";
	        url += "name=" + $fbShareButton.attr('data-fb-name') + "&";
	        url += "description=" + $fbShareButton.attr('data-fb-description');

	        window.open(url, "_blank", "resizable=no, top=400, width=643, height=386");
	    },

	    twitterShare: function () {
	        var url = "https://twitter.com/intent/tweet?";
	        var $twitterShareButton = $(this);

	        url += "text=" + $twitterShareButton.attr('data-twitter-text') + "&";

	        window.open(url, "_blank", "resizable=no, top=400, width=643, height=386");
	    },

	    redditShare: function () {
	        var url = "http://www.reddit.com/submit?";
	        var $redditShareButton = $(this);

	        url += "url=" + $redditShareButton.attr('data-reddit-url') + "&";
	        url += "title=" + $redditShareButton.attr('data-reddit-title');

	        window.open(url, "_blank");
	    }
	};
	
})(jQuery, Cobalt, Waterdeep);
;
(function (Cobalt, Waterdeep, undefined) {
    "use strict";

    var collapsibleConfig = {
        groupSelector: '.j-collapsible',
        triggerSelector: '.j-collapsible__trigger',
        contentSelector: '.j-collapsible__content',
        itemSelector: '.j-collapsible__item',
    };

    function CollapsibleActions(key, collapsibleElem, visibilityCallback) {
        var triggerChunks = [];
        var contentChunks = [];
        var triggerCallbacks = [];
        var isOpened = true;

        var items = [];
        var keyword = null;

        function init() {
            var triggers = collapsibleElem.querySelectorAll(collapsibleConfig.triggerSelector);
            var contents = collapsibleElem.querySelectorAll(collapsibleConfig.contentSelector);

            for (var i = 0; i < triggers.length; i++) {
                triggerChunks.push(triggers[i]);
            }
            for (var i = 0; i < contents.length; i++) {
                contentChunks.push(contents[i]);
            }
            for (var i = 0; i < contentChunks.length; i++) {
                items = [...items, ...contentChunks[i].querySelectorAll(collapsibleConfig.itemSelector)];
            }

            attachListeners();
        }

        function destroy() {
            removeListeners();
        }

        function attachListeners() {
            for (var i = 0; i < triggerChunks.length; i++) {
                var triggerCallback = toggleCollapsible.bind(null);

                triggerCallbacks.push(triggerCallback);

                triggerChunks[i].addEventListener('click', triggerCallback);
            }
        }

        function removeListeners() {
            for (var i = 0; i < triggerChunks.length; i++) {
                triggerChunks[i].removeEventListener('click', triggerCallbacks[i]);
            }
        }

        function toggleCollapsible() {
            isOpened = !isOpened;

            updateVisibility();
        }

        function updateVisibility() {

            //Handles state of collapsible header
            for (var i = 0; i < triggerChunks.length; i++) {
                if (isOpened) {
                    triggerChunks[i].classList.remove("ddb-collapsible__header--closed");
                } else {
                    triggerChunks[i].classList.add("ddb-collapsible__header--closed");
                }

                // toggle aria attributes
                (controller => {
                    const expandedString = controller.getAttribute('aria-expanded');

                    if (expandedString) {
                        const expandedStatus = expandedString.toLowerCase() === 'true';

                        if (expandedStatus !== undefined) {
                            controller.setAttribute('aria-expanded', !expandedStatus);
                        }
                    }
                })(triggerChunks[i])
            }

            //Handles state of collapsible content
            for (var i = 0; i < contentChunks.length; i++) {
                if (isOpened) {
                    contentChunks[i].classList.remove("ddb-collapsible__content--closed");
                } else {
                    contentChunks[i].classList.add("ddb-collapsible__content--closed");
                }
            }

            //Filtering collapsible items
            var hiddenCount = 0;
            for (var i = 0; i < items.length; i++) {
                var item = items[i];
                var itemSearchAttributes = item.dataset.collapsibleSearch.split(/[|,]/);
                if (keyword !== null && !Waterdeep.FilterUtils.doesQueryMatchData(keyword, '', itemSearchAttributes)) {
                    item.classList.add("ddb-collapsible__item--hidden");
                    hiddenCount += 1;
                } else {
                    item.classList.remove("ddb-collapsible__item--hidden");
                }
            }

            //Filter collapsible group
            if (hiddenCount === items.length) {
                collapsibleElem.classList.add("ddb-collapsible--hidden");
            } else {
                collapsibleElem.classList.remove("ddb-collapsible--hidden");
            }

            visibilityCallback(key, hiddenCount === items.length);
        }

        init();

        return {
            destroy: destroy,
            setKeyword: function setKeyword(newKeyword) {
                keyword = newKeyword;
                updateVisibility();
            },
            setIsOpened: function setIsOpened(newStatus) {
                isOpened = newStatus;
                updateVisibility();
            },
        };
    }

    Waterdeep.CollapsibleListing = {
        windowWidth: 0,
        collapsibles: [],
        collapsibleHiddenVisibilities: [],
        searchGroup: null,
        searchValue: null,
        searchStickyTopPosition: 0,
        searchStickyTopCss: 0,

        handleCollapsibleVisibilityCallback: function handleCollapsibleVisibilityCallback(key, isHidden) {
            Waterdeep.CollapsibleListing.collapsibleHiddenVisibilities[key] = isHidden;
            Waterdeep.CollapsibleListing.updateVisibility();
        },

        handleSearchKeyUp: function handleSearchKeyUp(evt) {
            Waterdeep.CollapsibleListing.searchValue = evt.target.value.toLowerCase();

            if (evt.target.value === '') {
                Waterdeep.CollapsibleListing.searchValue = null;
            }

            Waterdeep.CollapsibleListing.collapsibles.forEach(function (group) {
                group.setKeyword(Waterdeep.CollapsibleListing.searchValue);

                if (Waterdeep.CollapsibleListing.searchValue !== null || Waterdeep.CollapsibleListing.searchvalue !== '') {
                    group.setIsOpened(true);
                }
            });

            Waterdeep.CollapsibleListing.handleClearVisibility();
        },

        handleSearchClear: function handleSearchClear() {
            Waterdeep.CollapsibleListing.searchValue = null;
            document.querySelector('.j-collapsible__search-input').value = '';

            Waterdeep.CollapsibleListing.collapsibles.forEach(function (group) {
                group.setKeyword(Waterdeep.CollapsibleListing.searchValue);
            });

            Waterdeep.CollapsibleListing.handleClearVisibility();
        },

        handleClearVisibility: function handleClearVisibility() {
            var clearTrigger = document.querySelector('.ddb-collapsible-filter__clear');

            if (Waterdeep.CollapsibleListing.searchValue !== null && Waterdeep.CollapsibleListing.searchvalue !== '') {
                clearTrigger.classList.remove('ddb-collapsible-filter__clear--hidden');
            } else {
                clearTrigger.classList.add('ddb-collapsible-filter__clear--hidden');
            }
        },

        handleOrientationChange: function handleOrientationChange() {
            var oldWidth = Waterdeep.CollapsibleListing.windowWidth;
            var count = 0;
            var orientationIntervalId = null;
            orientationIntervalId = setInterval(function () {
                if (oldWidth !== Waterdeep.CollapsibleListing.windowWidth || count > 15) {
                    clearInterval(orientationIntervalId);
                    return;
                }
                if (oldWidth !== window.innerWidth) {
                    Waterdeep.CollapsibleListing.updatePosition();
                }
                count++;
            }, 100);
        },

        updateVisibility: function updateVisibility() {
            var noResults = document.querySelector('.ddb-collapsible-filter__no-results');
            var collapsiblesHidden = Waterdeep.CollapsibleListing.collapsibleHiddenVisibilities.filter(function (hiddenCollapsible) {
                return hiddenCollapsible === false;
            });

            if (noResults !== null && collapsiblesHidden.length !== 0) {
                noResults.classList.add('ddb-collapsible-filter__no-results--hidden');
            } else {
                noResults.classList.remove('ddb-collapsible-filter__no-results--hidden');
            }
        },

        updatePosition: function updatePosition() {
            var searchGroup = Waterdeep.CollapsibleListing.searchGroup;
            var position = Waterdeep.CollapsibleListing.getPosition(searchGroup);
            Waterdeep.CollapsibleListing.searchStickyTopPosition = position.top;
            Waterdeep.CollapsibleListing.windowWidth = window.innerWidth;
            Waterdeep.CollapsibleListing.searchStickyTopCss = searchGroup.offsetTop;

            if (Waterdeep.CollapsibleListing.searchStickyTopPosition <= 48 && Waterdeep.CollapsibleListing.windowWidth < 1024) {
                searchGroup.classList.add('ddb-collapsible-filter--stuck');
            } else {
                searchGroup.classList.remove('ddb-collapsible-filter--stuck');
            }
        },

        getPosition: function getPosition(el) {
            const rect = el.getBoundingClientRect();
            return {
                top: rect.top,
            };
        },

        initialize: function initialize() {
            var collapsibles = document.querySelectorAll(collapsibleConfig.groupSelector);

            var searchGroup = document.querySelector('.j-collapsible__search');
            if (searchGroup !== null) {
                Waterdeep.CollapsibleListing.searchGroup = searchGroup;
                Waterdeep.CollapsibleListing.searchStickyTopCss = searchGroup.offsetTop;

                var searchInput = searchGroup.querySelector('.j-collapsible__search-input');
                if (searchInput !== null) {
                    searchInput.addEventListener('keyup', Waterdeep.CollapsibleListing.handleSearchKeyUp);
                    var clearInput = searchGroup.querySelector('.j-collapsible__search-clear');
                    clearInput.addEventListener('click', Waterdeep.CollapsibleListing.handleSearchClear);

                    var throttledUpdatePosition = window.throttle ? throttle(Waterdeep.CollapsibleListing.updatePosition, 20) : Waterdeep.CollapsibleListing.updatePosition;
                    window.addEventListener('scroll', throttledUpdatePosition);
                    window.addEventListener('resize', throttledUpdatePosition);

                    window.addEventListener('orientationchange', Waterdeep.CollapsibleListing.handleOrientationChange);
                }
            }

            for (var i = 0; i < collapsibles.length; i++) {
                var collapsible = collapsibles[i];

                Waterdeep.CollapsibleListing.collapsibles.push(new CollapsibleActions(i, collapsible, Waterdeep.CollapsibleListing.handleCollapsibleVisibilityCallback));
                Waterdeep.CollapsibleListing.collapsibleHiddenVisibilities[i] = true;
            }
        },

    };

})(Cobalt, Waterdeep);;
(function (Cobalt, Waterdeep, undefined) {
    "use strict";

    //localStorage availability testing: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
    function localStorageAvailable() {
        var storage;
        try {
            storage = window['localStorage'];
            var x = '__storage_test__';
            storage.setItem(x, x);
            storage.removeItem(x);
            return true;
        }
        catch (e) {
            return e instanceof DOMException && (
                // everything except Firefox
                e.code === 22 ||
                // Firefox
                e.code === 1014 ||
                // test name field too, because code might not be present
                // everything except Firefox
                e.name === 'QuotaExceededError' ||
                // Firefox
                e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
                // acknowledge QuotaExceededError only if there's something already stored
                (storage && storage.length !== 0);
        }
    }

    var sortOrderStorageKey = 'MY_CHARACTERS_SORT_PREFERENCE';

    var searchAndSortConfig = {
        searchGroupSelector: '.j-characters-listing__search',
        searchInputSelector: '.j-characters-listing__search-input',
        searchClearSelector: '.j-characters-listing__search-clear',
        sortSelector: '.j-characters-listing__sort',
        contentSelector: '.j-characters-listing__content',
        itemSelector: '.j-characters-listing__item',
        noResultsSelector: '.j-characters-listing__no-results',
        cardListSelector: '.rpgcharacter-listing', //this classname is generated, making it more difficult to follow the j- prefix convention
    };

    function SearchAndSortActions(key, contentElem) {
        var items = [];
        var cardList = null;
        var noResults = null;
        var keyword = null;
        var sortOption = null;

        function init() {
            var itemElems = contentElem.querySelectorAll(searchAndSortConfig.itemSelector);
            for (var i = 0; i < itemElems.length; i++) {
                var itemData = {
                    sortName: itemElems[i].dataset.sortName.toLowerCase(),
                    sortLevel: parseInt(itemElems[i].dataset.sortLevel),
                    sortCreated: new Date(itemElems[i].dataset.sortCreated),
                    sortModified: new Date(itemElems[i].dataset.sortModified),
                    searchTerms: itemElems[i].dataset.searchTerms.split(/[|,]/),
                    elem: itemElems[i],
                }
                items.push(itemData);
            }

            var cardListElem = contentElem.querySelector(searchAndSortConfig.cardListSelector);
            cardList = cardListElem;

            var noResultsElem = document.querySelector(searchAndSortConfig.noResultsSelector);
            noResults = noResultsElem;
        }

        function destroy() {

        }

        function updateVisibility() {
            var hiddenCount = 0;
            for (var i = 0; i < items.length; i++) {
                var item = items[i].elem;
                var itemSearchAttributes = items[i].searchTerms;
                if (keyword !== null && !Waterdeep.FilterUtils.doesQueryMatchData(keyword, '', itemSearchAttributes)) {
                    item.classList.add("ddb-campaigns-character-card-wrapper--hidden");
                    hiddenCount += 1;
                } else {
                    item.classList.remove("ddb-campaigns-character-card-wrapper--hidden");
                }
            }

            if (noResults !== null && hiddenCount === items.length) {
                noResults.classList.remove('ddb-characters-listing-actions__no-results--hidden');
            } else {
                noResults.classList.add('ddb-characters-listing-actions__no-results--hidden');            
            }
        }

        function sortCallback(a, b) {
            if (a < b) { return -1; }
            if (b < a) { return 1; }

            return 0;
        }

        function updateSortOrder() {
            var sortStrategy = null;

            switch (sortOption) {
                case 'name-asc':
                    sortStrategy = function (a, b) {
                        return sortCallback(a.sortName, b.sortName)
                    };
                    break;
                case 'name-desc':
                    sortStrategy = function (a, b) {
                        return sortCallback(b.sortName, a.sortName)
                    };
                    break;
                case 'level-asc':
                    sortStrategy = function (a, b) {
                        return sortCallback(a.sortLevel, b.sortLevel)
                    };
                    break;
                case 'level-desc':
                    sortStrategy = function (a, b) {
                        return sortCallback(b.sortLevel, a.sortLevel)
                    };
                    break;
                case 'created-asc':
                    sortStrategy = function (a, b) {
                        return sortCallback(b.sortCreated, a.sortCreated)
                    };
                    break;
                case 'created-desc':
                    sortStrategy = function (a, b) {
                        return sortCallback(a.sortCreated, b.sortCreated)
                    };
                    break;
                case 'modified-asc':
                    sortStrategy = function (a, b) {
                        return sortCallback(b.sortModified, a.sortModified)
                    };
                    break;
                case 'modified-desc':
                    sortStrategy = function (a, b) {
                        return sortCallback(a.sortModified, b.sortModified)
                    };
                    break;
            }

            if (sortStrategy !== null) {
                items = items.sort(sortStrategy)
            }

            for (i = 0; i < items.length; ++i) {
                cardList.appendChild(items[i].elem);
            }
        }

        function setSortPreference() {
            if (localStorageAvailable()) {
                localStorage.setItem(sortOrderStorageKey, sortOption);
            }
        }

        init();

        return {
            destroy: destroy,
            setKeyword: function setKeyword(newKeyword) {
                keyword = newKeyword;
                updateVisibility();
            },
            setSortOption: function setSortOption(newSortOption) {
                sortOption = newSortOption;
                updateSortOrder();
                setSortPreference();
            },
        };
    }

    Waterdeep.CharacterSearchAndSort = {
        contentGroups: [],
        searchGroup: null,
        searchValue: null,
        sortOption: null,

        handleSearchKeyUp: function handleSearchKeyUp(evt) {
            Waterdeep.CharacterSearchAndSort.searchValue = evt.target.value.toLowerCase();

            if (evt.target.value === '') {
                Waterdeep.CharacterSearchAndSort.searchValue = null;
            }

            Waterdeep.CharacterSearchAndSort.contentGroups.forEach(function (group) {
                group.setKeyword(Waterdeep.CharacterSearchAndSort.searchValue);
            });

            Waterdeep.CharacterSearchAndSort.handleClearVisibility();
        },

        handleSearchClear: function handleSearchClear() {
            Waterdeep.CharacterSearchAndSort.searchValue = null;
            document.querySelector(searchAndSortConfig.searchInputSelector).value = '';

            Waterdeep.CharacterSearchAndSort.contentGroups.forEach(function (group) {
                group.setKeyword(Waterdeep.CharacterSearchAndSort.searchValue);
            });

            Waterdeep.CharacterSearchAndSort.handleClearVisibility();
        },

        handleClearVisibility: function handleClearVisibility() {
            var clearTrigger = document.querySelector(searchAndSortConfig.searchClearSelector);

            if (Waterdeep.CharacterSearchAndSort.searchValue !== null && Waterdeep.CharacterSearchAndSort.searchvalue !== '') {
                clearTrigger.classList.remove('ddb-characters-listing-actions__search-clear--hidden');
            } else {
                clearTrigger.classList.add('ddb-characters-listing-actions__search-clear--hidden');
            }
        },

        handleSortChange: function handleSortChange(evt) {
            Waterdeep.CharacterSearchAndSort.sortOption = evt.target.value;

            Waterdeep.CharacterSearchAndSort.contentGroups.forEach(function (group) {
                group.setSortOption(Waterdeep.CharacterSearchAndSort.sortOption);
            });
        },

        initialize: function initialize() {
            var sortPreference = null;
            if (localStorageAvailable()) {
                if (window.Waterdeep && window.Waterdeep.User && window.Waterdeep.User.ID) {
                    sortOrderStorageKey = [sortOrderStorageKey, window.Waterdeep.User.ID].join(':');
                }
                sortPreference = localStorage.getItem(sortOrderStorageKey);
            }

            Waterdeep.CharacterSearchAndSort.sortOption = sortPreference;

            var searchGroup = document.querySelector(searchAndSortConfig.searchGroupSelector);
            if (searchGroup !== null) {
                Waterdeep.CharacterSearchAndSort.searchGroup = searchGroup;
            }

            var searchInput = searchGroup.querySelector(searchAndSortConfig.searchInputSelector);
            if (searchInput !== null) {
                searchInput.addEventListener('keyup', Waterdeep.CharacterSearchAndSort.handleSearchKeyUp);

                var clearInput = searchGroup.querySelector(searchAndSortConfig.searchClearSelector);
                clearInput.addEventListener('click', Waterdeep.CharacterSearchAndSort.handleSearchClear);
            }

            var sortSelect = document.querySelector(searchAndSortConfig.sortSelector);
            if (sortSelect !== null) {
                if (sortPreference) {
                    for (var i = 0; i < sortSelect.options.length; i++) {
                        if (sortSelect.options[i].value === sortPreference) {
                            sortSelect.options[i].selected = true;
                        }
                    }
                }

                sortSelect.addEventListener('change', Waterdeep.CharacterSearchAndSort.handleSortChange);
            }

            var contentGroups = document.querySelectorAll(searchAndSortConfig.contentSelector);
            for (var i = 0; i < contentGroups.length; i++) {
                var group = contentGroups[i];

                Waterdeep.CharacterSearchAndSort.contentGroups.push(new SearchAndSortActions(i, group));
            }

            Waterdeep.CharacterSearchAndSort.contentGroups.forEach(function (group) {
                group.setSortOption(Waterdeep.CharacterSearchAndSort.sortOption);
            });
        },

    };

})(Cobalt, Waterdeep);;
(function (Cobalt, Waterdeep, undefined) {
    "use strict";

    function checkQueryPiece(input, startIdx, pieceIdx, pieceCharIdx, pieces) {
        let i, ch;
        let length = input.length;
        for (i = startIdx; i < length; i++) {
            ch = input.charAt(i);
            switch (ch) {
                case ' ':
                case '-':
                case '.':
                case '"':
                    continue; //ignore spaces, dashes, periods, and double quotes
                default:
                    if (pieceIdx < pieces.length) {
                        let piece = pieces[pieceIdx];
                        if (pieceCharIdx < piece.length && ch === piece.charAt(pieceCharIdx)) {
                            //if current character matches, check next character in piece
                            if (checkQueryPiece(input, i + 1, pieceIdx, pieceCharIdx + 1, pieces)) {
                                return true;
                            }
                            //if path for next character doesn't match, try path from start of next piece
                            if (checkQueryPiece(input, i + 1, pieceIdx + 1, 0, pieces)) {
                                return true;
                            }
                        }
                        if (pieceCharIdx === 0) {
                            //if first character of piece doesn't match, allow skipping that piece
                            if (checkQueryPiece(input, i, pieceIdx + 1, 0, pieces)) {
                                return true;
                            }
                        }
                    }
                    return false; //no match if no path above reaches end of input string
            }
        }
        return true; //match if reached end of input string
    }

    function doesQueryMatchData(query, primaryText, tags=[]) {
        if (!query) return true;

        var ignoredCharRegex = /["+\(\)']/g;
        
        let input = query.replace(ignoredCharRegex, "").toLowerCase().trim();

        if (!input) {
            // if there is no query don't filter anything
            return true;
        }

        let processedPrimaryText = primaryText.replace(ignoredCharRegex, "").toLowerCase().trim();
        let processedTags = tags && tags.length ? tags.map(tag => tag ? tag.toLowerCase().trim() : tag) : [];
        let pieces = processedPrimaryText.split(/[ -]/);
        if (checkQueryPiece(input, 0, 0, 0, pieces)) {
            //don't filter out item if heading matches
            return true;
        }

        // if heading isn't a match, see if input is an exact match for associated tags
        if (!processedTags.length) {
            // filter out item if no tags specified
            return false;
        }

        let tagMatch = false;
        processedTags.forEach(tag => {
            if (tagMatch || !tag) {
                return;
            }
            let pieces = tag.replace(ignoredCharRegex, "").split(/[ -]/);
            tagMatch = checkQueryPiece(input, 0, 0, 0, pieces);
        });

        return tagMatch;
    }

    Waterdeep.FilterUtils = {
        initialize: function initialize() {

        },

        doesQueryMatchData: doesQueryMatchData,
    };

})(Cobalt, Waterdeep);;
Waterdeep.Routes.AttachmentAdd = function(attachmentID, routeValues) {
    return Waterdeep.Routes.buildRoute("/attachment/{0}/add".format(attachmentID), routeValues);
};
Waterdeep.Routes.AttachmentDelete = function(attachmentID, routeValues) {
    return Waterdeep.Routes.buildRoute("/attachment/{0}/delete".format(attachmentID), routeValues);
};
Waterdeep.Routes.AttachmentDeleteAttachment = function(modelTypeID, id, routeValues) {
    return Waterdeep.Routes.buildRoute("/attachment/delete-attachment/{0}-{1}".format(modelTypeID, id), routeValues);
};
Waterdeep.Routes.AttachmentRename = function(attachmentID, routeValues) {
    return Waterdeep.Routes.buildRoute("/attachment/{0}/rename".format(attachmentID), routeValues);
};
Waterdeep.Routes.AudioRename = function(audioID, routeValues) {
    return Waterdeep.Routes.buildRoute("/audio/{0}/rename".format(audioID), routeValues);
};
Waterdeep.Routes.AuthenticationAjaxCheckAvailableEmail = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/user/email/available", routeValues);
};
Waterdeep.Routes.AuthenticationAjaxUserNameIsAvilableCheck = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/user/available", routeValues);
};
Waterdeep.Routes.AuthenticationPrivacyPolicyJson = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/privacy-policy/json", routeValues);
};
Waterdeep.Routes.AuthenticationPrivacyPolicySignedJson = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/privacy-policy-signed/json", routeValues);
};
Waterdeep.Routes.AvatarActivateAvatar = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax-activate-avatar", routeValues);
};
Waterdeep.Routes.AvatarDeleteAvatar = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax-delete-avatar", routeValues);
};
Waterdeep.Routes.AvatarDisableAvatar = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax-disable-avatar", routeValues);
};
Waterdeep.Routes.AvatarUploadAvatar = function(entityTypeID, entityID, routeValues) {
    return Waterdeep.Routes.buildRoute("/avatar/{0}-{1}/upload".format(entityTypeID, entityID), routeValues);
};
Waterdeep.Routes.CategoryPostGetData = function(postID, routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/posts/{0}/get-data".format(postID), routeValues);
};
Waterdeep.Routes.CommentGetCommentRevision = function(commentID, revisionNumber, routeValues) {
    return Waterdeep.Routes.buildRoute("/comments/{0}/revisions/{1}/get.json".format(commentID, revisionNumber), routeValues);
};
Waterdeep.Routes.CommentGetCommentRevisions = function(commentID, routeValues) {
    return Waterdeep.Routes.buildRoute("/comments/{0}/revisions".format(commentID), routeValues);
};
Waterdeep.Routes.CommentRatingModal = function(entityTypeID, entityID, routeValues) {
    return Waterdeep.Routes.buildRoute("/comments/rating-modal/{0}-{1}".format(entityTypeID, entityID), routeValues);
};
Waterdeep.Routes.CommentRevisionRollback = function(commentID, revisionNumber, routeValues) {
    return Waterdeep.Routes.buildRoute("/comments/{0}/revisions/{1}/rollback".format(commentID, revisionNumber), routeValues);
};
Waterdeep.Routes.CommonStorePreferences = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/store-preferences", routeValues);
};
Waterdeep.Routes.CPAchievementDelete = function(id, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/achievements/delete/{0}".format(id), routeValues);
};
Waterdeep.Routes.CPAjaxAutoCompleteRouteName = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/ajaxautocompleteroutename", routeValues);
};
Waterdeep.Routes.CPAjaxAutoCompleteSiteName = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/ajaxautocompletesitename", routeValues);
};
Waterdeep.Routes.CPAjaxAutoCompleteTitle = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/ajaxautocompletetitle", routeValues);
};
Waterdeep.Routes.CPAnnouncementDelete = function(announcementID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/announcements/{0}/delete".format(announcementID), routeValues);
};
Waterdeep.Routes.CPAnnouncementUnDelete = function(announcementID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/announcement/{0}/undelete".format(announcementID), routeValues);
};
Waterdeep.Routes.CPCacheManagerInvalidateDataKey = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/cache-manager/invalidate-data-key", routeValues);
};
Waterdeep.Routes.CPCategoryContentBulkModeration = function(categoryID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/cms/folders/{0}/bulk-content-moderation".format(categoryID), routeValues);
};
Waterdeep.Routes.CPDomainPolicyDelete = function(domainPolicyID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/domain-policy/{0}/delete".format(domainPolicyID), routeValues);
};
Waterdeep.Routes.CPForumForm = function(parentForumID, displayOrder, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/ajax-forum-form/{0}/{1}".format(parentForumID, displayOrder), routeValues);
};
Waterdeep.Routes.CPGetNameForSite = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/getnameforsite", routeValues);
};
Waterdeep.Routes.CPGetSubNamespaces = function(namespaceID, routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/localization/getsubnamespaces/{0}".format(namespaceID), routeValues);
};
Waterdeep.Routes.CPGetWarningMessageTemplate = function(warningMessageID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/warning-messages/{0}/get-template.json".format(warningMessageID), routeValues);
};
Waterdeep.Routes.CPLocalizationIndex = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/localization", routeValues);
};
Waterdeep.Routes.CPLocalizationPhraseEdit = function(phraseID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/localization/phrase/{0}".format(phraseID), routeValues);
};
Waterdeep.Routes.CPPageGetUrl = function(parentFolderID, routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/get-page-url/{0}".format(parentFolderID), routeValues);
};
Waterdeep.Routes.CPPostGetUrl = function(categoryID, routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/get-post-url/{0}".format(categoryID), routeValues);
};
Waterdeep.Routes.CPPostRestoreRevision = function(postID, routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/posts/{0}/restore-revision".format(postID), routeValues);
};
Waterdeep.Routes.CPProfileFieldChangeGroup = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/profile-fields/update-group", routeValues);
};
Waterdeep.Routes.CPProfileFieldGroupUpdateDisplayOrder = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/profile-fields-groups/update-display-order", routeValues);
};
Waterdeep.Routes.CPProfileFieldUpdateDisplayOrder = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/profile-fields/update-display-order", routeValues);
};
Waterdeep.Routes.CPRoleDelete = function(entityTypeID, entityID, roleID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/user-groups/{0}-{1}/{2}/delete".format(entityTypeID, entityID, roleID), routeValues);
};
Waterdeep.Routes.CPUserNonceBillingTransactions = function(userID, routeValues) {
    return Waterdeep.Routes.buildRoute("/cp/users/{0}/nonce-billing-transactions".format(userID), routeValues);
};
Waterdeep.Routes.FeedbackSend = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/send-feedback", routeValues);
};
Waterdeep.Routes.ForumForumTopicsFilter = function(id, routeValues) {
    return Waterdeep.Routes.buildRoute("/page-block/forum-filters/{0}".format(id), routeValues);
};
Waterdeep.Routes.ForumGetAllForumSeenInfo = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/new-content/seeninfo", routeValues);
};
Waterdeep.Routes.ForumGetForumLatestThreads = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/page-block/forum-filters/get-threads.json", routeValues);
};
Waterdeep.Routes.ForumSetAllForumSeen = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/forums/set-all-forum-seen", routeValues);
};
Waterdeep.Routes.ForumSetAllForumThreadSeen = function(forumID, routeValues) {
    return Waterdeep.Routes.buildRoute("/forums/{0}/set-all-forum-thread-seen".format(forumID), routeValues);
};
Waterdeep.Routes.ForumSetForumSeen = function(forumID, routeValues) {
    return Waterdeep.Routes.buildRoute("/forums/{0}/set-forum-seen".format(forumID), routeValues);
};
Waterdeep.Routes.InfractionsGetWarningDefinitionDescription = function(userID, points, routeValues) {
    return Waterdeep.Routes.buildRoute("/user/{0}/warning/{1}/description.json".format(userID, points), routeValues);
};
Waterdeep.Routes.InfractionsGetWarningDefinitionDescriptionByComment = function(userID, commentID, points, routeValues) {
    return Waterdeep.Routes.buildRoute("/user/{0}/{1}/warning/{2}/description.json".format(userID, commentID, points), routeValues);
};
Waterdeep.Routes.PollDelete = function(parentTypeID, parentID, pollID, routeValues) {
    return Waterdeep.Routes.buildRoute("/polls/{0}-{1}/{2}/delete".format(parentTypeID, parentID, pollID), routeValues);
};
Waterdeep.Routes.PollGetPollForm = function(forumID, index, routeValues) {
    return Waterdeep.Routes.buildRoute("/polls/{0}/get-poll-form/{1}".format(forumID, index), routeValues);
};
Waterdeep.Routes.PollHasUserVoted = function(pollID, routeValues) {
    return Waterdeep.Routes.buildRoute("/polls/{0}/has-user-voted".format(pollID), routeValues);
};
Waterdeep.Routes.PrivateMessageAjaxAutoCompleteContact = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/private-message-auto-complete", routeValues);
};
Waterdeep.Routes.PrivateMessageCreateConversationFolder = function(conversationID, routeValues) {
    return Waterdeep.Routes.buildRoute("/private-messages/{0}/create-folder".format(conversationID), routeValues);
};
Waterdeep.Routes.PrivateMessageDeleteConversationFolder = function(conversationFolderID, routeValues) {
    return Waterdeep.Routes.buildRoute("/private-messages/delete-folder/{0}".format(conversationFolderID), routeValues);
};
Waterdeep.Routes.PrivateMessageIndex = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/private-messages", routeValues);
};
Waterdeep.Routes.PrivateMessageInvite = function(conversationID, routeValues) {
    return Waterdeep.Routes.buildRoute("/private-messages/{0}/invite".format(conversationID), routeValues);
};
Waterdeep.Routes.PrivateMessageMoveToConversationFolder = function(conversationID, conversationFolderID, routeValues) {
    return Waterdeep.Routes.buildRoute("/private-messages/{0}/move-to/{1}".format(conversationID, conversationFolderID), routeValues);
};
Waterdeep.Routes.RatingGetUserRatings = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/get-user-ratings", routeValues);
};
Waterdeep.Routes.ShoutboxAddMessage = function(commentID, routeValues) {
    return Waterdeep.Routes.buildRoute("/shoutbox/{0}/add-message".format(commentID), routeValues);
};
Waterdeep.Routes.ShoutboxDeleteMessage = function(commentID, routeValues) {
    return Waterdeep.Routes.buildRoute("/shoutbox/{0}/delete-message".format(commentID), routeValues);
};
Waterdeep.Routes.ShoutboxGetNewComments = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/shoutbox/get-new-comments", routeValues);
};
Waterdeep.Routes.ShoutboxGetShowShoutboxPreference = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/shoutbox/get-show-shoutbox-preference", routeValues);
};
Waterdeep.Routes.ShoutboxSaveShowShoutboxPreference = function(showShoutbox, routeValues) {
    return Waterdeep.Routes.buildRoute("/shoutbox/save-show-shoutbox-preference/{0}".format(showShoutbox), routeValues);
};
Waterdeep.Routes.SmileyGetSmilies = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/smilies/get-all", routeValues);
};
Waterdeep.Routes.TagAjaxGetTags = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax-get-tags", routeValues);
};
Waterdeep.Routes.UserAjaxAutoCompleteUsername = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/autocomplete-username", routeValues);
};
Waterdeep.Routes.UserGetUserSurrogateShortDetails = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax-get-surrogate-details", routeValues);
};
Waterdeep.Routes.UserWarningAcknowledgementChoice = function(choiceValue, routeValues) {
    return Waterdeep.Routes.buildRoute("/warning-acknowledgement/choice/{0}".format(choiceValue), routeValues);
};
Waterdeep.Routes.UserWarningAcknowledgementModal = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/warning-acknowledgement/get.json", routeValues);
};
Waterdeep.Routes.UserContentBulkModeration = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/my-content/bulk-moderation", routeValues);
};
Waterdeep.Routes.UserContentCreateFolder = function(routeValues) {
    return Waterdeep.Routes.buildRoute("/my-content/create-folder", routeValues);
};
Waterdeep.Routes.UserContentPostRestoreRevision = function(postID, revisionNumber, routeValues) {
    return Waterdeep.Routes.buildRoute("/ajax/my-content/{0}/restore-revision/{1}".format(postID, revisionNumber), routeValues);
};
;
Waterdeep.Localization.setLanguages([{"id":1,"name":"English","pluralForm":1,"phraseID":315,"localizedName":"English","code":"en"},{"id":2,"name":"Français (French)","pluralForm":2,"phraseID":316,"localizedName":"Français","code":"fr"},{"id":3,"name":"Deutsch (German)","pluralForm":1,"phraseID":317,"localizedName":"Deutsch","code":"de"},{"id":4,"name":"Español (Spanish)","pluralForm":1,"phraseID":318,"localizedName":"Español","code":"es"},{"id":5,"name":"Pусский (Russian)","pluralForm":7,"phraseID":319,"localizedName":"Pусский","code":"ru"},{"id":7,"name":"汉语 (Simplified Chinese)","pluralForm":0,"phraseID":320,"localizedName":"汉语","code":"zh"},{"id":8,"name":"日本語 (Japanese)","pluralForm":0,"phraseID":321,"localizedName":"日本語","code":"ja"},{"id":9,"name":"한국어 (Korean)","pluralForm":0,"phraseID":322,"localizedName":"한국어","code":"ko"},{"id":10,"name":"Svenska (Swedish)","pluralForm":1,"phraseID":323,"localizedName":"Svenska","code":"sv"},{"id":11,"name":"Bahasa Indonesia (Indonesian)","pluralForm":0,"phraseID":324,"localizedName":"Bahasa Indonesia","code":"id"},{"id":13,"name":"Ελληνικά (Greek)","pluralForm":1,"phraseID":325,"localizedName":"Ελληνικά","code":"el"},{"id":14,"name":"Polski (Polish)","pluralForm":9,"phraseID":326,"localizedName":"Polski","code":"pl"},{"id":15,"name":"Italiano (Italian)","pluralForm":1,"phraseID":966,"localizedName":"Italiano","code":"it"},{"id":16,"name":"繁體中文 (Traditional Chinese)","pluralForm":0,"phraseID":1189,"localizedName":"繁體中文","code":"tw"}]);
;
Waterdeep.Localization.Global = {
	Buttons: {
	                  ByValue: {},
		Cancel: function() {
			/// <summary>
			/// Gets the localized text for the phrase Cancel with text like "Cancel"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Create: function() {
			/// <summary>
			/// Gets the localized text for the phrase Create with text like "Create"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Delete: function() {
			/// <summary>
			/// Gets the localized text for the phrase Delete with text like "Delete"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Edit: function() {
			/// <summary>
			/// Gets the localized text for the phrase Edit with text like "Edit"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Push: function() {
			/// <summary>
			/// Gets the localized text for the phrase Push with text like "Push"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Update: function() {
			/// <summary>
			/// Gets the localized text for the phrase Update with text like "Update"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Common: {
	                  ByValue: {},
		Add: function() {
			/// <summary>
			/// Gets the localized text for the phrase Add with text like "Add"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		AddCharacter: function() {
			/// <summary>
			/// Gets the localized text for the phrase AddCharacter with text like "Add a character"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		AdvancedSearch: function() {
			/// <summary>
			/// Gets the localized text for the phrase AdvancedSearch with text like "Advanced Search"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Apply: function() {
			/// <summary>
			/// Gets the localized text for the phrase Apply with text like "Apply"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Ascending: function() {
			/// <summary>
			/// Gets the localized text for the phrase Ascending with text like "Ascending"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ClickHere: function() {
			/// <summary>
			/// Gets the localized text for the phrase ClickHere with text like "click here"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ColonConnector: function() {
			/// <summary>
			/// Gets the localized text for the phrase ColonConnector with text like ": "
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Comments: function() {
			/// <summary>
			/// Gets the localized text for the phrase Comments with text like "Comments"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ConfirmDelete: function(prompt) {
			/// <summary>
			/// Gets the localized text for the phrase ConfirmDelete with text like "Are you sure you want to delete {prompt}?"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Descending: function() {
			/// <summary>
			/// Gets the localized text for the phrase Descending with text like "Descending"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Description: function() {
			/// <summary>
			/// Gets the localized text for the phrase Description with text like "Description"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		EditMyAccount: function() {
			/// <summary>
			/// Gets the localized text for the phrase EditMyAccount with text like "Edit My Account"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		EmailErrorMessage: function() {
			/// <summary>
			/// Gets the localized text for the phrase EmailErrorMessage with text like "Must be an e-mail address."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		EqualErrorMessage: function(actual, expected) {
			/// <summary>
			/// Gets the localized text for the phrase EqualErrorMessage with text like "{actual} must be equal to {expected}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ErrorOccured: function() {
			/// <summary>
			/// Gets the localized text for the phrase ErrorOccured with text like "Sorry, an error occurred while processing your request."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		IntegerValueErrorMessageMaximum: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase IntegerValueErrorMessageMaximum with text like "Must be at most {num}."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		IntegerValueErrorMessageMinimum: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase IntegerValueErrorMessageMinimum with text like "Must be at least {num}."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		LengthErrorMessageMaximum: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase LengthErrorMessageMaximum with text like "Must be at most {num} PLURAL[{num};character;characters] long."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		LengthErrorMessageMinimum: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase LengthErrorMessageMinimum with text like "Must be at least {num} PLURAL[{num};character;characters] long."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Logout: function() {
			/// <summary>
			/// Gets the localized text for the phrase Logout with text like "Sign Out"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Milliseconds: function(numMilliseconds) {
			/// <summary>
			/// Gets the localized text for the phrase Milliseconds with text like "{numMilliseconds} PLURAL[{numMilliseconds};millisecond;milliseconds]"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		More: function() {
			/// <summary>
			/// Gets the localized text for the phrase More with text like "More"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MyCharacters: function() {
			/// <summary>
			/// Gets the localized text for the phrase MyCharacters with text like "My Characters"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Name: function() {
			/// <summary>
			/// Gets the localized text for the phrase Name with text like "Name"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		New: function() {
			/// <summary>
			/// Gets the localized text for the phrase New with text like "New"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Normal: function() {
			/// <summary>
			/// Gets the localized text for the phrase Normal with text like "Normal"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		NumberOfPrivateMessagesAbbr: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase NumberOfPrivateMessagesAbbr with text like "{num} PLURAL[{num};PM;PMs]"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PageOf: function(currentPage, pageCount) {
			/// <summary>
			/// Gets the localized text for the phrase PageOf with text like "Page {currentPage} of {pageCount}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PageXOfY: function(current, total) {
			/// <summary>
			/// Gets the localized text for the phrase PageXOfY with text like "Page {current} of {total}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PleaseLogIn: function() {
			/// <summary>
			/// Gets the localized text for the phrase PleaseLogIn with text like "Please log in."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PleaseWaitProcessing: function() {
			/// <summary>
			/// Gets the localized text for the phrase PleaseWaitProcessing with text like "Please wait, processing ..."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PrivateMessagesAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase PrivateMessagesAbbr with text like "PMs"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		QuoteFrom: function(quotee) {
			/// <summary>
			/// Gets the localized text for the phrase QuoteFrom with text like "Quote from {quotee}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Remove: function() {
			/// <summary>
			/// Gets the localized text for the phrase Remove with text like "Remove"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		RequiredErrorMessage: function() {
			/// <summary>
			/// Gets the localized text for the phrase RequiredErrorMessage with text like "This field is required."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		RestoreContent: function() {
			/// <summary>
			/// Gets the localized text for the phrase RestoreContent with text like "Restore Content"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SelectCharacter: function() {
			/// <summary>
			/// Gets the localized text for the phrase SelectCharacter with text like "Select a Character"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SimpleSearch: function() {
			/// <summary>
			/// Gets the localized text for the phrase SimpleSearch with text like "Simple search"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Submit: function() {
			/// <summary>
			/// Gets the localized text for the phrase Submit with text like "Submit"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		TestStuff: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase TestStuff with text like "This is just a test. {num} PLURAL[{num};bird;birds]."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Title: function() {
			/// <summary>
			/// Gets the localized text for the phrase Title with text like "Title"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		UserAsCharacter: function(username) {
			/// <summary>
			/// Gets the localized text for the phrase UserAsCharacter with text like "{username} as "
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		UserAvatar: function(username) {
			/// <summary>
			/// Gets the localized text for the phrase UserAvatar with text like "{username}\u0027s avatar"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Username: function() {
			/// <summary>
			/// Gets the localized text for the phrase Username with text like "Username"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		WelcomeUser: function(username) {
			/// <summary>
			/// Gets the localized text for the phrase WelcomeUser with text like "Welcome, {username}!"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	ContentManagement: {
	                  ByValue: {},
		AddMediaGallery: function() {
			/// <summary>
			/// Gets the localized text for the phrase AddMediaGallery with text like "Add Media Gallery"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ExistingFolders: function() {
			/// <summary>
			/// Gets the localized text for the phrase ExistingFolders with text like "Existing Folders"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		HideAddGallery: function() {
			/// <summary>
			/// Gets the localized text for the phrase HideAddGallery with text like "Don\u0027t Add Media Gallery"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Insert: function() {
			/// <summary>
			/// Gets the localized text for the phrase Insert with text like "Insert"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		InsertAnImage: function() {
			/// <summary>
			/// Gets the localized text for the phrase InsertAnImage with text like "Insert an Image"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		OnSelectedTemplate: function(numberSelected) {
			/// <summary>
			/// Gets the localized text for the phrase OnSelectedTemplate with text like "Apply to Selected ({numberSelected})"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PageFormDoNotSetDate: function() {
			/// <summary>
			/// Gets the localized text for the phrase PageFormDoNotSetDate with text like "Don\u0027t Set Date"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PageFormSetDate: function() {
			/// <summary>
			/// Gets the localized text for the phrase PageFormSetDate with text like "Set Date"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PublishOnTemplate: function(when) {
			/// <summary>
			/// Gets the localized text for the phrase PublishOnTemplate with text like "Publish {when}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SelectImage: function() {
			/// <summary>
			/// Gets the localized text for the phrase SelectImage with text like "Select an Image"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	ControlPanel: {
	                  ByValue: {},
		AddNewHeader: function() {
			/// <summary>
			/// Gets the localized text for the phrase AddNewHeader with text like "Add New Header"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		AddSubNavigationLink: function() {
			/// <summary>
			/// Gets the localized text for the phrase AddSubNavigationLink with text like "\u0026lt;div class=\"header\"\u0026gt;Add Sub-Navigation\u0026lt;/div\u0026gt;Add a Sub-Navigation Link"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		BulkConfirm: function(Action) {
			/// <summary>
			/// Gets the localized text for the phrase BulkConfirm with text like "Are you sure you want to {Action} these items?"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		CompLegacySubscription: function() {
			/// <summary>
			/// Gets the localized text for the phrase CompLegacySubscription with text like "Issue Comp"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Contactology_Campaigns: function() {
			/// <summary>
			/// Gets the localized text for the phrase Contactology Campaigns with text like "Contactology Campaigns"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		EntitySubscriptionTypes: function() {
			/// <summary>
			/// Gets the localized text for the phrase EntitySubscriptionTypes with text like "Entity Subscription Types"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		LegacySubscriptions: function() {
			/// <summary>
			/// Gets the localized text for the phrase LegacySubscriptions with text like "Legacy Subscriptions"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		LegacySubscriptionSearch: function() {
			/// <summary>
			/// Gets the localized text for the phrase LegacySubscriptionSearch with text like "Search Legacy Subscriptions"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MenuLegacySubscriptions: function() {
			/// <summary>
			/// Gets the localized text for the phrase MenuLegacySubscriptions with text like "Legacy Subscriptions"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MinimumPostCount: function() {
			/// <summary>
			/// Gets the localized text for the phrase MinimumPostCount with text like "Minimum Post Count"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MovePrivateMessagesPrompt: function(actionSelect) {
			/// <summary>
			/// Gets the localized text for the phrase MovePrivateMessagesPrompt with text like "Are you sure you want to move these private message(s) into the \"{actionSelect}\" folder?"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PushNotification: function() {
			/// <summary>
			/// Gets the localized text for the phrase PushNotification with text like "Push Notification"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		RemoveLinkTooltip: function() {
			/// <summary>
			/// Gets the localized text for the phrase RemoveLinkTooltip with text like "\u0026lt;div class=\"header\"\u0026gt;Remove Link\u0026lt;/div\u0026gt;Remove this link from your web site navigation."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SubscriptionID: function() {
			/// <summary>
			/// Gets the localized text for the phrase SubscriptionID with text like "Subscription ID"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SubscriptionTypeEdit: function() {
			/// <summary>
			/// Gets the localized text for the phrase SubscriptionTypeEdit with text like "Subscription Type Edit"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SubscriptionTypePush: function() {
			/// <summary>
			/// Gets the localized text for the phrase SubscriptionTypePush with text like "Push Subscription Type Notification"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SubscriptionTypes: function() {
			/// <summary>
			/// Gets the localized text for the phrase SubscriptionTypes with text like "Subscription Types"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SimpleSearch: function() {
			/// <summary>
			/// Gets the localized text for the phrase SimpleSearch with text like "Simple Search"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue1 : function() { return Waterdeep.Localization.Global.ControlPanel.SimpleSearch; }
                                	},
	Dates: {
	                  ByValue: {},
		AprilAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase AprilAbbr with text like "Apr"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		AugustAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase AugustAbbr with text like "Aug"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Days: function(numDays) {
			/// <summary>
			/// Gets the localized text for the phrase Days with text like "{numDays} PLURAL[{numDays};day;days]"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		DecemberAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase DecemberAbbr with text like "Dec"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		FebruaryAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase FebruaryAbbr with text like "Feb"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		FridayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase FridayAbbr with text like "Fri"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		FutureFormat: function(time) {
			/// <summary>
			/// Gets the localized text for the phrase FutureFormat with text like "{time} from now"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Hours: function(numHours) {
			/// <summary>
			/// Gets the localized text for the phrase Hours with text like "{numHours} PLURAL[{numHours};hour;hours]"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		JanuaryAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase JanuaryAbbr with text like "Jan"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		JulyAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase JulyAbbr with text like "Jul"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		JuneAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase JuneAbbr with text like "Jun"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		LessThanOneMinute: function() {
			/// <summary>
			/// Gets the localized text for the phrase LessThanOneMinute with text like "\u0026lt;1 min"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MarchAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase MarchAbbr with text like "Mar"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase MayAbbr with text like "May"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Minutes: function(numMinutes) {
			/// <summary>
			/// Gets the localized text for the phrase Minutes with text like "{numMinutes} PLURAL[{numMinutes};min;mins]"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MondayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase MondayAbbr with text like "Mon"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		NovemberAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase NovemberAbbr with text like "Nov"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		OctoberAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase OctoberAbbr with text like "Oct"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		OneMinute: function() {
			/// <summary>
			/// Gets the localized text for the phrase OneMinute with text like "1 min"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		PastFormat: function(time) {
			/// <summary>
			/// Gets the localized text for the phrase PastFormat with text like "{time} ago"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SaturdayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase SaturdayAbbr with text like "Sat"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Seconds: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase Seconds with text like "{num} sec"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SeptemberAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase SeptemberAbbr with text like "Sep"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		StandardDateFormat: function(date, month, year) {
			/// <summary>
			/// Gets the localized text for the phrase StandardDateFormat with text like "{month} {date}, {year}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		StandardDateTimeFormat: function(date, dayName, hour, minute, month, second, year) {
			/// <summary>
			/// Gets the localized text for the phrase StandardDateTimeFormat with text like "{dayName}, {month}, {date} {year} {hour}:{minute}:{second}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SundayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase SundayAbbr with text like "Sun"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ThursdayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase ThursdayAbbr with text like "Thu"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		TuesdayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase TuesdayAbbr with text like "Tue"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		WednesdayAbbr: function() {
			/// <summary>
			/// Gets the localized text for the phrase WednesdayAbbr with text like "Wed"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	ErrorMessages: {
	                  ByValue: {},
		NumericPrecisionDecimalDigitCountErrorMessageTemplate: function(providedDigitCount, requiredDigitCount) {
			/// <summary>
			/// Gets the localized text for the phrase NumericPrecisionDecimalDigitCountErrorMessageTemplate with text like "The value you provided has {providedDigitCount} decimal digits and the decimal digit limit is {requiredDigitCount} digits."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		TagEmpty: function() {
			/// <summary>
			/// Gets the localized text for the phrase TagEmpty with text like "You cannot add an empty tag."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Files: {
	                  ByValue: {},
		AddAttachment: function() {
			/// <summary>
			/// Gets the localized text for the phrase AddAttachment with text like "Add this attachment back."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ChangeDescription: function() {
			/// <summary>
			/// Gets the localized text for the phrase ChangeDescription with text like "Change this attachment\u0027s description"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		DeleteAttachment: function() {
			/// <summary>
			/// Gets the localized text for the phrase DeleteAttachment with text like "Delete this attachment"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		FileTooLarge: function(friendlySize) {
			/// <summary>
			/// Gets the localized text for the phrase FileTooLarge with text like "The file provided is too large. Please provide a file less than {friendlySize}."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Forums: {
	                  ByValue: {},
		Add: function() {
			/// <summary>
			/// Gets the localized text for the phrase Add with text like "Add"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		CreateForum: function() {
			/// <summary>
			/// Gets the localized text for the phrase CreateForum with text like "Create Forum"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Delete: function() {
			/// <summary>
			/// Gets the localized text for the phrase Delete with text like "Delete"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		EditForum: function() {
			/// <summary>
			/// Gets the localized text for the phrase EditForum with text like "Edit Forum"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		GoToFirstUnreadPost: function() {
			/// <summary>
			/// Gets the localized text for the phrase GoToFirstUnreadPost with text like "Go to first unread post"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		JumpToPage: function() {
			/// <summary>
			/// Gets the localized text for the phrase JumpToPage with text like "Jump to page"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		LockThread: function() {
			/// <summary>
			/// Gets the localized text for the phrase LockThread with text like "Lock this thread"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		MarkForumRead: function() {
			/// <summary>
			/// Gets the localized text for the phrase MarkForumRead with text like "Mark Forum as Read"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Moderator: function() {
			/// <summary>
			/// Gets the localized text for the phrase Moderator with text like "Moderator"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Move: function() {
			/// <summary>
			/// Gets the localized text for the phrase Move with text like "Move"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		OnSelected: function(numberSelected) {
			/// <summary>
			/// Gets the localized text for the phrase OnSelected with text like "On Selected ({numberSelected})"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		RestoreContentDescription: function() {
			/// <summary>
			/// Gets the localized text for the phrase RestoreContentDescription with text like "Click to restore your last entered text, in case of an error with your last attempt"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SearchForums: function() {
			/// <summary>
			/// Gets the localized text for the phrase SearchForums with text like "Search Forums"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SelectAll: function() {
			/// <summary>
			/// Gets the localized text for the phrase SelectAll with text like "Select All"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SendMessage: function() {
			/// <summary>
			/// Gets the localized text for the phrase SendMessage with text like "Send a Message"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Unread: function() {
			/// <summary>
			/// Gets the localized text for the phrase Unread with text like "Unread"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ViewPosts: function() {
			/// <summary>
			/// Gets the localized text for the phrase ViewPosts with text like "View Posts"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ViewProfile: function() {
			/// <summary>
			/// Gets the localized text for the phrase ViewProfile with text like "View User Profile"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Languages: {
	                  ByValue: {},
		Arabic: function() {
			/// <summary>
			/// Gets the localized text for the phrase Arabic with text like "Arabic"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Brazillian_Portugese: function() {
			/// <summary>
			/// Gets the localized text for the phrase Brazillian Portugese with text like "Brazillian Portugese"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		BritishEnglish: function() {
			/// <summary>
			/// Gets the localized text for the phrase BritishEnglish with text like "British English"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		English: function() {
			/// <summary>
			/// Gets the localized text for the phrase English with text like "English"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		French: function() {
			/// <summary>
			/// Gets the localized text for the phrase French with text like "French"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		German: function() {
			/// <summary>
			/// Gets the localized text for the phrase German with text like "German"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Greek: function() {
			/// <summary>
			/// Gets the localized text for the phrase Greek with text like "Greek"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Indonesian: function() {
			/// <summary>
			/// Gets the localized text for the phrase Indonesian with text like "Indonesian"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Italian: function() {
			/// <summary>
			/// Gets the localized text for the phrase Italian with text like "Italian"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Japanese: function() {
			/// <summary>
			/// Gets the localized text for the phrase Japanese with text like "Japanese"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Korean: function() {
			/// <summary>
			/// Gets the localized text for the phrase Korean with text like "Korean"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		LatinAmericanSpanish: function() {
			/// <summary>
			/// Gets the localized text for the phrase LatinAmericanSpanish with text like "Latin American Spanish"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Polish: function() {
			/// <summary>
			/// Gets the localized text for the phrase Polish with text like "Polish"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Português_do_Brasil__Brazilian_Portuguese_: function() {
			/// <summary>
			/// Gets the localized text for the phrase Português do Brasil (Brazilian Portuguese) with text like "Português do Brasil (Brazilian Portuguese)"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Russian: function() {
			/// <summary>
			/// Gets the localized text for the phrase Russian with text like "Russian"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		SimplifiedChinese: function() {
			/// <summary>
			/// Gets the localized text for the phrase SimplifiedChinese with text like "Simplified Chinese"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Spanish: function() {
			/// <summary>
			/// Gets the localized text for the phrase Spanish with text like "Spanish"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Swedish: function() {
			/// <summary>
			/// Gets the localized text for the phrase Swedish with text like "Swedish"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		TraditionalChinese: function() {
			/// <summary>
			/// Gets the localized text for the phrase TraditionalChinese with text like "Traditional Chinese"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Uzbec: function() {
			/// <summary>
			/// Gets the localized text for the phrase Uzbec with text like "Uzbec"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Vietnamese: function() {
			/// <summary>
			/// Gets the localized text for the phrase Vietnamese with text like "Vietnamese"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	MailTemplates: {
	                  ByValue: {},
		ReportBody: function(nickName, notificationPageUrl, reason, reportedContent, reportedContentUrl, reportedUserLink, reportingUserName, reportPageUrl, siteTitle, userCustomNote, userName) {
			/// <summary>
			/// Gets the localized text for the phrase ReportBody with text like "Hello {nickName},\u0026lt;p\u0026gt;{reportingUserName} has reported this \u0026lt;a href=\"{reportedContentUrl}\"\u0026gt;content\u0026lt;/a\u0026gt; on \u0026lt;a href=\"{reportPageUrl}\"\u0026gt;{siteTitle}\u0026lt;/a\u0026gt; for the reason {reason}.\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;{userCustomNote}\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;You can view the report by \u0026lt;a href=\"{reportPageUrl}\"\u0026gt;visiting the report page\u0026lt;/a\u0026gt;.\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;Reported content:\u0026lt;blockquote\u0026gt;Posted by \u0026lt;a href=\"{reportedUserLink}\"\u0026gt;{userName}\u0026lt;/a\u0026gt;\u0026lt;p\u0026gt;{reportedContent}\u0026lt;/p\u0026gt;\u0026lt;/blockquote\u0026gt;\u0026lt;/p\u0026gt;__\u0026lt;p style=\"font-size:11px\"\u0026gt;To unsubscribe from these email notifications, go to \u0026lt;a href=\"{notificationPageUrl}\"\u0026gt;your notifications page.\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt;"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Polls: {
	                  ByValue: {},
		AddChoice: function() {
			/// <summary>
			/// Gets the localized text for the phrase AddChoice with text like "Add Choice"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		AddPoll: function() {
			/// <summary>
			/// Gets the localized text for the phrase AddPoll with text like "Add a poll"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ChoiceNumberTemplate: function(num) {
			/// <summary>
			/// Gets the localized text for the phrase ChoiceNumberTemplate with text like "Choice #{num}"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		HideResults: function() {
			/// <summary>
			/// Gets the localized text for the phrase HideResults with text like "Hide Results"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		RemoveChoice: function() {
			/// <summary>
			/// Gets the localized text for the phrase RemoveChoice with text like "Remove Choice"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		RemovePoll: function() {
			/// <summary>
			/// Gets the localized text for the phrase RemovePoll with text like "Don\u0027t add a poll"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		ViewResults: function() {
			/// <summary>
			/// Gets the localized text for the phrase ViewResults with text like "View Results"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Ratings: {
	                  ByValue: {},
		YouRatedThis: function(rating, ratingAverage, ratingCount) {
			/// <summary>
			/// Gets the localized text for the phrase YouRatedThis with text like "You rated this {rating} PLURAL[{rating};star;stars]. {ratingCount} PLURAL[{ratingCount};user;users] rated it for a total average of {ratingAverage} PLURAL[{ratingAverage};star;stars]."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Reporting: {
	                  ByValue: {},
		Report: function() {
			/// <summary>
			/// Gets the localized text for the phrase Report with text like "Report"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	TinyMCE: {
	                  ByValue: {},
		XenonMediaPluginDesc: function() {
			/// <summary>
			/// Gets the localized text for the phrase XenonMediaPluginDesc with text like "Add a file from a Folder"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Upsells: {
	                  ByValue: {},
		SubscriptionRequiresLogin: function() {
			/// <summary>
			/// Gets the localized text for the phrase SubscriptionRequiresLogin with text like "You must be logged in to Subscribe."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	UserRegistration: {
	                  ByValue: {},
		ConfirmPassword: function() {
			/// <summary>
			/// Gets the localized text for the phrase ConfirmPassword with text like "Confirm Password"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Password: function() {
			/// <summary>
			/// Gets the localized text for the phrase Password with text like "Password"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		RecoverAccountStep2Info2: function() {
			/// <summary>
			/// Gets the localized text for the phrase RecoverAccountStep2Info2 with text like "\u0026amp;nbsp;"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		Username: function() {
			/// <summary>
			/// Gets the localized text for the phrase Username with text like "Username"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
		UsernameIsTaken: function() {
			/// <summary>
			/// Gets the localized text for the phrase UsernameIsTaken with text like "That username is taken."
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		}
		
	},
	Widgets: {
	                  ByValue: {},
		LatestPosts: function() {
			/// <summary>
			/// Gets the localized text for the phrase LatestPosts with text like "Latest Posts"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue2 : function() { return Waterdeep.Localization.Global.Widgets.LatestPosts; },
                                		LatestNews: function() {
			/// <summary>
			/// Gets the localized text for the phrase LatestNews with text like "Latest News"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue4 : function() { return Waterdeep.Localization.Global.Widgets.LatestNews; },
                                		Poll: function() {
			/// <summary>
			/// Gets the localized text for the phrase Poll with text like "Poll"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue5 : function() { return Waterdeep.Localization.Global.Widgets.Poll; },
                                		WhosOnline: function() {
			/// <summary>
			/// Gets the localized text for the phrase WhosOnline with text like "Who\u0027s Online"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue6 : function() { return Waterdeep.Localization.Global.Widgets.WhosOnline; },
                                		RandomPicture: function() {
			/// <summary>
			/// Gets the localized text for the phrase RandomPicture with text like "Random Picture"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue7 : function() { return Waterdeep.Localization.Global.Widgets.RandomPicture; },
                                		Calendar: function() {
			/// <summary>
			/// Gets the localized text for the phrase Calendar with text like "Calendar"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue8 : function() { return Waterdeep.Localization.Global.Widgets.Calendar; },
                                		Recruitment: function() {
			/// <summary>
			/// Gets the localized text for the phrase Recruitment with text like "Recruitment"
			/// </summary>
			/// <returns>A localized string.</returns>
			return Waterdeep.Localization.localize(arguments);
		},
		
                                ByValue9 : function() { return Waterdeep.Localization.Global.Widgets.Recruitment; }
                                	}
};
Waterdeep.Localization[1] = Waterdeep.Localization.Global.Buttons.Create;
Waterdeep.Localization[2] = Waterdeep.Localization.Global.Buttons.Edit;
Waterdeep.Localization[3] = Waterdeep.Localization.Global.Buttons.Update;
Waterdeep.Localization[4] = Waterdeep.Localization.Global.Buttons.Delete;
Waterdeep.Localization[32] = Waterdeep.Localization.Global.Common.ErrorOccured;
Waterdeep.Localization[96] = Waterdeep.Localization.Global.Common.Logout;
Waterdeep.Localization[104] = Waterdeep.Localization.Global.Common.EditMyAccount;
Waterdeep.Localization[106] = Waterdeep.Localization.Global.Common.WelcomeUser;
Waterdeep.Localization[107] = Waterdeep.Localization.Global.Forums.SearchForums;
Waterdeep.Localization[115] = Waterdeep.Localization.Global.Dates.FutureFormat;
Waterdeep.Localization[116] = Waterdeep.Localization.Global.Dates.PastFormat;
Waterdeep.Localization[117] = Waterdeep.Localization.Global.Dates.LessThanOneMinute;
Waterdeep.Localization[118] = Waterdeep.Localization.Global.Dates.OneMinute;
Waterdeep.Localization[119] = Waterdeep.Localization.Global.Dates.Minutes;
Waterdeep.Localization[120] = Waterdeep.Localization.Global.Dates.Hours;
Waterdeep.Localization[121] = Waterdeep.Localization.Global.Dates.Days;
Waterdeep.Localization[122] = Waterdeep.Localization.Global.Dates.StandardDateFormat;
Waterdeep.Localization[123] = Waterdeep.Localization.Global.Dates.StandardDateTimeFormat;
Waterdeep.Localization[126] = Waterdeep.Localization.Global.Dates.SundayAbbr;
Waterdeep.Localization[127] = Waterdeep.Localization.Global.Dates.MondayAbbr;
Waterdeep.Localization[128] = Waterdeep.Localization.Global.Dates.TuesdayAbbr;
Waterdeep.Localization[129] = Waterdeep.Localization.Global.Dates.WednesdayAbbr;
Waterdeep.Localization[130] = Waterdeep.Localization.Global.Dates.ThursdayAbbr;
Waterdeep.Localization[131] = Waterdeep.Localization.Global.Dates.FridayAbbr;
Waterdeep.Localization[132] = Waterdeep.Localization.Global.Dates.SaturdayAbbr;
Waterdeep.Localization[133] = Waterdeep.Localization.Global.Dates.JanuaryAbbr;
Waterdeep.Localization[134] = Waterdeep.Localization.Global.Dates.FebruaryAbbr;
Waterdeep.Localization[135] = Waterdeep.Localization.Global.Dates.MarchAbbr;
Waterdeep.Localization[136] = Waterdeep.Localization.Global.Dates.AprilAbbr;
Waterdeep.Localization[137] = Waterdeep.Localization.Global.Dates.MayAbbr;
Waterdeep.Localization[138] = Waterdeep.Localization.Global.Dates.JuneAbbr;
Waterdeep.Localization[139] = Waterdeep.Localization.Global.Dates.JulyAbbr;
Waterdeep.Localization[140] = Waterdeep.Localization.Global.Dates.AugustAbbr;
Waterdeep.Localization[141] = Waterdeep.Localization.Global.Dates.SeptemberAbbr;
Waterdeep.Localization[142] = Waterdeep.Localization.Global.Dates.OctoberAbbr;
Waterdeep.Localization[143] = Waterdeep.Localization.Global.Dates.NovemberAbbr;
Waterdeep.Localization[144] = Waterdeep.Localization.Global.Dates.DecemberAbbr;
Waterdeep.Localization[147] = Waterdeep.Localization.Global.Forums.LockThread;
Waterdeep.Localization[151] = Waterdeep.Localization.Global.Common.Title;
Waterdeep.Localization[154] = Waterdeep.Localization.Global.Forums.JumpToPage;
Waterdeep.Localization[155] = Waterdeep.Localization.Global.Forums.ViewProfile;
Waterdeep.Localization[156] = Waterdeep.Localization.Global.Forums.ViewPosts;
Waterdeep.Localization[157] = Waterdeep.Localization.Global.Forums.SendMessage;
Waterdeep.Localization[158] = Waterdeep.Localization.Global.Common.Submit;
Waterdeep.Localization[177] = Waterdeep.Localization.Global.Common.Add;
Waterdeep.Localization[181] = Waterdeep.Localization.Global.Common.Description;
Waterdeep.Localization[187] = Waterdeep.Localization.Global.Buttons.Cancel;
Waterdeep.Localization[193] = Waterdeep.Localization.Global.Forums.Delete;
Waterdeep.Localization[194] = Waterdeep.Localization.Global.Forums.Add;
Waterdeep.Localization[195] = Waterdeep.Localization.Global.Forums.SelectAll;
Waterdeep.Localization[196] = Waterdeep.Localization.Global.Forums.OnSelected;
Waterdeep.Localization[218] = Waterdeep.Localization.Global.Forums.Move;
Waterdeep.Localization[219] = Waterdeep.Localization.Global.Common.Name;
Waterdeep.Localization[221] = Waterdeep.Localization.Global.Common.Username;
Waterdeep.Localization[225] = Waterdeep.Localization.Global.Forums.Moderator;
Waterdeep.Localization[230] = Waterdeep.Localization.Global.Common.UserAvatar;
Waterdeep.Localization[266] = Waterdeep.Localization.Global.Common.MyCharacters;
Waterdeep.Localization[283] = Waterdeep.Localization.Global.UserRegistration.Username;
Waterdeep.Localization[284] = Waterdeep.Localization.Global.UserRegistration.Password;
Waterdeep.Localization[285] = Waterdeep.Localization.Global.UserRegistration.ConfirmPassword;
Waterdeep.Localization[314] = Waterdeep.Localization.Global.Forums.GoToFirstUnreadPost;
Waterdeep.Localization[315] = Waterdeep.Localization.Global.Languages.English;
Waterdeep.Localization[316] = Waterdeep.Localization.Global.Languages.French;
Waterdeep.Localization[317] = Waterdeep.Localization.Global.Languages.German;
Waterdeep.Localization[318] = Waterdeep.Localization.Global.Languages.Spanish;
Waterdeep.Localization[319] = Waterdeep.Localization.Global.Languages.Russian;
Waterdeep.Localization[320] = Waterdeep.Localization.Global.Languages.SimplifiedChinese;
Waterdeep.Localization[321] = Waterdeep.Localization.Global.Languages.Japanese;
Waterdeep.Localization[322] = Waterdeep.Localization.Global.Languages.Korean;
Waterdeep.Localization[323] = Waterdeep.Localization.Global.Languages.Swedish;
Waterdeep.Localization[324] = Waterdeep.Localization.Global.Languages.Indonesian;
Waterdeep.Localization[325] = Waterdeep.Localization.Global.Languages.Greek;
Waterdeep.Localization[326] = Waterdeep.Localization.Global.Languages.Polish;
Waterdeep.Localization[361] = Waterdeep.Localization.Global.Common.PageXOfY;
Waterdeep.Localization[378] = Waterdeep.Localization.Global.Common.RequiredErrorMessage;
Waterdeep.Localization[379] = Waterdeep.Localization.Global.Common.LengthErrorMessageMaximum;
Waterdeep.Localization[380] = Waterdeep.Localization.Global.Common.LengthErrorMessageMinimum;
Waterdeep.Localization[382] = Waterdeep.Localization.Global.Common.EmailErrorMessage;
Waterdeep.Localization[393] = Waterdeep.Localization.Global.Forums.CreateForum;
Waterdeep.Localization[394] = Waterdeep.Localization.Global.Forums.EditForum;
Waterdeep.Localization[395] = Waterdeep.Localization.Global.Forums.MarkForumRead;
Waterdeep.Localization[441] = Waterdeep.Localization.Global.Common.UserAsCharacter;
Waterdeep.Localization[444] = Waterdeep.Localization.Global.Files.FileTooLarge;
Waterdeep.Localization[445] = Waterdeep.Localization.Global.Common.SelectCharacter;
Waterdeep.Localization[446] = Waterdeep.Localization.Global.Common.AddCharacter;
Waterdeep.Localization[447] = Waterdeep.Localization.Global.Common.QuoteFrom;
Waterdeep.Localization[451] = Waterdeep.Localization.Global.Common.More;
Waterdeep.Localization[461] = Waterdeep.Localization.Global.Dates.Seconds;
Waterdeep.Localization[463] = Waterdeep.Localization.Global.Files.DeleteAttachment;
Waterdeep.Localization[464] = Waterdeep.Localization.Global.Files.AddAttachment;
Waterdeep.Localization[465] = Waterdeep.Localization.Global.Files.ChangeDescription;
Waterdeep.Localization[466] = Waterdeep.Localization.Global.Common.Comments;
Waterdeep.Localization[469] = Waterdeep.Localization.Global.Polls.ChoiceNumberTemplate;
Waterdeep.Localization[475] = Waterdeep.Localization.Global.Polls.AddPoll;
Waterdeep.Localization[476] = Waterdeep.Localization.Global.Polls.RemovePoll;
Waterdeep.Localization[490] = Waterdeep.Localization.Global.Common.Normal;
Waterdeep.Localization[493] = Waterdeep.Localization.Global.Polls.AddChoice;
Waterdeep.Localization[494] = Waterdeep.Localization.Global.Polls.RemoveChoice;
Waterdeep.Localization[502] = Waterdeep.Localization.Global.Common.Milliseconds;
Waterdeep.Localization[513] = Waterdeep.Localization.Global.Common.IntegerValueErrorMessageMaximum;
Waterdeep.Localization[514] = Waterdeep.Localization.Global.Common.IntegerValueErrorMessageMinimum;
Waterdeep.Localization[516] = Waterdeep.Localization.Global.Polls.ViewResults;
Waterdeep.Localization[517] = Waterdeep.Localization.Global.Polls.HideResults;
Waterdeep.Localization[521] = Waterdeep.Localization.Global.Common.EqualErrorMessage;
Waterdeep.Localization[536] = Waterdeep.Localization.Global.ContentManagement.OnSelectedTemplate;
Waterdeep.Localization[544] = Waterdeep.Localization.Global.ContentManagement.AddMediaGallery;
Waterdeep.Localization[569] = Waterdeep.Localization.Global.ContentManagement.HideAddGallery;
Waterdeep.Localization[571] = Waterdeep.Localization.Global.ContentManagement.PublishOnTemplate;
Waterdeep.Localization[588] = Waterdeep.Localization.Global.ContentManagement.PageFormSetDate;
Waterdeep.Localization[589] = Waterdeep.Localization.Global.ContentManagement.PageFormDoNotSetDate;
Waterdeep.Localization[593] = Waterdeep.Localization.Global.TinyMCE.XenonMediaPluginDesc;
Waterdeep.Localization[617] = Waterdeep.Localization.Global.Common.PleaseWaitProcessing;
Waterdeep.Localization[628] = Waterdeep.Localization.Global.Common.PrivateMessagesAbbr;
Waterdeep.Localization[629] = Waterdeep.Localization.Global.Common.NumberOfPrivateMessagesAbbr;
Waterdeep.Localization[642] = Waterdeep.Localization.Global.ContentManagement.SelectImage;
Waterdeep.Localization[644] = Waterdeep.Localization.Global.ContentManagement.Insert;
Waterdeep.Localization[800] = Waterdeep.Localization.Global.Common.SimpleSearch;
Waterdeep.Localization[802] = Waterdeep.Localization.Global.Common.AdvancedSearch;
Waterdeep.Localization[806] = Waterdeep.Localization.Global.Common.Ascending;
Waterdeep.Localization[807] = Waterdeep.Localization.Global.Common.Descending;
Waterdeep.Localization[825] = Waterdeep.Localization.Global.UserRegistration.UsernameIsTaken;
Waterdeep.Localization[961] = Waterdeep.Localization.Global.Widgets.LatestNews;
Waterdeep.Localization[966] = Waterdeep.Localization.Global.Languages.Italian;
Waterdeep.Localization[967] = Waterdeep.Localization.Global.Widgets.Poll;
Waterdeep.Localization[971] = Waterdeep.Localization.Global.Widgets.WhosOnline;
Waterdeep.Localization[976] = Waterdeep.Localization.Global.Widgets.RandomPicture;
Waterdeep.Localization[1027] = Waterdeep.Localization.Global.Common.Remove;
Waterdeep.Localization[1053] = Waterdeep.Localization.Global.Widgets.Calendar;
Waterdeep.Localization[1054] = Waterdeep.Localization.Global.Widgets.LatestPosts;
Waterdeep.Localization[1055] = Waterdeep.Localization.Global.Widgets.Recruitment;
Waterdeep.Localization[1158] = Waterdeep.Localization.Global.UserRegistration.RecoverAccountStep2Info2;
Waterdeep.Localization[1189] = Waterdeep.Localization.Global.Languages.TraditionalChinese;
Waterdeep.Localization[1190] = Waterdeep.Localization.Global.Languages.LatinAmericanSpanish;
Waterdeep.Localization[1191] = Waterdeep.Localization.Global.Languages.BritishEnglish;
Waterdeep.Localization[1258] = Waterdeep.Localization.Global.Common.ConfirmDelete;
Waterdeep.Localization[2057] = Waterdeep.Localization.Global.ControlPanel.AddNewHeader;
Waterdeep.Localization[2104] = Waterdeep.Localization.Global.Common.Apply;
Waterdeep.Localization[2114] = Waterdeep.Localization.Global.ControlPanel.MinimumPostCount;
Waterdeep.Localization[2255] = Waterdeep.Localization.Global.Common.ClickHere;
Waterdeep.Localization[2337] = Waterdeep.Localization.Global.Common.ColonConnector;
Waterdeep.Localization[2673] = Waterdeep.Localization.Global.Common.PageOf;
Waterdeep.Localization[2794] = Waterdeep.Localization.Global.ErrorMessages.TagEmpty;
Waterdeep.Localization[3897] = Waterdeep.Localization.Global.ContentManagement.ExistingFolders;
Waterdeep.Localization[3900] = Waterdeep.Localization.Global.Ratings.YouRatedThis;
Waterdeep.Localization[3915] = Waterdeep.Localization.Global.Common.PleaseLogIn;
Waterdeep.Localization[3952] = Waterdeep.Localization.Global.ControlPanel.RemoveLinkTooltip;
Waterdeep.Localization[3958] = Waterdeep.Localization.Global.Reporting.Report;
Waterdeep.Localization[3978] = Waterdeep.Localization.Global.ContentManagement.InsertAnImage;
Waterdeep.Localization[4014] = Waterdeep.Localization.Global.ControlPanel.BulkConfirm;
Waterdeep.Localization[4218] = Waterdeep.Localization.Global.ControlPanel.AddSubNavigationLink;
Waterdeep.Localization[4244] = Waterdeep.Localization.Global.Forums.RestoreContentDescription;
Waterdeep.Localization[4245] = Waterdeep.Localization.Global.Common.RestoreContent;
Waterdeep.Localization[4251] = Waterdeep.Localization.Global.ErrorMessages.NumericPrecisionDecimalDigitCountErrorMessageTemplate;
Waterdeep.Localization[4412] = Waterdeep.Localization.Global.Common.TestStuff;
Waterdeep.Localization[4446] = Waterdeep.Localization.Global.Common.New;
Waterdeep.Localization[5450] = Waterdeep.Localization.Global.Languages.Uzbec;
Waterdeep.Localization[5463] = Waterdeep.Localization.Global.Languages.Vietnamese;
Waterdeep.Localization[5519] = Waterdeep.Localization.Global.Languages.Brazillian_Portugese;
Waterdeep.Localization[5543] = Waterdeep.Localization.Global.ControlPanel.CompLegacySubscription;
Waterdeep.Localization[5544] = Waterdeep.Localization.Global.ControlPanel.Contactology_Campaigns;
Waterdeep.Localization[5554] = Waterdeep.Localization.Global.ControlPanel.EntitySubscriptionTypes;
Waterdeep.Localization[5560] = Waterdeep.Localization.Global.ControlPanel.LegacySubscriptionSearch;
Waterdeep.Localization[5576] = Waterdeep.Localization.Global.ControlPanel.MenuLegacySubscriptions;
Waterdeep.Localization[5583] = Waterdeep.Localization.Global.Buttons.Push;
Waterdeep.Localization[5584] = Waterdeep.Localization.Global.ControlPanel.PushNotification;
Waterdeep.Localization[5590] = Waterdeep.Localization.Global.Upsells.SubscriptionRequiresLogin;
Waterdeep.Localization[5591] = Waterdeep.Localization.Global.ControlPanel.SubscriptionTypeEdit;
Waterdeep.Localization[5592] = Waterdeep.Localization.Global.ControlPanel.SubscriptionTypePush;
Waterdeep.Localization[5593] = Waterdeep.Localization.Global.ControlPanel.SubscriptionTypes;
Waterdeep.Localization[5609] = Waterdeep.Localization.Global.ControlPanel.LegacySubscriptions;
Waterdeep.Localization[5610] = Waterdeep.Localization.Global.ControlPanel.SubscriptionID;
Waterdeep.Localization[5612] = Waterdeep.Localization.Global.ControlPanel.SimpleSearch;
Waterdeep.Localization[5806] = Waterdeep.Localization.Global.Forums.Unread;
Waterdeep.Localization[5976] = Waterdeep.Localization.Global.Languages.Arabic;
Waterdeep.Localization[5997] = Waterdeep.Localization.Global.MailTemplates.ReportBody;
Waterdeep.Localization[6104] = Waterdeep.Localization.Global.ControlPanel.MovePrivateMessagesPrompt;
Waterdeep.Localization[6374] = Waterdeep.Localization.Global.Languages.Português_do_Brasil__Brazilian_Portuguese_;
;
// English
Waterdeep.Localization.populate(1, {"Global":{"Buttons":{"Cancel":"Cancel","Create":"Create","Delete":"Delete","Edit":"Edit","Push":"Push","Update":"Update"},"Common":{"Add":"Add","AddCharacter":"Add a character","AdvancedSearch":"Advanced Search","Apply":"Apply","Ascending":"Ascending","ClickHere":"click here","ColonConnector":": ","Comments":"Comments","ConfirmDelete":"Are you sure you want to delete {0}?","Descending":"Descending","Description":"Description","EditMyAccount":"Edit My Account","EmailErrorMessage":"Must be an e-mail address.","EqualErrorMessage":"{0} must be equal to {1}","ErrorOccured":"Sorry, an error occurred while processing your request.","IntegerValueErrorMessageMaximum":"Must be at most {0}.","IntegerValueErrorMessageMinimum":"Must be at least {0}.","LengthErrorMessageMaximum":"Must be at most {0} PLURAL[{0};character;characters] long.","LengthErrorMessageMinimum":"Must be at least {0} PLURAL[{0};character;characters] long.","Logout":"Sign Out","Milliseconds":"{0} PLURAL[{0};millisecond;milliseconds]","More":"More","MyCharacters":"My Characters","Name":"Name","New":"New","Normal":"Normal","NumberOfPrivateMessagesAbbr":"{0} PLURAL[{0};PM;PMs]","PageOf":"Page {0} of {1}","PageXOfY":"Page {0} of {1}","PleaseLogIn":"Please log in.","PleaseWaitProcessing":"Please wait, processing ...","PrivateMessagesAbbr":"PMs","QuoteFrom":"Quote from {0}","Remove":"Remove","RequiredErrorMessage":"This field is required.","RestoreContent":"Restore Content","SelectCharacter":"Select a Character","SimpleSearch":"Simple search","Submit":"Submit","TestStuff":"This is just a test. {0} PLURAL[{0};bird;birds].","Title":"Title","UserAsCharacter":"{0} as ","UserAvatar":"{0}\u0027s avatar","Username":"Username","WelcomeUser":"Welcome, {0}!"},"ContentManagement":{"AddMediaGallery":"Add Media Gallery","ExistingFolders":"Existing Folders","HideAddGallery":"Don\u0027t Add Media Gallery","Insert":"Insert","InsertAnImage":"Insert an Image","OnSelectedTemplate":"Apply to Selected ({0})","PageFormDoNotSetDate":"Don\u0027t Set Date","PageFormSetDate":"Set Date","PublishOnTemplate":"Publish {0}","SelectImage":"Select an Image"},"ControlPanel":{"AddNewHeader":"Add New Header","AddSubNavigationLink":"\u003cdiv class=\"header\"\u003eAdd Sub-Navigation\u003c/div\u003e\r\nAdd a Sub-Navigation Link","BulkConfirm":"Are you sure you want to {0} these items?","CompLegacySubscription":"Issue Comp","Contactology Campaigns":"Contactology Campaigns","EntitySubscriptionTypes":"Entity Subscription Types","LegacySubscriptions":"Legacy Subscriptions","LegacySubscriptionSearch":"Search Legacy Subscriptions","MenuLegacySubscriptions":"Legacy Subscriptions","MinimumPostCount":"Minimum Post Count","MovePrivateMessagesPrompt":"Are you sure you want to move these private message(s) into the \"{0}\" folder?","PushNotification":"Push Notification","RemoveLinkTooltip":"\u003cdiv class=\"header\"\u003eRemove Link\u003c/div\u003e\r\nRemove this link from your web site navigation.","SubscriptionID":"Subscription ID","SubscriptionTypeEdit":"Subscription Type Edit","SubscriptionTypePush":"Push Subscription Type Notification","SubscriptionTypes":"Subscription Types","SimpleSearch":"Simple Search"},"Dates":{"AprilAbbr":"Apr","AugustAbbr":"Aug","Days":"{0} PLURAL[{0};day;days]","DecemberAbbr":"Dec","FebruaryAbbr":"Feb","FridayAbbr":"Fri","FutureFormat":"{0} from now","Hours":"{0} PLURAL[{0};hour;hours]","JanuaryAbbr":"Jan","JulyAbbr":"Jul","JuneAbbr":"Jun","LessThanOneMinute":"\u003c1 min","MarchAbbr":"Mar","MayAbbr":"May","Minutes":"{0} PLURAL[{0};min;mins]","MondayAbbr":"Mon","NovemberAbbr":"Nov","OctoberAbbr":"Oct","OneMinute":"1 min","PastFormat":"{0} ago","SaturdayAbbr":"Sat","Seconds":"{0} sec","SeptemberAbbr":"Sep","StandardDateFormat":"{1} {0}, {2}","StandardDateTimeFormat":"{1}, {4}, {0} {6} {2}:{3}:{5}","SundayAbbr":"Sun","ThursdayAbbr":"Thu","TuesdayAbbr":"Tue","WednesdayAbbr":"Wed"},"ErrorMessages":{"NumericPrecisionDecimalDigitCountErrorMessageTemplate":"The value you provided has {0} decimal digits and the decimal digit limit is {1} digits.","TagEmpty":"You cannot add an empty tag."},"Files":{"AddAttachment":"Add this attachment back.","ChangeDescription":"Change this attachment\u0027s description","DeleteAttachment":"Delete this attachment","FileTooLarge":"The file provided is too large. Please provide a file less than {0}."},"Forums":{"Add":"Add","CreateForum":"Create Forum","Delete":"Delete","EditForum":"Edit Forum","GoToFirstUnreadPost":"Go to first unread post","JumpToPage":"Jump to page","LockThread":"Lock this thread","MarkForumRead":"Mark Forum as Read","Moderator":"Moderator","Move":"Move","OnSelected":"On Selected ({0})","RestoreContentDescription":"Click to restore your last entered text, in case of an error with your last attempt","SearchForums":"Search Forums","SelectAll":"Select All","SendMessage":"Send a Message","Unread":"Unread","ViewPosts":"View Posts","ViewProfile":"View User Profile"},"Languages":{"Arabic":"Arabic","Brazillian Portugese":"Brazillian Portugese","BritishEnglish":"British English","English":"English","French":"French","German":"German","Greek":"Greek","Indonesian":"Indonesian","Italian":"Italian","Japanese":"Japanese","Korean":"Korean","LatinAmericanSpanish":"Latin American Spanish","Polish":"Polish","Português do Brasil (Brazilian Portuguese)":"Português do Brasil (Brazilian Portuguese)","Russian":"Russian","SimplifiedChinese":"Simplified Chinese","Spanish":"Spanish","Swedish":"Swedish","TraditionalChinese":"Traditional Chinese","Uzbec":"Uzbec","Vietnamese":"Vietnamese"},"MailTemplates":{"ReportBody":"Hello {0},\r\n\r\n\u003cp\u003e{6} has reported this \u003ca href=\"{4}\"\u003econtent\u003c/a\u003e on \u003ca href=\"{7}\"\u003e{8}\u003c/a\u003e for the reason {2}.\u003c/p\u003e\r\n\u003cp\u003e{9}\u003c/p\u003e\r\n\u003cp\u003eYou can view the report by \u003ca href=\"{7}\"\u003evisiting the report page\u003c/a\u003e.\u003c/p\u003e\r\n\r\n\u003cp\u003eReported content:\r\n\u003cblockquote\u003e\r\nPosted by \u003ca href=\"{5}\"\u003e{10}\u003c/a\u003e\r\n\u003cp\u003e\r\n{3}\r\n\u003c/p\u003e\r\n\u003c/blockquote\u003e\u003c/p\u003e\r\n\r\n__\r\n\u003cp style=\"font-size:11px\"\u003eTo unsubscribe from these email notifications, go to \u003ca href=\"{1}\"\u003eyour notifications page.\u003c/a\u003e\u003c/p\u003e"},"Polls":{"AddChoice":"Add Choice","AddPoll":"Add a poll","ChoiceNumberTemplate":"Choice #{0}","HideResults":"Hide Results","RemoveChoice":"Remove Choice","RemovePoll":"Don\u0027t add a poll","ViewResults":"View Results"},"Ratings":{"YouRatedThis":"You rated this {0} PLURAL[{0};star;stars]. {2} PLURAL[{2};user;users] rated it for a total average of {1} PLURAL[{1};star;stars]."},"Reporting":{"Report":"Report"},"TinyMCE":{"XenonMediaPluginDesc":"Add a file from a Folder"},"Upsells":{"SubscriptionRequiresLogin":"You must be logged in to Subscribe."},"UserRegistration":{"ConfirmPassword":"Confirm Password","Password":"Password","RecoverAccountStep2Info2":"\u0026nbsp;","Username":"Username","UsernameIsTaken":"That username is taken."},"Widgets":{"LatestPosts":"Latest Posts","LatestNews":"Latest News","Poll":"Poll","WhosOnline":"Who\u0027s Online","RandomPicture":"Random Picture","Calendar":"Calendar","Recruitment":"Recruitment"}}});
;
