<commit_before>/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */
/*global define, $, FileError, brackets, window */

/**
 * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument
 *
 * # STARTING
 *
 * To start a session call `open`. This will read the currentDocument from brackets,
 * launch the LiveBrowser (currently Chrome) with the remote debugger port open,
 * establish the Inspector connection to the remote debugger, and finally load all
 * agents.
 *
 * # STOPPING
 *
 * To stop a session call `close`. This will close the active browser window,
 * disconnect the Inspector, unload all agents, and clean up.
 *
 * # STATUS
 *
 * Status updates are dispatched as `statusChange` jQuery events. The status
 * codes are:
 *
 * -1: Error
 * 0: Inactive
 * 1: Connecting to the remote debugger
 * 2: Loading agents
 * 3: Active
 */
define(function LiveDevelopment(require, exports, module) {
    "use strict";

    var DocumentManager = require("document/DocumentManager");
    var EditorManager = require("editor/EditorManager");
    var NativeApp = require("utils/NativeApp");
    var Dialogs = require("widgets/Dialogs");
    var Strings = require("strings");
    var StringUtils = require("utils/StringUtils");

    // Inspector
    var Inspector = require("LiveDevelopment/Inspector/Inspector");

    // Documents
    var HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument");
    var CSSDocument = require("LiveDevelopment/Documents/CSSDocument");
    var JSDocument = require("LiveDevelopment/Documents/JSDocument");

    // Agents
    var agents = {
        "console": require("LiveDevelopment/Agents/ConsoleAgent"),
        "remote": require("LiveDevelopment/Agents/RemoteAgent"),
        "network": require("LiveDevelopment/Agents/NetworkAgent"),
        "dom": require("LiveDevelopment/Agents/DOMAgent"),
        "css": require("LiveDevelopment/Agents/CSSAgent")
        /* FUTURE
        "script": require("LiveDevelopment/Agents/ScriptAgent"),
        "highlight": require("LiveDevelopment/Agents/HighlightAgent"),
        "goto": require("LiveDevelopment/Agents/GotoAgent"),
        "edit": require("LiveDevelopment/Agents/EditAgent")
        */
    };

    var _htmlDocumentPath; // the path of the html file open for live development
    var _liveDocument; // the document open for live editing.
    var _relatedDocuments; // CSS and JS documents that are used by the live HTML document

    /** Augments the given Brackets document with information that's useful for live development. */
    function _setDocInfo(doc) {
        // FUTURE: some of these things should just be moved into core Document; others should
        // be in a LiveDevelopment-specific object attached to the doc.
        var matches = /^(.*\/)(.+\.([^.]+))$/.exec(doc.file.fullPath);
        if (matches) {
            var prefix = "file://";

            // The file.fullPath on Windows starts with a drive letter ("C:").
            // In order to make it a valid file: URL we need to add an
            // additional slash to the prefix.
            if (brackets.platform === "win") {
                prefix += "/";
            }

            doc.extension = matches[3];
            doc.url = encodeURI(prefix + doc.file.fullPath);

            // the root represents the document that should be displayed in the browser
            // for live development (the file for HTML files, index.html for others)
            var fileName = /^html?$/.test(matches[3]) ? matches[2] : "index.html";
            doc.root = {url: encodeURI(prefix + matches[1] + fileName)};
        }
    }

    /** Get the current document from the document manager
     * _adds extension, url and root to the document
     */
    function _getCurrentDocument() {
        var doc = DocumentManager.getCurrentDocument();
        if (doc) {
            _setDocInfo(doc);
        }
        return doc;
    }

    /** Determine which document class should be used for a given document
     * @param {Document} document
     */
    function _classForDocument(doc) {
        switch (doc.extension) {
        case "css":
            return CSSDocument;
        /* FUTURE:
        case "js":
            return JSDocument;
        case "html":
        case "htm":
            return HTMLDocument;
        default:
            throw "Invalid document type: " + doc.extension;
        */
        }

        return null;
    }

    /**
     * Removes the given CSS/JSDocument from _relatedDocuments. Signals that the
     * given file is no longer associated with the HTML document that is live (e.g.
     * if the related file has been deleted on disk).
     */
    function _handleRelatedDocumentDeleted(event, liveDoc) {
        var index = _relatedDocuments.indexOf(liveDoc);
        if (index !== -1) {
            $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
            _relatedDocuments.splice(index, 1);
        }
    }

    /** Close a live document */
    function _closeDocument() {
        if (_liveDocument) {
            _liveDocument.close();
            _liveDocument = undefined;
        }
        if (_relatedDocuments) {
            _relatedDocuments.forEach(function (liveDoc) {
                liveDoc.close();
                $(liveDoc).off("deleted", _handleRelatedDocumentDeleted);
            });
            _relatedDocuments = undefined;
        }
    }

    /** Create a live version of a Brackets document */
    function _createDocument(doc, editor) {
        var DocClass = _classForDocument(doc);
        if (DocClass) {
            return new DocClass(doc, editor);
        } else {
            return null;
        }
    }

    /** Convert a file: URL to a local full file path */
    function _urlToPath(url) {
        var path;
        if (url.indexOf("file://") === 0) {
            path = url.slice(7);
            if (path && brackets.platform === "win" && path.charAt(0) === "/") {
                path = path.slice(1);
            }
        }
        return decodeURI(path);
    }

    /** Open a live document
     * @param {Document} source document to open
     */
    function _openDocument(doc, editor) {
        _closeDocument();
        _liveDocument = _createDocument(doc, editor);

        // Gather related CSS documents.
        // FUTURE: Gather related JS documents as well.
        _relatedDocuments = [];
        agents.css.getStylesheetURLs().forEach(function (url) {
            // FUTURE: when we get truly async file handling, we might need to prevent other
            // stuff from happening while we wait to add these listeners
            DocumentManager.getDocumentForPath(_urlToPath(url))
                .done(function (doc) {
                    _setDocInfo(doc);
                    var liveDoc = _createDocument(doc);
                    if (liveDoc) {
                        _relatedDocuments.push(liveDoc);
                        $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
                    }
                });
        });
    }

    /** Unload the agents */
    function unloadAgents() {
        var i;
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].unload) {
                agents[i].unload();
            }
        }
    }

    /** Load the agents */
    function loadAgents() {
        var i, promises = [];
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].load) {
                promises.push(agents[i].load());
            }
        }
        return promises;
    }

    /** Update the status
     * @param {integer} new status
     */
    function _setStatus(status) {
        exports.status = status;
        $(exports).triggerHandler("statusChange", status);
    }

    /** Triggered by Inspector.error */
    function _onError(error) {
        console.error(error.message);
    }

    /** Run when all agents are loaded */
    function _onLoad() {
        var doc = _getCurrentDocument();
        if (doc) {
            var editor = EditorManager.getCurrentFullEditor();
            _openDocument(doc, editor);
        }
        _setStatus(3);
    }

    /** Triggered by Inspector.connect */
    function _onConnect() {
        var promises = loadAgents();
        _setStatus(2);
        $.when.apply(undefined, promises).then(_onLoad, _onError);
    }

    /** Triggered by Inspector.disconnect */
    function _onDisconnect() {
        unloadAgents();
        _closeDocument();
        _setStatus(0);
    }

    /** Open the Connection and go live */
    function open() {
        var doc = _getCurrentDocument();
        var browserStarted = false;
        var retryCount = 0;

        function showWrongDocError() {
            Dialogs.showModalDialog(
                Dialogs.DIALOG_ID_ERROR,
                Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                Strings.LIVE_DEV_NEED_HTML_MESSAGE
            );
        }

        if (!doc || !doc.root) {
            showWrongDocError();

        } else {
            // For Sprint 6, we only open live development connections for HTML files
            // FUTURE: Remove this test when we support opening connections for different
            // file types.
            if (!doc.extension || doc.extension.indexOf("htm") !== 0) {
                showWrongDocError();
                return;
            }

            _setStatus(1);
            Inspector.connectToURL(doc.root.url).fail(function onConnectFail(err) {
                if (err === "CANCEL") {
                    return;
                }
                if (retryCount > 6) {
                    _setStatus(-1);
                    Dialogs.showModalDialog(
                        Dialogs.DIALOG_ID_LIVE_DEVELOPMENT,
                        Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                        Strings.LIVE_DEVELOPMENT_ERROR_MESSAGE
                    ).done(function (id) {
                        if (id === Dialogs.DIALOG_BTN_OK) {
                            // User has chosen to reload Chrome, quit the running instance
                            _setStatus(0);
                            NativeApp.closeLiveBrowser()
                                .done(function () {
                                    browserStarted = false;
                                    window.setTimeout(open);
                                })
                                .fail(function (err) {
                                    // Report error?
                                    _setStatus(-1);
                                    browserStarted = false;
                                });
                        }
                    });
                    return;
                }
                retryCount++;

                if (!browserStarted && exports.status !== -1) {
                    // If err === FileError.ERR_NOT_FOUND, it means a remote debugger connection
                    // is available, but the requested URL is not loaded in the browser. In that
                    // case we want to launch the live browser (to open the url in a new tab)
                    // without using the --remote-debugging-port flag. This works around issues
                    // on Windows where Chrome can't be opened more than once with the
                    // --remote-debugging-port flag set.
                    NativeApp.openLiveBrowser(
                        doc.root.url,
                        err !== FileError.ERR_NOT_FOUND
                    )
                        .done(function () {
                            browserStarted = true;
                        })
                        .fail(function (err) {
                            var message;

                            _setStatus(-1);
                            if (err === FileError.NOT_FOUND_ERR) {
                                message = Strings.ERROR_CANT_FIND_CHROME;
                            } else {
                                message = StringUtils.format(Strings.ERROR_LAUNCHING_BROWSER, err);
                            }

                            Dialogs.showModalDialog(
                                Dialogs.DIALOG_ID_ERROR,
                                Strings.ERROR_LAUNCHING_BROWSER_TITLE,
                                message
                            );
                        });
                }

                if (exports.status !== -1) {
                    window.setTimeout(function retryConnect() {
                        Inspector.connectToURL(doc.root.url).fail(onConnectFail);
                    }, 500);
                }
            });
        }
    }

    /** Close the Connection */
    function close() {
        if (Inspector.connected()) {
            Inspector.Runtime.evaluate("window.close()");
        }
        Inspector.disconnect();
        _setStatus(0);
    }

    /** Triggered by a document change from the DocumentManager */
    function _onDocumentChange() {
        var doc = _getCurrentDocument();
        if (!doc) {
            return;
        }

        if (Inspector.connected()) {
            if (agents.network && agents.network.wasURLRequested(doc.url)) {
                _closeDocument();
                var editor = EditorManager.getCurrentFullEditor();
                _openDocument(doc, editor);
            } else {
                /* FUTURE: support live connections for docments other than html */
                if (doc.extension && doc.extension.indexOf("htm") === 0 && doc.file.fullPath !== _htmlDocumentPath) {
                    close();
                    window.setTimeout(open);
                    _htmlDocumentPath = doc.file.fullPath;
                }
            }
        } else if (exports.config.autoconnect) {
            window.setTimeout(open);
        }
    }

    function getLiveDocForPath(path) {
        var docsToSearch = [];
        if (_relatedDocuments) {
            docsToSearch = docsToSearch.concat(_relatedDocuments);
        }
        if (_liveDocument) {
            docsToSearch = docsToSearch.concat(_liveDocument);
        }
        var foundDoc;
        docsToSearch.some(function matchesPath(ele) {
            if (ele.doc.file.fullPath === path) {
                foundDoc = ele;
                return true;
            }
            return false;
        });

        return foundDoc;
    }

    /** Hide any active highlighting */
    function hideHighlight() {
        if (Inspector.connected() && agents.highlight) {
            agents.highlight.hide();
        }
    }

    /** Initialize the LiveDevelopment Session */
    function init(theConfig) {
        exports.config = theConfig;
        Inspector.on("connect", _onConnect);
        Inspector.on("disconnect", _onDisconnect);
        Inspector.on("error", _onError);
        Inspector.on("load", _onLoad);
        $(DocumentManager).on("currentDocumentChange", _onDocumentChange);
    }

    // Export public functions
    exports.agents = agents;
    exports.open = open;
    exports.close = close;
    exports.getLiveDocForPath = getLiveDocForPath;
    exports.hideHighlight = hideHighlight;
    exports.init = init;
});<commit_msg>Improve console output of LiveDevelopment errors<commit_after>/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */
/*global define, $, FileError, brackets, window */

/**
 * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument
 *
 * # STARTING
 *
 * To start a session call `open`. This will read the currentDocument from brackets,
 * launch the LiveBrowser (currently Chrome) with the remote debugger port open,
 * establish the Inspector connection to the remote debugger, and finally load all
 * agents.
 *
 * # STOPPING
 *
 * To stop a session call `close`. This will close the active browser window,
 * disconnect the Inspector, unload all agents, and clean up.
 *
 * # STATUS
 *
 * Status updates are dispatched as `statusChange` jQuery events. The status
 * codes are:
 *
 * -1: Error
 * 0: Inactive
 * 1: Connecting to the remote debugger
 * 2: Loading agents
 * 3: Active
 */
define(function LiveDevelopment(require, exports, module) {
    "use strict";

    var DocumentManager = require("document/DocumentManager");
    var EditorManager = require("editor/EditorManager");
    var NativeApp = require("utils/NativeApp");
    var Dialogs = require("widgets/Dialogs");
    var Strings = require("strings");
    var StringUtils = require("utils/StringUtils");

    // Inspector
    var Inspector = require("LiveDevelopment/Inspector/Inspector");

    // Documents
    var HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument");
    var CSSDocument = require("LiveDevelopment/Documents/CSSDocument");
    var JSDocument = require("LiveDevelopment/Documents/JSDocument");

    // Agents
    var agents = {
        "console": require("LiveDevelopment/Agents/ConsoleAgent"),
        "remote": require("LiveDevelopment/Agents/RemoteAgent"),
        "network": require("LiveDevelopment/Agents/NetworkAgent"),
        "dom": require("LiveDevelopment/Agents/DOMAgent"),
        "css": require("LiveDevelopment/Agents/CSSAgent")
        /* FUTURE
        "script": require("LiveDevelopment/Agents/ScriptAgent"),
        "highlight": require("LiveDevelopment/Agents/HighlightAgent"),
        "goto": require("LiveDevelopment/Agents/GotoAgent"),
        "edit": require("LiveDevelopment/Agents/EditAgent")
        */
    };

    var _htmlDocumentPath; // the path of the html file open for live development
    var _liveDocument; // the document open for live editing.
    var _relatedDocuments; // CSS and JS documents that are used by the live HTML document

    /** Augments the given Brackets document with information that's useful for live development. */
    function _setDocInfo(doc) {
        // FUTURE: some of these things should just be moved into core Document; others should
        // be in a LiveDevelopment-specific object attached to the doc.
        var matches = /^(.*\/)(.+\.([^.]+))$/.exec(doc.file.fullPath);
        if (matches) {
            var prefix = "file://";

            // The file.fullPath on Windows starts with a drive letter ("C:").
            // In order to make it a valid file: URL we need to add an
            // additional slash to the prefix.
            if (brackets.platform === "win") {
                prefix += "/";
            }

            doc.extension = matches[3];
            doc.url = encodeURI(prefix + doc.file.fullPath);

            // the root represents the document that should be displayed in the browser
            // for live development (the file for HTML files, index.html for others)
            var fileName = /^html?$/.test(matches[3]) ? matches[2] : "index.html";
            doc.root = {url: encodeURI(prefix + matches[1] + fileName)};
        }
    }

    /** Get the current document from the document manager
     * _adds extension, url and root to the document
     */
    function _getCurrentDocument() {
        var doc = DocumentManager.getCurrentDocument();
        if (doc) {
            _setDocInfo(doc);
        }
        return doc;
    }

    /** Determine which document class should be used for a given document
     * @param {Document} document
     */
    function _classForDocument(doc) {
        switch (doc.extension) {
        case "css":
            return CSSDocument;
        /* FUTURE:
        case "js":
            return JSDocument;
        case "html":
        case "htm":
            return HTMLDocument;
        default:
            throw "Invalid document type: " + doc.extension;
        */
        }

        return null;
    }

    /**
     * Removes the given CSS/JSDocument from _relatedDocuments. Signals that the
     * given file is no longer associated with the HTML document that is live (e.g.
     * if the related file has been deleted on disk).
     */
    function _handleRelatedDocumentDeleted(event, liveDoc) {
        var index = _relatedDocuments.indexOf(liveDoc);
        if (index !== -1) {
            $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
            _relatedDocuments.splice(index, 1);
        }
    }

    /** Close a live document */
    function _closeDocument() {
        if (_liveDocument) {
            _liveDocument.close();
            _liveDocument = undefined;
        }
        if (_relatedDocuments) {
            _relatedDocuments.forEach(function (liveDoc) {
                liveDoc.close();
                $(liveDoc).off("deleted", _handleRelatedDocumentDeleted);
            });
            _relatedDocuments = undefined;
        }
    }

    /** Create a live version of a Brackets document */
    function _createDocument(doc, editor) {
        var DocClass = _classForDocument(doc);
        if (DocClass) {
            return new DocClass(doc, editor);
        } else {
            return null;
        }
    }

    /** Convert a file: URL to a local full file path */
    function _urlToPath(url) {
        var path;
        if (url.indexOf("file://") === 0) {
            path = url.slice(7);
            if (path && brackets.platform === "win" && path.charAt(0) === "/") {
                path = path.slice(1);
            }
        }
        return decodeURI(path);
    }

    /** Open a live document
     * @param {Document} source document to open
     */
    function _openDocument(doc, editor) {
        _closeDocument();
        _liveDocument = _createDocument(doc, editor);

        // Gather related CSS documents.
        // FUTURE: Gather related JS documents as well.
        _relatedDocuments = [];
        agents.css.getStylesheetURLs().forEach(function (url) {
            // FUTURE: when we get truly async file handling, we might need to prevent other
            // stuff from happening while we wait to add these listeners
            DocumentManager.getDocumentForPath(_urlToPath(url))
                .done(function (doc) {
                    _setDocInfo(doc);
                    var liveDoc = _createDocument(doc);
                    if (liveDoc) {
                        _relatedDocuments.push(liveDoc);
                        $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
                    }
                });
        });
    }

    /** Unload the agents */
    function unloadAgents() {
        var i;
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].unload) {
                agents[i].unload();
            }
        }
    }

    /** Load the agents */
    function loadAgents() {
        var i, promises = [];
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].load) {
                promises.push(agents[i].load());
            }
        }
        return promises;
    }

    /** Update the status
     * @param {integer} new status
     */
    function _setStatus(status) {
        exports.status = status;
        $(exports).triggerHandler("statusChange", status);
    }

    /** Triggered by Inspector.error */
    function _onError(error) {
        var message = error.message;

        // Additional information, like exactly which parameter could not be processed.
        var data = error.data;
        if ($.isArray(data)) {
            message += "\n" + data.join("\n");
        }

        // Show the message, but include the error object for further information (e.g. error code)
        console.error(message, error);
    }

    /** Run when all agents are loaded */
    function _onLoad() {
        var doc = _getCurrentDocument();
        if (doc) {
            var editor = EditorManager.getCurrentFullEditor();
            _openDocument(doc, editor);
        }
        _setStatus(3);
    }

    /** Triggered by Inspector.connect */
    function _onConnect() {
        var promises = loadAgents();
        _setStatus(2);
        $.when.apply(undefined, promises).then(_onLoad, _onError);
    }

    /** Triggered by Inspector.disconnect */
    function _onDisconnect() {
        unloadAgents();
        _closeDocument();
        _setStatus(0);
    }

    /** Open the Connection and go live */
    function open() {
        var doc = _getCurrentDocument();
        var browserStarted = false;
        var retryCount = 0;

        function showWrongDocError() {
            Dialogs.showModalDialog(
                Dialogs.DIALOG_ID_ERROR,
                Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                Strings.LIVE_DEV_NEED_HTML_MESSAGE
            );
        }

        if (!doc || !doc.root) {
            showWrongDocError();

        } else {
            // For Sprint 6, we only open live development connections for HTML files
            // FUTURE: Remove this test when we support opening connections for different
            // file types.
            if (!doc.extension || doc.extension.indexOf("htm") !== 0) {
                showWrongDocError();
                return;
            }

            _setStatus(1);
            Inspector.connectToURL(doc.root.url).fail(function onConnectFail(err) {
                if (err === "CANCEL") {
                    return;
                }
                if (retryCount > 6) {
                    _setStatus(-1);
                    Dialogs.showModalDialog(
                        Dialogs.DIALOG_ID_LIVE_DEVELOPMENT,
                        Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                        Strings.LIVE_DEVELOPMENT_ERROR_MESSAGE
                    ).done(function (id) {
                        if (id === Dialogs.DIALOG_BTN_OK) {
                            // User has chosen to reload Chrome, quit the running instance
                            _setStatus(0);
                            NativeApp.closeLiveBrowser()
                                .done(function () {
                                    browserStarted = false;
                                    window.setTimeout(open);
                                })
                                .fail(function (err) {
                                    // Report error?
                                    _setStatus(-1);
                                    browserStarted = false;
                                });
                        }
                    });
                    return;
                }
                retryCount++;

                if (!browserStarted && exports.status !== -1) {
                    // If err === FileError.ERR_NOT_FOUND, it means a remote debugger connection
                    // is available, but the requested URL is not loaded in the browser. In that
                    // case we want to launch the live browser (to open the url in a new tab)
                    // without using the --remote-debugging-port flag. This works around issues
                    // on Windows where Chrome can't be opened more than once with the
                    // --remote-debugging-port flag set.
                    NativeApp.openLiveBrowser(
                        doc.root.url,
                        err !== FileError.ERR_NOT_FOUND
                    )
                        .done(function () {
                            browserStarted = true;
                        })
                        .fail(function (err) {
                            var message;

                            _setStatus(-1);
                            if (err === FileError.NOT_FOUND_ERR) {
                                message = Strings.ERROR_CANT_FIND_CHROME;
                            } else {
                                message = StringUtils.format(Strings.ERROR_LAUNCHING_BROWSER, err);
                            }

                            Dialogs.showModalDialog(
                                Dialogs.DIALOG_ID_ERROR,
                                Strings.ERROR_LAUNCHING_BROWSER_TITLE,
                                message
                            );
                        });
                }

                if (exports.status !== -1) {
                    window.setTimeout(function retryConnect() {
                        Inspector.connectToURL(doc.root.url).fail(onConnectFail);
                    }, 500);
                }
            });
        }
    }

    /** Close the Connection */
    function close() {
        if (Inspector.connected()) {
            Inspector.Runtime.evaluate("window.close()");
        }
        Inspector.disconnect();
        _setStatus(0);
    }

    /** Triggered by a document change from the DocumentManager */
    function _onDocumentChange() {
        var doc = _getCurrentDocument();
        if (!doc) {
            return;
        }

        if (Inspector.connected()) {
            if (agents.network && agents.network.wasURLRequested(doc.url)) {
                _closeDocument();
                var editor = EditorManager.getCurrentFullEditor();
                _openDocument(doc, editor);
            } else {
                /* FUTURE: support live connections for docments other than html */
                if (doc.extension && doc.extension.indexOf("htm") === 0 && doc.file.fullPath !== _htmlDocumentPath) {
                    close();
                    window.setTimeout(open);
                    _htmlDocumentPath = doc.file.fullPath;
                }
            }
        } else if (exports.config.autoconnect) {
            window.setTimeout(open);
        }
    }

    function getLiveDocForPath(path) {
        var docsToSearch = [];
        if (_relatedDocuments) {
            docsToSearch = docsToSearch.concat(_relatedDocuments);
        }
        if (_liveDocument) {
            docsToSearch = docsToSearch.concat(_liveDocument);
        }
        var foundDoc;
        docsToSearch.some(function matchesPath(ele) {
            if (ele.doc.file.fullPath === path) {
                foundDoc = ele;
                return true;
            }
            return false;
        });

        return foundDoc;
    }

    /** Hide any active highlighting */
    function hideHighlight() {
        if (Inspector.connected() && agents.highlight) {
            agents.highlight.hide();
        }
    }

    /** Initialize the LiveDevelopment Session */
    function init(theConfig) {
        exports.config = theConfig;
        Inspector.on("connect", _onConnect);
        Inspector.on("disconnect", _onDisconnect);
        Inspector.on("error", _onError);
        Inspector.on("load", _onLoad);
        $(DocumentManager).on("currentDocumentChange", _onDocumentChange);
    }

    // Export public functions
    exports.agents = agents;
    exports.open = open;
    exports.close = close;
    exports.getLiveDocForPath = getLiveDocForPath;
    exports.hideHighlight = hideHighlight;
    exports.init = init;
});<|endoftext|>


<commit_before>module.exports = function(deployTarget) {
  var ENV = {};

  ENV['bugsnag'] = {
    apiKey: process.env.BUGSNAG_API_KEY,
    publicUrl: process.env.BUGSNAG_PUBLIC_URL,
  };

  return ENV;
};
<commit_msg>configure ember-deploy for s3<commit_after>module.exports = function(deployTarget) {
  var ENV = {};

  ENV['bugsnag'] = {
    apiKey: process.env.BUGSNAG_API_KEY,
    publicUrl: process.env.BUGSNAG_PUBLIC_URL,
  };

  ENV.s3 = {
    accessKeyId: process.env.AWS_ACCESS_KEY,
    secretAccessKey: process.env.AWS_SECRET_KEY,
    bucket: process.env.AWS_BUCKET,
    region: process.env.AWS_REGION,
    filePattern: '**/*.{js,css,png,gif,ico,jpg,map,xml,txt,svg,swf,eot,ttf,woff,woff2,html}'
  };

  return ENV;
};
<|endoftext|>


<commit_before>/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 * @author Jonathan Diehl <jdiehl@adobe.com>
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */
/*global define, $ */

/**
 * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument
 *
 * # STARTING
 *
 * To start a session call `open`. This will read the currentDocument from brackets,
 * launch the LiveBrowser (currently Chromium) with the remote debugger port open,
 * establish the Inspector connection to the remote debugger, and finally load all
 * agents.
 *
 * # STOPPING
 *
 * To stop a session call `close`. This will close the active browser window,
 * disconnect the Inspector, unload all agents, and clean up.
 *
 * # STATUS
 *
 * Status updates are dispatched as `statusChange` jQuery events. The status
 * codes are:
 *
 * 0: Inactive
 * 1: Connecting to the remote debugger
 * 2: Loading agents
 * 3: Active
 */
define(function LiveDevelopment(require, exports, module) {
    'use strict';

    var DocumentManager = require("document/DocumentManager");
    var EditorManager = require("editor/EditorManager");
    var NativeApp = require("utils/NativeApp").NativeApp;

    // Inspector
    var Inspector = require("LiveDevelopment/Inspector/Inspector");

    // Documents
    var HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument");
    var CSSDocument = require("LiveDevelopment/Documents/CSSDocument");
    var JSDocument = require("LiveDevelopment/Documents/JSDocument");

    // Agents
    var agents = {
        "console": require("LiveDevelopment/Agents/ConsoleAgent"),
        "remote": require("LiveDevelopment/Agents/RemoteAgent"),
        "network": require("LiveDevelopment/Agents/NetworkAgent"),
        "dom": require("LiveDevelopment/Agents/DOMAgent"),
        "css": require("LiveDevelopment/Agents/CSSAgent")
        /* FUTURE
        "script": require("LiveDevelopment/Agents/ScriptAgent"),
        "highlight": require("LiveDevelopment/Agents/HighlightAgent"),
        "goto": require("LiveDevelopment/Agents/GotoAgent"),
        "edit": require("LiveDevelopment/Agents/EditAgent")
        */
    };

    var _liveDocument; // the live document
    var _document; // the open live-document

    /** Get the current document from the document manager
     * _adds extension, url and root to the document
     */
    function _getCurrentDocument() {
        var doc = DocumentManager.getCurrentDocument();
        if (doc) {
            var matches = /^(.*\/)(.+\.([^.]+))$/.exec(doc.file.fullPath);
            doc.extension = matches[3];
            doc.url = encodeURI("file://" + doc.file.fullPath);

            // the root represents the document that should be displayed in the browser
            // for live development (the file for HTML files, index.html for others)
            var fileName = /^html?$/.test(matches[3]) ? matches[2] : "index.html";
            doc.root = {url: encodeURI("file://" + matches[1] + fileName)};
        }
        return doc;
    }

    /** Determine which document class should be used for a given document
     * @param {Document} document
     */
    function _classForDocument(doc) {
        switch (doc.extension) {
        case "css":
            return CSSDocument;
        /* FUTURE:
        case "js":
            return JSDocument;
        case "html":
        case "htm":
            return HTMLDocument;
        default:
            throw "Invalid document type: " + doc.extension;
        */
        }

        return null;
    }

    /** Close a live document */
    function _closeDocument() {
        if (_liveDocument) {
            _liveDocument.close();
            _liveDocument = undefined;
        }
    }

    /** Open a live document
     * @param {Document} source document to open
     */
    function _openDocument(doc, editor) {
        _closeDocument();
        var DocumentClass = _classForDocument(doc);
        if (DocumentClass) {
            _liveDocument = new DocumentClass(doc, editor);
        }
    }

    /** Unload the agents */
    function unloadAgents() {
        var i;
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].unload) {
                agents[i].unload();
            }
        }
    }

    /** Load the agents */
    function loadAgents() {
        var i, promises = [];
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].load) {
                promises.push(agents[i].load());
            }
        }
        return promises;
    }

    /** Update the status
     * @param {integer} new status
     */
    function _setStatus(status) {
        exports.status = status;
        $(exports).triggerHandler("statusChange", status);
    }

    /** Triggered by Inspector.error */
    function _onError(error) {
        console.error(error.message);
    }

    /** Run when all agents are loaded */
    function _onLoad() {
        var doc = _getCurrentDocument();
        if (doc) {
            var editor = EditorManager.getCurrentFullEditor();
            _openDocument(doc, editor);
        }
        _setStatus(3);
    }

    /** Triggered by Inspector.connect */
    function _onConnect() {
        var promises = loadAgents();
        _setStatus(2);
        $.when.apply(undefined, promises).then(_onLoad, _onError);
    }

    /** Triggered by Inspector.disconnect */
    function _onDisconnect() {
        unloadAgents();
        _closeDocument();
        _setStatus(0);
    }

    /** Open the Connection and go live */
    function open() {
        var doc = _getCurrentDocument();
        var browserStarted = false;
        if (doc) {
            _setStatus(1);
            Inspector.connectToURL(doc.root.url).fail(function onConnectFail(err) {
                if (err === "CANCEL") {
                    return;
                }
                if (!browserStarted) {
                    NativeApp.openLiveBrowser(doc.root.url);
                    browserStarted = true;
                }
                setTimeout(function retryConnect() {
                    doc = _getCurrentDocument();
                    Inspector.connectToURL(doc.root.url).fail(onConnectFail);
                }, 500);
            });
        }
    }

    /** Close the Connection */
    function close() {
        if (Inspector.connected()) {
            Inspector.Runtime.evaluate("window.close()");
        }
        Inspector.disconnect();
    }

    /** Triggered by a document change from the DocumentManager */
    function _onDocumentChange() {
        var doc = _getCurrentDocument();
        if (Inspector.connected()) {
            if (!doc) {
                close();
            } else if (agents.network && agents.network.wasURLRequested(doc.url)) {
                _closeDocument();
                var editor = EditorManager.getCurrentFullEditor();
                _openDocument(doc, editor);
            } else {
                close();
                setTimeout(open);
            }
        } else if (exports.config.autoconnect) {
            setTimeout(open);
        }
    }

    /** Hide any active highlighting */
    function hideHighlight() {
        if (Inspector.connected() && agents.highlight) {
            agents.highlight.hide();
        }
    }

    /** Initialize the LiveDevelopment Session */
    function init(theConfig) {
        exports.config = theConfig;
        Inspector.on("connect", _onConnect);
        Inspector.on("disconnect", _onDisconnect);
        Inspector.on("error", _onError);
        Inspector.on("load", _onLoad);
        $(DocumentManager).on("currentDocumentChange", _onDocumentChange);
    }

    // Export public functions
    exports.agents = agents;
    exports.open = open;
    exports.close = close;
    exports.hideHighlight = hideHighlight;
    exports.init = init;
});<commit_msg>Add null check.<commit_after>/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 * @author Jonathan Diehl <jdiehl@adobe.com>
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */
/*global define, $ */

/**
 * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument
 *
 * # STARTING
 *
 * To start a session call `open`. This will read the currentDocument from brackets,
 * launch the LiveBrowser (currently Chromium) with the remote debugger port open,
 * establish the Inspector connection to the remote debugger, and finally load all
 * agents.
 *
 * # STOPPING
 *
 * To stop a session call `close`. This will close the active browser window,
 * disconnect the Inspector, unload all agents, and clean up.
 *
 * # STATUS
 *
 * Status updates are dispatched as `statusChange` jQuery events. The status
 * codes are:
 *
 * 0: Inactive
 * 1: Connecting to the remote debugger
 * 2: Loading agents
 * 3: Active
 */
define(function LiveDevelopment(require, exports, module) {
    'use strict';

    var DocumentManager = require("document/DocumentManager");
    var EditorManager = require("editor/EditorManager");
    var NativeApp = require("utils/NativeApp").NativeApp;

    // Inspector
    var Inspector = require("LiveDevelopment/Inspector/Inspector");

    // Documents
    var HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument");
    var CSSDocument = require("LiveDevelopment/Documents/CSSDocument");
    var JSDocument = require("LiveDevelopment/Documents/JSDocument");

    // Agents
    var agents = {
        "console": require("LiveDevelopment/Agents/ConsoleAgent"),
        "remote": require("LiveDevelopment/Agents/RemoteAgent"),
        "network": require("LiveDevelopment/Agents/NetworkAgent"),
        "dom": require("LiveDevelopment/Agents/DOMAgent"),
        "css": require("LiveDevelopment/Agents/CSSAgent")
        /* FUTURE
        "script": require("LiveDevelopment/Agents/ScriptAgent"),
        "highlight": require("LiveDevelopment/Agents/HighlightAgent"),
        "goto": require("LiveDevelopment/Agents/GotoAgent"),
        "edit": require("LiveDevelopment/Agents/EditAgent")
        */
    };

    var _liveDocument; // the live document
    var _document; // the open live-document

    /** Get the current document from the document manager
     * _adds extension, url and root to the document
     */
    function _getCurrentDocument() {
        var doc = DocumentManager.getCurrentDocument();
        if (doc) {
            var matches = /^(.*\/)(.+\.([^.]+))$/.exec(doc.file.fullPath);
            doc.extension = matches[3];
            doc.url = encodeURI("file://" + doc.file.fullPath);

            // the root represents the document that should be displayed in the browser
            // for live development (the file for HTML files, index.html for others)
            var fileName = /^html?$/.test(matches[3]) ? matches[2] : "index.html";
            doc.root = {url: encodeURI("file://" + matches[1] + fileName)};
        }
        return doc;
    }

    /** Determine which document class should be used for a given document
     * @param {Document} document
     */
    function _classForDocument(doc) {
        switch (doc.extension) {
        case "css":
            return CSSDocument;
        /* FUTURE:
        case "js":
            return JSDocument;
        case "html":
        case "htm":
            return HTMLDocument;
        default:
            throw "Invalid document type: " + doc.extension;
        */
        }

        return null;
    }

    /** Close a live document */
    function _closeDocument() {
        if (_liveDocument) {
            _liveDocument.close();
            _liveDocument = undefined;
        }
    }

    /** Open a live document
     * @param {Document} source document to open
     */
    function _openDocument(doc, editor) {
        _closeDocument();
        var DocumentClass = _classForDocument(doc);
        if (DocumentClass) {
            _liveDocument = new DocumentClass(doc, editor);
        }
    }

    /** Unload the agents */
    function unloadAgents() {
        var i;
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].unload) {
                agents[i].unload();
            }
        }
    }

    /** Load the agents */
    function loadAgents() {
        var i, promises = [];
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].load) {
                promises.push(agents[i].load());
            }
        }
        return promises;
    }

    /** Update the status
     * @param {integer} new status
     */
    function _setStatus(status) {
        exports.status = status;
        $(exports).triggerHandler("statusChange", status);
    }

    /** Triggered by Inspector.error */
    function _onError(error) {
        console.error(error.message);
    }

    /** Run when all agents are loaded */
    function _onLoad() {
        var doc = _getCurrentDocument();
        if (doc) {
            var editor = EditorManager.getCurrentFullEditor();
            _openDocument(doc, editor);
        }
        _setStatus(3);
    }

    /** Triggered by Inspector.connect */
    function _onConnect() {
        var promises = loadAgents();
        _setStatus(2);
        $.when.apply(undefined, promises).then(_onLoad, _onError);
    }

    /** Triggered by Inspector.disconnect */
    function _onDisconnect() {
        unloadAgents();
        _closeDocument();
        _setStatus(0);
    }

    /** Open the Connection and go live */
    function open() {
        var doc = _getCurrentDocument();
        var browserStarted = false;
        if (doc && doc.root) {
            _setStatus(1);
            Inspector.connectToURL(doc.root.url).fail(function onConnectFail(err) {
                if (err === "CANCEL") {
                    return;
                }
                if (!browserStarted) {
                    NativeApp.openLiveBrowser(doc.root.url);
                    browserStarted = true;
                }
                setTimeout(function retryConnect() {
                    doc = _getCurrentDocument();
                    Inspector.connectToURL(doc.root.url).fail(onConnectFail);
                }, 500);
            });
        }
    }

    /** Close the Connection */
    function close() {
        if (Inspector.connected()) {
            Inspector.Runtime.evaluate("window.close()");
        }
        Inspector.disconnect();
    }

    /** Triggered by a document change from the DocumentManager */
    function _onDocumentChange() {
        var doc = _getCurrentDocument();
        if (Inspector.connected()) {
            if (!doc) {
                close();
            } else if (agents.network && agents.network.wasURLRequested(doc.url)) {
                _closeDocument();
                var editor = EditorManager.getCurrentFullEditor();
                _openDocument(doc, editor);
            } else {
                close();
                setTimeout(open);
            }
        } else if (exports.config.autoconnect) {
            setTimeout(open);
        }
    }

    /** Hide any active highlighting */
    function hideHighlight() {
        if (Inspector.connected() && agents.highlight) {
            agents.highlight.hide();
        }
    }

    /** Initialize the LiveDevelopment Session */
    function init(theConfig) {
        exports.config = theConfig;
        Inspector.on("connect", _onConnect);
        Inspector.on("disconnect", _onDisconnect);
        Inspector.on("error", _onError);
        Inspector.on("load", _onLoad);
        $(DocumentManager).on("currentDocumentChange", _onDocumentChange);
    }

    // Export public functions
    exports.agents = agents;
    exports.open = open;
    exports.close = close;
    exports.hideHighlight = hideHighlight;
    exports.init = init;
});<|endoftext|>


<commit_before>/**
    这个模块用来获得有效token
    使用：

    var appID = require('./config').appID,
      appSecret = require('./config').appSecret;

    getToken(appID, appSecret).then(function(token){
      console.log(token);
    });

    http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html
 */

var request = require('request');
var fs = require('fs');

function getToken(tokenUrl){
  console.log(tokenUrl);
  return new Promise(function(resolve, reject){
    var token;

    //先看是否有token缓存，这里选择用文件缓存，可以用其他的持久存储作为缓存
    if(fs.existsSync('token.dat')){
      token = JSON.parse(fs.readFileSync('token.dat'));
    }

    //如果没有缓存或者过期
    if(!token || token.timeout < Date.now()){
      console.log(tokenUrl);
      request(tokenUrl, function(err, res, data){
        console.log(tokenUrl);
        var result = JSON.parse(data);
        result.timeout = Date.now() + 7000000;
        //更新token并缓存
        //因为access_token的有效期是7200秒，每天可以取2000次
        //所以差不多缓存7000秒左右肯定是够了
        fs.writeFileSync('token.dat', JSON.stringify(result));
        resolve(result);
      });
    }else{
      resolve(token);
    }

  });
}

module.exports = {getToken: getToken};<commit_msg>commit 17<commit_after>/**
    这个模块用来获得有效token
    使用：

    var appID = require('./config').appID,
      appSecret = require('./config').appSecret;

    getToken(appID, appSecret).then(function(token){
      console.log(token);
    });

    http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html
 */

var request = require('request');
var fs = require('fs');

function getToken(tokenUrl){
  console.log(tokenUrl);
  return new Promise(function(resolve, reject){
    var token;

    //先看是否有token缓存，这里选择用文件缓存，可以用其他的持久存储作为缓存
    if(fs.existsSync('token1.dat')){
      token = JSON.parse(fs.readFileSync('token1.dat'));
      console.log(token);
    }

    //如果没有缓存或者过期
    if(!token || token.timeout < Date.now()){
      console.log(tokenUrl);
      request(tokenUrl, function(err, res, data){
        console.log(tokenUrl);
        var result = JSON.parse(data);
        result.timeout = Date.now() + 7000000;
        //更新token并缓存
        //因为access_token的有效期是7200秒，每天可以取2000次
        //所以差不多缓存7000秒左右肯定是够了
        fs.writeFileSync('token1.dat', JSON.stringify(result));
        resolve(result);
      });
    }else{
      resolve(token);
    }

  });
}

module.exports = {getToken: getToken};<|endoftext|>


<commit_before>
'use strict';
// Storing multiple constant values inside of an object
// Keep in mind the values in the object mean they can be modified
// Which makes no sense for a constant, use wisely if you do this

app.directive('loader',
  function() {

    return {
      restrict:'E',
      template: function($element, $attrs) {
        return `

        `
      }
    }

})

app.directive('selectLimit',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend : '&'
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

               Show
                <select
                  ng-model="elemData.limit"
                  class="form-control select-limit input-sm"
                  ng-change="elemSend(elemData);"
                  ng-init="list = [10, 25, 50, 100, 500]"
                  ng-options="x for x in list" >
                </select>
                entries

      `
    };

});

app.directive('searchField',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend : '&'
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

            Search:
                <input ng-enter="elemSend(elemData)" ng-model="elemData.search.keyword" type="search" class="form-control search-field input-sm" placeholder="enter keywords..." />

      `
    };

});

app.directive('checkBox',
  function () {

    return {
      restrict: 'E',
      scope: {
        allRecords: '=',
        data: '='
      },
      link: function($scope, $element, $attrs) {
        // code will here as per future requirements....
      },
      controller: function($scope, $rootScope) {

        $scope.selectAll = function() {
          $rootScope.checkedArray = new Array();
          angular.forEach($scope.allRecords, function(value, index) {
            if($scope.allRecords.isCheckAll) {
              $rootScope.checkedArray.push(value._id); value.selected = true;
            } else { value.selected = false; }
          })
        }
        $scope.selectOne = function() { console.log($scope);
          $rootScope.checkedArray = new Array();
          angular.forEach($scope.allRecords, function(value, index) {
            if($scope.allRecords[index].selected) { $rootScope.checkedArray.push(value._id); }
          })
          if($rootScope.checkedArray.length == 0) $scope.allRecords.isCheckAll = false ;
        }
      },
      template: function($elements, $attrs) {

        return  $attrs.$attr.checkAll
          ? `<input type="checkbox" ng-model="allRecords.isCheckAll" ng-change="selectAll();" class="flat">`
          : `<input type="checkbox" ng-checked="allRecords.isCheckAll" ng-model="data.selected" ng-change="selectOne();" value="{{data._id}}" class="flat" /> `;
      }
    };

});

app.directive('currentPageInfo',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '='
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

Showing {{ elemData.limit * (elemData.currentPage - 1 ) + 1 }} to {{ elemData.limit * (elemData.currentPage - 1 ) + elemData.limit }} of {{ elemData.totalItems }} entries

      `
    };

});

app.directive('goToPage', ['$api', '$msg',
  function ($api, $msg) {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend  : '&'
      },
      link : function($scope, $element, $attrs) {
        // DOM manipulation will be here..
        var numField = angular.element($element[0].querySelector('input'));

        numField.on('keyup', function(e) {
          if(0 == this.value || "" == this.value) { this.value = $scope.elemData.currentPage = 1; }
          if(this.value > $scope.elemData.numPages) { this.value = $scope.elemData.currentPage = $scope.elemData.numPages; }
        })
      },
      template: `

             Go to
              <input ng-enter="elemSend(elemData);" ng-model="elemData.currentPage" type="number" min="1" max="{{ elemData.numPages }}" class="form-control input-sm go-to">  page

      `
    };

}]);

app.directive('pagination',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend  : '&'
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

      `
    };

});               <commit_msg>Managing Assets<commit_after>
'use strict';
// Storing multiple constant values inside of an object
// Keep in mind the values in the object mean they can be modified
// Which makes no sense for a constant, use wisely if you do this

app.directive('loader',
  function() {

    return {
      restrict:'E',
      template: function($element, $attrs) {
        return `

        `
      }
    }

})

app.directive('selectLimit',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend : '&'
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

               Show
                <select
                  ng-model="elemData.limit"
                  class="form-control select-limit input-sm"
                  ng-change="elemSend(elemData);"
                  ng-init="list = [10, 25, 50, 100, 500]"
                  ng-options="x for x in list" >
                </select>
                entries

      `
    };

});

app.directive('searchField',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend : '&'
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

            Search:
                <input ng-enter="elemSend(elemData)" ng-model="elemData.search.keyword" type="search" class="form-control search-field input-sm" placeholder="enter keywords..." />

      `
    };

});

app.directive('checkBox',
  function () {

    return {
      restrict: 'E',
      scope: {
        allRecords: '=',
        data: '='
      },
      link: function($scope, $element, $attrs) {
        // code will here as per future requirements....
      },
      controller: function($scope, $rootScope) {

        $scope.selectAll = function() {
          $rootScope.checkedArray = new Array();
          angular.forEach($scope.allRecords, function(value, index) {
            if($scope.allRecords.isCheckAll) {
              $rootScope.checkedArray.push(value._id); value.selected = true;
            } else { value.selected = false; }
          })
        }
        $scope.selectOne = function() {
          $rootScope.checkedArray = new Array();
          angular.forEach($scope.allRecords, function(value, index) {
            if($scope.allRecords[index].selected) { $rootScope.checkedArray.push(value._id); }
          })
          if($rootScope.checkedArray.length == 0) $scope.allRecords.isCheckAll = false ;
        }
      },
      template: function($elements, $attrs) {

        return  $attrs.$attr.checkAll
          ? `<input type="checkbox" ng-model="allRecords.isCheckAll" ng-change="selectAll();" class="flat">`
          : `<input type="checkbox" ng-checked="allRecords.isCheckAll" ng-model="data.selected" ng-change="selectOne();" value="{{data._id}}" class="flat" /> `;
      }
    };

});

app.directive('currentPageInfo',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '='
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

Showing {{ elemData.limit * (elemData.currentPage - 1 ) + 1 }} to {{ elemData.limit * (elemData.currentPage - 1 ) + elemData.limit }} of {{ elemData.totalItems }} entries

      `
    };

});

app.directive('goToPage', ['$api', '$msg',
  function ($api, $msg) {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend  : '&'
      },
      link : function($scope, $element, $attrs) {
        // DOM manipulation will be here..
        var numField = angular.element($element[0].querySelector('input'));

        numField.on('keyup', function(e) {
          if(0 == this.value || "" == this.value) { this.value = $scope.elemData.currentPage = 1; }
          if(this.value > $scope.elemData.numPages) { this.value = $scope.elemData.currentPage = $scope.elemData.numPages; }
        })
      },
      template: `

             Go to
              <input ng-enter="elemSend(elemData);" ng-model="elemData.currentPage" type="number" min="1" max="{{ elemData.numPages }}" class="form-control input-sm go-to">  page

      `
    };

}]);

app.directive('pagination',
  function () {

    return {
      restrict: 'E',
      scope: {
        elemData  : '=',
        elemSend  : '&'
      },
      link : function($scope, $element, $attrs) {
          // code will here as per future requirements....
      },
      template: `

      `
    };

});               <|endoftext|>


<commit_before>/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import axios from 'axios';
import qs from 'qs';
import { Message } from '@alifd/next';
import { browserHistory } from 'react-router';
import { isPlainObject } from './nacosutil';
// import { SUCCESS_RESULT_CODE } from '../constants';

const API_GENERAL_ERROR_MESSAGE = 'Request error, please try again later!';

function goLogin() {
  const url = window.location.href;
  localStorage.removeItem('token');
  const base_url = url.split('#')[0];
  window.location.href = `${base_url}#/login`;
}

const request = () => {
  const instance = axios.create();

  instance.interceptors.request.use(
    config => {
      const { url, params, data, method, headers } = config;
      if (!params) {
        config.params = {};
      }
      if (!url.includes('auth/users/login')) {
        let token = {};
        try {
          token = JSON.parse(localStorage.token);
        } catch (e) {
          console.log(e);
          goLogin();
        }
        const { accessToken = '', username = '' } = token;
        config.params.accessToken = accessToken;
        // support #3548 and fix #5835
        if (!url.includes('auth')) {
          config.params.username = username;
        }
        config.headers = Object.assign({}, headers, { accessToken });
      }
      if (data && isPlainObject(data) && ['post', 'put'].includes(method)) {
        config.data = qs.stringify(data);
        if (!headers) {
          config.headers = {};
        }
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
      }
      return config;
    },
    error => Promise.reject(error)
  );

  instance.interceptors.response.use(
    response => {
      const { success, resultCode, resultMessage = API_GENERAL_ERROR_MESSAGE } = response.data;
      // if (!success && resultCode !== SUCCESS_RESULT_CODE) {
      //   Message.error(resultMessage);
      //   return Promise.reject(new Error(resultMessage));
      // }
      return response.data;
    },
    error => {
      if (error.response) {
        const { data = {}, status } = error.response;
        let message = `HTTP ERROR: ${status}`;
        if (typeof data === 'string') {
          message = data;
        } else if (typeof data === 'object') {
          message = data.message;
        }
        Message.error(message);

        if (
          [401, 403].includes(status) &&
          ['unknown user!', 'token invalid!', 'token expired!'].includes(message)
        ) {
          goLogin();
        }
        return Promise.reject(error.response);
      }
      Message.error(API_GENERAL_ERROR_MESSAGE);
      return Promise.reject(error);
    }
  );

  return instance;
};

export default request();
<commit_msg>[ISSUE #8107] 403 go to home page when modify user's password (#8114)<commit_after>/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import axios from 'axios';
import qs from 'qs';
import { Message } from '@alifd/next';
import { browserHistory } from 'react-router';
import { isPlainObject } from './nacosutil';
// import { SUCCESS_RESULT_CODE } from '../constants';

const API_GENERAL_ERROR_MESSAGE = 'Request error, please try again later!';

function goLogin() {
  const url = window.location.href;
  localStorage.removeItem('token');
  const base_url = url.split('#')[0];
  window.location.href = `${base_url}#/login`;
}

const request = () => {
  const instance = axios.create();

  instance.interceptors.request.use(
    config => {
      const { url, params, data, method, headers } = config;
      if (!params) {
        config.params = {};
      }
      if (!url.includes('auth/users/login')) {
        let token = {};
        try {
          token = JSON.parse(localStorage.token);
        } catch (e) {
          console.log(e);
          goLogin();
        }
        const { accessToken = '', username = '' } = token;
        config.params.accessToken = accessToken;
        // support #3548 and fix #5835
        if (!url.includes('auth')) {
          config.params.username = username;
        }
        config.headers = Object.assign({}, headers, { accessToken });
      }
      if (data && isPlainObject(data) && ['post', 'put'].includes(method)) {
        config.data = qs.stringify(data);
        if (!headers) {
          config.headers = {};
        }
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
      }
      return config;
    },
    error => Promise.reject(error)
  );

  instance.interceptors.response.use(
    response => {
      const { success, resultCode, resultMessage = API_GENERAL_ERROR_MESSAGE } = response.data;
      // if (!success && resultCode !== SUCCESS_RESULT_CODE) {
      //   Message.error(resultMessage);
      //   return Promise.reject(new Error(resultMessage));
      // }
      return response.data;
    },
    error => {
      if (error.response) {
        const { data = {}, status } = error.response;
        let message = `HTTP ERROR: ${status}`;
        if (typeof data === 'string') {
          message = data;
        } else if (typeof data === 'object') {
          message = data.message;
        }
        Message.error(message);

        if (
          [401, 403].includes(status) &&
          ['unknown user!', 'token invalid!', 'token expired!', 'authorization failed!'].includes(
            message
          )
        ) {
          goLogin();
        }
        return Promise.reject(error.response);
      }
      Message.error(API_GENERAL_ERROR_MESSAGE);
      return Promise.reject(error);
    }
  );

  return instance;
};

export default request();
<|endoftext|>


<commit_before>Package.describe({
  summary: "Serves a Meteor app over HTTP",
  version: '1.8.0'
});

Npm.depends({"basic-auth-connect": "1.0.0",
             "cookie-parser": "1.4.3",
             connect: "3.6.5",
             compression: "1.7.1",
             errorhandler: "1.5.0",
             parseurl: "1.3.2",
             send: "0.16.1",
             "stream-to-string": "1.1.0",
             "qs": "6.4.0",
             useragent: "2.3.0"});

Npm.strip({
  multiparty: ["test/"],
  useragent: ["test/"]
});

Cordova.depends({
  'cordova-plugin-whitelist': '1.3.3',
  'cordova-plugin-wkwebview-engine': '1.1.4',
  'cordova-plugin-meteor-webapp': '1.7.1-beta.1'
});

Package.onUse(function (api) {
  api.use('ecmascript');
  api.use([
    'logging',
    'underscore',
    'routepolicy',
    'modern-browsers',
    'boilerplate-generator',
    'webapp-hashing',
    'inter-process-messaging',
  ], 'server');

  // At response serving time, webapp uses browser-policy if it is loaded. If
  // browser-policy is loaded, then it must be loaded after webapp
  // (browser-policy depends on webapp). So we don't explicitly depend in any
  // way on browser-policy here, but we use it when it is loaded, and it can be
  // loaded after webapp.
  api.mainModule('webapp_server.js', 'server');
  api.export('WebApp', 'server');
  api.export('WebAppInternals', 'server');
  api.export('main', 'server');

  api.mainModule('webapp_client.js', 'client');
  api.export('WebApp', 'client');

  api.mainModule('webapp_cordova.js', 'web.cordova');
});

Package.onTest(function (api) {
  api.use(['tinytest', 'ecmascript', 'webapp', 'http', 'underscore']);
  api.addFiles('webapp_tests.js', 'server');
  api.addFiles('webapp_client_tests.js', 'client');
  api.addFiles('socket_file_tests.js', 'server');

  api.addAssets('modern_test_asset.js', 'web.browser');
  api.addAssets('legacy_test_asset.js', 'legacy');
});
<commit_msg>Update cordova-plugin-whitelist to 1.3.4.<commit_after>Package.describe({
  summary: "Serves a Meteor app over HTTP",
  version: '1.8.0'
});

Npm.depends({"basic-auth-connect": "1.0.0",
             "cookie-parser": "1.4.3",
             connect: "3.6.5",
             compression: "1.7.1",
             errorhandler: "1.5.0",
             parseurl: "1.3.2",
             send: "0.16.1",
             "stream-to-string": "1.1.0",
             "qs": "6.4.0",
             useragent: "2.3.0"});

Npm.strip({
  multiparty: ["test/"],
  useragent: ["test/"]
});

Cordova.depends({
  'cordova-plugin-whitelist': '1.3.4',
  'cordova-plugin-wkwebview-engine': '1.1.4',
  'cordova-plugin-meteor-webapp': '1.7.1-beta.1'
});

Package.onUse(function (api) {
  api.use('ecmascript');
  api.use([
    'logging',
    'underscore',
    'routepolicy',
    'modern-browsers',
    'boilerplate-generator',
    'webapp-hashing',
    'inter-process-messaging',
  ], 'server');

  // At response serving time, webapp uses browser-policy if it is loaded. If
  // browser-policy is loaded, then it must be loaded after webapp
  // (browser-policy depends on webapp). So we don't explicitly depend in any
  // way on browser-policy here, but we use it when it is loaded, and it can be
  // loaded after webapp.
  api.mainModule('webapp_server.js', 'server');
  api.export('WebApp', 'server');
  api.export('WebAppInternals', 'server');
  api.export('main', 'server');

  api.mainModule('webapp_client.js', 'client');
  api.export('WebApp', 'client');

  api.mainModule('webapp_cordova.js', 'web.cordova');
});

Package.onTest(function (api) {
  api.use(['tinytest', 'ecmascript', 'webapp', 'http', 'underscore']);
  api.addFiles('webapp_tests.js', 'server');
  api.addFiles('webapp_client_tests.js', 'client');
  api.addFiles('socket_file_tests.js', 'server');

  api.addAssets('modern_test_asset.js', 'web.browser');
  api.addAssets('legacy_test_asset.js', 'legacy');
});
<|endoftext|>


<commit_before>/*
 * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at:
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */
 define(
  function(require) {
    const registerSuite = require('intern!object');
    const assert = require('intern/chai!assert');
    const ion = require('dist/amd/es6/Ion');

    var suite = {
      name: 'Text Reader'
    };

    suite['Read string value'] = function() {
      var ionToRead = "\"string\"";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ionReader.value(), "string");
    };

    suite['Read boolean value'] = function() {
      var ionToRead = "true";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ionReader.value(), true);
    };

    suite['Read boolean value in struct'] = function() {
      var ionToRead = "{ a: false }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();
      ionReader.stepIn();
      ionReader.next();

      assert.equal(ionReader.value(), false);
    };

      suite['resolves symbol IDs'] = function() {
          let ionToRead = `$ion_symbol_table::{ symbols:[ "rock", "paper", "scissors" ]}{ $5: $6, $10: $11, $12: 'taco' }`;
          let ionReader = ion.makeReader(ionToRead);
          ionReader.next();
          ionReader.stepIn();
          ionReader.next();
          assert.equal(ionReader.fieldName(), 'version');
          assert.equal(ionReader.value(), 'imports');
          ionReader.next();
          assert.equal(ionReader.fieldName(), "rock");
          assert.equal(ionReader.value(), "paper");
          ionReader.next();
          assert.equal(ionReader.fieldName(), "scissors");
          assert.equal(ionReader.value(), 'taco');
          ionReader.next();
          ionReader.stepOut();
          //assert.equal(ionReader.value(), false);
      };

    suite['Parse through struct'] = function() {
      var ionToRead = "{ key : \"string\" }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ion.IonTypes.STRUCT, ionReader.valueType());

      ionReader.stepIn(); // Step into the base struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "key");
      assert.equal(ionReader.value(), "string");
    };

    suite['Parse through struct can skip over container'] = function() {
      var ionToRead = "{ a: { key1 : \"string1\" }, b: { key2 : \"string2\" } }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ion.IonTypes.STRUCT, ionReader.valueType());

      ionReader.stepIn(); // Step into the base struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "a");

      ionReader.next();

      assert.equal(ionReader.fieldName(), "b");

      ionReader.stepIn(); // Step into the "b" struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "key2");
      assert.equal(ionReader.value(), "string2");
    };

    suite['Parse through struct can skip over nested containers'] = function() {
      var ionToRead = "{ outerkey1 : { innerkey1 : {a1: \"a1\", b1: \"b1\"} }, outerkey2 : { innerkey2 : {a2: \"a2\", b2: \"b2\"} } }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ion.IonTypes.STRUCT, ionReader.valueType());

      ionReader.stepIn(); // Step into the base struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "outerkey1");

      ionReader.next();

      assert.equal(ionReader.fieldName(), "outerkey2");

      ionReader.stepIn(); // Step into the "b" struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "innerkey2");
    };

      suite['Accept IVM like symbols and throw on IVMs except $ion_1_0'] = function() {
          let ionToRead = "$ion_1_0 $ion_schema_1_0";
          let ionReader = ion.makeReader(ionToRead);
          try {
              ionReader.next();
              ionReader.next();
          } catch(error) {
              throw new Error("Allowable IVM like symbol threw an error ");
          }
          ionToRead = "$ion_2_0";
          ionReader = ion.makeReader(ionToRead);
          try {
              ionReader.next();
          }catch(error) {
              ionToRead = "$ion_1_999";
              ionReader = ion.makeReader(ionToRead);
              try {
                  ionReader.next();
              } catch(error) {
                  ionToRead = "$ion_999_0";
                  ionReader = ion.makeReader(ionToRead);
                  try {
                      ionReader.next();
                  } catch(error) {
                      return true;
                  }
                  throw new Error("Unsupported IVM symbol did not throw an error ");
              }
              throw new Error("Unsupported IVM symbol did not throw an error ");
          }
          throw new Error("Unsupported IVM symbol did not throw an error ");
      };

    registerSuite(suite);
  }
);
<commit_msg>made error reporting in IVM unit test a bit clearer and added periods.<commit_after>/*
 * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at:
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */
 define(
  function(require) {
    const registerSuite = require('intern!object');
    const assert = require('intern/chai!assert');
    const ion = require('dist/amd/es6/Ion');

    var suite = {
      name: 'Text Reader'
    };

    suite['Read string value'] = function() {
      var ionToRead = "\"string\"";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ionReader.value(), "string");
    };

    suite['Read boolean value'] = function() {
      var ionToRead = "true";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ionReader.value(), true);
    };

    suite['Read boolean value in struct'] = function() {
      var ionToRead = "{ a: false }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();
      ionReader.stepIn();
      ionReader.next();

      assert.equal(ionReader.value(), false);
    };

      suite['resolves symbol IDs'] = function() {
          let ionToRead = `$ion_symbol_table::{ symbols:[ "rock", "paper", "scissors" ]}{ $5: $6, $10: $11, $12: 'taco' }`;
          let ionReader = ion.makeReader(ionToRead);
          ionReader.next();
          ionReader.stepIn();
          ionReader.next();
          assert.equal(ionReader.fieldName(), 'version');
          assert.equal(ionReader.value(), 'imports');
          ionReader.next();
          assert.equal(ionReader.fieldName(), "rock");
          assert.equal(ionReader.value(), "paper");
          ionReader.next();
          assert.equal(ionReader.fieldName(), "scissors");
          assert.equal(ionReader.value(), 'taco');
          ionReader.next();
          ionReader.stepOut();
          //assert.equal(ionReader.value(), false);
      };

    suite['Parse through struct'] = function() {
      var ionToRead = "{ key : \"string\" }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ion.IonTypes.STRUCT, ionReader.valueType());

      ionReader.stepIn(); // Step into the base struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "key");
      assert.equal(ionReader.value(), "string");
    };

    suite['Parse through struct can skip over container'] = function() {
      var ionToRead = "{ a: { key1 : \"string1\" }, b: { key2 : \"string2\" } }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ion.IonTypes.STRUCT, ionReader.valueType());

      ionReader.stepIn(); // Step into the base struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "a");

      ionReader.next();

      assert.equal(ionReader.fieldName(), "b");

      ionReader.stepIn(); // Step into the "b" struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "key2");
      assert.equal(ionReader.value(), "string2");
    };

    suite['Parse through struct can skip over nested containers'] = function() {
      var ionToRead = "{ outerkey1 : { innerkey1 : {a1: \"a1\", b1: \"b1\"} }, outerkey2 : { innerkey2 : {a2: \"a2\", b2: \"b2\"} } }";
      var ionReader = ion.makeReader(ionToRead);
      ionReader.next();

      assert.equal(ion.IonTypes.STRUCT, ionReader.valueType());

      ionReader.stepIn(); // Step into the base struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "outerkey1");

      ionReader.next();

      assert.equal(ionReader.fieldName(), "outerkey2");

      ionReader.stepIn(); // Step into the "b" struct.
      ionReader.next();

      assert.equal(ionReader.fieldName(), "innerkey2");
    };

      suite['Accept IVM like symbols and throw on IVMs except $ion_1_0'] = function() {
          let ionToRead = "$ion_1_0 $ion_schema_1_0";
          let ionReader = ion.makeReader(ionToRead);
          try {
              ionReader.next();
              ionReader.next();
          } catch(error) {
              throw new Error("Allowable IVM like symbol threw an error " + error);
          }
          ionToRead = "$ion_2_0";
          ionReader = ion.makeReader(ionToRead);
          try {
              ionReader.next();
          }catch(error) {
              ionToRead = "$ion_1_999";
              ionReader = ion.makeReader(ionToRead);
              try {
                  ionReader.next();
              } catch(error) {
                  ionToRead = "$ion_999_0";
                  ionReader = ion.makeReader(ionToRead);
                  try {
                      ionReader.next();
                  } catch(error) {
                      return true;
                  }
                  throw new Error("Unsupported IVM symbol did not throw an error.");
              }
              throw new Error("Unsupported IVM symbol did not throw an error.");
          }
          throw new Error("Unsupported IVM symbol did not throw an error.");
      };

    registerSuite(suite);
  }
);
<|endoftext|>


<commit_before>const Util = require('./Util.js');

module.exports = class UserRecord {
  constructor(arg) {
    if (arg) { // build from backup
      this.record = arg.record;
      this.thirty = arg.thirty;
      this.jp = arg.jp;
      this.en = arg.en;
      this.vc = arg.vc; // ? arg.vc : 0;
      this.chans = arg.chans;
      this.rxn = arg.rxn ? arg.rxn : {};
    } else { // build from scratch
      this.record = new Array(31); //31 days
      this.thirty = 0;
      this.jp = 0;
      this.en = 0;
      this.vc = 0;
      this.chans = {}; // {<channel ID>: # messages, <ID>: #}
      this.rxn = {};
    }
  }

  // channelID in string, today is an int between 0-30
  add(content, channelID, today) {
    this.thirty++;
    let lang = Util.lang(content, false);
    if (!this.record[today]) {
      this.record[today] = {};
      this.record[today][channelID] = 0;
    } else if (!this.record[today][channelID]) {
      this.record[today][channelID] = 0;
    }
    if (!this.chans[channelID]) {
      this.chans[channelID] = 0;
    }
    if (lang & Util.LANG.JPN) { // is Japanese
      if (!this.record[today]['jpn']) {
        this.record[today]['jpn'] = 0;
      }
      this.record[today]['jpn']++;
      this.jp++;
    } else if (lang & Util.LANG.ENG) {
      if (!this.record[today]['eng']) {
        this.record[today]['eng'] = 0;
      }
      this.record[today]['eng']++;
      this.en++;
    }
    this.chans[channelID]++;
    this.record[today][channelID]++;
  }

  addReacts(reaction, today) {
    if (!this.record[today]['rxn']) {
      this.record[today]['rxn'] = {};
    }
    if (!this.record[today]['rxn'][reaction]) {
      this.record[today]['rxn'][reaction] = 0;
    }
    this.record[today]['rxn'][reaction]++;
    if (this.rxn[reaction]) {
      this.rxn[reaction]++;
    } else {
      this.rxn[reaction] = 1;
    }
  }
  removeReacts(reaction, today) {
    if (!this.record[today]['rxn']) return;
    if (!this.record[today]['rxn'][reaction]) return;
    this.record[today]['rxn'][reaction]--;
    if (this.rxn[reaction]) {
      this.rxn[reaction]--;
    }
  }

  addVoiceTime(today, ms) {
    if (!this.record[today]) {
      this.record[today] = {};
    }
    if (!this.record[today]['vc']) {
      this.record[today]['vc'] = 0;
    }
    let min = Math.round(ms / 60000);
    this.record[today]['vc'] += min;
    this.vc += min;
  }

  totalStats() {
    return this.thirty;
  }

  voiceTime() {
    return this.vc;
  }

  totalReactions() {
    return this.rxn;
  }

  channelStats(channelID) {
    let result = this.chans[channelID];
    return result ? result : 0;
  }

  // Cleans up the old messages.
  // Returns true if this user hasn't spoken in the last 30 days.
  adjust(today) {
    let earliestDay = (today) % 31; // (today - 1) % 30?
    for (var chan in this.record[earliestDay]) {
      if (chan == 'jpn') {
        this.jp -= this.record[earliestDay]['jpn'];
        delete this.record[earliestDay]['jpn'];
        continue;
      }
      if (chan == 'eng') {
        this.en -= this.record[earliestDay]['eng'];
        delete this.record[earliestDay]['eng'];
        continue;
      }
      if (chan == 'rxn') { // reactions
        let reactions = this.record[earliestDay]['rxn'];
        for (let r in reactions) {
          this.rxn[r] -= reactions[r];
          if (this.rxn[r] <= 0) delete this.rxn[r];
        }
        delete this.record[earliestDay]['rxn'];
        continue;
      }
      if (chan == 'vc') { // voice
        this.vc -= this.record[earliestDay]['vc'];
        delete this.record[earliestDay]['vc'];
        continue;
      }
      let num = this.record[earliestDay][chan];
      this.chans[chan] -= num;
      if (this.chans[chan] <= 0) {
        delete this.chans[chan]; // if the user hasn't spoken in this channel
      }
      this.thirty -= num;
      delete this.record[earliestDay][chan];

    }
    //this.record[earliestDay] == {};
    return this.thirty <= 0 && this.vc <= 0;
  }
};
<commit_msg>fix addReact<commit_after>const Util = require('./Util.js');

module.exports = class UserRecord {
  constructor(arg) {
    if (arg) { // build from backup
      this.record = arg.record;
      this.thirty = arg.thirty;
      this.jp = arg.jp;
      this.en = arg.en;
      this.vc = arg.vc; // ? arg.vc : 0;
      this.chans = arg.chans;
      this.rxn = arg.rxn ? arg.rxn : {};
    } else { // build from scratch
      this.record = new Array(31); //31 days
      this.thirty = 0;
      this.jp = 0;
      this.en = 0;
      this.vc = 0;
      this.chans = {}; // {<channel ID>: # messages, <ID>: #}
      this.rxn = {};
    }
  }

  // channelID in string, today is an int between 0-30
  add(content, channelID, today) {
    this.thirty++;
    let lang = Util.lang(content, false);
    if (!this.record[today]) {
      this.record[today] = {};
      this.record[today][channelID] = 0;
    } else if (!this.record[today][channelID]) {
      this.record[today][channelID] = 0;
    }
    if (!this.chans[channelID]) {
      this.chans[channelID] = 0;
    }
    if (lang & Util.LANG.JPN) { // is Japanese
      if (!this.record[today]['jpn']) {
        this.record[today]['jpn'] = 0;
      }
      this.record[today]['jpn']++;
      this.jp++;
    } else if (lang & Util.LANG.ENG) {
      if (!this.record[today]['eng']) {
        this.record[today]['eng'] = 0;
      }
      this.record[today]['eng']++;
      this.en++;
    }
    this.chans[channelID]++;
    this.record[today][channelID]++;
  }

  addReacts(reaction, today) {
    if (!this.record[today]) {
      this.record[today] = {};
      this.record[today]['rxn'] = {};
    } else if (!this.record[today]['rxn']) {
      this.record[today]['rxn'] = {};
    }
    if (!this.record[today]['rxn'][reaction]) {
      this.record[today]['rxn'][reaction] = 0;
    }
    this.record[today]['rxn'][reaction]++;
    if (this.rxn[reaction]) {
      this.rxn[reaction]++;
    } else {
      this.rxn[reaction] = 1;
    }
  }
  removeReacts(reaction, today) {
    if (!this.record[today] || !this.record[today]['rxn']) return;
    if (!this.record[today]['rxn'][reaction]) return;
    this.record[today]['rxn'][reaction]--;
    if (this.rxn[reaction]) {
      this.rxn[reaction]--;
    }
  }

  addVoiceTime(today, ms) {
    if (!this.record[today]) {
      this.record[today] = {};
    }
    if (!this.record[today]['vc']) {
      this.record[today]['vc'] = 0;
    }
    let min = Math.round(ms / 60000);
    this.record[today]['vc'] += min;
    this.vc += min;
  }

  totalStats() {
    return this.thirty;
  }

  voiceTime() {
    return this.vc;
  }

  totalReactions() {
    return this.rxn;
  }

  channelStats(channelID) {
    let result = this.chans[channelID];
    return result ? result : 0;
  }

  // Cleans up the old messages.
  // Returns true if this user hasn't spoken in the last 30 days.
  adjust(today) {
    let earliestDay = (today) % 31; // (today - 1) % 30?
    for (var chan in this.record[earliestDay]) {
      if (chan == 'jpn') {
        this.jp -= this.record[earliestDay]['jpn'];
        delete this.record[earliestDay]['jpn'];
        continue;
      }
      if (chan == 'eng') {
        this.en -= this.record[earliestDay]['eng'];
        delete this.record[earliestDay]['eng'];
        continue;
      }
      if (chan == 'rxn') { // reactions
        let reactions = this.record[earliestDay]['rxn'];
        for (let r in reactions) {
          this.rxn[r] -= reactions[r];
          if (this.rxn[r] <= 0) delete this.rxn[r];
        }
        delete this.record[earliestDay]['rxn'];
        continue;
      }
      if (chan == 'vc') { // voice
        this.vc -= this.record[earliestDay]['vc'];
        delete this.record[earliestDay]['vc'];
        continue;
      }
      let num = this.record[earliestDay][chan];
      this.chans[chan] -= num;
      if (this.chans[chan] <= 0) {
        delete this.chans[chan]; // if the user hasn't spoken in this channel
      }
      this.thirty -= num;
      delete this.record[earliestDay][chan];

    }
    //this.record[earliestDay] == {};
    return this.thirty <= 0 && this.vc <= 0;
  }
};
<|endoftext|>


<commit_before>import SpellChecker from 'spellchecker';
import path from 'path';
import fs from 'fs';

import platform from './platform';
import languageCodes from './language-codes';
import files from './files';

let hunspellDictionaries = null;

export function getDictionaryPath() {
  let dict = path.join(__dirname, '..', 'node_modules', 'spellchecker', 'vendor', 'hunspell_dictionaries');
  try {
    if (platform.isLinux) {
      let usrDict = path.join('/usr', 'share', 'hunspell');
      if (fs.statSyncNoException(usrDict)) {
        dict = usrDict;
      }
    }

    // HACK: Special case being in an asar archive
    const unpacked = dict.replace('.asar' + path.sep, '.asar.unpacked' + path.sep);
    if (fs.statSyncNoException(unpacked)) {
      dict = unpacked;
    }
  } catch (ex) {
    // ignore
  }
  return dict;
}

export function getAvailableDictionaries() {
  let availableDictionaries = SpellChecker.getAvailableDictionaries();
  if (availableDictionaries.length) {
    return availableDictionaries;
  }

  if (!hunspellDictionaries) {
    try {
      hunspellDictionaries = files.getDictionariesSync(getDictionaryPath());
    } catch (err) {
      logError(err);
    }
  }

  hunspellDictionaries = hunspellDictionaries || [];
  hunspellDictionaries = hunspellDictionaries.filter(dict => {
    return languageCodes[dict] || languageCodes[dict.replace('-', '_').split('_')[0]];
  });

  log('filtered dictionaries:', hunspellDictionaries);
  return hunspellDictionaries;
}
<commit_msg>Use default dictionaries if hunspell is not installed (Linux)<commit_after>import SpellChecker from 'spellchecker';
import path from 'path';
import fs from 'fs';

import platform from './platform';
import languageCodes from './language-codes';
import files from './files';

let hunspellDictionaries = null;

export function getDictionaryDefaultPath() {
  let dict = path.join(__dirname, '..', 'node_modules', 'spellchecker', 'vendor', 'hunspell_dictionaries');
  try {
    // HACK: Special case being in an asar archive
    const unpacked = dict.replace('.asar' + path.sep, '.asar.unpacked' + path.sep);
    if (fs.statSyncNoException(unpacked)) {
      dict = unpacked;
    }
  } catch (ex) {
    // ignore
  }
  return dict;
}

export function getDictionaryPath() {
  let dict = path.join(__dirname, '..', 'node_modules', 'spellchecker', 'vendor', 'hunspell_dictionaries');
  try {
    if (platform.isLinux) {
      let usrDict = path.join('/usr', 'share', 'hunspell');
      if (fs.statSyncNoException(usrDict)) {
        dict = usrDict;
      }
    }

    // HACK: Special case being in an asar archive
    const unpacked = dict.replace('.asar' + path.sep, '.asar.unpacked' + path.sep);
    if (fs.statSyncNoException(unpacked)) {
      dict = unpacked;
    }
  } catch (ex) {
    // ignore
  }
  return dict;
}

export function getAvailableDictionaries() {
  let availableDictionaries = SpellChecker.getAvailableDictionaries();
  if (availableDictionaries.length) {
    return availableDictionaries;
  }

  const dictionariesPath = getDictionaryPath();
  if (!hunspellDictionaries) {
    try {
      hunspellDictionaries = files.getDictionariesSync(dictionariesPath);
    } catch (err) {
      logError(err);
    }
  }

  if (platform.isLinux && (!hunspellDictionaries || hunspellDictionaries.length == 0)) {
    const dictionariesDefaultPath = getDictionaryDefaultPath();
    if (dictionariesDefaultPath != dictionariesPath) {
      try {
        hunspellDictionaries = files.getDictionariesSync(getDictionaryDefaultPath());
      } catch (err) {
        logError(err);
      }
    }
  }

  hunspellDictionaries = hunspellDictionaries || [];
  hunspellDictionaries = hunspellDictionaries.filter(dict => {
    return languageCodes[dict] || languageCodes[dict.replace('-', '_').split('_')[0]];
  });

  log('filtered dictionaries:', hunspellDictionaries);
  return hunspellDictionaries;
}
<|endoftext|>


<commit_before>const ExtractTextPlugin = require('extract-text-webpack-plugin')

const isProd = process.env.NODE_ENV === 'production'

module.exports = {
  loaders: {
    stylus: ExtractTextPlugin.extract({
      use: 'css-loader!stylus-loader',
      fallback: 'vue-style-loader'
    })
  },
  preserveWhitespace: false,
  postcss: [
    require('autoprefixer')({
      browsers: ['last 3 versions']
    })
  ]
}
<commit_msg>remove unnecessary isProd<commit_after>const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
  loaders: {
    stylus: ExtractTextPlugin.extract({
      use: 'css-loader!stylus-loader',
      fallback: 'vue-style-loader'
    })
  },
  preserveWhitespace: false,
  postcss: [
    require('autoprefixer')({
      browsers: ['last 3 versions']
    })
  ]
}
<|endoftext|>