var CanvasJS;
(function (CanvasJS) {
    CanvasJS.DESIGN_GRID_UNIT = 5;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    let CanvasType;
    (function (CanvasType) {
        CanvasType[CanvasType["Design"] = 0] = "Design";
        CanvasType[CanvasType["Actual"] = 1] = "Actual";
    })(CanvasType = CanvasJS.CanvasType || (CanvasJS.CanvasType = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class Surface extends Jade.UI.Control {
        constructor(options) {
            super(options);
        }
    }
    CanvasJS.Surface = Surface;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class SurfaceBehavior {
        constructor(options) {
            this.m_options = null;
            this.m_options = new Jade.StateBag(options);
        }
        get options() {
            return this.m_options;
        }
        start() {
        }
        stop() {
        }
    }
    CanvasJS.SurfaceBehavior = SurfaceBehavior;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class TypeResolver {
        constructor(options) {
            this.m_element = options.element;
            this.m_designScript = options.designScript;
            this.m_actualScript = options.actualScript;
        }
        get designScript() {
            return this.m_designScript;
        }
        get actualScript() {
            return this.m_actualScript;
        }
        getView(canvasType) {
            let type = null;
            let result = null;
            try {
                switch (canvasType) {
                    case CanvasJS.CanvasType.Actual:
                        type = Jade.Type.getType(this.actualScript);
                        break;
                    case CanvasJS.CanvasType.Design:
                        type = Jade.Type.getType(this.designScript);
                        break;
                }
                if (type != null) {
                    result = new type({
                        $source: this.m_element
                    });
                }
                else {
                    result = this.getInvalidElementView(canvasType);
                }
            }
            catch {
                result = this.getInvalidElementView(canvasType);
            }
            return result;
        }
        getViewOf(canvasType) {
            return this.getView(canvasType);
        }
        clone(options) {
            let result = null;
            let state = _.extend(this.m_element.toJSON(), {
                document: this.m_element.document
            }, options);
            ;
            result = this.m_element.document.createElement(state);
            return result;
        }
        getInvalidElementView(canvasType) {
            let result = null;
            switch (canvasType) {
                case CanvasJS.CanvasType.Actual:
                    result = new CanvasJS.Actual.InvalidElementView({
                        $source: this.m_element
                    });
                    break;
                case CanvasJS.CanvasType.Design:
                    result = new CanvasJS.Design.InvalidElementView({
                        $source: this.m_element
                    });
                    break;
            }
            return result;
        }
        static isGroupType(input) {
            return input instanceof CanvasJS.Actual.GroupActualView ||
                input instanceof CanvasJS.Design.GroupDesignView ||
                input instanceof CanvasJS.GroupModel ||
                input["componentScript"] === CanvasJS.GROUP_COMPONENT_SCRIPT_DEFAULT;
        }
        static createElement(state) {
            let type = null;
            let result = null;
            try {
                type = Jade.Type.getType(state.componentScript);
                if (type != null) {
                    result = new type(state);
                }
                else {
                    result = new CanvasJS.ElementModel(state);
                }
            }
            catch {
                result = new CanvasJS.ElementModel(state);
            }
            return result;
        }
    }
    CanvasJS.TypeResolver = TypeResolver;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class DocumentModel {
        constructor(state) {
            this.m_state = new Jade.StateBag(state);
            this.state.on("change", () => {
                this.onStateChangedTrigger();
            });
            this.fill(state);
        }
        get id() {
            return this.state.get("id");
        }
        get attributes() {
            return this.state.get("attributes");
        }
        get elements() {
            return this.m_elements;
        }
        get state() {
            return this.m_state;
        }
        get hasChanges() {
            return this.state.get("hasChanges", false);
        }
        set hasChanges(value) {
            this.state.set("hasChanges", value);
        }
        get eventsBus() {
            this.ensureEventBus();
            return this.m_eventBus;
        }
        toJSON() {
            let elements = [];
            this.elements.each((element) => {
                elements[elements.length] = element.toJSON();
            });
            return _.extend(this.state.toJSON(), {
                elements: elements
            });
        }
        getErroredElements() {
            let result = new Jade.MappedCollection({
                key: "id"
            });
            this.elements.each((element) => {
                if (element.errors.length > 0) {
                    result.add(element);
                }
            });
            return result;
        }
        clone() {
            return new DocumentModel(this.toJSON());
        }
        createElement(state, addToElements = false) {
            let result = null;
            state.document = this;
            result = CanvasJS.TypeResolver.createElement(state);
            if (result != null && addToElements) {
                this.elements.add(result);
            }
            return result;
        }
        addStateChangeHandler(handler) {
            return this.eventsBus.subscribe("state:changed", handler);
        }
        fill(state) {
            this.m_elements = new Jade.ObservableMappedCollection({
                key: "id",
                callbacks: {
                    onAfterAdd: (e) => {
                        this.onStateChangedTrigger();
                        this.onElementRemoved(e);
                    },
                    onAfterRemove: (e) => {
                        this.onStateChangedTrigger();
                        this.onElementRemoved(e);
                    },
                    onAfterInsert: (e) => {
                        this.onStateChangedTrigger();
                        this.onElementInserted(e);
                    }
                }
            });
            if (state == null || !state.hasOwnProperty("elements")) {
                return;
            }
            _.each(state.elements, (data) => {
                data.document = this;
                let element = this.createElement(data);
                if (element != null) {
                    this.elements.add(element);
                }
            });
            this.m_fillComplete = true;
        }
        onElementRemoved(e) {
        }
        onElementAdded(e) {
        }
        onElementInserted(e) {
        }
        onStateChanged() {
            this.hasChanges = true;
        }
        onStateChangedTrigger() {
            if (this.m_fillComplete == true) {
                this.onStateChanged();
                this.eventsBus.publish("state:changed");
            }
        }
        ensureEventBus() {
            if (this.m_eventBus == null) {
                this.m_eventBus = new Jade.EventBus();
            }
        }
    }
    CanvasJS.DocumentModel = DocumentModel;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class ElementError {
        constructor(options) {
            this.m_code = options.code;
            this.m_message = options.message;
            this.m_recoverable = options.recoverable;
            this.m_componentId = options.componentId;
        }
        get code() {
            return this.m_code;
        }
        get componentId() {
            return this.m_componentId;
        }
        get message() {
            return this.m_message;
        }
        get recoverable() {
            return this.m_recoverable;
        }
    }
    CanvasJS.ElementError = ElementError;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class ElementModel {
        constructor(state) {
            this.m_suspendStateChanged = false;
            this.m_state = new Jade.StateBag();
            this.m_document = state.document;
            delete state.document;
            this.state.on("change", () => {
                this.onStateChanged();
                this.triggerStateChanged();
            });
            if (state.id == null) {
                state.id = Jade.Guid.new();
            }
            this.m_state.set(state, { silent: true });
            this.resolver = new CanvasJS.TypeResolver({
                element: this,
                designScript: "CanvasJS.ElementDesign",
                actualScript: "CanvasJS.ElementActual"
            });
        }
        get state() {
            return this.m_state;
        }
        get id() {
            return this.state.get("id");
        }
        set id(value) {
            this.state.set("id", value);
        }
        get componentName() {
            return this.state.get("componentName");
        }
        set componentName(value) {
            this.state.set("componentName", value);
        }
        get componentType() {
            return this.state.get("componentType");
        }
        set componentType(value) {
            this.state.set("componentType", value);
        }
        get componentScript() {
            return this.state.get("componentScript");
        }
        get document() {
            return this.getDocument();
        }
        get height() {
            return this.state.get("height");
        }
        set height(value) {
            this.state.set("height", value);
        }
        get width() {
            return this.state.get("width");
        }
        set width(value) {
            this.state.set("width", value);
        }
        get x() {
            return this.state.get("x");
        }
        set x(value) {
            this.state.set("x", value);
        }
        get y() {
            return this.state.get("y");
        }
        set y(value) {
            this.state.set("y", value);
        }
        get anchorBottom() {
            return this.state.get("anchorBottom", null);
        }
        set anchorBottom(value) {
            this.state.set("anchorBottom", value);
        }
        get anchorRight() {
            return this.state.get("anchorRight", null);
        }
        set anchorRight(value) {
            this.state.set("anchorRight", value);
        }
        get onStateChangeCallback() {
            return this.m_onStateChangeCallback;
        }
        set onStateChangeCallback(value) {
            if (_.isFunction(value)) {
                this.m_onStateChangeCallback = value;
            }
        }
        get resolver() {
            return this.m_resolver;
        }
        set resolver(value) {
            this.m_resolver = value;
        }
        get errors() {
            return this.state.get("errors", []);
        }
        get hasErrors() {
            return this.errors.length > 0;
        }
        get hasNonRecoverableErrors() {
            let result = false;
            _.each(this.errors, (error) => {
                if (!error.recoverable && !result) {
                    result = true;
                }
            });
            return result;
        }
        get maxHeight() {
            return this.state.get("maxHeight");
        }
        set maxHeight(value) {
            this.state.set("maxHeight", value);
        }
        get minHeight() {
            return this.state.get("minHeight");
        }
        set minHeight(value) {
            this.state.set("minHeight", value);
        }
        get maxWidth() {
            return this.state.get("maxWidth");
        }
        set maxWidth(value) {
            this.state.set("maxWidth", value);
        }
        get minWidth() {
            return this.state.get("minWidth");
        }
        set minWidth(value) {
            this.state.set("minWidth", value);
        }
        get suspendStateChanged() {
            return this.m_suspendStateChanged;
        }
        set suspendStateChanged(value) {
            this.m_suspendStateChanged = value;
        }
        getDocument() {
            return this.m_document;
        }
        onStateChanged() {
            if (this.document != null) {
                this.document.hasChanges = true;
            }
        }
        triggerStateChanged() {
            if (!this.suspendStateChanged && _.isFunction(this.onStateChangeCallback)) {
                this.onStateChangeCallback();
            }
        }
        toJSON() {
            return this.state.toJSON();
        }
        delete() {
            this.document.elements.remove(this);
        }
        has(name) {
            return this[name] !== undefined;
        }
    }
    CanvasJS.ElementModel = ElementModel;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    CanvasJS.GROUP_COMPONENT_SCRIPT_DEFAULT = "CanvasJS.GroupModel";
    class GroupModel extends CanvasJS.ElementModel {
        constructor(state) {
            super(state);
            this.state.set("componentScript", this.state.get("componentScript", CanvasJS.GROUP_COMPONENT_SCRIPT_DEFAULT));
            this.state.set("componentType", this.state.get("componentType", GroupModel.componentTypeDefault));
            this.resolver = new CanvasJS.TypeResolver({
                actualScript: "CanvasJS.Actual.GroupActualView",
                designScript: "CanvasJS.Design.GroupDesignView",
                element: this
            });
        }
        get elements() {
            return this.state.get("elements", []);
        }
        static get componentTypeDefault() {
            return this.m_componentTypeDefault;
        }
        static set componentTypeDefault(value) {
            this.m_componentTypeDefault = value;
        }
    }
    CanvasJS.GroupModel = GroupModel;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class DocumentRoot extends Jade.UI.Control {
        get source() {
            return this.m_source;
        }
    }
    class DocumentView extends DocumentRoot {
        constructor(options) {
            super(_.extend(options, {
                id: options.$source.id
            }));
            this.m_source = options.$source;
            this.state.unset("$source", { silent: true });
            this.source.addStateChangeHandler(() => { this.onStateChanged(); });
        }
        get parameters() {
            return this.state.get("parameters");
        }
        template() {
            return `<div data-role="document"></div>`;
        }
        toJSON() {
            return this.source.toJSON();
        }
        getParametersOf() {
            return this.parameters;
        }
    }
    CanvasJS.DocumentView = DocumentView;
    class DocumentViewBase extends DocumentView {
        get source() {
            return this.m_source;
        }
    }
    CanvasJS.DocumentViewBase = DocumentViewBase;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    class ElementRoot extends Jade.UI.Control {
        get source() {
            return this.m_source;
        }
    }
    class ElementView extends ElementRoot {
        get height() {
            return this.source.height;
        }
        set height(value) {
            this.source.height;
        }
        get width() {
            return this.source.width;
        }
        set width(value) {
            this.source.width = value;
        }
        get x() {
            return this.source.x;
        }
        set x(value) {
            this.source.x = value;
        }
        get y() {
            return this.source.y;
        }
        set y(value) {
            this.source.y = value;
        }
        get anchorBottom() {
            return this.source.anchorBottom;
        }
        set anchorBottom(value) {
            this.source.anchorBottom = value;
        }
        get anchorRight() {
            return this.source.anchorRight;
        }
        set anchorRight(value) {
            this.source.anchorRight = value;
        }
        get nodeHeight() {
            return this.node == null ? 0 : this.node.outerHeight();
        }
        get nodeWidth() {
            return this.node == null ? 0 : this.node.outerWidth();
        }
        template() {
            return "";
        }
        toJSON() {
            return this.source.toJSON();
        }
        onBrowserResize() {
            this.onStateChanged();
        }
    }
    CanvasJS.ElementView = ElementView;
    class ElementViewBase extends ElementView {
        constructor(options) {
            super(_.extend(options, { id: options.$source.id }));
            this.m_source = options.$source;
            this.state.unset("$source", { silent: true });
            this.source.onStateChangeCallback = _.bind(this.onStateChanged, this);
        }
        get source() {
            return this.m_source;
        }
    }
    CanvasJS.ElementViewBase = ElementViewBase;
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Actual;
    (function (Actual) {
        let CanvasCss;
        (function (CanvasCss) {
            CanvasCss["Element"] = "-canvasjs-actual-element";
        })(CanvasCss = Actual.CanvasCss || (Actual.CanvasCss = {}));
    })(Actual = CanvasJS.Actual || (CanvasJS.Actual = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Actual;
    (function (Actual) {
        class Environment {
            static get document() {
                return this.store.get("document");
            }
            static get surface() {
                return this.store.get("surface");
            }
            static get events() {
                return this.context.events;
            }
            static get store() {
                return this.context.store;
            }
            static get context() {
                this.ensureContext();
                return this.m_context;
            }
            static getControlID(node) {
                let result = null;
                if (node instanceof jQuery) {
                    result = node;
                }
                else {
                    result = $(node);
                }
                return result.attr("id");
            }
            static reset() {
                this.m_context = null;
                Jade.UI.Controls.ContextMenuGroups.reset();
                Jade.UI.Controls.RibbonBarSections.reset();
                Jade.UI.Controls.RibbonBarGroups.reset();
            }
            static ensureContext() {
                if (this.m_context == null) {
                    this.m_context = Jade.Application
                        .instance
                        .contexts
                        .current;
                }
            }
        }
        Actual.Environment = Environment;
    })(Actual = CanvasJS.Actual || (CanvasJS.Actual = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Actual;
    (function (Actual) {
        class DocumentActualView extends CanvasJS.DocumentViewBase {
            constructor(options) {
                super(options);
                Actual.Environment.store.set("document", this);
                this.fill();
            }
            onDestroy(e) {
                super.onDestroy(e);
                Actual.Environment.store.unset("document");
            }
            fill() {
                this.source.elements.each((item) => {
                    let view = item.resolver.getViewOf(CanvasJS.CanvasType.Actual);
                    if (view != null) {
                        this.controls.add(view);
                    }
                });
            }
        }
        Actual.DocumentActualView = DocumentActualView;
        class DocumentActualViewBase extends DocumentActualView {
            get source() {
                return this.m_source;
            }
        }
        Actual.DocumentActualViewBase = DocumentActualViewBase;
    })(Actual = CanvasJS.Actual || (CanvasJS.Actual = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Actual;
    (function (Actual) {
        class ElementActualView extends CanvasJS.ElementViewBase {
            onActivate(e) {
                this.node.css({
                    top: `${this.y}px`,
                    left: `${this.x}px`
                });
                this.node.css({
                    height: this.anchorBottom == null ? this.height : "",
                    width: this.anchorRight == null ? this.width : "",
                    right: this.anchorRight != null ? this.anchorRight : "",
                    bottom: this.anchorBottom != null ? this.anchorBottom : "",
                });
            }
            wrapTemplate(template) {
                let elementNode = $(`<div class="${Actual.CanvasCss.Element}"></div>`);
                elementNode.append(template);
                return elementNode;
            }
        }
        Actual.ElementActualView = ElementActualView;
        class ElementActualViewBase extends ElementActualView {
            get source() {
                return this.m_source;
            }
        }
        Actual.ElementActualViewBase = ElementActualViewBase;
    })(Actual = CanvasJS.Actual || (CanvasJS.Actual = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Actual;
    (function (Actual) {
        class GroupActualView extends Actual.ElementActualViewBase {
        }
        Actual.GroupActualView = GroupActualView;
    })(Actual = CanvasJS.Actual || (CanvasJS.Actual = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Actual;
    (function (Actual) {
        class InvalidElementView extends Actual.ElementActualViewBase {
            template() {
                return `<table style="height:100%;width:100%;border:1px solid red;background-color:#FFFFFF;">
                        <tr>
                            <td style="text-align:center;vertical-align:middle;">${this.source.componentName}</td>
                        </tr>
                    </table>`;
            }
        }
        Actual.InvalidElementView = InvalidElementView;
    })(Actual = CanvasJS.Actual || (CanvasJS.Actual = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class Environment {
            static get gridUnit() {
                return 5;
            }
            static get document() {
                return this.store.get("document");
            }
            static get documentExists() {
                return this.nodeExists(this.document);
            }
            static get surface() {
                return this.store.get("surface");
            }
            static get surfaceExists() {
                return this.nodeExists(this.surface);
            }
            static get dialog() {
                return this.store.get("dialog");
            }
            static get selection() {
                return this.store.get("selection");
            }
            static get selectionBox() {
                return this.store.get("selectionbox");
            }
            static get toolBox() {
                return this.store.get("toolbox");
            }
            static get toolBoxExists() {
                return this.nodeExists(this.toolBox);
            }
            static get statusBar() {
                return this.store.get("statusbar");
            }
            static get statusBarExists() {
                return this.nodeExists(this.statusBar);
            }
            static get ribbonBar() {
                return this.store.get("ribbonbar");
            }
            static get ribbonBarExists() {
                return this.nodeExists(this.ribbonBar);
            }
            static get events() {
                return this.context.events;
            }
            static get store() {
                return this.context.store;
            }
            static get context() {
                this.ensureContext();
                return this.m_context;
            }
            static getControlID(node) {
                let result = null;
                if (node instanceof jQuery) {
                    result = node;
                }
                else {
                    result = $(node);
                }
                return result.attr("id");
            }
            static reset() {
                this.m_context = null;
                Jade.UI.Controls.ContextMenuGroups.reset();
                Jade.UI.Controls.RibbonBarSections.reset();
                Jade.UI.Controls.RibbonBarGroups.reset();
            }
            static ensureContext() {
                if (this.m_context == null) {
                    this.m_context = Jade.Application
                        .instance
                        .contexts
                        .current;
                }
            }
            static nodeExists(control) {
                return control != null && control.node != null && control.node.length > 0;
            }
        }
        Design.Environment = Environment;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        let ClipboardActionType;
        (function (ClipboardActionType) {
            ClipboardActionType[ClipboardActionType["copy"] = 1] = "copy";
            ClipboardActionType[ClipboardActionType["cut"] = 2] = "cut";
            ClipboardActionType[ClipboardActionType["paste"] = 3] = "paste";
        })(ClipboardActionType = Design.ClipboardActionType || (Design.ClipboardActionType = {}));
        class Clipboard {
            static copy() {
                let action = new Design.ClipboardAction({
                    type: ClipboardActionType.copy,
                    data: Design.Environment.selection.toArray()
                });
                this.setClipboardItem(action.toJSON(), () => {
                });
            }
            static cut() {
                let action = new Design.ClipboardAction({
                    type: ClipboardActionType.cut,
                    data: Design.Environment.selection.toArray()
                });
                this.setClipboardItem(action.toJSON(), () => {
                    let items = Design.Environment.selection.toArray();
                    let remove = new Array();
                    Design.Environment.selection.inDomOrder().each((element) => {
                        remove[remove.length] = element.toJSON();
                    });
                    Design.Environment.selection.clear();
                    Design.Environment.selection.box.hide();
                    _.each(items, (item) => {
                        Design.Environment.document.controls.remove(item);
                    });
                });
            }
            static paste() {
                this.getClipboardItem((item) => {
                    let action = null;
                    let event = null;
                    if (item != null) {
                        action = new Design.ClipboardAction(item);
                        event = new Design.ClipboardPasteEvent({
                            states: action.getData(),
                            reset: item.type == ClipboardActionType.copy,
                            committed: () => {
                                if (item.type != ClipboardActionType.copy) {
                                    this.clear();
                                }
                                else {
                                    this.setClipboardItem(action.toJSON(), () => { });
                                }
                            }
                        });
                        if (_.isFunction(Design.ClipboardPasteEvent.handler)) {
                            Design.ClipboardPasteEvent.handler(event);
                        }
                        else {
                            event.commit(event.states);
                        }
                    }
                });
            }
            static duplicate() {
                let action = new Design.ClipboardAction({
                    type: ClipboardActionType.copy,
                    data: Design.Environment.selection.toArray()
                });
                let event = new Design.ClipboardPasteEvent({
                    states: action.getData(),
                    reset: true
                });
                if (_.isFunction(Design.ClipboardPasteEvent.handler)) {
                    Design.ClipboardPasteEvent.handler(event);
                }
                else {
                    event.commit(event.states);
                }
            }
            static hasContent(success) {
                this.getClipboardItem((item) => {
                    success(item != null);
                });
            }
            static getClipboardItem(callback) {
                new Design.ClipboardTable().get(callback);
            }
            static setClipboardItem(item, success) {
                new Design.ClipboardTable().set(item, success);
            }
            static clear(success) {
                new Design.ClipboardTable().delete(success);
            }
        }
        Design.Clipboard = Clipboard;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ClipboardAction {
            constructor(options) {
                this.m_type = null;
                this.m_data = [];
                this.m_dataMap = {};
                this.m_executionCount = 0;
                this.m_type = options.type;
                if (options.data.length > 0 && options.data[0] instanceof Design.ElementDesignView) {
                    this.processDataForStorage(options.data);
                }
                else {
                    this.m_data = options.data;
                }
                this.m_executionCount = options.executionCount || 0;
            }
            get type() {
                return this.m_type;
            }
            get data() {
                return this.m_data;
            }
            toJSON() {
                return {
                    id: "canvas.clipboard",
                    type: this.type,
                    data: this.data,
                    executionCount: this.m_executionCount
                };
            }
            getData() {
                this.m_executionCount += 1;
                this.processDataForRetrieval();
                return this.data;
            }
            processDataForStorage(data) {
                let elements = new Design.SelectionCollection();
                let domOrdered = null;
                let json = null;
                _.each(data, (element) => {
                    if (CanvasJS.TypeResolver.isGroupType(element)) {
                        this.processGroupForStorage(element, elements);
                    }
                    else {
                        this.processElementForStorage(element, elements);
                    }
                });
                domOrdered = elements.inDomOrder();
                domOrdered.each((element) => {
                    if (!CanvasJS.TypeResolver.isGroupType(element)) {
                        json = _.extend({
                            ___selected: element.isSelected
                        }, element.source.toJSON());
                        this.data[this.data.length] = json;
                    }
                });
                domOrdered.each((element) => {
                    if (CanvasJS.TypeResolver.isGroupType(element)) {
                        json = _.extend({
                            ___selected: element.isSelected
                        }, element.source.toJSON());
                        this.data[this.data.length] = json;
                    }
                });
            }
            processElementForStorage(element, elements) {
                let index = this.data.length;
                this.m_dataMap[element.ID] = index;
                elements.add(element);
            }
            processGroupForStorage(group, elements) {
                group.grouped.each((element) => {
                    if (CanvasJS.TypeResolver.isGroupType(element)) {
                        this.processGroupForStorage(element, elements);
                    }
                    else {
                        this.processElementForStorage(element, elements);
                    }
                });
                this.processElementForStorage(group, elements);
            }
            processDataForRetrieval() {
                _.each(this.data, (item, index) => {
                    this.m_dataMap[item.id] = index;
                    if (this.type == Design.ClipboardActionType.copy) {
                        item.id = UUID.genV4().toString();
                        item.x = (item.x + 20),
                            item.y = (item.y + 20);
                    }
                });
                _.each(this.data, (item) => {
                    if (CanvasJS.TypeResolver.isGroupType(item)) {
                        let grouped = [];
                        _.each(item.elements, (id) => {
                            grouped[grouped.length] = this.m_data[this.m_dataMap[id]].id;
                        });
                        item.elements = grouped;
                    }
                });
            }
        }
        Design.ClipboardAction = ClipboardAction;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ClipboardPasteEvent {
            constructor(options) {
                this.m_states = [];
                this.m_selected = {};
                this.m_states = options.states.slice(0);
                this.m_cancelled = options.cancelled;
                this.m_committed = options.committed;
                this.m_reset = options.reset;
                this.storeSelected(this.states);
            }
            static get handler() {
                return this.m_handler;
            }
            static set handler(value) {
                this.m_handler = value;
            }
            get reset() {
                return this.m_reset;
            }
            get selected() {
                return this.m_selected;
            }
            get states() {
                return this.m_states;
            }
            cancel() {
                Design.Environment.selection.clear();
                Design.Environment.selection.box.hide();
                if (_.isFunction(this.m_cancelled)) {
                    this.m_cancelled();
                }
            }
            commit(newStates) {
                Design.Environment.selection.clear();
                Design.Environment.selection.box.hide();
                let elements = [];
                _.each(newStates, (state) => {
                    let element = Design.Environment.document.createElement(state, true);
                    if (element != null) {
                        elements.push(element);
                    }
                });
                elements.forEach(element => {
                    let shouldBeSelected = !element?.grouping?.isGrouped &&
                        this.selected[element.source.id] === true;
                    if (shouldBeSelected) {
                        Design.Environment.selection.add(element);
                    }
                });
                Design.Environment.selection.box.show();
                if (_.isFunction(this.m_committed)) {
                    this.m_committed();
                }
            }
            storeSelected(states) {
                _.each(states, (state) => {
                    if (state != null) {
                        if (state["___selected"] != undefined) {
                            this.selected[state.id] = true;
                        }
                    }
                });
            }
        }
        Design.ClipboardPasteEvent = ClipboardPasteEvent;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ClipboardTable extends Jade.Data.TableOf {
            constructor() {
                super({
                    name: "settings"
                });
            }
            get(success, error) {
                super.getOf("canvas.clipboard", success, error);
            }
            set(value, success, error) {
                super.setOf(null, value, success, error);
            }
            delete(success, error) {
                super.delete("canvas.clipboard", success, error);
            }
        }
        Design.ClipboardTable = ClipboardTable;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class AlignBottomCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/align-bottom",
                    tooltip: "Align Bottom",
                    label: "Align Bottom",
                    icon: "object_alignment_bottom.png",
                    enabled: false,
                    display: "icon",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let selection = Design.Environment.selection;
                let bottomMostValue = this.getBottomMostValue();
                selection.each((element) => {
                    element.setPosition({
                        top: bottomMostValue - element.dimensions.height,
                        left: element.dimensions.left
                    });
                });
                selection.box.show();
            }
            getBottomMostValue() {
                var result = null;
                let selection = Design.Environment.selection;
                selection.each((element) => {
                    let dimensions = element.dimensions;
                    if (result == null || element.dimensions.bottom > result) {
                        result = dimensions.bottom;
                    }
                });
                return result;
            }
        }
        Design.AlignBottomCommand = AlignBottomCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class AlignCenterCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/align-center",
                    tooltip: "Align Center",
                    label: "Align Center",
                    icon: "object_alignment_horizontal.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let selection = Design.Environment.selection;
                var largestElement = null;
                selection.each((element) => {
                    let dimensions = element.dimensions;
                    if (largestElement == null || largestElement.dimensions.width < dimensions.width) {
                        largestElement = element;
                    }
                });
                selection.each((element) => {
                    let remainder = (largestElement.dimensions.width - element.dimensions.width);
                    let half = Jade.Arithmetic.round(remainder / 2, Design.Environment.gridUnit);
                    let left = Jade.Arithmetic.round(largestElement.dimensions.left + half, Design.Environment.gridUnit);
                    element.setPosition({
                        top: element.dimensions.top,
                        left: left
                    });
                });
                selection.box.show();
            }
        }
        Design.AlignCenterCommand = AlignCenterCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class AlignLeftCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/align-left",
                    tooltip: "Align Left",
                    label: "Align Left",
                    icon: "object_alignment_left.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let elements = new Jade.Collection();
                Design.Environment.selection.each((item) => {
                    elements.add(item);
                });
                Design.Alignment.AlignLeft(elements);
                Design.Environment.selection.box.show();
            }
        }
        Design.AlignLeftCommand = AlignLeftCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class AlignMiddleCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/align-middle",
                    tooltip: "Align Middle",
                    label: "Align Middle",
                    icon: "object_alignment_vertical.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let selection = Design.Environment.selection;
                let largestHeightElement = this.getLargestHeightElement();
                selection.each((element) => {
                    let remainder = (largestHeightElement.dimensions.height - element.dimensions.height);
                    let half = Jade.Arithmetic.round(remainder / 2, Design.Environment.gridUnit);
                    let top = Jade.Arithmetic.round(largestHeightElement.dimensions.top + half, Design.Environment.gridUnit);
                    element.setPosition({
                        top: top,
                        left: element.dimensions.left
                    });
                });
                selection.box.show();
            }
            getLargestHeightElement() {
                var result = null;
                let selection = Design.Environment.selection;
                selection.each((element) => {
                    let dimensions = element.dimensions;
                    if (result == null || result.dimensions.height < dimensions.height) {
                        result = element;
                    }
                });
                return result;
            }
        }
        Design.AlignMiddleCommand = AlignMiddleCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class AlignRightCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/align-right",
                    tooltip: "Align Right",
                    label: "Align Right",
                    icon: "object_alignment_right.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let selection = Design.Environment.selection;
                var rightMostValue = null;
                selection.each((element) => {
                    let dimensions = element.dimensions;
                    if (rightMostValue == null || element.dimensions.right > rightMostValue) {
                        rightMostValue = dimensions.right;
                    }
                });
                selection.each((element) => {
                    element.setPosition({
                        top: element.dimensions.top,
                        left: rightMostValue - element.dimensions.width
                    });
                });
                selection.box.show();
            }
        }
        Design.AlignRightCommand = AlignRightCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class AlignTopCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/align-top",
                    label: "Align Top",
                    tooltip: "Align Top",
                    icon: "object_alignment_top.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let elements = new Jade.Collection();
                Design.Environment.selection.each((item) => {
                    elements.add(item);
                });
                Design.Alignment.AlignTop(elements);
                Design.Environment.selection.box.show();
            }
        }
        Design.AlignTopCommand = AlignTopCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class BackgroundColorCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "element/background-color",
                    tooltip: "Background Color",
                    label: "Background Color",
                    enabled: false,
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                Design.Environment.selection.each((element) => {
                    if (element.source.has("backgroundColor")) {
                        element.source["backgroundColor"] = e;
                    }
                });
            }
        }
        Design.BackgroundColorCommand = BackgroundColorCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class BorderColorCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "element/border-color",
                    tooltip: "Border Color",
                    label: "Border Color",
                    enabled: false,
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                let isEnabled = false;
                Design.Environment.selection.each((element) => {
                    if (element.source.has("borderColor")) {
                        isEnabled = true;
                        return;
                    }
                });
                this.enabled = isEnabled;
            }
            onExecute(e) {
                Design.Environment.selection.each((element) => {
                    if (element.source.has("borderColor")) {
                        element.source.state.set({
                            borderColor: e
                        });
                    }
                });
            }
        }
        Design.BorderColorCommand = BorderColorCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class BorderStyleCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "element/border-style",
                    tooltip: "Border Style",
                    label: "Border Style",
                    enabled: false,
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                Design.Environment.selection.each((element) => {
                    if (element.source.state.has("borderStyle")) {
                        element.source.state.set({
                            borderStyle: e
                        });
                    }
                });
            }
        }
        Design.BorderStyleCommand = BorderStyleCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class BorderWidthCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "element/border-width",
                    tooltip: "Border Width",
                    label: "Border Width",
                    enabled: false,
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                Design.Environment.selection.each((element) => {
                    if (element.source.state.has("borderWidth")) {
                        element.source.state.set({
                            borderWidth: e
                        });
                    }
                });
            }
        }
        Design.BorderWidthCommand = BorderWidthCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class BringForwardCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/bring-forward",
                    icon: "front.png",
                    label: "Bring To Front",
                    tooltip: "Move the selected elements in front of all other elements.",
                    display: "icon label",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                let elements = new Jade.Collection();
                Design.Environment.document.controls.each((element) => {
                    if (Design.Environment.selection.contains(element)) {
                        elements.add(element);
                    }
                });
                elements.each((element) => {
                    element.bringForward();
                });
            }
        }
        Design.BringForwardCommand = BringForwardCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class StandardCommands extends Jade.CommandGroup {
            constructor() {
                super("canvas/standard");
            }
            registerCommands(e) {
                e.commands.add(new Design.SendBackCommand());
                e.commands.add(new Design.BringForwardCommand());
                e.commands.add(new Design.AlignRightCommand());
                e.commands.add(new Design.AlignLeftCommand());
                e.commands.add(new Design.AlignCenterCommand());
                e.commands.add(new Design.FillHorizontalCommand());
                e.commands.add(new Design.FillVerticalCommand());
                e.commands.add(new Design.AlignTopCommand());
                e.commands.add(new Design.AlignMiddleCommand());
                e.commands.add(new Design.AlignBottomCommand());
                e.commands.add(new Design.DistributeHorizontallyCommand());
                e.commands.add(new Design.DistributeVerticallyCommand());
                e.commands.add(new Design.GroupCommand());
                e.commands.add(new Design.UngroupCommand());
                e.commands.add(new Design.DeleteCommand());
                e.commands.add(new Design.BackgroundColorCommand());
                e.commands.add(new Design.BorderColorCommand());
                e.commands.add(new Design.BorderStyleCommand());
                e.commands.add(new Design.BorderWidthCommand());
                e.commands.add(new Design.CutCommand());
                e.commands.add(new Design.CopyCommand());
                e.commands.add(new Design.PasteCommand());
                e.commands.add(new Design.DuplicateCommand());
            }
        }
        Design.StandardCommands = StandardCommands;
        class ClipboardCommands extends Jade.CommandGroup {
            constructor() {
                super("canvas/clipboard");
            }
            registerCommands(e) {
                e.commands.add(new Design.CutCommand());
                e.commands.add(new Design.CopyCommand());
                e.commands.add(new Design.PasteCommand());
                e.commands.add(new Design.DuplicateCommand());
            }
        }
        Design.ClipboardCommands = ClipboardCommands;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
Jade.Application.onStart(function () {
    Jade.CommandGroups.add(CanvasJS.Design.StandardCommands);
    Jade.CommandGroups.add(CanvasJS.Design.ClipboardCommands);
});
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class CopyCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "clipboard/copy",
                    label: "Copy",
                    tooltip: "Copies the selected elements and puts them in the canvas clipboard.",
                    enabled: false,
                    display: "label",
                    icon: "copy.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                Design.Clipboard.copy();
                Design.EventTrigger.triggerSelectionChangedEvent();
                Design.Environment.context.events.publish(Design.CanvasEvent.ELEMENT_COPY);
            }
        }
        Design.CopyCommand = CopyCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class CutCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "clipboard/cut",
                    label: "Cut",
                    tooltip: "Removes the selected elements from this canvas and puts them in the canvas clipboard.",
                    enabled: false,
                    display: "label",
                    icon: "cut.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                Design.Clipboard.cut();
                Design.EventTrigger.triggerSelectionChangedEvent();
                Design.Environment.context.events.publish(Design.CanvasEvent.ELEMENT_CUT);
            }
        }
        Design.CutCommand = CutCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DeleteCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/delete",
                    label: "Delete",
                    tooltip: "Delete the selected elements.",
                    icon: "delete.png",
                    enabled: false,
                    display: "label",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                if (e != null && e.suppressConfirmation) {
                    this.deleteSelections();
                    return;
                }
                Jade.UI.Dialogs.MessageDialog.open({
                    dialogButtons: Jade.UI.Dialogs.MessageDialogButtonStyle.OKCancel,
                    dialogStyle: Jade.UI.Dialogs.MessageDialogStyle.Warning,
                    title: "Delete Elements?",
                    message: `Delete ${Design.Environment.selection.count} selected elements?`,
                    select: {
                        ok: (sender, e) => {
                            sender.close();
                            this.deleteSelections();
                        }
                    }
                });
            }
            deleteSelections() {
                let elements = Design.Environment.selection.toArray();
                let states = [];
                this.gatherElementStates(states, elements);
                let event = new Design.DeleteElementEvent({
                    states: states,
                    committed: () => {
                        this.deleteElements(elements);
                    }
                });
                if (Design.DeleteElementEvent.handler != null && event.hasDestroyableElements()) {
                    Design.DeleteElementEvent.handler(event);
                }
                else {
                    this.deleteElements(elements);
                }
            }
            gatherElementStates(states, elements) {
                _.each(elements, (element) => {
                    if (element instanceof Design.GroupDesignView) {
                        this.gatherElementStates(states, element.grouped.toArray());
                    }
                    else {
                        states[states.length] = element.source.toJSON();
                    }
                });
            }
            deleteElements(elements) {
                let toDelete = Design.Environment.selection.toArray();
                _.each(toDelete, (element) => {
                    Design.Environment.selection.remove(element);
                    Design.Environment.document.controls.remove(element);
                    element.destroy();
                });
                Design.Environment.selection.box.hide();
                Design.Environment.events.publish(Design.CanvasEvent.ELEMENT_DELETE);
            }
        }
        Design.DeleteCommand = DeleteCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DeleteElementEvent {
            constructor(options) {
                this.m_states = [];
                this.m_states = options.states.slice(0);
                this.m_cancelled = options.cancelled;
                this.m_committed = options.committed;
            }
            static get handler() {
                return this.m_handler;
            }
            static set handler(value) {
                this.m_handler = value;
            }
            get states() {
                return this.m_states;
            }
            cancel() {
                if (_.isFunction(this.m_cancelled)) {
                    this.m_cancelled();
                }
            }
            commit(newStates) {
                if (_.isFunction(this.m_committed)) {
                    this.m_committed();
                }
            }
            hasDestroyableElements() {
                return _.some(this.states, { "isDestroyable": true });
            }
        }
        Design.DeleteElementEvent = DeleteElementEvent;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DistributeHorizontallyCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/distribute-horizontally",
                    label: "Distribute Horizontally",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 2;
            }
            onExecute(e) {
                let selection = Design.Environment.selection;
                let sortedElement = _.sortBy(selection.toArray(), (item) => {
                    return item.dimensions.left;
                });
                let occupiedWidth = 0;
                sortedElement.forEach((element) => {
                    occupiedWidth += element.dimensions.width;
                });
                let unoccupiedWidth = selection.dimensions.width - occupiedWidth;
                let itemCount = sortedElement.length == 1 ? 1 : sortedElement.length - 1;
                var gap = Jade.Arithmetic.round(unoccupiedWidth / itemCount, Design.Environment.gridUnit);
                _.each(sortedElement, (element, index) => {
                    let prev = null;
                    if (index > 0 && index < sortedElement.length - 1) {
                        prev = sortedElement[index - 1];
                        element.setPosition({
                            top: element.dimensions.top,
                            left: (prev.dimensions.left + prev.dimensions.width) + gap
                        });
                    }
                });
                selection.box.show();
            }
        }
        Design.DistributeHorizontallyCommand = DistributeHorizontallyCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DistributeVerticallyCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/distribute-vertically",
                    label: "Distribute Vertically",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 2;
            }
            onExecute(e) {
                let selection = Design.Environment.selection;
                let sortedElement = _.sortBy(selection.toArray(), (item) => {
                    return item.dimensions.top;
                });
                let occupiedHeight = 0;
                sortedElement.forEach((element) => {
                    occupiedHeight += element.dimensions.height;
                });
                let unoccupiedHeight = selection.dimensions.height - occupiedHeight;
                let itemCount = sortedElement.length == 1 ? 1 : sortedElement.length - 1;
                var gap = Jade.Arithmetic.round(unoccupiedHeight / itemCount, Design.Environment.gridUnit);
                _.each(sortedElement, (element, index) => {
                    let prev = null;
                    if (index > 0 && index < sortedElement.length - 1) {
                        prev = sortedElement[index - 1];
                        element.setPosition({
                            top: (prev.dimensions.top + prev.dimensions.height) + gap,
                            left: element.dimensions.left
                        });
                    }
                });
                selection.box.show();
            }
        }
        Design.DistributeVerticallyCommand = DistributeVerticallyCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DuplicateCommand extends Jade.Command {
            constructor() {
                super(...arguments);
                this.m_duplicates = new Array();
            }
            getDefaultValuesForProps() {
                return {
                    id: "clipboard/duplicate",
                    label: "Duplicate",
                    tooltip: "Creates and inserts copies the selected elements.",
                    enabled: false,
                    display: "label",
                    icon: "element_copy.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                Design.Clipboard.duplicate();
            }
        }
        Design.DuplicateCommand = DuplicateCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class FillHorizontalCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/fill-horizontal",
                    tooltip: "Horizontal Fill",
                    icon: "fill_horizontal.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let elements = new Jade.Collection();
                let selection = Design.Environment.selection;
                let selectionWidth = Design.Dimensions.fromNodes(selection.box.node).width;
                selection.each((item) => {
                    elements.add(item);
                });
                Design.Alignment.AlignLeft(elements);
                selection.each((item) => {
                    item.setArea({ height: item.dimensions.height, width: selectionWidth });
                });
                selection.box.show();
            }
        }
        Design.FillHorizontalCommand = FillHorizontalCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class FillVerticalCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/fill-vertical",
                    tooltip: "Vertical Fill",
                    icon: "fill_vertical.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1;
            }
            onExecute(e) {
                let elements = new Jade.Collection();
                let selection = Design.Environment.selection;
                let selectionHeight = Design.Dimensions.fromNodes(selection.box.node).height;
                selection.each((item) => {
                    elements.add(item);
                });
                Design.Alignment.AlignTop(elements);
                selection.each((item) => {
                    item.setArea({ height: selectionHeight, width: item.dimensions.width });
                });
                selection.box.show();
            }
        }
        Design.FillVerticalCommand = FillVerticalCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class GroupCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/group",
                    label: "Group",
                    tooltip: "Group the selected elements.",
                    icon: "grouped.png",
                    enabled: false,
                    display: "icon",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 1
                    && Design.Environment.document.node.find(`.${Design.CanvasCss.Selected}.${Design.CanvasCss.Grouped}:not(.${Design.CanvasCss.Group})`).length == 0;
            }
            onExecute(e) {
                let ids = new Array();
                if (this.enabled == false) {
                    return;
                }
                Design.Environment.selection.inDomOrder().each((item) => {
                    ids[ids.length] = item.ID;
                });
                let group = new CanvasJS.GroupModel({
                    id: Jade.Guid.new(),
                    document: Design.Environment.document.source,
                    elements: ids,
                }).resolver.getViewOf(CanvasJS.CanvasType.Design);
                Design.Environment.document.controls.add(group);
                Design.Environment.selection.clear();
                Design.Environment.selection.add(group);
            }
        }
        Design.GroupCommand = GroupCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class PasteCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "clipboard/paste",
                    label: "Paste",
                    tooltip: "Inserts a copy of the elements currently in the canvas clipboard.",
                    enabled: true,
                    display: "label",
                    icon: "clipboard_paste.png",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                Design.Clipboard.hasContent((result) => {
                    this.enabled = result;
                });
            }
            onExecute(e) {
                Design.Clipboard.paste();
                Design.EventTrigger.triggerSelectionChangedEvent();
                Design.Environment.context.events.publish(Design.CanvasEvent.ELEMENT_PASTE);
            }
        }
        Design.PasteCommand = PasteCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SelectionAreaCommand extends Jade.Command {
            constructor(props) {
                super({
                    id: "selection/area"
                });
                this.props.add("helper", props.helper);
            }
            get helper() {
                return this.props.get("helper");
            }
            onExecute(e) {
                this.positionElements();
            }
            positionElements() {
                let delta = this.helper.getOriginalDimensons().delta(this.helper.getDimensons());
                Design.Environment.selection.each((element) => {
                    let relativeDimensions = Design.Dimensions.relativeDimension(element.node, delta);
                    element.setArea(relativeDimensions);
                    element.setPosition(relativeDimensions);
                    element.onResize();
                });
                Design.Environment.selection.box.show();
            }
        }
        Design.SelectionAreaCommand = SelectionAreaCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SelectionPositionCommand extends Jade.Command {
            constructor(props) {
                super({
                    id: "selection/position"
                });
                this.props.add("ghost", props.ghost);
            }
            get ghost() {
                return this.props.get("ghost");
            }
            onExecute(e) {
                this.positionElements();
                this.positionSelectionHandle();
            }
            positionElements() {
                let ghostDimensions = Design.Dimensions.fromNodes(this.ghost.node);
                let delta = Design.Environment.selection.dimensions.delta(ghostDimensions);
                let relativeDimensions = null;
                Design.Environment.selection.each((element) => {
                    relativeDimensions = Design.Dimensions.relativeDimension(element.node, delta);
                    element.setPosition(relativeDimensions);
                });
            }
            positionSelectionHandle() {
                Design.Environment.selection.box.node.css({
                    top: `${this.ghost.top}px`,
                    left: `${this.ghost.left}px`
                });
            }
        }
        Design.SelectionPositionCommand = SelectionPositionCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SendBackCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/send-back",
                    label: "Send To Back",
                    tooltip: "Move the selected elements behind all other elements.",
                    icon: "back.png",
                    display: "icon",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = Design.Environment.selection.count > 0;
            }
            onExecute(e) {
                let selections = Design.Environment.selection.inDomOrder();
                selections.reverse();
                selections.each((element) => {
                    element.sendBack();
                });
            }
        }
        Design.SendBackCommand = SendBackCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class UngroupCommand extends Jade.Command {
            getDefaultValuesForProps() {
                return {
                    id: "selection/ungroup",
                    label: "Ungroup",
                    tooltip: "Ungroup the elements in the selected group.",
                    icon: "ungrouped.png",
                    enabled: false,
                    display: "icon",
                    iconSetId: "canvasjs"
                };
            }
            onStateChanged(state) {
                this.enabled = this.selectionContainsGroups();
            }
            onExecute(e) {
                if (this.enabled == false) {
                    return;
                }
                Design.Environment.selection.each((item) => {
                    if (item instanceof Design.GroupDesignView) {
                        item.ungroup();
                        Design.Environment.document.controls.remove(item);
                    }
                });
                Design.Environment.selection.clear();
                Design.Environment.selection.box.hide();
            }
            selectionContainsGroups() {
                let result = false;
                Design.Environment.selection.each((item) => {
                    if (item instanceof Design.GroupDesignView) {
                        result = true;
                        return false;
                    }
                });
                return result;
            }
        }
        Design.UngroupCommand = UngroupCommand;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        let ScrollDirection;
        (function (ScrollDirection) {
            ScrollDirection[ScrollDirection["none"] = 0] = "none";
            ScrollDirection[ScrollDirection["up"] = 1] = "up";
            ScrollDirection[ScrollDirection["right"] = 2] = "right";
            ScrollDirection[ScrollDirection["down"] = 3] = "down";
            ScrollDirection[ScrollDirection["left"] = 4] = "left";
        })(ScrollDirection = Design.ScrollDirection || (Design.ScrollDirection = {}));
        class Scroll {
            constructor(options) {
                this.m_container = null;
                this.m_isScrolling = false;
                this.m_boundaries = null;
                this.m_setContainerScrollDebounced = _.debounce(this.setContainerScroll, Design.Environment.gridUnit);
                this.m_container = options.container;
                this.m_boundaries = new Design.ScrollBoundaries({
                    container: options.container
                });
            }
            get container() {
                return this.m_container;
            }
            get isScrolling() {
                return this.m_isScrolling;
            }
            set isScrolling(value) {
                this.m_isScrolling = value;
            }
            startScroll(e, ui) {
                this.isScrolling = true;
                this.m_mouseXDelta = ((e.pageX - this.container.offset().left) + this.container.scrollLeft()) - ui.position.left;
                this.m_mouseYDelta = ((e.pageY - this.container.offset().top) + this.container.scrollTop()) - ui.position.top;
            }
            stopScroll() {
                this.isScrolling = false;
                this.container.scrollTop(this.container.scrollTop() + 1);
                this.container.scrollTop(this.container.scrollTop() - 1);
            }
            scroll(e, ui) {
                let x = null;
                let y = null;
                if (e != null) {
                    x = (e.pageX - this.container.offset().left) + this.container.scrollLeft();
                    y = (e.pageY - this.container.offset().top) + this.container.scrollTop();
                    if (ui) {
                        ui.position.top = Jade.Arithmetic.round(y - this.m_mouseYDelta, Design.Environment.gridUnit);
                        ui.position.left = Jade.Arithmetic.round(x - this.m_mouseXDelta, Design.Environment.gridUnit);
                    }
                    this.m_setContainerScrollDebounced(e.pageX, e.pageY);
                }
            }
            setContainerScroll(mouseX, mouseY) {
                if (!this.isScrolling) {
                    return;
                }
                let command = this.m_boundaries.getScroll(mouseX, mouseY);
                switch (command.direction) {
                    case ScrollDirection.up:
                        this.container.scrollTop(this.container.scrollTop() - (command.acceleration * 5));
                        break;
                    case ScrollDirection.down:
                        this.container.scrollTop(this.container.scrollTop() + (command.acceleration * 5));
                        break;
                    case ScrollDirection.left:
                        this.container.scrollLeft(this.container.scrollLeft() - (command.acceleration * 5));
                        break;
                    case ScrollDirection.right:
                        this.container.scrollLeft(this.container.scrollLeft() + (command.acceleration * 5));
                        break;
                    default:
                        break;
                }
            }
        }
        Design.Scroll = Scroll;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ScrollBoundaries {
            constructor(options) {
                this.m_mouseX = null;
                this.m_mouseY = null;
                this.m_container = null;
                this.m_container = options.container;
            }
            get container() {
                return this.m_container;
            }
            get mouseX() {
                return this.m_mouseX;
            }
            get mouseY() {
                return this.m_mouseY;
            }
            get top() {
                return this.container.offset().top;
            }
            get left() {
                return this.container.offset().left;
            }
            get bottom() {
                return this.container.offset().top + this.container.height();
            }
            get right() {
                return this.container.offset().left + this.container.width();
            }
            get isScrollableUp() {
                return this.container.scrollTop() > 0;
            }
            get isScrollableDown() {
                return (this.container.get(0).scrollHeight - this.container.scrollTop()) > 0;
            }
            get isScrollableRight() {
                return (this.container.get(0).scrollWidth - this.container.scrollLeft()) > 0;
            }
            get isScrollableLeft() {
                return this.container.scrollLeft() > 0;
            }
            get locationTop() {
                return this.mouseY - this.top;
            }
            get locationRight() {
                return this.right - this.mouseX;
            }
            get locationBottom() {
                return this.bottom - this.mouseY;
            }
            get locationLeft() {
                return this.mouseX - this.left;
            }
            getScroll(mouseX, mouseY) {
                let result = { direction: Design.ScrollDirection.none, acceleration: 0 };
                this.m_mouseX = mouseX;
                this.m_mouseY = mouseY;
                switch (true) {
                    case this.isScrollableUp && this.locationTop <= 100:
                        result = { direction: Design.ScrollDirection.up, acceleration: this.getAcceleration(this.locationTop) };
                        break;
                    case this.isScrollableDown && this.locationBottom <= 100:
                        result = { direction: Design.ScrollDirection.down, acceleration: this.getAcceleration(this.locationBottom) };
                        break;
                    case this.isScrollableLeft && this.locationLeft <= 100:
                        result = { direction: Design.ScrollDirection.left, acceleration: this.getAcceleration(this.locationLeft) };
                        break;
                    case this.isScrollableRight && this.locationRight <= 100:
                        result = { direction: Design.ScrollDirection.right, acceleration: this.getAcceleration(this.locationRight) };
                        break;
                    default:
                        break;
                }
                return result;
            }
            getAcceleration(value) {
                let result = 0;
                switch (true) {
                    case value <= 100 && value > 75:
                        result = 2;
                        break;
                    case value <= 75 && value > 50:
                        result = 4;
                        break;
                    case value <= 50 && value > 25:
                        result = 6;
                        break;
                    case value <= 25:
                        result = 8;
                        break;
                }
                return result;
            }
        }
        Design.ScrollBoundaries = ScrollBoundaries;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class Selection {
            constructor() {
                this.m_elements = new Design.SelectionCollection();
            }
            get elements() {
                return this.m_elements;
            }
            get count() {
                return this.elements.count;
            }
            get box() {
                return Design.Environment.selectionBox;
            }
            get dimensions() {
                return this.elements.dimensions;
            }
            first() {
                return this.elements.first();
            }
            last() {
                return this.elements.last();
            }
            add(element) {
                var result = this.elements.add(element);
                if (result) {
                    if (element.node) {
                        element.node.addClass(Design.CanvasCss.Selected);
                    }
                    element.onSelect();
                    Design.EventTrigger.triggerSelectionChangedEvent();
                }
            }
            remove(element) {
                var result = this.elements.remove(element);
                if (result != null) {
                    if (element.node) {
                        element.node.removeClass(Design.CanvasCss.Selected);
                    }
                    element.onDeselect();
                    Design.EventTrigger.triggerSelectionChangedEvent();
                }
            }
            clear() {
                let copy = this.elements.toArray();
                _.each(copy, (element) => {
                    this.remove(element);
                });
                Design.EventTrigger.triggerSelectionChangedEvent();
            }
            each(fn) {
                this.elements.each(fn);
            }
            toArray() {
                return this.elements.toArray();
            }
            contains(element) {
                return this.elements.contains(element);
            }
            item(index) {
                return this.elements.item(index);
            }
            inDomOrder() {
                return this.elements.inDomOrder();
            }
            get isResizing() {
                return this.box.node.hasClass(Design.CanvasCss.SelectionBoxResizing);
            }
        }
        Design.Selection = Selection;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SelectionCollection extends Jade.ObservableCollection {
            constructor() {
                super(...arguments);
                this.m_dictionary = {};
            }
            get dimensions() {
                return new Design.Dimensions(Design.Dimensions.fromElements(this.toArray()));
            }
            add(element) {
                let result = false;
                if (element && !this.contains(element)) {
                    result = super.add(element);
                    this.m_dictionary[element.ID] = element;
                }
                return result;
            }
            remove(element) {
                var result = null;
                if (element != null) {
                    super.remove(element);
                    delete this.m_dictionary[element.ID];
                    result = element;
                }
                return result;
            }
            insert(element, index) {
                let result = false;
                if (element && !this.contains(element)) {
                    result = super.insert(element, index);
                    this.m_dictionary[element.ID] = element;
                }
                return result;
            }
            clear() {
                super.clear();
                this.m_dictionary = {};
            }
            contains(component) {
                return component != null && this.m_dictionary.hasOwnProperty(component.ID);
            }
            sort(fn) {
                if (fn) {
                    super.sort(fn);
                }
                else {
                    super.sort((item1, item2) => {
                        return item2.node.index() - item1.node.index();
                    });
                }
            }
            getById(id) {
                return this.m_dictionary[id];
            }
            inDomOrder() {
                let result = new Jade.Collection();
                Design.Environment.document.controls.each((element) => {
                    if (this.contains(element)) {
                        result.add(element);
                    }
                });
                return result;
            }
        }
        Design.SelectionCollection = SelectionCollection;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class EventTrigger {
            static triggerSelectionChangedEvent() {
                EventTrigger.m_triggerSelectionChangedEvent();
            }
            static triggerBrowserFocusedEvent() {
                EventTrigger.m_triggerBrowserFocusedEvent();
            }
        }
        EventTrigger.m_triggerSelectionChangedEvent = _.debounce(() => {
            Design.Environment
                .context
                .commands
                .setState({});
            Design.Environment
                .events
                .publish(Design.CanvasEvent.SELECTION_CHANGE);
        }, 100);
        EventTrigger.m_triggerBrowserFocusedEvent = _.debounce(() => {
            Design.Environment
                .context
                .commands
                .setState({});
        }, 100);
        Design.EventTrigger = EventTrigger;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        let IGeometryBoxEvent;
        (function (IGeometryBoxEvent) {
            IGeometryBoxEvent[IGeometryBoxEvent["none"] = 0] = "none";
            IGeometryBoxEvent[IGeometryBoxEvent["size"] = 1] = "size";
            IGeometryBoxEvent[IGeometryBoxEvent["move"] = 2] = "move";
        })(IGeometryBoxEvent = Design.IGeometryBoxEvent || (Design.IGeometryBoxEvent = {}));
        class GeometryBox extends Jade.UI.Control {
            constructor(options) {
                super(options);
                this.m_executingEvent = IGeometryBoxEvent.none;
                this.m_executingEventArgs = null;
                this.m_handles = new Design.GeometryBoxHandles({
                    box: this
                });
            }
            get dimensions() {
                return new Design.Dimensions(Design.Dimensions.fromNodes(this.node));
            }
            get role() {
                return this.state.get("role");
            }
            get visible() {
                return this.node.is(":visible");
            }
            set visible(value) {
                this.node.css({
                    visibility: value ? "" : "hidden"
                });
            }
            get executingEvent() {
                return this.m_executingEvent;
            }
            get resizable() {
                return this.node.data("ui-resizable");
            }
            get draggable() {
                return this.node.data("ui-draggable");
            }
            get handles() {
                return this.m_handles;
            }
            hide() {
            }
            show() {
            }
            onActivate(e) {
                this.isBrowserResizeAware = true;
                this.resizable_onInit();
                this.draggable_onInit();
                this.node.on(Jade.BrowserEvent.CLICK, $.proxy(this.onClick, this));
                this.node.on(Jade.BrowserEvent.DOUBLECLICK, $.proxy(this.onDoubleClick, this));
                this.node.on(Jade.BrowserEvent.MOUSEUP, $.proxy(this.onMouseUp, this));
            }
            onSizeStart(e) {
            }
            onSizing(e) {
            }
            onSizeStop(e) {
            }
            onMoveStart(e) {
            }
            onMoving(e) {
            }
            onMoveStop(e) {
            }
            onClick(e) {
            }
            onDoubleClick(e) {
            }
            onMouseUp(e) {
                if (this.m_executingEvent != IGeometryBoxEvent.none) {
                    if (this.m_executingEvent == IGeometryBoxEvent.move) {
                        this.visible = true;
                        this.onMoveStop(this.m_executingEventArgs);
                        this.show();
                    }
                }
                this.setExecutingEvent(IGeometryBoxEvent.none);
                this.m_executingEventArgs = null;
            }
            onResizeStart(e, ui) {
                this.setExecutingEvent(IGeometryBoxEvent.size);
                this.m_executingEventArgs = new Design.GeometryBoxSizeEventArgs({
                    box: this,
                    event: e,
                    sized: ui
                });
                this.onSizeStart(this.m_executingEventArgs);
            }
            onResize(e, ui) {
                this.m_executingEventArgs = new Design.GeometryBoxSizeEventArgs({
                    box: this,
                    event: e,
                    sized: ui
                });
                this.onSizing(this.m_executingEventArgs);
            }
            onResizeStop(e, ui) {
                this.m_executingEventArgs = new Design.GeometryBoxSizeEventArgs({
                    box: this,
                    event: e,
                    sized: ui
                });
                this.onSizeStop(this.m_executingEventArgs);
                this.setExecutingEvent(IGeometryBoxEvent.none);
            }
            onDragStart(e, ui) {
                this.setExecutingEvent(IGeometryBoxEvent.move);
                this.visible = true;
                $(ui.helper).css({
                    cursor: "move"
                });
                this.onMoveStart(new Design.GeometryBoxMoveEventArgs({
                    box: this,
                    event: e,
                    moved: ui
                }));
            }
            onDrag(e, ui) {
                this.m_executingEventArgs = new Design.GeometryBoxMoveEventArgs({
                    box: this,
                    event: e,
                    moved: ui
                });
                this.onMoving(this.m_executingEventArgs);
            }
            onDragStop(e, ui) {
                this.m_executingEventArgs = new Design.GeometryBoxMoveEventArgs({
                    box: this,
                    event: e,
                    moved: ui
                });
                this.onMoveStop(this.m_executingEventArgs);
                this.setExecutingEvent(IGeometryBoxEvent.none);
            }
            draggable_onInit() {
                this.node.draggable({
                    addClasses: false,
                    appendTo: Design.CanvasCssSelector.Document,
                    containment: Design.Environment.document.node,
                    helper: "clone",
                    scroll: false,
                    distance: Design.Environment.gridUnit,
                    grid: [Design.Environment.gridUnit, Design.Environment.gridUnit],
                    start: $.proxy(this.onDragStart, this),
                    drag: $.proxy(this.onDrag, this),
                    stop: $.proxy(this.onDragStop, this)
                });
            }
            resizable_onInit() {
                this.node.resizable({
                    handles: "all",
                    grid: [Design.Environment.gridUnit, Design.Environment.gridUnit],
                    minHeight: Design.Environment.gridUnit,
                    minWidth: Design.Environment.gridUnit,
                    autoHide: false,
                    start: $.proxy(this.onResizeStart, this),
                    resize: $.proxy(this.onResize, this),
                    stop: $.proxy(this.onResizeStop, this)
                });
            }
            setExecutingEvent(event) {
                setTimeout(() => {
                    this.m_executingEvent = event;
                }, event == IGeometryBoxEvent.none ? 250 : 0);
            }
        }
        Design.GeometryBox = GeometryBox;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class GeometryBoxEventArgs {
            constructor(options) {
                this.m_box = options.box;
                this.m_event = options.event;
            }
            get box() {
                return this.m_box;
            }
            get event() {
                return this.m_event;
            }
        }
        Design.GeometryBoxEventArgs = GeometryBoxEventArgs;
        class GeometryBoxMoveEventArgs extends GeometryBoxEventArgs {
            constructor(options) {
                super(options);
                this.m_moved = options.moved;
            }
            ;
            get moved() {
                return this.m_moved;
            }
            get helper() {
                return $(this.moved.helper);
            }
        }
        Design.GeometryBoxMoveEventArgs = GeometryBoxMoveEventArgs;
        class GeometryBoxSizeEventArgs extends GeometryBoxEventArgs {
            constructor(options) {
                super(options);
                this.m_sized = options.sized;
            }
            ;
            get sized() {
                return this.m_sized;
            }
            get handle() {
                return this.box.resizable.axis;
            }
        }
        Design.GeometryBoxSizeEventArgs = GeometryBoxSizeEventArgs;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class GeometryBoxGhost {
            constructor(options) {
                this.m_node = null;
                this.m_top = null;
                this.m_left = null;
                this.m_offsetTop = null;
                this.m_offsetLeft = null;
                this.m_node = options.ui.helper;
                this.m_top = Math.round(options.ui.position.top);
                this.m_left = Math.round(options.ui.position.left);
                this.m_offsetTop = Math.round(options.ui.offset.top);
                this.m_offsetLeft = Math.round(options.ui.offset.left);
            }
            get node() {
                return this.m_node;
            }
            get top() {
                return this.m_top;
            }
            get left() {
                return this.m_left;
            }
            get height() {
                return Math.round(this.node.innerHeight());
            }
            get width() {
                return Math.round(this.node.innerWidth());
            }
            get offsetTop() {
                return this.m_offsetTop;
            }
            get offsetLeft() {
                return this.m_offsetLeft;
            }
            getDimensons() {
                return new Design.Dimensions({
                    top: this.top,
                    left: this.left,
                    height: this.node.innerHeight(),
                    width: this.node.innerWidth(),
                });
            }
        }
        Design.GeometryBoxGhost = GeometryBoxGhost;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        let GeometryBoxHandle;
        (function (GeometryBoxHandle) {
            GeometryBoxHandle["n"] = "n";
            GeometryBoxHandle["s"] = "s";
            GeometryBoxHandle["e"] = "e";
            GeometryBoxHandle["w"] = "w";
            GeometryBoxHandle["ne"] = "ne";
            GeometryBoxHandle["nw"] = "nw";
            GeometryBoxHandle["se"] = "se";
            GeometryBoxHandle["sw"] = "sw";
        })(GeometryBoxHandle = Design.GeometryBoxHandle || (Design.GeometryBoxHandle = {}));
        class GeometryBoxHandles {
            constructor(options) {
                this.m_handles = [
                    GeometryBoxHandle.e,
                    GeometryBoxHandle.n,
                    GeometryBoxHandle.ne,
                    GeometryBoxHandle.nw,
                    GeometryBoxHandle.s,
                    GeometryBoxHandle.se,
                    GeometryBoxHandle.sw,
                    GeometryBoxHandle.w
                ];
                this.m_handleClassPrefix = "ui-resizable-";
                this.m_box = options.box;
            }
            get box() {
                return this.m_box;
            }
            show(handles) {
                if (handles == null) {
                    handles = this.m_handles;
                }
                _.each(handles, (handle) => {
                    this.getHandle(handle).show();
                });
            }
            hide(handles) {
                if (handles == null) {
                    handles = this.m_handles;
                }
                _.each(handles, (handle) => {
                    this.getHandle(handle).hide();
                });
            }
            showAll() {
                _.each(this.m_handles, (handle) => {
                    this.getHandle(handle).show();
                });
            }
            hideAll() {
                _.each(this.m_handles, (handle) => {
                    this.getHandle(handle).hide();
                });
            }
            showVertical() {
                let handles = [GeometryBoxHandle.n, GeometryBoxHandle.s];
                this.hideAll();
                _.each(handles, (handle) => {
                    this.getHandle(handle).show();
                });
            }
            showHorizontal() {
                let handles = [GeometryBoxHandle.e, GeometryBoxHandle.w];
                this.hideAll();
                _.each(handles, (handle) => {
                    this.getHandle(handle).show();
                });
            }
            getHandle(handle) {
                return this.box.node.find(`.${this.m_handleClassPrefix}${handle}`);
            }
        }
        Design.GeometryBoxHandles = GeometryBoxHandles;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SelectionBoxBase extends Design.GeometryBox {
            constructor() {
                super(...arguments);
                this.m_onDocumentReadyInterval = window.setInterval(() => {
                    if (Design.Environment.document != null && Design.Environment.document.node != null) {
                        Design.Environment.document.node.on(Jade.BrowserEvent.MOUSEDOWN, `.${Design.CanvasCss.Element}`, this.m_onElementMouseDown);
                        Design.Environment.document.node.on(Jade.BrowserEvent.DOUBLECLICK, $.proxy(this.m_onDocumentDoubleClick, this));
                        clearInterval(this.m_onDocumentReadyInterval);
                    }
                }, 100);
                this.m_onElementMouseDown = (e) => {
                    this.onElementMouseDown(e);
                };
                this.m_onDocumentDoubleClick = (e) => {
                    this.onDocumentDoubleClick(e);
                };
                this.m_onDocumentDrop = (e) => {
                    this.onDocumentDrop(e);
                };
            }
            hide() {
                Design.Environment.document.controls.detach(this);
            }
            show() {
                if (Design.Environment.selection.count > 0) {
                    if (this.isDetached) {
                        Design.Environment.document.controls.add(this);
                    }
                    this.node.show();
                    this.draw();
                }
            }
            draw() {
                Design.Environment.selection.dimensions.copyDimensionsToTarget(this.node);
            }
            template() {
                return `<div class="${Design.CanvasCss.SelectionBox}">
                        <div>
                            <div>&nbsp;</div>
                        </div>
                    </div>`;
            }
            onInit(e) {
                super.onInit(e);
                Design.Environment.store.add("selectionbox", this);
                this.subscriptions.add(Design.CanvasEvent.SELECTION_BOX_DROP, (e) => {
                    this.m_onDocumentDrop(e);
                });
            }
            onActivate(e) {
                super.onActivate(e);
                this.node.hide();
            }
            onDestroy(e) {
                super.onDestroy(e);
                if (Design.Environment.documentExists) {
                    Design.Environment.document.node.off(Jade.BrowserEvent.DOUBLECLICK, this.m_onDocumentDoubleClick);
                    Design.Environment.document.node.off(Jade.BrowserEvent.MOUSEDOWN, `.${Design.CanvasCss.Element}`, this.m_onElementMouseDown);
                }
            }
            onElementMouseDown(e) {
                let node = $(e.currentTarget);
                let element = null;
                let shouldIgnoreSelect = false;
                if ((e.which !== 1 && e.which !== 3) || node.length == 0) {
                    return;
                }
                element = Design.Convert.fromNodeToDesignView(node);
                if (element == null) {
                    return;
                }
                shouldIgnoreSelect = element.node.hasClass(Design.CanvasCss.IgnoreSelect);
                if (shouldIgnoreSelect) {
                    element = Design.Dimensions.getAtCoordinates(e.pageX, e.pageY);
                }
                if (element == null) {
                    return;
                }
                Design.Environment.document.node.addClass("ELEMENT-SOURCED");
                this.onElementInclude(new Design.SelectionBoxIncludeEventArgs({
                    event: e,
                    element: element,
                    isNewSelection: !e.ctrlKey && !e.metaKey
                }));
                this.show();
                $(e.target).trigger("mouseup");
                this.node.trigger("mouseup");
                e.target = this.node.get(0);
                this.node.trigger(e);
            }
            onDocumentDoubleClick(e) {
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE, Design.Dimensions.fromNodes(Design.Environment.document.node));
                Design.Environment.document.node.find(`.${Design.CanvasCss.IgnoreSelect}`).removeClass(Design.CanvasCss.IgnoreSelect);
                Design.Environment.selection.clear();
                this.hide();
            }
            onBrowserResize() {
                super.onBrowserResize();
                if (this.executingEvent == Design.IGeometryBoxEvent.none
                    && !this.isDetached
                    && this.visible
                    && Design.Environment.selection
                    && Design.Environment.selection.count > 0) {
                    this.draw();
                }
            }
            onClick(e) {
                super.onClick(e);
                if (e.ctrlKey || e.metaKey) {
                    let element = Design.Dimensions.getAtCoordinates(e.pageX, e.pageY);
                    if (element) {
                        if (Design.Environment.selection.contains(element)) {
                            this.onElementExclude(new Design.SelectionBoxExcludeEventArgs({
                                event: e,
                                element: element
                            }));
                        }
                        else {
                            this.onElementInclude(new Design.SelectionBoxIncludeEventArgs({
                                event: e,
                                element: element,
                                isNewSelection: false
                            }));
                        }
                        this.draw();
                    }
                    e.stopPropagation();
                    return;
                }
                Design.Environment.document.node.find(`.${Design.CanvasCss.IgnoreSelect}`).removeClass(Design.CanvasCss.IgnoreSelect);
            }
            onDoubleClick(e) {
                let element = Design.Dimensions.getAtCoordinates(e.pageX, e.pageY);
                let isElementAlreadySelected = Design.Environment.selection.contains(element);
                ;
                let isElementNotInstanceOfGroup = !(element instanceof Design.GroupDesignView);
                let isCurrentSelectionCountOne = Design.Environment.selection.count === 1;
                let isSelectionSingleGroup = Design.Environment.selection.first() instanceof Design.GroupDesignView;
                ;
                if (element && !e.ctrlKey) {
                    if (isCurrentSelectionCountOne &&
                        isElementAlreadySelected &&
                        isElementNotInstanceOfGroup) {
                        this.onElementInspect(new Design.SelectionBoxInspectEventArgs({
                            event: e,
                            element: element
                        }));
                    }
                    else {
                        if (isSelectionSingleGroup) {
                            Design.Environment.selection.first().node.addClass(Design.CanvasCss.IgnoreSelect);
                        }
                        this.onElementInclude(new Design.SelectionBoxIncludeEventArgs({
                            event: e,
                            element: element,
                            isNewSelection: false
                        }));
                        Design.Environment.selection.clear();
                        Design.Environment.selection.add(element);
                        this.show();
                    }
                }
                else {
                    Design.Environment.selection.clear();
                    this.hide();
                }
                e.stopPropagation();
            }
            onElementInclude(e) {
            }
            onElementExclude(e) {
            }
            onElementInspect(e) {
            }
            onElementsMoved() {
            }
            onElementsSized() {
            }
            onMoveStart(e) {
                super.onMoveStart(e);
                Design.Environment.surface.scrolling.startScroll(e.event, e.moved);
            }
            onMoving(e) {
                super.onMoving(e);
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE, {
                    dimensions: Design.Dimensions.fromNodes(e.helper)
                });
                Design.Environment.surface.scrolling.scroll(e.event, e.moved);
            }
            onMoveStop(e) {
                super.onMoveStop(e);
                Design.Environment.surface.scrolling.stopScroll();
                Design.Environment.document.node.removeClass("ELEMENT-SOURCED");
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE);
            }
            onSizing(e) {
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE, {
                    dimensions: Design.Dimensions.fromNodes($(e.sized.helper))
                });
            }
            onSizeStop(e) {
                super.onSizeStop(e);
                let command = new Design.SelectionAreaCommand({
                    helper: new Design.SelectionBoxHelper({
                        e: e.event,
                        ui: e.sized
                    })
                });
                command.execute();
                this.show();
                this.onElementsSized();
            }
            onDocumentDrop(e) {
                let command = new Design.SelectionPositionCommand({
                    ghost: new Design.GeometryBoxGhost({
                        event: e.event,
                        ui: e.dropped
                    })
                });
                command.execute();
                this.onElementsMoved();
            }
        }
        Design.SelectionBoxBase = SelectionBoxBase;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SelectionBox extends Design.SelectionBoxBase {
            show() {
                super.show();
                this.showHandles();
            }
            onElementInclude(e) {
                if (e.isNewSelection) {
                    Design.Environment.selection.clear();
                }
                Design.Environment.selection.add(e.element);
                Design.Environment.events.publish(Design.CanvasEvent.ELEMENT_SELECT, e.element.ID);
                this.showHandles();
            }
            onElementExclude(e) {
                Design.Environment.selection.remove(e.element);
                if (Design.Environment.selection.count == 0) {
                    this.hide();
                }
                this.showHandles();
            }
            onElementsSized() {
                this.draw();
            }
            showHandles() {
                let allowedHandles = Design.AllowedSizingHandles.getVisibleHandles(Design.Environment.selection.toArray());
                this.handles.hideAll();
                this.handles.show(allowedHandles);
            }
        }
        Design.SelectionBox = SelectionBox;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SelectionBoxEventArgs {
            constructor(options) {
                this.m_event = options.event;
                this.m_element = options.element;
            }
            get event() {
                return this.m_event;
            }
            get element() {
                return this.m_element;
            }
            get isCtrlKeyPressed() {
                return this.event.ctrlKey || this.event.metaKey;
            }
        }
        Design.SelectionBoxEventArgs = SelectionBoxEventArgs;
        class SelectionBoxExcludeEventArgs extends SelectionBoxEventArgs {
        }
        Design.SelectionBoxExcludeEventArgs = SelectionBoxExcludeEventArgs;
        class SelectionBoxIncludeEventArgs extends SelectionBoxEventArgs {
            constructor(options) {
                super(options);
                this.m_isNewSelection = options.isNewSelection;
            }
            get isNewSelection() {
                return this.m_isNewSelection || false;
            }
        }
        Design.SelectionBoxIncludeEventArgs = SelectionBoxIncludeEventArgs;
        class SelectionBoxInspectEventArgs extends SelectionBoxEventArgs {
        }
        Design.SelectionBoxInspectEventArgs = SelectionBoxInspectEventArgs;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SelectionBoxHelper {
            constructor(options) {
                this.m_node = null;
                this.m_target = null;
                this.m_top = null;
                this.m_left = null;
                this.m_height = null;
                this.m_width = null;
                this.m_originalTop = null;
                this.m_originalLeft = null;
                this.m_originalHeight = null;
                this.m_originalWidth = null;
                this.m_node = options.ui.helper;
                this.m_target = options.ui.element;
                this.m_top = Math.round(options.ui.position.top);
                this.m_left = Math.round(options.ui.position.left);
                this.m_height = Math.round(options.ui.size.height);
                this.m_width = Math.round(options.ui.size.width);
                this.m_originalTop = Math.round(options.ui.originalPosition.top);
                this.m_originalLeft = Math.round(options.ui.originalPosition.left);
                this.m_originalHeight = Math.round(options.ui.originalSize.height);
                this.m_originalWidth = Math.round(options.ui.originalSize.width);
            }
            get node() {
                return this.m_node;
            }
            get target() {
                return this.m_target;
            }
            get top() {
                return this.m_top;
            }
            get left() {
                return this.m_left;
            }
            get height() {
                return this.m_height;
            }
            get width() {
                return this.m_width;
            }
            get originalTop() {
                return this.m_originalTop;
            }
            get originalLeft() {
                return this.m_originalLeft;
            }
            get originalHeight() {
                return this.m_originalHeight;
            }
            get originalWidth() {
                return this.m_originalWidth;
            }
            getDimensons() {
                return new Design.Dimensions({
                    top: this.top,
                    left: this.left,
                    height: this.height,
                    width: this.width,
                });
            }
            getOriginalDimensons() {
                return new Design.Dimensions({
                    top: this.originalTop,
                    left: this.originalLeft,
                    height: this.originalHeight,
                    width: this.originalWidth,
                });
            }
        }
        Design.SelectionBoxHelper = SelectionBoxHelper;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class StatusBar extends Jade.UI.Control {
            constructor(options) {
                super(options);
                Design.Environment.store.set("statusbar", this);
                Design.Environment.events.subscribe(Design.CanvasEvent.SELECTION_CHANGE, _.bind(this.selectionChange, this));
                Design.Environment.events.subscribe(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE, _.bind(this.selectionDimesionsChange, this));
            }
            get dimensions() {
                return this.node.find("[role=dimensions]");
            }
            get selections() {
                return this.node.find("[role=selections]");
            }
            get errors() {
                return this.node.find("[role=selections]");
            }
            template() {
                return `
                <div class="${Design.CanvasCss.StatusBar}">
                    <div role="dimensions"></div>
                    <div role="selections"></div>
                </div>`;
            }
            setDimesionsDisplay(d) {
                this.dimensions.html(`
                X: <span style="color:red;">${d.left}</span> Y: <span style="color:red;">${d.top}</span> / 
                H: <span style="color:blue;">${d.height}</span> W: <span style="color:blue;">${d.width}</span>
            `);
            }
            setSelectionsDisplay(count) {
                this.selections.html(`Selected: <span style="color:green;">${count}</span>`);
            }
            selectionDimesionsChange(options) {
                if (options != null && options.dimensions != null) {
                    this.setDimesionsDisplay(options.dimensions);
                }
                else {
                    this.setDimesionsDisplay(Design.Environment.selection.dimensions);
                }
            }
            selectionChange() {
                this.setSelectionsDisplay(Design.Environment.selection.count);
                this.setDimesionsDisplay(Design.Environment.selection.dimensions);
            }
        }
        Design.StatusBar = StatusBar;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class Surface extends Jade.UI.Control {
            constructor(options) {
                super(options);
                this.m_scroll = null;
                this.m_behaviors = null;
                this.m_behaviors = new Jade.Collection();
                Design.Environment.store.set("surface", this);
            }
            get behaviors() {
                return this.m_behaviors;
            }
            get scrolling() {
                return this.m_scroll;
            }
            onActivate() {
                Design.Environment.store.set("selection", new Design.Selection());
                this.m_scroll = new Design.Scroll({
                    container: this.node
                });
            }
            onDestroy() {
                this.behaviors.each((behavior) => {
                    behavior.stop();
                });
            }
            focus() {
                setTimeout(() => {
                    this.node.focus();
                }, 100);
            }
            loadDocument(document) {
                if (document) {
                    this.controls.add(document);
                    this.applyBehaviors();
                }
            }
            refresh() {
                this.behaviors.each((behavior) => {
                    behavior.start();
                });
            }
            clearMessage() {
                this.node.find(".-canvasjs-surface-message").remove();
                if (Design.Environment.document) {
                    Design.Environment.document.node.show();
                }
            }
            addMessage(message) {
                let messageTemplate = `
                <table class="-canvasjs-surface-message">
                    <tbody>
                        <tr>
                            <td style=\"font-size:24px;text-align:center;\">
                                ${message}
                            </td>
                            </tr>
                    <tbody>
                </table>
            `;
                this.node.append(messageTemplate);
                if (Design.Environment.document) {
                    Design.Environment.document.node.hide();
                }
            }
            showGridLines(show) {
                if (show) {
                    this.node.addClass("grid-lines");
                }
                else {
                    this.node.removeClass("grid-lines");
                }
            }
            template() {
                return `<div class="${Design.CanvasCss.Surface}"></div>`;
            }
            applyBehaviors() {
                let behaviorTypes = this.defaultBeahviorTypes();
                behaviorTypes.each((behaviorType) => {
                    this.behaviors.add(new behaviorType());
                });
                this.behaviors.each((behavior) => {
                    behavior.start();
                });
            }
            defaultBeahviorTypes() {
                let result = new Jade.Collection();
                result.add(Design.CaptureKeystrokeBehavior);
                result.add(Design.DragSelectElementsBehavior);
                result.add(Design.DocumentDropBehavior);
                result.add(Design.DocumentClickBehavior);
                result.add(Design.ContextMenuBehavior);
                result.add(Design.RibbonBarBehavior);
                return result;
            }
        }
        Design.Surface = Surface;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class SurfaceBehavior {
            constructor(options) {
                this.m_options = null;
                this.m_options = new Jade.StateBag(options);
            }
            get options() {
                return this.m_options;
            }
            start() {
            }
            stop() {
            }
        }
        Design.SurfaceBehavior = SurfaceBehavior;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class CaptureKeystrokeBehavior extends Design.SurfaceBehavior {
            start() {
                Design.Environment.context.hotkeys.register_combo({
                    keys: "up",
                    on_keydown: () => {
                        if (this.m_debouncedMoveYFunction == null) {
                            this.m_debouncedMoveYFunction = _.debounce(_.bind(this.moveY, this), 75);
                        }
                        this.m_debouncedMoveYFunction(-Design.Environment.gridUnit);
                    },
                    is_exclusive: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "down",
                    on_keydown: () => {
                        if (this.m_debouncedMoveYFunction == null) {
                            this.m_debouncedMoveYFunction = _.debounce(_.bind(this.moveY, this), 75);
                        }
                        this.m_debouncedMoveYFunction(Design.Environment.gridUnit);
                    },
                    is_exclusive: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "left",
                    on_keydown: () => {
                        if (this.m_debouncedMoveXFunction == null) {
                            this.m_debouncedMoveXFunction = _.debounce(_.bind(this.moveX, this), 75);
                        }
                        this.m_debouncedMoveXFunction(-Design.Environment.gridUnit);
                    },
                    is_exclusive: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "right",
                    on_keydown: () => {
                        if (this.m_debouncedMoveXFunction == null) {
                            this.m_debouncedMoveXFunction = _.debounce(_.bind(this.moveX, this), 75);
                        }
                        this.m_debouncedMoveXFunction(Design.Environment.gridUnit);
                    },
                    is_exclusive: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "shift up",
                    on_keydown: () => {
                        if (this.m_debouncedAdjustHeightFunction == null) {
                            this.m_debouncedAdjustHeightFunction = _.debounce(_.bind(this.adjustHeight, this), 75);
                        }
                        this.m_debouncedAdjustHeightFunction(-Design.Environment.gridUnit);
                    },
                    is_sequence: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "shift down",
                    on_keydown: () => {
                        if (this.m_debouncedAdjustHeightFunction == null) {
                            this.m_debouncedAdjustHeightFunction = _.debounce(_.bind(this.adjustHeight, this), 75);
                        }
                        this.m_debouncedAdjustHeightFunction(Design.Environment.gridUnit);
                    },
                    is_sequence: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "shift left",
                    on_keydown: () => {
                        if (this.m_debouncedAdjustWidthFunction == null) {
                            this.m_debouncedAdjustWidthFunction = _.debounce(_.bind(this.adjustWidth, this), 75);
                        }
                        this.m_debouncedAdjustWidthFunction(-Design.Environment.gridUnit);
                    },
                    is_sequence: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "shift right",
                    on_keydown: () => {
                        if (this.m_debouncedAdjustWidthFunction == null) {
                            this.m_debouncedAdjustWidthFunction = _.debounce(_.bind(this.adjustWidth, this), 75);
                        }
                        this.m_debouncedAdjustWidthFunction(Design.Environment.gridUnit);
                    },
                    is_sequence: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "tab",
                    on_keydown: () => {
                        if (this.m_debouncedShiftTabFunction == null) {
                            this.m_debouncedShiftTabFunction = _.debounce(_.bind(this.tab, this), 75);
                        }
                        this.m_debouncedShiftTabFunction(false);
                    },
                    is_exclusive: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "shift tab",
                    on_keydown: () => {
                        if (this.m_debouncedShiftTabFunction == null) {
                            this.m_debouncedShiftTabFunction = _.debounce(_.bind(this.tab, this), 75);
                        }
                        this.m_debouncedShiftTabFunction(true);
                    },
                    is_sequence: true,
                    is_exclusive: true,
                    is_solitary: true
                });
                Design.Environment.context.hotkeys.simple_combo("delete", () => {
                    if (Design.Environment.selection.count > 0) {
                        (new Design.DeleteCommand()).execute();
                    }
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl a",
                    on_keydown: () => {
                        Design.Environment.document.controls.each((element) => {
                            if (element instanceof Design.ElementDesignView && !element.grouping.isGrouped) {
                                Design.Environment.selection.add(element);
                            }
                        });
                        Design.Environment.selection.box.show();
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl c",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/clipboard:clipboard/copy");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl x",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/clipboard:clipboard/cut");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl v",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/clipboard:clipboard/paste");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl d",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/clipboard:clipboard/duplicate");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl g",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/standard:selection/group");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl u",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/standard:selection/ungroup");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl b",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/standard:selection/send-back");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "ctrl f",
                    on_keydown: () => {
                        Design.Environment.context.commands.execute("canvas/standard:selection/bring-forward");
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
                Design.Environment.context.hotkeys.register_combo({
                    keys: "enter",
                    on_keydown: () => {
                        if (Design.Environment.selection.count == 1 && !(Design.Environment.selection.first() instanceof Design.GroupDesignView)) {
                            Design.Environment.context.commands.execute("canvas/standard/external:element/properties", Design.Environment.selection.first());
                        }
                    },
                    prevent_default: true,
                    prevent_repeat: true
                });
            }
            tab(shiftTab) {
                let currentNode = Design.Environment
                    .document
                    .node
                    .find(`.${Design.CanvasCss.Element}.${Design.CanvasCss.Selected}:visible`);
                let firstNode = Design.Environment
                    .document
                    .node
                    .find(`.${Design.CanvasCss.Element}:first-child:visible`);
                let lastNode = Design.Environment
                    .document
                    .node
                    .find(`.${Design.CanvasCss.Element}:last-child:visible`);
                if (currentNode.length == 0) {
                    currentNode = firstNode;
                }
                let nextNode = null;
                if (shiftTab) {
                    nextNode = currentNode.prev(`.${Design.CanvasCss.Element}:visible`);
                    if (nextNode.length == 0) {
                        nextNode = lastNode;
                    }
                }
                else {
                    nextNode = currentNode.next(`.${Design.CanvasCss.Element}:visible`);
                    if (nextNode.length == 0) {
                        nextNode = firstNode;
                    }
                }
                if (nextNode.length > 0) {
                    Design.Environment.selection.clear();
                    Design.Environment.selection.add(Design.Convert.fromNodeToDesignView(nextNode));
                    Design.Environment.selection.box.show();
                    nextNode.focus();
                }
            }
            moveX(left) {
                let oldDimensions = Design.Environment.selection.dimensions;
                let newX = oldDimensions.left + left;
                let exceedsX = (newX < 0) || ((newX + oldDimensions.width) - Design.Environment.gridUnit >= Design.Environment.surface.node[0].scrollWidth);
                let newDimensions = null;
                if (exceedsX) {
                    return;
                }
                newDimensions = new Design.Dimensions({
                    top: oldDimensions.top,
                    left: newX,
                    height: oldDimensions.height,
                    width: oldDimensions.width
                });
                let deltaDimensions = oldDimensions.delta(newDimensions);
                Design.Environment.selection.each((element) => {
                    let relativeDimensions = Design.Dimensions.relativeDimension(element.node, deltaDimensions);
                    element.setPosition(relativeDimensions);
                });
                newDimensions.copyDimensionsToTarget(Design.Environment.selection.box.node);
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE);
            }
            moveY(top) {
                let oldDimensions = Design.Environment.selection.dimensions;
                let newY = oldDimensions.top + top;
                let exceedsY = (newY < 0) || ((newY + oldDimensions.height) - Design.Environment.gridUnit >= Design.Environment.surface.node[0].scrollHeight);
                let newDimensions = null;
                if (exceedsY) {
                    return;
                }
                newDimensions = new Design.Dimensions({
                    top: newY,
                    left: oldDimensions.left,
                    height: oldDimensions.height,
                    width: oldDimensions.width
                });
                let deltaDimensions = oldDimensions.delta(newDimensions);
                Design.Environment.selection.each((element) => {
                    let relativeDimensions = Design.Dimensions.relativeDimension(element.node, deltaDimensions);
                    element.setPosition(relativeDimensions);
                });
                newDimensions.copyDimensionsToTarget(Design.Environment.selection.box.node);
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE);
            }
            adjustHeight(unit) {
                if (Design.Environment.selection.count == 0) {
                    return;
                }
                Design.Environment.selection.each((element) => {
                    if (element instanceof Design.GroupDesignView) {
                        element.setArea({
                            height: element.grouped.dimensions.height + unit,
                            width: element.grouped.dimensions.width
                        });
                    }
                    else {
                        element.setArea({
                            height: element.source.height + unit,
                            width: element.source.width
                        });
                    }
                });
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE);
                Design.Environment.selection.box.show();
            }
            adjustWidth(unit) {
                if (Design.Environment.selection.count == 0) {
                    return;
                }
                Design.Environment.selection.each((element) => {
                    if (element instanceof Design.GroupDesignView) {
                        element.setArea({
                            height: element.grouped.dimensions.height,
                            width: element.grouped.dimensions.width + unit
                        });
                    }
                    else {
                        element.setArea({
                            height: element.source.height,
                            width: element.source.width + unit
                        });
                    }
                });
                Design.Environment.events.publish(Design.CanvasEvent.SELECTION_DIMENSIONS_CHANGE);
                Design.Environment.selection.box.show();
            }
        }
        Design.CaptureKeystrokeBehavior = CaptureKeystrokeBehavior;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ContextMenuBehavior extends Design.SurfaceBehavior {
            constructor() {
                super(...arguments);
                this.m_contextMenu = null;
                this.m_discriminatorFn = (e) => {
                    if (e.which === 3) {
                        e.cancelBubble = true;
                        e.stopPropagation();
                        e.stopImmediatePropagation();
                        e.preventDefault();
                        this.element_onRightClick(e);
                        return false;
                    }
                };
            }
            start() {
                $(document).on("contextmenu", `${Design.CanvasCssSelector.SelectionBox}`, this.m_discriminatorFn);
            }
            stop() {
                $(document).off("contextmenu", `${Design.CanvasCssSelector.SelectionBox}`, this.m_discriminatorFn);
            }
            element_onRightClick(e) {
                if (this.m_contextMenu == null) {
                    this.m_contextMenu = new Jade.UI.Controls.ContextMenu({
                        container: $(Design.CanvasCssSelector.Workspace)
                    });
                }
                let toolings = new Array();
                Design.Environment.selection.each((element) => {
                    toolings[toolings.length] = element.tooling;
                });
                let toolingsTags = Jade.UI.Controls.Tooling.getCommon(toolings);
                setTimeout(() => {
                    this.m_contextMenu.show({ x: e.pageX, y: e.pageY, groups: toolingsTags });
                }, 100);
            }
        }
        Design.ContextMenuBehavior = ContextMenuBehavior;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DocumentClickBehavior extends Design.SurfaceBehavior {
            start() {
                Design.Environment.surface.node.on("click", `.${Design.CanvasCss.Surface}, .${Design.CanvasCss.Document}, .${Design.CanvasCss.Element}, .${Design.CanvasCss.SelectionBox}`, $.proxy(this.surface_onClick, this));
                Design.Environment.surface.node.on("focus", `input, select, a, radio, textarea, button`, (e) => {
                    $(e.target).blur();
                });
            }
            stop() {
                if (Design.Environment.surfaceExists) {
                    Design.Environment.surface.node.off("click");
                }
            }
            surface_onClick(e) {
                let target = $(e.currentTarget);
                let isElement = target.hasClass("ELEMENT-SOURCED");
                let isSelectionBox = target.hasClass(Design.CanvasCss.SelectionBox);
                switch (true) {
                    case isSelectionBox:
                        e.stopPropagation();
                        e.preventDefault();
                        e.cancelBubble = true;
                        break;
                    case isElement:
                        target.removeClass("ELEMENT-SOURCED");
                        break;
                }
            }
        }
        Design.DocumentClickBehavior = DocumentClickBehavior;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DocumentDropBehavior extends Design.SurfaceBehavior {
            start() {
                Design.Environment.document.node.droppable({
                    accept: `.${Design.CanvasCss.SelectionBox}, .${Design.CanvasCss.ToolBoxItem}`,
                    tolerance: "pointer",
                    drop: $.proxy(this.onDrop, this)
                });
            }
            onDrop(e, ui) {
                let args = { event: e, dropped: ui };
                switch (true) {
                    case ui.draggable.hasClass(Design.CanvasCss.SelectionBox):
                        Design.Environment.events.publish(Design.CanvasEvent.SELECTION_BOX_DROP, args);
                        break;
                    case ui.draggable.hasClass(Design.CanvasCss.ToolBoxItem):
                        Design.Environment.events.publish(Design.CanvasEvent.TOOLBOX_ITEMS_DROP, new Design.ToolBoxItemDropEventArgs({
                            event: e,
                            dropped: ui
                        }));
                        break;
                }
            }
        }
        Design.DocumentDropBehavior = DocumentDropBehavior;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DragSelectElementsBehavior extends Design.SurfaceBehavior {
            start() {
                Design.Environment.surface.node.selectable({
                    appendTo: undefined,
                    filter: `.${Design.CanvasCss.Element}`,
                    tolerance: "fit",
                    delay: 100,
                    distance: 25,
                    classes: {
                        "ui-selectable": Design.CanvasCss.Selectable,
                        "ui-selectee": Design.CanvasCss.Selectee,
                        "ui-selecting": Design.CanvasCss.Selecting,
                        "ui-selected": Design.CanvasCss.Selected
                    },
                    start: $.proxy(this.selection_onStart, this),
                    stop: $.proxy(this.selection_onStop, this)
                });
            }
            selection_onStart(e) {
                if (e.ctrlKey) {
                    _.each(Design.Environment.selection.toArray(), (element) => {
                        if (element.node.hasClass(Design.CanvasCss.Grouped)) {
                            Design.Environment.selection.remove(element);
                        }
                    });
                }
                Design.Environment.document.node
                    .find(`.${Design.CanvasCss.IgnoreSelect}`)
                    .removeClass(Design.CanvasCss.IgnoreSelect);
                Design.Environment.selection.box.hide();
            }
            selection_onStop(e) {
                let selections = Design.Environment.document.node.find(`.${Design.CanvasCss.Selected}:not(.${Design.CanvasCss.Grouped})`);
                let nodes = selections.closest(`.${Design.CanvasCss.Element}`);
                Design.Environment.document.node
                    .find(`.${Design.CanvasCss.Selected}`)
                    .removeClass(Design.CanvasCss.Selected);
                if (selections.length = 0) {
                    return;
                }
                let elementIds = Design.Convert.fromNodesToDesignViewIds(nodes);
                this.select(e, elementIds);
            }
            select(e, ids) {
                let selections = new Jade.MappedCollection({ key: "ID" });
                let selectionIds = ids.toArray();
                if (!e.ctrlKey) {
                    Design.Environment.selection.clear();
                }
                else {
                    _.each(Design.Environment.selection.toArray(), (element) => {
                        if (element.node.hasClass(Design.CanvasCss.Grouped)) {
                            Design.Environment.selection.remove(element);
                        }
                    });
                }
                selections = Design.Convert.fromIdsToDesignViews(selectionIds);
                selections.each((element) => {
                    Design.Environment.selection.add(element);
                });
                Design.Environment.selection.box.show();
            }
        }
        Design.DragSelectElementsBehavior = DragSelectElementsBehavior;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class RibbonBarBehavior extends Design.SurfaceBehavior {
            start() {
                this.m_eventSubscription =
                    Design.Environment.events.subscribe(Design.CanvasEvent.SELECTION_CHANGE, (e) => {
                        this.onSelectionChange(e);
                    });
            }
            stop() {
                if (this.m_eventSubscription != null) {
                    this.m_eventSubscription.unsubscribe();
                }
            }
            onSelectionChange(e) {
                let toolings = new Array();
                Design.Environment.selection.each((element) => {
                    toolings[toolings.length] = element.tooling;
                });
                let toolingTags = Jade.UI.Controls.Tooling.getCommon(toolings);
                Design.Environment.ribbonBar.show(toolingTags);
            }
        }
        Design.RibbonBarBehavior = RibbonBarBehavior;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBox extends Jade.UI.Control {
            constructor(options) {
                super(options);
                this.m_toolBoxItems = new Design.ToolBoxItemCollection();
                Design.Environment.store.add("toolbox", this);
                this.subscriptions.add(Design.CanvasEvent.TOOLBOX_ITEMS_DROP, (e) => {
                    this.onToolBoxItemDrop(e);
                });
            }
            get toolBoxItems() {
                return this.m_toolBoxItems;
            }
            onComplete(e) {
                Design.Environment.events.publish(Design.CanvasEvent.TOOLBOX_ITEMS_LOAD);
            }
            onToolBoxItemDrop(e) {
                let toolBoxItem = Design.Environment.toolBox.getToolBoxItem(e.toolBoxItemId);
                if (toolBoxItem != null) {
                    toolBoxItem.execute({
                        x: e.x,
                        y: e.y
                    });
                }
            }
            getToolBoxItem(id) {
                return this.toolBoxItems.get(id);
            }
            loadToolBoxItems(items) {
                this.onToolBoxItemsDiscovered(items);
                let surface = Design.Environment.surface;
                this.node.find(`.${Design.CanvasCss.ToolBoxItem}`).draggable({
                    start: (e, ui) => {
                        surface.scrolling.startScroll(e, ui);
                    },
                    drag: (e, ui) => {
                        ui.position.left = e.pageX - 6;
                        ui.position.top = e.pageY - 6;
                        surface.scrolling.scroll(e);
                    },
                    stop: (e, ui) => {
                        surface.scrolling.stopScroll();
                    },
                    appendTo: "body",
                    helper: () => {
                        return `<div class="-canvas-toolbox-draghint"></div>`;
                    }
                });
            }
            template() {
                return `<div class="${Design.CanvasCss.ToolBox}">
                <div data-role="title">Toolbox</div>  
                <div data-role="groups" data-controls></div>   
            </div>`;
            }
            onToolBoxItemsDiscovered(items) {
                this.m_toolBoxItems = new Design.ToolBoxItemCollection(items);
                this.controls.clear();
                _.each(this.toolBoxItems.getGroups(), (groupName) => {
                    this.addToolBoxGroup(groupName);
                });
            }
            addToolBoxGroup(groupName) {
                let group = new Design.ToolBoxGroup({
                    insertAt: "div[data-role=groups]",
                    name: groupName,
                    toolBoxItems: this.toolBoxItems.getItemsInGroup(groupName)
                });
                this.controls.add(group);
            }
        }
        Design.ToolBox = ToolBox;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBoxItem {
            constructor(options) {
                this.m_state = new Jade.StateBag();
                this.state.set({
                    id: UUID.genV4()
                });
                this.state.set(options);
            }
            get state() {
                return this.m_state;
            }
            get name() {
                return this.state.get("name");
            }
            get ID() {
                return this.state.get("id");
            }
            get icon() {
                return this.state.get("icon");
            }
            get iconSet() {
                return this.state.get("iconSet");
            }
            get group() {
                return this.state.get("group");
            }
            fireToolBoxItemAddedEvent(e) {
                Design.Environment.events.publish(Design.CanvasEvent.TOOLBOX_ITEMS_ADD, e);
            }
            execute(e) {
            }
        }
        Design.ToolBoxItem = ToolBoxItem;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBoxAction extends Design.ToolBoxItem {
            get parameters() {
                return this.state.get("parameters");
            }
        }
        Design.ToolBoxAction = ToolBoxAction;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBoxElement extends Design.ToolBoxItem {
            get instance() {
                return _.clone(this.state.get("instance", {}));
            }
            get script() {
                return this.instance.script;
            }
            execute(e) {
                let state = _.extend(this.instance, {
                    x: e.x + Design.Environment.gridUnit,
                    y: e.y + Design.Environment.gridUnit
                });
                let element = Design.Environment.document.createElement(state);
                if (element) {
                    Design.Environment.selection.clear();
                    Design.Environment.selection.add(element);
                    Design.Environment.selection.box.show();
                }
            }
        }
        Design.ToolBoxElement = ToolBoxElement;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBoxGroup extends Jade.UI.Control {
            constructor(options) {
                super(options);
            }
            get name() {
                return this.state.get("name");
            }
            get label() {
                return this.node.find("DIV[role=label]");
            }
            get items() {
                return this.node.find("DIV[role=items]");
            }
            get toolBoxItems() {
                return this.state.get("toolBoxItems");
            }
            onActivate(e) {
                this.label.on("click", (e) => {
                    if (this.items.is(":visible")) {
                        this.items.css({
                            display: "none"
                        });
                    }
                    else {
                        this.items.css({
                            display: "block"
                        });
                    }
                });
            }
            template() {
                return `<div class="${Design.CanvasCss.ToolBoxGroup}">
                        <div role="label">${this.name}</div>
                        <div role="items">${this.getToolBoxItems()}</div>
                    </div>`;
            }
            getToolBoxItems() {
                let result = new Array();
                _.each(this.toolBoxItems, (item) => {
                    let url = `url(${Jade.IconSet.get(item.iconSet).resolve(item.icon, Jade.IconSetSizeSpecificDirectory.x16)})`;
                    result[result.length] = `<div id="${item.ID}" class="${Design.CanvasCss.ToolBoxItem}" style="background-image:${url}">${item.name}</div>`;
                });
                return result.join("");
            }
        }
        Design.ToolBoxGroup = ToolBoxGroup;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBoxItemCollection extends Jade.MappedCollection {
            constructor(data) {
                super({
                    key: "ID",
                    data: []
                });
                if (_.isArray(data)) {
                    data.forEach((state) => {
                        this.add(this.createToolBoxItem(state));
                    });
                }
            }
            getGroups() {
                var groups = new Array();
                this.each((item) => {
                    groups[groups.length] = item.group;
                });
                return _.sortedUniq(groups);
            }
            getItemsInGroup(groupName) {
                var result = new Array();
                this.each((item) => {
                    if (item.group === groupName) {
                        result[result.length] = item;
                    }
                });
                return result;
            }
            createToolBoxItem(state) {
                let result = null;
                let item = Jade.Type.getType(state.script);
                if (item != null) {
                    result = new item(state);
                }
                return result;
            }
        }
        Design.ToolBoxItemCollection = ToolBoxItemCollection;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBoxItemDropEventArgs {
            constructor(options) {
                this.m_toolBoxItemId = options.dropped.draggable.attr("id");
                this.calculateDropCoordinates(options.event.pageX, options.event.pageY);
            }
            get x() {
                return this.m_x;
            }
            get y() {
                return this.m_y;
            }
            get toolBoxItemId() {
                return this.m_toolBoxItemId;
            }
            calculateDropCoordinates(x, y) {
                let coords = Design.Environment.surface.node.offset();
                let scrollX = Design.Environment.surface.node.scrollLeft();
                let scrollY = Design.Environment.surface.node.scrollTop();
                this.m_x = Jade.Arithmetic.round((x - coords.left) + scrollX, Design.Environment.gridUnit);
                this.m_y = Jade.Arithmetic.round((y - coords.top) + scrollY, Design.Environment.gridUnit);
            }
        }
        Design.ToolBoxItemDropEventArgs = ToolBoxItemDropEventArgs;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ToolBoxMessage extends Jade.UI.Control {
            constructor(options) {
                super(options);
            }
            get messageNode() {
                return this.node.find("td");
            }
            get message() {
                return this.state.get("message", "");
            }
            template() {
                return `<div style="height:100%;width:100%;box-sizing:border-box;"><table style="height:100%;width:100%;"><tr><td style="vertical-align:middle;text-align:center;">${this.message}</td></tr></table></div>`;
            }
            onStateChanged() {
                super.onStateChanged();
                this.messageNode.html(this.message);
            }
        }
        Design.ToolBoxMessage = ToolBoxMessage;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class RibbonBar extends Jade.UI.Controls.RibbonBar {
            constructor(options) {
                super(options);
                Design.Environment.store.add("ribbonbar", this);
            }
            onActivate(e) {
                super.onActivate(e);
                this.show(["element"]);
            }
        }
        Design.RibbonBar = RibbonBar;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class Alignment {
            static AlignLeft(elements) {
                var leftMostValue = null;
                elements.each((element) => {
                    let dimensions = element.dimensions;
                    if (leftMostValue == null || element.dimensions.left < leftMostValue) {
                        leftMostValue = dimensions.left;
                    }
                });
                elements.each((element) => {
                    element.setPosition({
                        top: element.dimensions.top,
                        left: leftMostValue
                    });
                });
            }
            static AlignTop(elements) {
                var topMostValue = null;
                elements.each((element) => {
                    let dimensions = element.dimensions;
                    if (topMostValue == null || element.dimensions.top < topMostValue) {
                        topMostValue = dimensions.top;
                    }
                });
                elements.each((element) => {
                    element.setPosition({
                        top: topMostValue,
                        left: element.dimensions.left
                    });
                });
            }
        }
        Design.Alignment = Alignment;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class AllowedSizingHandles {
            static getVisibleHandles(controls) {
                let result = [];
                _.each(controls, (control) => {
                    if (control[this.ATTRIBUTE_KEY] == null) {
                        result = this.handles;
                        return false;
                    }
                    else {
                        result = result.concat(control[this.ATTRIBUTE_KEY].slice(0));
                    }
                });
                return result;
            }
        }
        AllowedSizingHandles.handles = [
            Design.GeometryBoxHandle.e,
            Design.GeometryBoxHandle.n,
            Design.GeometryBoxHandle.ne,
            Design.GeometryBoxHandle.nw,
            Design.GeometryBoxHandle.s,
            Design.GeometryBoxHandle.se,
            Design.GeometryBoxHandle.sw,
            Design.GeometryBoxHandle.w
        ];
        AllowedSizingHandles.ATTRIBUTE_KEY = "___sizingHandles___";
        Design.AllowedSizingHandles = AllowedSizingHandles;
        function allowedSizingHandles(...handles) {
            return function attribute(constr) {
                return class extends constr {
                    constructor(...args) {
                        super(...args);
                        this[AllowedSizingHandles.ATTRIBUTE_KEY] = handles;
                    }
                };
            };
        }
        Design.allowedSizingHandles = allowedSizingHandles;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        let CanvasCss;
        (function (CanvasCss) {
            CanvasCss["Design"] = "-canvasjs-design";
            CanvasCss["Workspace"] = "-canvasjs-workspace";
            CanvasCss["ToolBox"] = "-canvasjs-toolbox";
            CanvasCss["ToolBoxPanelBar"] = "-canvasjs-toolbox-panelbar";
            CanvasCss["ToolBoxItem"] = "-canvasjs-toolbox-item";
            CanvasCss["ToolBoxGroup"] = "-canvasjs-toolbox-group";
            CanvasCss["Surface"] = "-canvasjs-surface";
            CanvasCss["Document"] = "-canvasjs-document";
            CanvasCss["Element"] = "-canvasjs-element";
            CanvasCss["ElementOverlay"] = "-canvasjs-overlay";
            CanvasCss["ElementTransparency"] = "-canvasjs-transparency";
            CanvasCss["ElementHighlight"] = "-canvasjs-highlight";
            CanvasCss["Selectable"] = "ui-selectable";
            CanvasCss["Selectee"] = "ui-selectee";
            CanvasCss["Selecting"] = "ui-selecting";
            CanvasCss["Selected"] = "ui-selected";
            CanvasCss["SelectionBox"] = "-canvasjs-selection-box";
            CanvasCss["SelectionBoxResizing"] = "ui-resizable-resizing";
            CanvasCss["SelectionBoxDimensions"] = "-canvasjs-selection-box-dimensions";
            CanvasCss["Group"] = "-canvasjs-group";
            CanvasCss["GroupMaster"] = "-canvasjs-group-master";
            CanvasCss["Grouped"] = "-canvasjs-grouped";
            CanvasCss["StatusBar"] = "-canvasjs-statusbar";
            CanvasCss["IgnoreSelect"] = "-canvas-ignore-select";
        })(CanvasCss = Design.CanvasCss || (Design.CanvasCss = {}));
        class CanvasCssSelector {
            static get root() {
                return `[data-cjsid=${Design.Environment.context.ID}]`;
            }
            static get selector() {
                return this.getSelector("");
            }
            static get Design() {
                return this.getSelector(CanvasCss.Design);
            }
            static get Workspace() {
                return `${this.root}.${CanvasCss.Workspace}`;
            }
            static get ToolBox() {
                return this.getSelector(CanvasCss.ToolBox);
            }
            static get ToolBoxPanelBar() {
                return this.getSelector(CanvasCss.ToolBoxPanelBar);
            }
            static get ToolBoxItem() {
                return this.getSelector(CanvasCss.ToolBoxItem);
            }
            static get ToolBoxGroup() {
                return this.getSelector(CanvasCss.ToolBoxGroup);
            }
            static get Surface() {
                return this.getSelector(CanvasCss.Surface);
            }
            static get Document() {
                return this.getSelector(CanvasCss.Document);
            }
            static get Element() {
                return this.getSelector(CanvasCss.Element);
            }
            static get ElementOverlay() {
                return this.getSelector(CanvasCss.ElementOverlay);
            }
            static get ElementTransparency() {
                return this.getSelector(CanvasCss.ElementTransparency);
            }
            static get ElementHighlight() {
                return this.getSelector(CanvasCss.ElementHighlight);
            }
            static get Selectable() {
                return this.getSelector(CanvasCss.Selectable);
            }
            static get Selectee() {
                return this.getSelector(CanvasCss.Selectee);
            }
            static get Selecting() {
                return this.getSelector(CanvasCss.Selecting);
            }
            static get Selected() {
                return this.getSelector(CanvasCss.Selected);
            }
            static get SelectionBox() {
                return this.getSelector(CanvasCss.SelectionBox);
            }
            static get SelectionBoxResizing() {
                return this.getSelector(CanvasCss.SelectionBoxResizing);
            }
            static get SelectionBoxDimensions() {
                return this.getSelector(CanvasCss.SelectionBoxDimensions);
            }
            static get Group() {
                return this.getSelector(CanvasCss.Group);
            }
            static get GroupMaster() {
                return this.getSelector(CanvasCss.GroupMaster);
            }
            static get Grouped() {
                return this.getSelector(CanvasCss.Grouped);
            }
            static get StatusBar() {
                return this.getSelector(CanvasCss.StatusBar);
            }
            static get IgnoreSelect() {
                return this.getSelector(CanvasCss.IgnoreSelect);
            }
            static getSelector(value) {
                return `${this.root} .${value}`;
            }
        }
        Design.CanvasCssSelector = CanvasCssSelector;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        let CanvasEvent;
        (function (CanvasEvent) {
            CanvasEvent["SELECTION_CHANGE"] = "canvas/selection/change";
            CanvasEvent["SELECTION_DIMENSIONS_CHANGE"] = "canvas/selection/dimensions/change";
            CanvasEvent["SELECTION_BOX_DROP"] = "canvas/document/selection-box/ondrop";
            CanvasEvent["ELEMENT_SELECT"] = "canvas/element/select";
            CanvasEvent["ELEMENT_DELETE"] = "canvas/element/delete";
            CanvasEvent["ELEMENT_EDIT"] = "canvas/element/edit";
            CanvasEvent["ELEMENT_CUT"] = "canvas/element/cut";
            CanvasEvent["ELEMENT_COPY"] = "canvas/element/copy";
            CanvasEvent["ELEMENT_PASTE"] = "canvas/element/paste";
            CanvasEvent["TOOLBOX_ITEMS_LOAD"] = "canvas/toolbox-items/load";
            CanvasEvent["TOOLBOX_ITEMS_DROP"] = "canvas/toolbox-items/ondrop";
            CanvasEvent["TOOLBOX_ITEMS_ADD"] = "canvas/toolbox-items/add";
            CanvasEvent["DOCUMENT_LOAD"] = "canvas/document/load";
        })(CanvasEvent = Design.CanvasEvent || (Design.CanvasEvent = {}));
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class Convert {
            static fromNodesToDesignViews(nodes) {
                let result = new Jade.MappedCollection({ key: "ID" });
                nodes.each((index, node) => {
                    let element = this.fromNodeToDesignView($(node));
                    if (element != null) {
                        result.add(element);
                    }
                });
                return result;
            }
            static fromNodeToDesignView(node) {
                let result = null;
                if (node instanceof jQuery) {
                    result = Design.Environment.document.controls.getById(node.attr("id"));
                }
                return result;
            }
            static fromNodesToDesignViewIds(nodes) {
                let result = new Jade.Collection();
                if (nodes instanceof jQuery) {
                    nodes.each((index, node) => {
                        result.add($(node).attr("id"));
                    });
                }
                return result;
            }
            static fromIdsToDesignViews(ids) {
                let result = new Jade.MappedCollection({ key: "ID" });
                _.each(ids, (id) => {
                    let element = Design.Environment.document.controls.getById(id);
                    if (element != null) {
                        result.add(element);
                    }
                });
                return result;
            }
        }
        Design.Convert = Convert;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class Dimensions {
            constructor(input) {
                this.m_units = {
                    top: 0,
                    left: 0,
                    bottom: 0,
                    right: 0,
                    height: 0,
                    width: 0
                };
                this.m_units.top = input.top;
                this.m_units.left = input.left;
                this.m_units.bottom = input.bottom;
                this.m_units.right = input.right;
                this.m_units.height = input.height;
                this.m_units.width = input.width;
            }
            get units() {
                return this.m_units;
            }
            get top() {
                return this.m_units.top;
            }
            get left() {
                return this.m_units.left;
            }
            get bottom() {
                return this.m_units.bottom;
            }
            get right() {
                return this.m_units.right;
            }
            get height() {
                return this.m_units.height;
            }
            get width() {
                return this.m_units.width;
            }
            delta(input) {
                let result = new Dimensions({
                    top: input.top - this.top,
                    left: input.left - this.left,
                    height: input.height - this.height,
                    width: input.width - this.width
                });
                return result;
            }
            toJSON() {
                return this.m_units;
            }
            copyDimensionsToTarget(target) {
                var node = null;
                if (target instanceof jQuery) {
                    node = target;
                }
                else {
                    node = target.node;
                }
                node.css({
                    height: Math.round(this.height),
                    width: Math.round(this.width),
                    top: Math.round(this.top),
                    left: Math.round(this.left)
                });
            }
            static fromUnits(units) {
                let result = { top: 0, left: 0, bottom: 0, right: 0, height: 0, width: 0 };
                let scrollLeft = Design.Environment.documentExists ? Design.Environment.document.node.scrollLeft() : 0;
                let scrollTop = Design.Environment.documentExists ? Design.Environment.document.node.scrollTop() : 0;
                _.each(units, (unit, index) => {
                    let bottom = (unit.top + unit.height);
                    let right = (unit.left + unit.width);
                    if (index === 0) {
                        result.top = unit.top + (scrollTop / 2);
                        result.bottom = bottom + (scrollTop / 2);
                        result.left = unit.left + (scrollLeft / 2);
                        result.right = right + (scrollLeft / 2);
                    }
                    else {
                        result.top = (unit.top < result.top ? unit.top : result.top) + scrollTop;
                        result.bottom = (bottom > result.bottom ? bottom : result.bottom) + scrollTop;
                        result.left = (unit.left < result.left ? unit.left : result.left) + scrollLeft;
                        result.right = (right > result.right ? right : result.right) + scrollLeft;
                    }
                });
                result.height = result.bottom - result.top;
                result.width = result.right - result.left;
                return result;
            }
            static fromNodes(nodes) {
                let units = new Jade.Collection();
                nodes.each((index, htmlElement) => {
                    units.add(Dimensions.fromNode($(htmlElement)));
                });
                return Dimensions.fromUnits(units.toArray());
            }
            static fromElements(elements) {
                let result = null;
                if (_.isArray(elements)) {
                    let units = new Array();
                    _.each(elements, (element) => {
                        units[units.length] = element.dimensions;
                    });
                    result = Dimensions.fromUnits(units);
                }
                else {
                    result = Dimensions.fromElements(elements);
                }
                return result;
            }
            static fromHtml(htmlElements) {
                let result = Dimensions.fromNodes($(htmlElements));
                return result;
            }
            static getAtCoordinates(x, y) {
                let result = null;
                let list = Design.Environment.document.controls.toArray();
                _.reverse(list);
                _.each(list, (control) => {
                    let isElement = control.node.hasClass(Design.CanvasCss.Element)
                        && !control.node.hasClass(Design.CanvasCss.Group);
                    if (isElement && this.isWithinRange(x, y, control.node)) {
                        result = control;
                        return false;
                    }
                });
                return result;
            }
            ;
            static relativeDimension(element, delta) {
                let result = null;
                let value = Dimensions.fromNodes(element);
                let height = value.height + delta.height;
                let width = value.width + delta.width;
                result = new Dimensions({
                    top: value.top + delta.top,
                    left: value.left + delta.left,
                    height: height >= Dimensions.MIN_HEIGHT ? height : Dimensions.MIN_HEIGHT,
                    width: width >= Dimensions.MIN_WIDTH ? width : Dimensions.MIN_WIDTH,
                });
                return result;
            }
            static isWithinRange(x, y, element) {
                let values = {
                    top: element.offset().top,
                    bottom: element.offset().top + element.outerHeight(),
                    left: element.offset().left,
                    right: element.offset().left + element.outerWidth()
                };
                return values.top <= y
                    && values.bottom >= y
                    && values.left <= x
                    && values.right >= x;
            }
            static fromNode(node) {
                let result = { top: 0, left: 0, bottom: 0, right: 0, height: 0, width: 0 };
                if ((node instanceof jQuery)) {
                    result.height = Math.round(node.innerHeight());
                    result.width = Math.round(node.innerWidth());
                    result.top = Math.round(node.position().top);
                    result.left = Math.round(node.position().left);
                }
                return result;
            }
        }
        Dimensions.MIN_HEIGHT = 10;
        Dimensions.MIN_WIDTH = 10;
        Design.Dimensions = Dimensions;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ElementCollection extends Jade.Collection {
            inDomOrder() {
                let result = new Jade.Collection();
                Design.Environment.document.controls.each((element) => {
                    this.each((item) => {
                        if (item.ID == element.ID) {
                            result.add(element);
                        }
                    });
                });
                return result;
            }
        }
        Design.ElementCollection = ElementCollection;
        class GroupedElementCollection extends ElementCollection {
            constructor() {
                super(...arguments);
                this.m_groupsOnly = null;
                this.m_elementsOnly = null;
            }
            get dimensions() {
                return Design.Dimensions.fromElements(this.toArray());
            }
            get groupsOnly() {
                this.ensureCollectionsArePopulated();
                return this.m_groupsOnly;
            }
            get elementsOnly() {
                this.ensureCollectionsArePopulated();
                return this.m_elementsOnly;
            }
            onChange() {
                this.m_groupsOnly = null;
                this.m_elementsOnly = null;
            }
            ensureCollectionsArePopulated() {
                if (this.m_groupsOnly != null && this.m_elementsOnly != null) {
                    return;
                }
                this.m_groupsOnly = new ElementCollection();
                this.m_elementsOnly = new ElementCollection();
                this.each((element) => {
                    if (element != null) {
                        if (element instanceof Design.GroupDesignView) {
                            this.m_groupsOnly.add(element);
                        }
                        else {
                            this.m_elementsOnly.add(element);
                        }
                    }
                });
            }
        }
        Design.GroupedElementCollection = GroupedElementCollection;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DimensionsChangedEventArgs {
            constructor(options) {
                this.m_old = null;
                this.m_new = null;
                this.m_old = options.old;
                this.m_new = options.new;
            }
            get old() {
                return this.m_old;
            }
            get new() {
                return this.m_new;
            }
        }
        Design.DimensionsChangedEventArgs = DimensionsChangedEventArgs;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class DocumentDesignView extends CanvasJS.DocumentViewBase {
            saveSource() {
                this.source.elements.clear();
                this.controls.each((item) => {
                    if (item instanceof Design.ElementDesignView) {
                        this.source.elements.add(item.source);
                    }
                });
                return this.source;
            }
            createElement(state, addToElements = false) {
                return this.createElementOf(state, addToElements);
            }
            createElementOf(state, addToElements = false) {
                let model = CanvasJS.Design.Environment.document.source.createElement(state, addToElements);
                let result = model.resolver.getViewOf(CanvasJS.CanvasType.Design);
                if (result != null && addToElements) {
                    this.controls.add(result);
                }
                return result;
            }
            onActivate(e) {
                super.onActivate(e);
                this.node.addClass(CanvasJS.Design.CanvasCss.Document);
                this.addSelectionBox();
            }
            addSelectionBox() {
            }
        }
        Design.DocumentDesignView = DocumentDesignView;
        class DocumentDesignViewBase extends DocumentDesignView {
            get source() {
                return this.m_source;
            }
        }
        Design.DocumentDesignViewBase = DocumentDesignViewBase;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        let ElementDesignView = class ElementDesignView extends CanvasJS.ElementViewBase {
            constructor() {
                super(...arguments);
                this.m_grouping = new Design.ElementDesignViewGrouping(this);
                this.m_tooling = new Jade.UI.Controls.Tooling();
            }
            get dimensions() {
                return new Design.Dimensions(Design.Dimensions.fromNodes(this.node));
            }
            get isSelected() {
                return this.node.hasClass(Design.CanvasCss.Selected);
            }
            get grouping() {
                return this.m_grouping;
            }
            get tooling() {
                return this.m_tooling;
            }
            template() {
                return "";
            }
            setPosition(units) {
                let oldUnits = this.dimensions;
                let newUnits = oldUnits;
                if (units != null) {
                    newUnits = new Design.Dimensions({
                        top: units.top,
                        left: units.left,
                        height: oldUnits.height,
                        width: oldUnits.width
                    });
                }
                this.source.state.set({
                    y: newUnits.top,
                    x: newUnits.left
                });
                this.node.css({
                    top: `${newUnits.top}px`,
                    left: `${newUnits.left}px`
                });
                if (this.isSelected) {
                    this.grouping.onPositionChanged(newUnits);
                }
                this.onPositionChanged(new Design.DimensionsChangedEventArgs({
                    old: oldUnits,
                    new: newUnits
                }));
            }
            setArea(units) {
                let oldDimensions = this.dimensions;
                let newDimensions = null;
                let oldUnits = this.dimensions.units;
                let newUnits = _.clone(oldUnits);
                if (units != null) {
                    newUnits = {
                        top: oldUnits.top,
                        left: oldUnits.left,
                        height: units.height,
                        width: units.width
                    };
                }
                let minHeightExceedsMaxHeight = this.source.minHeight > this.source.maxHeight;
                let minWidthExceedsMaxWidth = this.source.minWidth > this.source.maxWidth;
                let exceedsMinHeight = this.source.minHeight != null
                    && newUnits.height < this.source.minHeight;
                let exceedsMaxHeight = this.source.maxHeight != null
                    && newUnits.height > this.source.maxHeight;
                let exceedsMinWidth = this.source.minWidth != null
                    && newUnits.width < this.source.minWidth;
                let exceedsMaxWidth = this.source.maxWidth != null
                    && newUnits.width > this.source.maxWidth;
                if (exceedsMinHeight) {
                    newUnits.height = this.source.minHeight;
                }
                if (exceedsMaxHeight) {
                    newUnits.height = minHeightExceedsMaxHeight ?
                        this.source.minHeight : this.source.maxHeight;
                }
                if (exceedsMinWidth) {
                    newUnits.width = this.source.minWidth;
                }
                if (exceedsMaxWidth) {
                    newUnits.width = minWidthExceedsMaxWidth ?
                        this.source.minWidth : this.source.maxWidth;
                }
                this.source.state.set({
                    height: newUnits.height,
                    width: newUnits.width
                });
                newDimensions = new Design.Dimensions(newUnits);
                this.node.css({
                    height: this.anchorBottom == null ? newUnits.height : "",
                    width: this.anchorRight == null ? newUnits.width : "",
                    right: this.anchorRight != null ? this.anchorRight : "",
                    bottom: this.anchorBottom != null ? this.anchorBottom : "",
                });
                if (this.isSelected) {
                    this.grouping.onAreaChanged(newDimensions);
                }
                this.onAreaChanged(new Design.DimensionsChangedEventArgs({
                    old: oldDimensions,
                    new: newDimensions
                }));
            }
            onSelect() {
            }
            onDeselect() {
            }
            bringForward() {
                Design.Environment.document.controls.detach(this);
                Design.Environment.document.controls.add(this);
            }
            sendBack() {
                Design.Environment.document.controls.detach(this);
                Design.Environment.document.controls.insert(this, 0);
            }
            destroy() {
                this.source.delete();
                this.grouping.ungroup();
                super.destroy();
            }
            onBrowserResize() {
                this.onStateChanged();
            }
            onResize() {
            }
            onActivate(e) {
                this.setArea({
                    height: this.height,
                    width: this.width
                });
                this.setPosition({
                    top: this.y,
                    left: this.x
                });
            }
            onStateChanged() {
                this.setArea({
                    height: this.height,
                    width: this.width
                });
                this.setPosition({
                    top: this.y,
                    left: this.x
                });
            }
            onAreaChanged(e) {
            }
            onPositionChanged(e) {
            }
            onTemplate(e) {
                if (this.state.changedAttributes()) {
                    this.setPosition({
                        top: this.y,
                        left: this.x
                    });
                    this.setArea({
                        height: this.height,
                        width: this.width
                    });
                }
            }
            overlay() {
                return `<div class="${Design.CanvasCss.ElementOverlay}">
                        <div class="${Design.CanvasCss.ElementTransparency}"></div>
                        <div class="${Design.CanvasCss.ElementHighlight}">
                            <div class="ne"></div>
                            <div class="nw"></div>
                            <div class="sw"></div>
                            <div class="se"></div>
                        </div>
                    </div>`;
            }
            wrapTemplate(template) {
                let elementNode = $(`<div class="${Design.CanvasCss.Element}"></div>`);
                elementNode.append(template);
                elementNode.append(this.overlay());
                return elementNode;
            }
        };
        ElementDesignView = __decorate([
            Jade.UI.Controls.toolingTags("element")
        ], ElementDesignView);
        Design.ElementDesignView = ElementDesignView;
        class ElementDesignViewBase extends ElementDesignView {
            get source() {
                return this.m_source;
            }
        }
        Design.ElementDesignViewBase = ElementDesignViewBase;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class ElementDesignViewGrouping {
            constructor(element) {
                this.m_onAreaChangedCallback = null;
                this.m_onPositionChangedCallback = null;
                this.m_onUngroup = null;
                this.m_element = element;
            }
            get Group() {
                return this.m_group;
            }
            get isGrouped() {
                return this.m_group != null;
            }
            ungroup() {
                if (this.m_onUngroup != null) {
                    this.m_onUngroup(this.m_element);
                }
                this.m_group = null;
                this.m_onAreaChangedCallback = null;
                this.m_onPositionChangedCallback = null;
                this.m_onUngroup = null;
            }
            group(options) {
                this.m_group = options.group;
                this.m_onAreaChangedCallback = options.onAreaChanged;
                this.m_onPositionChangedCallback = options.onPositionChanged;
                this.m_onUngroup = options.onUngroup;
            }
            onAreaChanged(newDimensions) {
                if (this.m_onAreaChangedCallback != null) {
                    this.m_onAreaChangedCallback(newDimensions);
                }
            }
            onPositionChanged(newDimensions) {
                if (this.m_onPositionChangedCallback != null) {
                    this.m_onPositionChangedCallback(newDimensions);
                }
            }
        }
        Design.ElementDesignViewGrouping = ElementDesignViewGrouping;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class GroupDesignView extends Design.ElementDesignViewBase {
            constructor(options) {
                super(options);
                this.m_grouped = null;
                this.state.set({
                    elements: options.elements,
                    componentType: "ProspectDirector.Web.UI.Canvas.Group"
                }, { silent: true });
            }
            get type() {
                return this.state.get("script");
            }
            get grouped() {
                return this.m_grouped;
            }
            get box() {
                return this.node.find("[role=box]");
            }
            get cssClass() {
                return Design.CanvasCss.Group;
            }
            onActivate(e) {
                this.group();
                this.node.css({
                    height: this.grouped.dimensions.height,
                    width: this.grouped.dimensions.width,
                    top: this.grouped.dimensions.top,
                    left: this.grouped.dimensions.left
                });
                this.node.addClass(Design.CanvasCss.Group);
            }
            onAreaChanged(e) {
                if (this.grouped != null) {
                    this.grouped.each((element) => {
                        element.setArea(Design.Dimensions.relativeDimension(element.node, e.old.delta(e.new)));
                    });
                }
            }
            onPositionChanged(e) {
                if (this.grouped != null) {
                    this.grouped.each((element) => {
                        element.setPosition(Design.Dimensions.relativeDimension(element.node, e.old.delta(e.new)));
                    });
                }
            }
            template() {
                return `<div role="box" style="position:absolute;top:0;left:0;right:0;bottom:0;box-sizing:border-box;overflow:hidden;" class="${Design.CanvasCss.Group}"></div>`;
            }
            bringForward() {
                super.bringForward();
                this.grouped.elementsOnly.inDomOrder().each((element) => {
                    Design.Environment.document.controls.detach(element);
                    Design.Environment.document.controls.add(element);
                });
            }
            sendBack() {
                super.sendBack();
                this.grouped.elementsOnly.inDomOrder().reverseCopy().each((element) => {
                    Design.Environment.document.controls.detach(element);
                    Design.Environment.document.controls.insert(element, 0);
                });
            }
            destroy() {
                this.grouped.elementsOnly.each((element) => {
                    element.grouping.ungroup();
                    Design.Environment.document.controls.remove(element);
                });
                this.grouped.groupsOnly.each((group) => {
                    group.grouping.ungroup();
                    Design.Environment.document.controls.remove(group);
                });
                super.destroy();
            }
            group() {
                let groupedElements = Design.Convert.fromIdsToDesignViews(this.source.elements);
                this.m_grouped = new Design.GroupedElementCollection(groupedElements.toArray());
                this.grouped.each((element) => {
                    if (element != null) {
                        element.grouping.group({
                            group: this,
                            onAreaChanged: (units) => { this.setAreaForContainedElements(units); },
                            onPositionChanged: (units) => { this.setPositionForContainedElements(units); },
                            onUngroup: (element) => { this.updateGroupingWhenGroupedElementIsRemoved(element); }
                        });
                    }
                });
                this.grouped.elementsOnly.each((element) => {
                    element.node.addClass(Design.CanvasCss.Grouped);
                    element.node.attr(GroupDesignView.GROUP_ID_ATTRIBUTE, this.ID);
                });
                this.grouped.groupsOnly.each((group) => {
                    group.node.css({ visibility: "hidden" });
                    group.node.addClass(Design.CanvasCss.Grouped);
                    group.node.removeClass(Design.CanvasCss.GroupMaster);
                });
                this.node.addClass(Design.CanvasCss.GroupMaster);
            }
            ungroup() {
                let groups = this.grouped.groupsOnly.toArray();
                _.each(this.grouped.toArray(), (element) => {
                    element.node.removeClass(Design.CanvasCss.Grouped);
                    element.node.removeAttr(GroupDesignView.GROUP_ID_ATTRIBUTE);
                    element.grouping.ungroup();
                });
                _.each(groups, (group) => {
                    if (group != null) {
                        group.node.css({ visibility: "visible" });
                        group.node.addClass(Design.CanvasCss.GroupMaster);
                    }
                });
                super.destroy();
            }
            onStateChanged() {
            }
            setAreaForContainedElements(units) {
                let newDimenions = this.grouped.dimensions;
                let deltaDimensions = this.dimensions.delta(newDimenions);
                let relativeDimensions = Design.Dimensions.relativeDimension(this.node, deltaDimensions);
                relativeDimensions.copyDimensionsToTarget(this);
                this.grouping.onAreaChanged(relativeDimensions);
            }
            setPositionForContainedElements(units) {
                let newDimenions = this.grouped.dimensions;
                let deltaDimensions = this.dimensions.delta(newDimenions);
                let relativeDimensions = Design.Dimensions.relativeDimension(this.node, deltaDimensions);
                relativeDimensions.copyDimensionsToTarget(this);
                this.grouping.onAreaChanged(relativeDimensions);
            }
            updateGroupingWhenGroupedElementIsRemoved(element) {
                let newDimensions = null;
                this.grouped.remove(element);
                newDimensions = this.grouped.dimensions;
                this.node.css({
                    top: newDimensions.top,
                    left: newDimensions.left,
                    height: newDimensions.height,
                    width: newDimensions.width
                });
            }
        }
        GroupDesignView.GROUP_ID_ATTRIBUTE = "groupId";
        Design.GroupDesignView = GroupDesignView;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class InvalidElementView extends Design.ElementDesignViewBase {
            template() {
                return `<table style="height:100%;width:100%;border:1px solid red;background-color:#FFFFFF;">
                        <tr>
                            <td style="text-align:center;vertical-align:middle;">${this.source.componentName}</td>
                        </tr>
                    </table>`;
            }
        }
        Design.InvalidElementView = InvalidElementView;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
var CanvasJS;
(function (CanvasJS) {
    var Design;
    (function (Design) {
        class Workspace extends Jade.UI.Control {
            onInit(e) {
                this.controls.add(new Design.RibbonBar({
                    insertAt: "div[data-id=toolbar]"
                }));
                this.controls.add(new Design.ToolBox({
                    insertAt: "div[data-id=toolbox]"
                }));
                this.controls.add(new Design.Surface({
                    insertAt: "div[data-id=surface]"
                }));
                this.controls.add(new Design.StatusBar({
                    insertAt: "div[data-id=statusbar]"
                }));
            }
            template() {
                return `<div class="${Design.CanvasCss.Workspace}" data-cjsid="${CanvasJS.Design.Environment.context.ID}">
                <div data-id="toolbar"></div>
                <div data-id="toolbox"></div>
                <div data-id="surface"></div>  
                <div data-id="statusbar"></div>   
            </div>`;
            }
        }
        Design.Workspace = Workspace;
    })(Design = CanvasJS.Design || (CanvasJS.Design = {}));
})(CanvasJS || (CanvasJS = {}));
