<commit_before>var path = require('path');
var cache = [];
var config = { cache: cache };

// Resources
cache.push({ file: path.join(__dirname, '/resources/sap-ui-core.js'), path: '/resources/sap-ui-core.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/thirdparty/jquery-mobile-custom.js'), path: '/resources/sap/ui/thirdparty/jquery-mobile-custom.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/library.js'), path: '/resources/sap/ui/core/library.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/themes/sap_bluecrystal/library.css'), path: '/resources/sap/ui/core/themes/sap_bluecrystal/library.css' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/library.js'), path: '/resources/sap/m/library.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Support.js'), path: '/resources/sap/m/Support.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/themes/sap_bluecrystal/library.css'), path: '/resources/sap/m/themes/sap_bluecrystal/library.css' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/App.js'), path: '/resources/sap/m/App.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/NavContainer.js'), path: '/resources/sap/m/NavContainer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/PopupSupport.js'), path: '/resources/sap/ui/core/PopupSupport.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/View.js'), path: '/resources/sap/ui/core/mvc/View.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/ExtensionPoint.js'), path: '/resources/sap/ui/core/ExtensionPoint.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/XMLView.js'), path: '/resources/sap/ui/core/mvc/XMLView.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/XMLTemplateProcessor.js'), path: '/resources/sap/ui/core/XMLTemplateProcessor.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/resource/ResourceModel.js'), path: '/resources/sap/ui/model/resource/ResourceModel.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/resource/ResourcePropertyBinding.js'), path: '/resources/sap/ui/model/resource/ResourcePropertyBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/jquery.sap.xml.js'), path: '/resources/jquery.sap.xml.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Renderer.js'), path: '/resources/sap/ui/core/Renderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/Controller.js'), path: '/resources/sap/ui/core/mvc/Controller.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Page.js'), path: '/resources/sap/m/Page.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabBar.js'), path: '/resources/sap/m/IconTabBar.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabFilter.js'), path: '/resources/sap/m/IconTabFilter.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Item.js'), path: '/resources/sap/ui/core/Item.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Panel.js'), path: '/resources/sap/m/Panel.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/IconPool.js'), path: '/resources/sap/ui/core/IconPool.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/CustomData.js'), path: '/resources/sap/ui/core/CustomData.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Input.js'), path: '/resources/sap/m/Input.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Bar.js'), path: '/resources/sap/m/Bar.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/BarInPageEnabler.js'), path: '/resources/sap/m/BarInPageEnabler.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Dialog.js'), path: '/resources/sap/m/Dialog.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/InstanceManager.js'), path: '/resources/sap/m/InstanceManager.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Toolbar.js'), path: '/resources/sap/m/Toolbar.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ToolbarLayoutData.js'), path: '/resources/sap/m/ToolbarLayoutData.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/LayoutData.js'), path: '/resources/sap/ui/core/LayoutData.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ToolbarSpacer.js'), path: '/resources/sap/m/ToolbarSpacer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/EnabledPropagator.js'), path: '/resources/sap/ui/core/EnabledPropagator.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Popup.js'), path: '/resources/sap/ui/core/Popup.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/IntervalTrigger.js'), path: '/resources/sap/ui/core/IntervalTrigger.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/EventBus.js'), path: '/resources/sap/ui/core/EventBus.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/delegate/ScrollEnablement.js'), path: '/resources/sap/ui/core/delegate/ScrollEnablement.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/theming/Parameters.js'), path: '/resources/sap/ui/core/theming/Parameters.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/InputBase.js'), path: '/resources/sap/m/InputBase.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/List.js'), path: '/resources/sap/m/List.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListBase.js'), path: '/resources/sap/m/ListBase.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/GroupHeaderListItem.js'), path: '/resources/sap/m/GroupHeaderListItem.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListItemBase.js'), path: '/resources/sap/m/ListItemBase.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/delegate/ItemNavigation.js'), path: '/resources/sap/ui/core/delegate/ItemNavigation.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Popover.js'), path: '/resources/sap/m/Popover.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Button.js'), path: '/resources/sap/m/Button.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/StandardListItem.js'), path: '/resources/sap/m/StandardListItem.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Table.js'), path: '/resources/sap/m/Table.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/messagebundle_en.properties'), path: '/resources/sap/m/messagebundle_en.properties' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/InvisibleText.js'), path: '/resources/sap/ui/core/InvisibleText.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/SegmentedButton.js'), path: '/resources/sap/m/SegmentedButton.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabHeader.js'), path: '/resources/sap/m/IconTabHeader.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Label.js'), path: '/resources/sap/m/Label.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONModel.js'), path: '/resources/sap/ui/model/json/JSONModel.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONListBinding.js'), path: '/resources/sap/ui/model/json/JSONListBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONPropertyBinding.js'), path: '/resources/sap/ui/model/json/JSONPropertyBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONTreeBinding.js'), path: '/resources/sap/ui/model/json/JSONTreeBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/AppRenderer.js'), path: '/resources/sap/m/AppRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/NavContainerRenderer.js'), path: '/resources/sap/m/NavContainerRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/XMLViewRenderer.js'), path: '/resources/sap/ui/core/mvc/XMLViewRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/ViewRenderer.js'), path: '/resources/sap/ui/core/mvc/ViewRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/PageRenderer.js'), path: '/resources/sap/m/PageRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/BarRenderer.js'), path: '/resources/sap/m/BarRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ButtonRenderer.js'), path: '/resources/sap/m/ButtonRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Icon.js'), path: '/resources/sap/ui/core/Icon.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/IconRenderer.js'), path: '/resources/sap/ui/core/IconRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/LabelRenderer.js'), path: '/resources/sap/m/LabelRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabBarRenderer.js'), path: '/resources/sap/m/IconTabBarRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabHeaderRenderer.js'), path: '/resources/sap/m/IconTabHeaderRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListRenderer.js'), path: '/resources/sap/m/ListRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListBaseRenderer.js'), path: '/resources/sap/m/ListBaseRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/themes/base/fonts/SAP-icons.ttf'), path: '/resources/sap/ui/core/themes/base/fonts/SAP-icons.ttf' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/StandardListItemRenderer.js'), path: '/resources/sap/m/StandardListItemRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListItemBaseRenderer.js'), path: '/resources/sap/m/ListItemBaseRenderer.js' });

// Public
cache.push({ dir: path.join(__dirname, '/public/'), prefix: '/public/' });

module.exports = config;<commit_msg>Update cache manifest via cache.js<commit_after>var path = require('path');
var cache = [];
var config = { cache: cache };

// Resources
cache.push({ file: path.join(__dirname, '/resources/sap-ui-core.js'), path: '/resources/sap-ui-core.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/thirdparty/jquery-mobile-custom.js'), path: '/resources/sap/ui/thirdparty/jquery-mobile-custom.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/library.js'), path: '/resources/sap/ui/core/library.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/themes/sap_bluecrystal/library.css'), path: '/resources/sap/ui/core/themes/sap_bluecrystal/library.css' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/library.js'), path: '/resources/sap/m/library.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Support.js'), path: '/resources/sap/m/Support.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/themes/sap_bluecrystal/library.css'), path: '/resources/sap/m/themes/sap_bluecrystal/library.css' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/App.js'), path: '/resources/sap/m/App.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/NavContainer.js'), path: '/resources/sap/m/NavContainer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/PopupSupport.js'), path: '/resources/sap/ui/core/PopupSupport.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/View.js'), path: '/resources/sap/ui/core/mvc/View.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/ExtensionPoint.js'), path: '/resources/sap/ui/core/ExtensionPoint.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/XMLView.js'), path: '/resources/sap/ui/core/mvc/XMLView.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/XMLTemplateProcessor.js'), path: '/resources/sap/ui/core/XMLTemplateProcessor.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/resource/ResourceModel.js'), path: '/resources/sap/ui/model/resource/ResourceModel.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/resource/ResourcePropertyBinding.js'), path: '/resources/sap/ui/model/resource/ResourcePropertyBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/jquery.sap.xml.js'), path: '/resources/jquery.sap.xml.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Renderer.js'), path: '/resources/sap/ui/core/Renderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/Controller.js'), path: '/resources/sap/ui/core/mvc/Controller.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Page.js'), path: '/resources/sap/m/Page.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabBar.js'), path: '/resources/sap/m/IconTabBar.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabFilter.js'), path: '/resources/sap/m/IconTabFilter.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Item.js'), path: '/resources/sap/ui/core/Item.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Panel.js'), path: '/resources/sap/m/Panel.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/IconPool.js'), path: '/resources/sap/ui/core/IconPool.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/CustomData.js'), path: '/resources/sap/ui/core/CustomData.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Input.js'), path: '/resources/sap/m/Input.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Bar.js'), path: '/resources/sap/m/Bar.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/BarInPageEnabler.js'), path: '/resources/sap/m/BarInPageEnabler.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Dialog.js'), path: '/resources/sap/m/Dialog.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/InstanceManager.js'), path: '/resources/sap/m/InstanceManager.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Toolbar.js'), path: '/resources/sap/m/Toolbar.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ToolbarLayoutData.js'), path: '/resources/sap/m/ToolbarLayoutData.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/LayoutData.js'), path: '/resources/sap/ui/core/LayoutData.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ToolbarSpacer.js'), path: '/resources/sap/m/ToolbarSpacer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/EnabledPropagator.js'), path: '/resources/sap/ui/core/EnabledPropagator.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Popup.js'), path: '/resources/sap/ui/core/Popup.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/IntervalTrigger.js'), path: '/resources/sap/ui/core/IntervalTrigger.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/EventBus.js'), path: '/resources/sap/ui/core/EventBus.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/delegate/ScrollEnablement.js'), path: '/resources/sap/ui/core/delegate/ScrollEnablement.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/theming/Parameters.js'), path: '/resources/sap/ui/core/theming/Parameters.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/InputBase.js'), path: '/resources/sap/m/InputBase.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/List.js'), path: '/resources/sap/m/List.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListBase.js'), path: '/resources/sap/m/ListBase.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/GroupHeaderListItem.js'), path: '/resources/sap/m/GroupHeaderListItem.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListItemBase.js'), path: '/resources/sap/m/ListItemBase.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/delegate/ItemNavigation.js'), path: '/resources/sap/ui/core/delegate/ItemNavigation.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Popover.js'), path: '/resources/sap/m/Popover.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Button.js'), path: '/resources/sap/m/Button.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/StandardListItem.js'), path: '/resources/sap/m/StandardListItem.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Table.js'), path: '/resources/sap/m/Table.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/messagebundle_en.properties'), path: '/resources/sap/m/messagebundle_en.properties' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/InvisibleText.js'), path: '/resources/sap/ui/core/InvisibleText.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/SegmentedButton.js'), path: '/resources/sap/m/SegmentedButton.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabHeader.js'), path: '/resources/sap/m/IconTabHeader.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/Label.js'), path: '/resources/sap/m/Label.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONModel.js'), path: '/resources/sap/ui/model/json/JSONModel.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONListBinding.js'), path: '/resources/sap/ui/model/json/JSONListBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONPropertyBinding.js'), path: '/resources/sap/ui/model/json/JSONPropertyBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/model/json/JSONTreeBinding.js'), path: '/resources/sap/ui/model/json/JSONTreeBinding.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/AppRenderer.js'), path: '/resources/sap/m/AppRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/NavContainerRenderer.js'), path: '/resources/sap/m/NavContainerRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/XMLViewRenderer.js'), path: '/resources/sap/ui/core/mvc/XMLViewRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/mvc/ViewRenderer.js'), path: '/resources/sap/ui/core/mvc/ViewRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/PageRenderer.js'), path: '/resources/sap/m/PageRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/BarRenderer.js'), path: '/resources/sap/m/BarRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ButtonRenderer.js'), path: '/resources/sap/m/ButtonRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/Icon.js'), path: '/resources/sap/ui/core/Icon.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/IconRenderer.js'), path: '/resources/sap/ui/core/IconRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/LabelRenderer.js'), path: '/resources/sap/m/LabelRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabBarRenderer.js'), path: '/resources/sap/m/IconTabBarRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/IconTabHeaderRenderer.js'), path: '/resources/sap/m/IconTabHeaderRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListRenderer.js'), path: '/resources/sap/m/ListRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListBaseRenderer.js'), path: '/resources/sap/m/ListBaseRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/themes/base/fonts/SAP-icons.ttf'), path: '/resources/sap/ui/core/themes/base/fonts/SAP-icons.ttf' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/StandardListItemRenderer.js'), path: '/resources/sap/m/StandardListItemRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/ListItemBaseRenderer.js'), path: '/resources/sap/m/ListItemBaseRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/PanelRenderer.js'), path: '/resources/sap/m/PanelRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/SegmentedButtonRenderer.js'), path: '/resources/sap/m/SegmentedButtonRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/InputRenderer.js'), path: '/resources/sap/m/InputRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/m/InputBaseRenderer.js'), path: '/resources/sap/m/InputBaseRenderer.js' });
cache.push({ file: path.join(__dirname, '/resources/sap/ui/core/ValueStateSupport.js'), path: '/resources/sap/ui/core/ValueStateSupport.js' });

// Public
cache.push({ dir: path.join(__dirname, '/public/'), prefix: '/public/' });

module.exports = config;<|endoftext|>


<commit_before>var ws = require("nodejs-websocket");
var os = require('os');

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function buildMessage(type, object) {
    var message = {};
    message.type = type;
    message.data = object;
    return JSON.stringify(message)
}

function safeAdd(array, eles) {
    if (typeof eles === "number") {
        if (array.indexOf(eles) < 0) {
            array.push(eles);
        }
    } else {
        eles.forEach(function (ele) {
            if (array.indexOf(ele) < 0) {
                array.push(ele);
            }
        });
    }
}

var server = ws.createServer(function (conn) {
    var code = getRandomInt(100000, 999999);
    conn.sendText(buildMessage("new", code));
    conn.code = code;
    conn.nodes = [];
    conn.on("text", function (str) {
        console.log(str);
        var message = JSON.parse(str);
        if ("conn" === message.type) {
            for (var index in server.connections) {
                var connection = server.connections[index];
                if (message.data == connection.code) {
                    safeAdd(connection.nodes, code);
                    safeAdd(conn.nodes, connection.code);
                    safeAdd(conn.nodes, connection.nodes);
                    // remove self
                    conn.nodes.splice(conn.nodes.indexOf(code), 1);
                    conn.sendText(buildMessage("status", {"action": "conn", "code": 200}));
                    connection.sendText(buildMessage("push", ""));
                    break;
                }
            }
        } else if ("pull" === message.type || "play" === message.type) {
            console.log("conn code: " + conn.code + ", nodes: " + conn.nodes);
            var nodes = conn.nodes;
            server.connections.forEach(function (connection) {
                for (var index in nodes) {
                    if (nodes[index] == connection.code) {
                        connection.sendText(str)
                    }
                }
            })
        }
    });
    conn.on("close", function (code, reason) {
        console.log("Connection closed")
    });
    conn.on("error", function (error) {
        console.log("Connection has error, it will be closed. The reason maybe browser has refresh, details:");
        console.error(error);
    })
}).listen(8001);

var interfaces = os.networkInterfaces();
var addresses = [];
for (var k in interfaces) {
    for (var k2 in interfaces[k]) {
        var address = interfaces[k][k2];
        if (address.family === 'IPv4' && !address.internal) {
            addresses.push(address.address);
        }
    }
}

console.log("Server running 8001");
console.log("Air play path: ws://" + addresses[0] + ":8001");<commit_msg>Refactor join group<commit_after>var ws = require("nodejs-websocket");
var os = require('os');

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function buildMessage(type, object) {
    var message = {};
    message.type = type;
    message.data = object;
    return JSON.stringify(message)
}

function safeAdd(array, eles) {
    if (typeof eles === "number") {
        if (array.indexOf(eles) < 0) {
            array.push(eles);
        }
    } else {
        eles.forEach(function (ele) {
            if (array.indexOf(ele) < 0) {
                array.push(ele);
            }
        });
    }
}

var server = ws.createServer(function (conn) {
    var code = getRandomInt(100000, 999999);
    conn.sendText(buildMessage("new", code));
    conn.code = code;
    conn.nodes = [];
    conn.master = null;
    conn.on("text", function (str) {
        console.log(str);
        var message = JSON.parse(str);
        if ("conn" === message.type) {
            for (var index in server.connections) {
                var connection = server.connections[index];
                if (message.data == connection.code) {
                    conn.master = connection;
                    safeAdd(connection.nodes, conn.code);
                    conn.sendText(buildMessage("status", {"action": "conn", "code": 200}));
                    connection.sendText(buildMessage("push", ""));
                    break;
                }
            }

        } else if ("pull" === message.type || "play" === message.type) {
            var nodes = [];
            if (conn.master != null) {
                safeAdd(nodes, conn.master.code);
                safeAdd(nodes, conn.master.nodes);
                nodes.splice(nodes.indexOf(conn.code), 1);
            } else {
                safeAdd(nodes, conn.nodes);
            }
            console.log("conn code: " + conn.code + ", nodes: " + nodes);
            server.connections.forEach(function (connection) {
                for (var index in nodes) {
                    if (nodes[index] == connection.code) {
                        connection.sendText(str)
                    }
                }
            })
        }
    });
    conn.on("close", function (code, reason) {
        console.log("Connection closed")
    });
    conn.on("error", function (error) {
        console.log("Connection has error, it will be closed. The reason maybe browser has refresh, details:");
        console.error(error);
    })
}).listen(8001);

var interfaces = os.networkInterfaces();
var addresses = [];
for (var k in interfaces) {
    for (var k2 in interfaces[k]) {
        var address = interfaces[k][k2];
        if (address.family === 'IPv4' && !address.internal) {
            addresses.push(address.address);
        }
    }
}

console.log("Server running 8001");
console.log("Air play path: ws://" + addresses[0] + ":8001");<|endoftext|>


<commit_before>'use strict';

function setStorage(keys, val) {
  if (typeof Storage === "undefined") {
    return;
  }

  if (keys.length == 1) {
    localStorage[keys[0]] = val;
    return;
  }

  var obj = {};
  var curr = obj;
  for (var i=1, len=keys.length; i<len-1; i++) {
    curr = curr[keys[i]] = {};
  }
  curr[keys[keys.length-1]] = val;

  localStorage[keys[0]] = JSON.stringify(obj);
}

function getStorage(keys) {
  if (typeof Storage === "undefined") {
    return undefined;
  }

  var str = localStorage[keys[0]];
  if (str == null) {
    return undefined;
  }
  var obj = JSON.parse(str);
  var curr = obj;
  for (var i=1, len=keys.length; i<len; i++) {
    curr = curr[keys[i]];
  }
  return curr;
}

function CodeCtrl($scope, $http, $location, $timeout) {
  $scope.mirror = CodeMirror.fromTextArea($('#codetext')[0], {
    mode: 'python',
    lineNumbers: true,
    theme: 'neat',
    indentUnit: 2,
    extraKeys: {
      'Tab': 'indentMore',
      'Shift-Enter': false,
    },
  });

  $(document).keydown(function(event) {
    var e = window.event || event;
    if (e.keyCode == 13 && e.shiftKey) {  // shift-enter
      $scope.runCode($scope.code());
    } else if (e.keyCode == 33) {  // page up
      $scope.location.path("/" + $scope.prevChapter());
      $scope.$apply();
      return false;
    } else if (e.keyCode == 34) {  // page down
      $scope.location.path("/" + $scope.nextChapter());
      $scope.$apply();
      return false;
    }
  });

  $scope.showDiffIfDirty = function() {
    if ($scope.dirty()) {
      $scope.showDiff();
    }
  };

  $scope.doDiff = function(left, right) {
    var target = $('#diffview')[0];
    target.innerHTML = '';
    var mv = CodeMirror.MergeView(target, {
      orig: right,
      value: left,
      mode: 'python',
      lineNumbers: true,
      highlightDifferences: true,
      connect: null,
    });
  };

  $scope.showDiff = function() {
    var cw = $('#workspace_top')[0];
    // Set the width to be the min of twice the code window width and the screen width:
    var w = Math.min(cw.clientWidth * 2, screen.width);
    var h = cw.clientHeight;

    var w = window.open('#/diff/' + $scope.chapter, "DiffWin-" + $scope.chapter, "width=" + w + ",height=" + h);
    w.focus();
  };

  $scope.code = function(code) {
    if (code === undefined) {
      return $scope.mirror.getValue();
    }
    $scope.mirror.setValue(code);
  };

  $scope.location = $location;

  // This naively assumes that the dirty state is "sticky" unless you force a
  // full recomputation. Works for most purposes in the UI.
  $scope._dirty = false;
  $scope.dirty = function(force_recompute) {
    if (force_recompute || !$scope._dirty) {
      $scope._dirty = ($scope.tutorial != undefined &&
                       $scope.code() != $scope.tutorial.code);
    }
    return $scope._dirty;
  };

  $scope.storageKey = function() {
    return "pytut-" + $scope.tutorial.name;
  };

  $scope.saveCode = function() {
    if ($scope.tutorial === undefined) {
      return;
    }
    if ($scope.inDiff) {
      return;
    }
    var dirty = $scope.dirty(true);

    // Save to the internal JS cache first.
    $scope.tutorial.userCode = (dirty) ? $scope.code() : undefined;

    // Also save to HTML5 local storage if possible.
    // This protects users against refresh and browser crashes.
    if (typeof(Storage) != "undefined") {
      if ($scope.tutorial.userCode === undefined) {
        localStorage.removeItem($scope.storageKey());
      } else {
        localStorage[$scope.storageKey()] = JSON.stringify({
          time_ms: +new Date(),
          user_code: $scope.tutorial.userCode,
        });
      }
    }
  };

  $scope.loadCode = function() {
    if ($scope.tutorial === undefined) {
      return;
    }

    // Get from localStorage if possible.
    if (typeof(Storage) != "undefined") {
      var val = localStorage[$scope.storageKey()];
      if (val !== undefined) {
        // TODO: Age out old things?
        $scope.tutorial.userCode = JSON.parse(val).user_code;
      }
    }
    // If there is data in userCode now, then we display that. Otherwise we get
    // the tutorial code and display that.
    if ($scope.tutorial.userCode !== undefined) {
      $scope.code($scope.tutorial.userCode);
    } else {
      $scope.code($scope.tutorial.code);
    }
    $scope.dirty(true);  // Force dirty bit recomputation.
  };
  // TOC should be off when we start.
  $scope.tocShowing = false;

  function parseTutorial(text) {
    var lines = text.split(/\r\n|\n|\r/);
    // If the file starts with comments right at the beginning, strip them off
    // (typically directives to editors).
    var cur = 0;
    for (; cur<lines.length; cur++) {
      if (lines[cur].trim() && lines[cur].search(/^\s*#.*$/) < 0) {
        break;
      }
    }
    // Remaining text is treated as a whole.
    text = lines.slice(cur).join('\n');
    var groups = text.match(/\s*"""([^]*?)\n\s*([^]*?)"""\s+([^]*)$/m)
    if (!groups) {
      return {title: "", description: "", code: ""};
    }

    return {
      title: groups[1].replace(/\\(["'])/g, '$1'),
      description: groups[2].replace(/\\(["'])/g, '$1'),
      code: groups[3].replace(/^(\s*)__doc__\s*=\s*/, '$1'),
    };
  }

  (function() {
    $scope.tutorials = [];
    $scope._preamble = '';
    var divs = $('#chapter-contents div');
    var index = 0;
    for (var i=0, l=divs.length; i<l; i++) {
      var d = $(divs[i]);
      var name = d.attr('name');
      // Discard empty starting lines (one belongs to the end of the tag).
      var text = d.text().replace(/^\s*\n/m, '');
      // Find the indentation of the first line.
      var indent = text.match(/^(\s*)/)[1];
      // Remove indentation from all lines.
      var indent_re = new RegExp('^' + indent, 'mg');
      text = text.replace(indent_re, '');

      if (name == '__preamble__') {
        $scope._preamble = text;
      } else {
        var parsed = parseTutorial(text);
        $scope.tutorials.push({
          name: name,
          index: index++,
          title: parsed.title,
          description: parsed.description,
          code: parsed.code,
        });
      }
    }
  }());

  (function() {
    function loadTutorial(index) {
      return $scope.tutorials[index];
    }
    $scope.tutorial = loadTutorial($scope.chapter-1);
    $scope.loadCode();

    // Redirect to the first page if none is specified.
    if (!$location.path()) {
      var c = getStorage(['pytut', 'curChapter']) || 1;
      $location.path('/' + c).replace();
    }

    function goToChapter(chapter) {
      setStorage(['pytut', 'curChapter'], chapter);
      if (chapter == 0) {
        // Special value - don't go to chapter 0.
        chapter = $scope.chapter;
        $scope.location.path("/" + $scope.chapter).replace();
      }
      $scope.tocShowing = false;
      if (chapter != $scope.chapter) {
        $scope.saveCode();
        $scope.chapter = chapter;
        $scope.tutorial = loadTutorial(chapter - 1);
        $scope.loadCode();
        $scope.clearOutput();
        $(document.body).scrollTop(0);
      }
    }

    // Notice when the path changes and use that to
    // navigate, but only after we actually have
    // data.
    $scope.$watch('location.path()', function(path) {
      var pieces = path.split(/[/]/).slice(1);
      var chapter = +pieces[pieces.length-1];
      // This must come before goToChapter, to avoid the diff saving code.
      $scope.inDiff = pieces[0] == 'diff';
      goToChapter(chapter);
      if ($scope.inDiff) {
        $scope.doDiff($scope.tutorial.code, $scope.code());
      }
    });
  }());

  // Set up a handy timer that watches when _time changes and starts a new
  // timeout to change it. It's a bit more elegant than creating a function
  // and creating a timeout from a timeout.
  $scope._time = new Date();
  $scope.$watch('_time', function() {
    $scope.saveCode();  // Also forces dirty bit recomputation.
    $timeout(function(){
      $scope._time = new Date();
    }, 5000);
  });

  $scope.addOutputText = function(text) {
    $scope._addText(text, "stdout");
  };

  $scope.addErrorText = function(text) {
    $scope._addText(text, "stderr");
  };

  $scope._addText = function(text, elementClass) {
    var output = $('#output');
    var scrolled = output.scrollHeight - output.clientHeight - output.scrollTop;
    var scrollDown = scrolled < 12;
    $('#output').append($('<pre>')
                        .addClass(elementClass)
                        .addClass('output-entry')
                        .text(text));
    if (scrollDown) {
      output.scrollTop = output.scrollHeight - output.clientHeight;
    }
  };

  $scope.clearOutput = function() {
    $('#output .output-entry').remove();
  };

  $scope.firstRun = true;

  // Creates a function that runs code on PyPy.js.
  // onLoaded is called when the vm has finished initializing.
  function makeRunOnBrython($B) {
    function started() {
      console.log("running code");
      $scope.codeRunning = true;
    }
    function done() {
      $scope.$apply(function() {
        $scope.codeRunning = false;
        $scope.firstRun = false;
        console.log("done");
      });
    }
    function loading() {
      $scope.vmLoaded = false;
    }
    function loaded() {
      $scope.vmLoaded = true;
      console.log("Python loaded");
    }

    function makePythonLines(code) {
      var lines = code.split(/\n/);
      for (var i=0, l=lines.length; i<l; i++) {
        var line = lines[i];
        lines[i] = '"' + line.replace(/["\\]/g, '\\$&') + '"';
      }
      return "__lines__ = [" + lines.join(',\n') + "\n]";
    }

    loading();

    function run() {
      if (!$scope.vmLoaded) {
        console.log("Python not ready - ignoring request to run code")
        return;
      }
      $scope.clearOutput();
      window.setTimeout(function() {
        started();
        try {
          var code = $scope.code();
          // TODO: find first *non-comment* line. This is brittle.
          if (code != null && code !== '' && '"\''.includes(code.trim().charAt(0))) {
            code = '__doc__ = ' + code;
          }
          var prefixedCode = 'exec(' + JSON.stringify($scope._preamble) + ');' + code;
          // TODO: figure out how to set the special var __doc__ properly.
          // TODO: figure out localsid stuff and module meaning.
          $B.run_script(prefixedCode, '__main__', 'localsid');
        } catch (err) {
          console.error("run_script exception: ", err);
        } finally {
          done();
        }
      }, 100);
    }
    loaded();
    return run;
  }

  // prettyError is used to make javascript exceptions easier on the eyes.
  $scope.prettyError = function(err) {
    // If we are dealing with Firefox, just output the message.
    if (err.stack[0] == '@') {
      return err.name + ": " + err.message;
    }
    var lines = err.stack.split(/\r\n|\r|\n/);
    var output = [lines[0]];
    // Now only keep lines that have <anonymous> as the file name, and filter
    // out irrelevant text from those.
    for (var i = 1; i < lines.length; i++) {
      var line = lines[i];
      if (line.match(/^\s*at .*runCode/)) {
        break;
      }
      line = line.replace(/\([^()]*\)/, '');
      line = line.replace(/\s*\(.*:(\d+):(\d+)\)$/, ":$1:$2");
      line = line.replace("Object.eval", "_Main_");
      output.push(line);
    }
    return output.join("\n");
  };

  // If PyPyJS loaded, we can use that.
  (function(document, window, undefined) {
    function hasDiffPath() {
      return $scope.location.path().split(/[/]/)[1] == 'diff';
    };

    $scope.runCode = function() {
      console.log("Can't run code yet - not wired up.");
    };
    $scope.vmLoaded = false;
    $scope.coderunning = false;
    if (hasDiffPath()) {
      // Note that we don't just check inDiff here, because it might not be set yet.
      return;
    }

    if (typeof window.__BRYTHON__ === "undefined") {
      throw new Error("Client-side Brython implementation not available");
    }
    console.log("Using client-side Brython implementation");
    $scope.runCode = makeRunOnBrython(__BRYTHON__);
  }(document, window))

  // This is useful for binding keys in the code window to do
  // nothing at all. We can't, for whatever reason, define this
  // function in-line.
  //
  // Note that we use this for Shift-Enter because it is a
  // document-wide keystroke that should run the code, but if
  // you're in the code window it causes a newline to be
  // inserted, too.
  $scope.doNothing = function(e) {}

  $scope.clearCode = function() {
    $scope.code('');
  }

  $scope.revertCode = function() {
    $scope.code($scope.tutorial.code);
    // Force dirty bit recomputation:
    $scope.dirty(true);
  };

  $scope.revertAll = function() {
    // Remove all local storage if we have it.
    if (typeof(Storage) != "undefined") {
      localStorage.clear();
    }
    $scope.revertCode();
  };

  $scope.prevChapter = function() {
    if ($scope.tutorial == undefined || $scope.tutorial.index <= 0) {
      return 0;  // special value meaning don't go there.
    }
    return $scope.tutorial.index;  // chapter - 1
  }

  $scope.nextChapter = function() {
    if ($scope.tutorial == undefined ||
        $scope.tutorial.index >= $scope.tutorials.length - 1) {
      return 0;  // special value - don't go there.
    }
    return $scope.tutorial.index + 2;  // chapter + 1
  }
}
<commit_msg>Add comment explaining exec choice.<commit_after>'use strict';

function setStorage(keys, val) {
  if (typeof Storage === "undefined") {
    return;
  }

  if (keys.length == 1) {
    localStorage[keys[0]] = val;
    return;
  }

  var obj = {};
  var curr = obj;
  for (var i=1, len=keys.length; i<len-1; i++) {
    curr = curr[keys[i]] = {};
  }
  curr[keys[keys.length-1]] = val;

  localStorage[keys[0]] = JSON.stringify(obj);
}

function getStorage(keys) {
  if (typeof Storage === "undefined") {
    return undefined;
  }

  var str = localStorage[keys[0]];
  if (str == null) {
    return undefined;
  }
  var obj = JSON.parse(str);
  var curr = obj;
  for (var i=1, len=keys.length; i<len; i++) {
    curr = curr[keys[i]];
  }
  return curr;
}

function CodeCtrl($scope, $http, $location, $timeout) {
  $scope.mirror = CodeMirror.fromTextArea($('#codetext')[0], {
    mode: 'python',
    lineNumbers: true,
    theme: 'neat',
    indentUnit: 2,
    extraKeys: {
      'Tab': 'indentMore',
      'Shift-Enter': false,
    },
  });

  $(document).keydown(function(event) {
    var e = window.event || event;
    if (e.keyCode == 13 && e.shiftKey) {  // shift-enter
      $scope.runCode($scope.code());
    } else if (e.keyCode == 33) {  // page up
      $scope.location.path("/" + $scope.prevChapter());
      $scope.$apply();
      return false;
    } else if (e.keyCode == 34) {  // page down
      $scope.location.path("/" + $scope.nextChapter());
      $scope.$apply();
      return false;
    }
  });

  $scope.showDiffIfDirty = function() {
    if ($scope.dirty()) {
      $scope.showDiff();
    }
  };

  $scope.doDiff = function(left, right) {
    var target = $('#diffview')[0];
    target.innerHTML = '';
    var mv = CodeMirror.MergeView(target, {
      orig: right,
      value: left,
      mode: 'python',
      lineNumbers: true,
      highlightDifferences: true,
      connect: null,
    });
  };

  $scope.showDiff = function() {
    var cw = $('#workspace_top')[0];
    // Set the width to be the min of twice the code window width and the screen width:
    var w = Math.min(cw.clientWidth * 2, screen.width);
    var h = cw.clientHeight;

    var w = window.open('#/diff/' + $scope.chapter, "DiffWin-" + $scope.chapter, "width=" + w + ",height=" + h);
    w.focus();
  };

  $scope.code = function(code) {
    if (code === undefined) {
      return $scope.mirror.getValue();
    }
    $scope.mirror.setValue(code);
  };

  $scope.location = $location;

  // This naively assumes that the dirty state is "sticky" unless you force a
  // full recomputation. Works for most purposes in the UI.
  $scope._dirty = false;
  $scope.dirty = function(force_recompute) {
    if (force_recompute || !$scope._dirty) {
      $scope._dirty = ($scope.tutorial != undefined &&
                       $scope.code() != $scope.tutorial.code);
    }
    return $scope._dirty;
  };

  $scope.storageKey = function() {
    return "pytut-" + $scope.tutorial.name;
  };

  $scope.saveCode = function() {
    if ($scope.tutorial === undefined) {
      return;
    }
    if ($scope.inDiff) {
      return;
    }
    var dirty = $scope.dirty(true);

    // Save to the internal JS cache first.
    $scope.tutorial.userCode = (dirty) ? $scope.code() : undefined;

    // Also save to HTML5 local storage if possible.
    // This protects users against refresh and browser crashes.
    if (typeof(Storage) != "undefined") {
      if ($scope.tutorial.userCode === undefined) {
        localStorage.removeItem($scope.storageKey());
      } else {
        localStorage[$scope.storageKey()] = JSON.stringify({
          time_ms: +new Date(),
          user_code: $scope.tutorial.userCode,
        });
      }
    }
  };

  $scope.loadCode = function() {
    if ($scope.tutorial === undefined) {
      return;
    }

    // Get from localStorage if possible.
    if (typeof(Storage) != "undefined") {
      var val = localStorage[$scope.storageKey()];
      if (val !== undefined) {
        // TODO: Age out old things?
        $scope.tutorial.userCode = JSON.parse(val).user_code;
      }
    }
    // If there is data in userCode now, then we display that. Otherwise we get
    // the tutorial code and display that.
    if ($scope.tutorial.userCode !== undefined) {
      $scope.code($scope.tutorial.userCode);
    } else {
      $scope.code($scope.tutorial.code);
    }
    $scope.dirty(true);  // Force dirty bit recomputation.
  };
  // TOC should be off when we start.
  $scope.tocShowing = false;

  function parseTutorial(text) {
    var lines = text.split(/\r\n|\n|\r/);
    // If the file starts with comments right at the beginning, strip them off
    // (typically directives to editors).
    var cur = 0;
    for (; cur<lines.length; cur++) {
      if (lines[cur].trim() && lines[cur].search(/^\s*#.*$/) < 0) {
        break;
      }
    }
    // Remaining text is treated as a whole.
    text = lines.slice(cur).join('\n');
    var groups = text.match(/\s*"""([^]*?)\n\s*([^]*?)"""\s+([^]*)$/m)
    if (!groups) {
      return {title: "", description: "", code: ""};
    }

    return {
      title: groups[1].replace(/\\(["'])/g, '$1'),
      description: groups[2].replace(/\\(["'])/g, '$1'),
      code: groups[3].replace(/^(\s*)__doc__\s*=\s*/, '$1'),
    };
  }

  (function() {
    $scope.tutorials = [];
    $scope._preamble = '';
    var divs = $('#chapter-contents div');
    var index = 0;
    for (var i=0, l=divs.length; i<l; i++) {
      var d = $(divs[i]);
      var name = d.attr('name');
      // Discard empty starting lines (one belongs to the end of the tag).
      var text = d.text().replace(/^\s*\n/m, '');
      // Find the indentation of the first line.
      var indent = text.match(/^(\s*)/)[1];
      // Remove indentation from all lines.
      var indent_re = new RegExp('^' + indent, 'mg');
      text = text.replace(indent_re, '');

      if (name == '__preamble__') {
        $scope._preamble = text;
      } else {
        var parsed = parseTutorial(text);
        $scope.tutorials.push({
          name: name,
          index: index++,
          title: parsed.title,
          description: parsed.description,
          code: parsed.code,
        });
      }
    }
  }());

  (function() {
    function loadTutorial(index) {
      return $scope.tutorials[index];
    }
    $scope.tutorial = loadTutorial($scope.chapter-1);
    $scope.loadCode();

    // Redirect to the first page if none is specified.
    if (!$location.path()) {
      var c = getStorage(['pytut', 'curChapter']) || 1;
      $location.path('/' + c).replace();
    }

    function goToChapter(chapter) {
      setStorage(['pytut', 'curChapter'], chapter);
      if (chapter == 0) {
        // Special value - don't go to chapter 0.
        chapter = $scope.chapter;
        $scope.location.path("/" + $scope.chapter).replace();
      }
      $scope.tocShowing = false;
      if (chapter != $scope.chapter) {
        $scope.saveCode();
        $scope.chapter = chapter;
        $scope.tutorial = loadTutorial(chapter - 1);
        $scope.loadCode();
        $scope.clearOutput();
        $(document.body).scrollTop(0);
      }
    }

    // Notice when the path changes and use that to
    // navigate, but only after we actually have
    // data.
    $scope.$watch('location.path()', function(path) {
      var pieces = path.split(/[/]/).slice(1);
      var chapter = +pieces[pieces.length-1];
      // This must come before goToChapter, to avoid the diff saving code.
      $scope.inDiff = pieces[0] == 'diff';
      goToChapter(chapter);
      if ($scope.inDiff) {
        $scope.doDiff($scope.tutorial.code, $scope.code());
      }
    });
  }());

  // Set up a handy timer that watches when _time changes and starts a new
  // timeout to change it. It's a bit more elegant than creating a function
  // and creating a timeout from a timeout.
  $scope._time = new Date();
  $scope.$watch('_time', function() {
    $scope.saveCode();  // Also forces dirty bit recomputation.
    $timeout(function(){
      $scope._time = new Date();
    }, 5000);
  });

  $scope.addOutputText = function(text) {
    $scope._addText(text, "stdout");
  };

  $scope.addErrorText = function(text) {
    $scope._addText(text, "stderr");
  };

  $scope._addText = function(text, elementClass) {
    var output = $('#output');
    var scrolled = output.scrollHeight - output.clientHeight - output.scrollTop;
    var scrollDown = scrolled < 12;
    $('#output').append($('<pre>')
                        .addClass(elementClass)
                        .addClass('output-entry')
                        .text(text));
    if (scrollDown) {
      output.scrollTop = output.scrollHeight - output.clientHeight;
    }
  };

  $scope.clearOutput = function() {
    $('#output .output-entry').remove();
  };

  $scope.firstRun = true;

  // Creates a function that runs code on PyPy.js.
  // onLoaded is called when the vm has finished initializing.
  function makeRunOnBrython($B) {
    function started() {
      console.log("running code");
      $scope.codeRunning = true;
    }
    function done() {
      $scope.$apply(function() {
        $scope.codeRunning = false;
        $scope.firstRun = false;
        console.log("done");
      });
    }
    function loading() {
      $scope.vmLoaded = false;
    }
    function loaded() {
      $scope.vmLoaded = true;
      console.log("Python loaded");
    }

    function makePythonLines(code) {
      var lines = code.split(/\n/);
      for (var i=0, l=lines.length; i<l; i++) {
        var line = lines[i];
        lines[i] = '"' + line.replace(/["\\]/g, '\\$&') + '"';
      }
      return "__lines__ = [" + lines.join(',\n') + "\n]";
    }

    loading();

    function run() {
      if (!$scope.vmLoaded) {
        console.log("Python not ready - ignoring request to run code")
        return;
      }
      $scope.clearOutput();
      window.setTimeout(function() {
        started();
        try {
          var code = $scope.code();
          // TODO: find first *non-comment* line. This is brittle.
          if (code != null && code !== '' && '"\''.includes(code.trim().charAt(0))) {
            code = '__doc__ = ' + code;
          }
          // Why exec? Because that's by far the easiest way to get all the code
          // on a single line (so that exception line number reporting works).
          // We use JSON.stringify because it also happens to play nicely with
          // just putting quotes around a string and otherwise being
          // parsimonious with escaping in a way that is Python-compatible, in
          // our case..
          var prefixedCode = 'exec(' + JSON.stringify($scope._preamble) + ');' + code;
          // TODO: figure out how to set the special var __doc__ properly.
          // TODO: figure out localsid stuff and module meaning.
          $B.run_script(prefixedCode, '__main__', 'localsid');
        } catch (err) {
          console.error("run_script exception: ", err);
        } finally {
          done();
        }
      }, 100);
    }
    loaded();
    return run;
  }

  // prettyError is used to make javascript exceptions easier on the eyes.
  $scope.prettyError = function(err) {
    // If we are dealing with Firefox, just output the message.
    if (err.stack[0] == '@') {
      return err.name + ": " + err.message;
    }
    var lines = err.stack.split(/\r\n|\r|\n/);
    var output = [lines[0]];
    // Now only keep lines that have <anonymous> as the file name, and filter
    // out irrelevant text from those.
    for (var i = 1; i < lines.length; i++) {
      var line = lines[i];
      if (line.match(/^\s*at .*runCode/)) {
        break;
      }
      line = line.replace(/\([^()]*\)/, '');
      line = line.replace(/\s*\(.*:(\d+):(\d+)\)$/, ":$1:$2");
      line = line.replace("Object.eval", "_Main_");
      output.push(line);
    }
    return output.join("\n");
  };

  // If PyPyJS loaded, we can use that.
  (function(document, window, undefined) {
    function hasDiffPath() {
      return $scope.location.path().split(/[/]/)[1] == 'diff';
    };

    $scope.runCode = function() {
      console.log("Can't run code yet - not wired up.");
    };
    $scope.vmLoaded = false;
    $scope.coderunning = false;
    if (hasDiffPath()) {
      // Note that we don't just check inDiff here, because it might not be set yet.
      return;
    }

    if (typeof window.__BRYTHON__ === "undefined") {
      throw new Error("Client-side Brython implementation not available");
    }
    console.log("Using client-side Brython implementation");
    $scope.runCode = makeRunOnBrython(__BRYTHON__);
  }(document, window))

  // This is useful for binding keys in the code window to do
  // nothing at all. We can't, for whatever reason, define this
  // function in-line.
  //
  // Note that we use this for Shift-Enter because it is a
  // document-wide keystroke that should run the code, but if
  // you're in the code window it causes a newline to be
  // inserted, too.
  $scope.doNothing = function(e) {}

  $scope.clearCode = function() {
    $scope.code('');
  }

  $scope.revertCode = function() {
    $scope.code($scope.tutorial.code);
    // Force dirty bit recomputation:
    $scope.dirty(true);
  };

  $scope.revertAll = function() {
    // Remove all local storage if we have it.
    if (typeof(Storage) != "undefined") {
      localStorage.clear();
    }
    $scope.revertCode();
  };

  $scope.prevChapter = function() {
    if ($scope.tutorial == undefined || $scope.tutorial.index <= 0) {
      return 0;  // special value meaning don't go there.
    }
    return $scope.tutorial.index;  // chapter - 1
  }

  $scope.nextChapter = function() {
    if ($scope.tutorial == undefined ||
        $scope.tutorial.index >= $scope.tutorials.length - 1) {
      return 0;  // special value - don't go there.
    }
    return $scope.tutorial.index + 2;  // chapter + 1
  }
}
<|endoftext|>


<commit_before>var win = Ti.UI.currentWindow;
win.backgroundColor = 'white';

var aboutView = Ti.UI.createView({
	top: 0,
	height: Ti.UI.SIZE,
	width: Ti.UI.FILL,
	layout: 'vertical',
});

var scrollView = Ti.UI.createScrollView({
  contentWidth: 'auto',
  contentHeight: 'auto',
  width: Ti.Platform.displayCaps.platformWidth,
  height: '100%',
});

var logo = Ti.UI.createImageView({
	image: "images/dohanews-full.png",
	top: '10dp',
});

var about = Ti.UI.createLabel({
	text: "We are Qatar’s first digital news organization.\n\nSince 2009, Doha News has been bringing you breaking news and the latest on politics, business, culture and life in and around Qatar.\n\nWe’re a startup staffed by a small but versatile team of experienced journalists, who’ve worked for Al Jazeera English, the BBC and the Wall Street Journal. Our goal is to educate, inform, and stimulate positive change in society.\n\nBlending curation with original reporting, our stories are driven by our community, but professionally written and edited to meet the highest standards of journalism.\n\nTips, comments or suggestions? Email us at editor@dohanews.co",
	font:{
			fontSize: '17dp',
			fontFamily: 'droidsans',
		},
	top: '10dp',
	left: '15dp',
	right: '15dp',
	height: Ti.UI.SIZE,
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var rate = Ti.UI.createButton({
	title: 'Rate Our App',
	top: '15dp',
	width: '50%',
});

rate.addEventListener('click', function(){
	Ti.Platform.openURL('https://play.google.com/store/apps/details?id=com.dohanews');
});

var createMember = function(name, position){
	var credit = Ti.UI.createView({
		width: Ti.UI.SIZE,
		height: Ti.UI.SIZE,
		//layout: 'vertical',
	});

	var member = Ti.UI.createLabel({
		text: name,
		font: {
			fontSize: '17dp',
			fontFamily: 'droidsans',
		},
		textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
		top: '5dp',
	});

	var title = Ti.UI.createLabel({
		text: position,
		font: {
			fontSize: '15dp',
			fontFamily: 'droidsans',
			//fontWeight: 'bold',
		},
		color: '#70193c',
		top: '23dp',
		textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
	});

	credit.add(member);
	credit.add(title);

	return credit;
};

var credits = Ti.UI.createLabel({
	text: 'Credits',
	top: '10dp',
	font: {
			fontSize: '19dp',
			fontFamily: 'droidsans',
			fontWeight: 'bold',
		},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var appTeam = Ti.UI.createLabel({
	text: 'App Team',
	top: '25dp',
	font: {
			fontSize: '17dp',
			fontFamily: 'droidsans',
			fontWeight: 'bold',
		},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var anas = createMember('Anas Halbawi', 'Project Manager & Lead Develper');
var ali = createMember('Ali Naqi', 'Product Manager & Developer');
var noshin = createMember('Noshin Nisa', 'User Interface Lead');
var zaid = createMember('Zaid Haque', 'User Interface Consultant');

var comd = createMember('Check Out My Design', 'Design Consultants');
comd.top = '10dp';

var coreTeam = Ti.UI.createLabel({
	text: 'Doha News Core Team',
	top: '15dp',
	font: {
			fontSize: '17dp',
			fontFamily: 'droidsans',
			fontWeight: 'bold',
		},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var omar = createMember('Omar Chatriwala',  'Publisher');
var shabina = createMember('Shabina S. Khatri', 'Editor');
var victoria = createMember('Victoria Scott', 'Assistant Editor');

var versionView = Ti.UI.createView({
	width: Ti.UI.SIZE,
	height: Ti.UI.SIZE,
	layout: 'vertical',
	top: '25dp',
});

var version = Ti.UI.createLabel({
	text: 'Version',
	font: {
		fontSize: '17dp',
		fontFamily: 'droidsans',
	},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var number = Ti.UI.createLabel({
	text: '1.0.0',
	font: {
		fontSize: '17dp',
		fontFamily: 'droidsans',
	},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

versionView.add(version);
versionView.add(number);

aboutView.add(logo);
aboutView.add(about);

aboutView.add(appTeam);
aboutView.add(anas);
aboutView.add(ali);
aboutView.add(noshin);
aboutView.add(zaid);

aboutView.add(comd);

aboutView.add(coreTeam);
aboutView.add(omar);
aboutView.add(shabina);
aboutView.add(victoria);

aboutView.add(versionView);

aboutView.add(rate);

scrollView.add(aboutView);
win.add(scrollView);<commit_msg>ios about<commit_after>var win = Ti.UI.currentWindow;
win.layout = 'vertical';
win.backgroundColor = 'white';

var common;

if (Ti.Platform.osname != 'android'){
	common = require('ios-common');
	var header = common.create_header(true);
	win.add(header);
}

var aboutView = Ti.UI.createView({
	top: 0,
	height: Ti.UI.SIZE,
	width: Ti.UI.FILL,
	layout: 'vertical',
});

var scrollView = Ti.UI.createScrollView({
  contentWidth: 'auto',
  contentHeight: 'auto',
  width: Ti.Platform.displayCaps.platformWidth,
  height: '100%',
});

var logo = Ti.UI.createImageView({
	image: "images/dohanews-full.png",
	top: '10dp',
});

var about = Ti.UI.createLabel({
	text: "We are Qatar’s first digital news organization.\n\nSince 2009, Doha News has been bringing you breaking news and the latest on politics, business, culture and life in and around Qatar.\n\nWe’re a startup staffed by a small but versatile team of experienced journalists, who’ve worked for Al Jazeera English, the BBC and the Wall Street Journal. Our goal is to educate, inform, and stimulate positive change in society.\n\nBlending curation with original reporting, our stories are driven by our community, but professionally written and edited to meet the highest standards of journalism.\n\nTips, comments or suggestions? Email us at editor@dohanews.co",
	font:{
			fontSize: '17dp',
			fontFamily: 'droidsans',
		},
	top: '10dp',
	left: '15dp',
	right: '15dp',
	height: Ti.UI.SIZE,
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var rate = Ti.UI.createButton({
	title: 'Rate Our App',
	top: '15dp',
	width: '50%',
});

rate.addEventListener('click', function(){
	Ti.Platform.openURL('https://play.google.com/store/apps/details?id=com.dohanews');
});

var createMember = function(name, position){
	var credit = Ti.UI.createView({
		width: Ti.UI.SIZE,
		height: Ti.UI.SIZE,
		//layout: 'vertical',
	});

	var member = Ti.UI.createLabel({
		text: name,
		font: {
			fontSize: '17dp',
			fontFamily: 'droidsans',
		},
		textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
		top: '5dp',
	});

	var title = Ti.UI.createLabel({
		text: position,
		font: {
			fontSize: '15dp',
			fontFamily: 'droidsans',
			//fontWeight: 'bold',
		},
		color: '#70193c',
		top: '23dp',
		textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
	});

	credit.add(member);
	credit.add(title);

	return credit;
};

var credits = Ti.UI.createLabel({
	text: 'Credits',
	top: '10dp',
	font: {
			fontSize: '19dp',
			fontFamily: 'droidsans',
			fontWeight: 'bold',
		},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var appTeam = Ti.UI.createLabel({
	text: 'App Team',
	top: '25dp',
	font: {
			fontSize: '17dp',
			fontFamily: 'droidsans',
			fontWeight: 'bold',
		},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var anas = createMember('Anas Halbawi', 'Project Manager & Lead Develper');
var ali = createMember('Ali Naqi', 'Product Manager & Developer');
var noshin = createMember('Noshin Nisa', 'User Interface Lead');
var zaid = createMember('Zaid Haque', 'User Interface Consultant');

var comd = createMember('Check Out My Design', 'Design Consultants');
comd.top = '10dp';

var coreTeam = Ti.UI.createLabel({
	text: 'Doha News Core Team',
	top: '15dp',
	font: {
			fontSize: '17dp',
			fontFamily: 'droidsans',
			fontWeight: 'bold',
		},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var omar = createMember('Omar Chatriwala',  'Publisher');
var shabina = createMember('Shabina S. Khatri', 'Editor');
var victoria = createMember('Victoria Scott', 'Assistant Editor');

var versionView = Ti.UI.createView({
	width: Ti.UI.SIZE,
	height: Ti.UI.SIZE,
	layout: 'vertical',
	top: '25dp',
});

var version = Ti.UI.createLabel({
	text: 'Version',
	font: {
		fontSize: '17dp',
		fontFamily: 'droidsans',
	},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

var number = Ti.UI.createLabel({
	text: '1.0.0',
	font: {
		fontSize: '17dp',
		fontFamily: 'droidsans',
	},
	textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
});

versionView.add(version);
versionView.add(number);

aboutView.add(logo);
aboutView.add(about);

aboutView.add(appTeam);
aboutView.add(anas);
aboutView.add(ali);
aboutView.add(noshin);
aboutView.add(zaid);

aboutView.add(comd);

aboutView.add(coreTeam);
aboutView.add(omar);
aboutView.add(shabina);
aboutView.add(victoria);

aboutView.add(versionView);

aboutView.add(rate);

scrollView.add(aboutView);
win.add(scrollView);<|endoftext|>


<commit_before>module.exports = function(num, size) {

	var h = Math.round(num / 4);

	var view = Ti.UI.createView({
		width:size,
		height:h,
		layout:'horizontal'
	});

	var yellow = Math.floor(num / 5);
	var black = Math.floor((5 - num) / 5);

	for (i = 0; i < yellow; i ++) {
		view.add(Ti.UI.createImageView({image:'images/star_yellow.png', left:5, heigh:h});
	}

	if (yellow + black < 5) {
		var diff = num - yellow;
		if (diff <= 0.33) {
			view.add(Ti.UI.createImageView({image:'images/star1_4.png', left:5, heigh:h});
		} else if (diff <= 0.66) {
			view.add(Ti.UI.createImageView({image:'images/star2_4.png', left:5, heigh:h});
		} else {
			view.add(Ti.UI.createImageView({image:'images/star3_4.png', left:5, heigh:h});
		}
	}

	for (i = 0; i < black; i ++) {
		view.add(Ti.UI.createImageView({image:'images/star_black.png', left:5, heigh:h});
	}

	return view;

}
<commit_msg>syntax error<commit_after>module.exports = function(num, size) {

	var h = Math.round(num / 4);

	var view = Ti.UI.createView({
		width:size,
		height:h,
		layout:'horizontal'
	});

	var yellow = Math.floor(num / 5);
	var black = Math.floor((5 - num) / 5);

	for (i = 0; i < yellow; i ++) {
		view.add(Ti.UI.createImageView({image:'images/star_yellow.png', left:5, heigh:h}));
	}

	if (yellow + black < 5) {
		var diff = num - yellow;
		if (diff <= 0.33) {
			view.add(Ti.UI.createImageView({image:'images/star1_4.png', left:5, heigh:h}));
		} else if (diff <= 0.66) {
			view.add(Ti.UI.createImageView({image:'images/star2_4.png', left:5, heigh:h}));
		} else {
			view.add(Ti.UI.createImageView({image:'images/star3_4.png', left:5, heigh:h}));
		}
	}

	for (i = 0; i < black; i ++) {
		view.add(Ti.UI.createImageView({image:'images/star_black.png', left:5, heigh:h}));
	}

	return view;

}
<|endoftext|>


<commit_before>'use strict'

const gulp = require('gulp')
const load = require('gulp-require-tasks')
const run = require('run-sequence')

load({
  path: process.cwd() + '/build',
})

gulp.task('lint', ['lint:ts', 'lint:css', 'lint:html'])

gulp.task('compile', ['compile:ts', 'compile:e2e'])

gulp.task('build', (done) => {
  run('clean:dest', ['lint', 'compile', 'bundle:js', 'bundle:html', 'clean:bundle', 'bundle:image', 'bundle:assets', 'bundle:fonts'], done)
})

gulp.task('default', ['build'])

gulp.task('watch', (done) => {
  run('watch:all', done)
})

gulp.task('unit-tests', (done) => {
  if (!argv.nobuild) {
    run('compile:ts', 'test:js', done)
  } else {
    run('test:js', done)
  }
})

gulp.task('e2e-tests', (done) => {
  if (!argv.nobuild) {
    run('build', 'test:e2e', 'serve:stop', done)
  } else {
    run('test:e2e', 'serve:stop', done)
  }
})

gulp.task('serve', ['serve:wwwroot'])
<commit_msg>Add missing module.<commit_after>'use strict'

const {argv, paths} = require('./settings')
const gulp = require('gulp')
const load = require('gulp-require-tasks')
const run = require('run-sequence')

load({
  path: process.cwd() + '/build',
})

gulp.task('lint', ['lint:ts', 'lint:css', 'lint:html'])

gulp.task('compile', ['compile:ts', 'compile:e2e'])

gulp.task('build', (done) => {
  run('clean:dest', ['lint', 'compile', 'bundle:js', 'bundle:html', 'clean:bundle', 'bundle:image', 'bundle:assets', 'bundle:fonts'], done)
})

gulp.task('default', ['build'])

gulp.task('watch', (done) => {
  run('watch:all', done)
})

gulp.task('unit-tests', (done) => {
  if (!argv.nobuild) {
    run('compile:ts', 'test:js', done)
  } else {
    run('test:js', done)
  }
})

gulp.task('e2e-tests', (done) => {
  if (!argv.nobuild) {
    run('build', 'test:e2e', 'serve:stop', done)
  } else {
    run('test:e2e', 'serve:stop', done)
  }
})

gulp.task('serve', ['serve:wwwroot'])
<|endoftext|>


<commit_before>'use strict'

var gulp = require('gulp')
var run = require('run-sequence')
var iif = require('gulp-if')
var ts = require('gulp-typescript')
var jspm = require('gulp-jspm')
var sourcemaps = require('gulp-sourcemaps')
var htmlreplace = require('gulp-html-replace')
var filenames = require('gulp-filenames')
var htmlmin = require('gulp-htmlmin')
var image = require('gulp-image-optimization')
var flatten = require('gulp-flatten')
var hash = require('gulp-hash-filename')
var util = require('gulp-util')
var del = require('del')
var path = require('path')

var paths = {
  wwwroot: './wwwroot/',
  src: './src/',
  test: './test/',
  jspmPackages: './src/jspm_packages/**/*'
}

var tsProject = ts.createProject('tsconfig.json')
var production = false

gulp.task('clean:dest', function () {
  return del(paths.wwwroot)
})

gulp.task('clean:js', function () {
  return del([paths.src + '**/*.{js,js.map}', '!' + paths.src + 'jspm.conf.js',
    paths.test + '**/*.{js,js.map}', '!' + paths.jspmPackages])
})

// -- Linting --

gulp.task('lint:ts', function (done) {
  if (production) {
    util.log('Skipping \'' + util.colors.cyan('gulp-tslint') + '\'')
    done()
    return
  }

  var tslint = require('gulp-tslint')
  return gulp.src([paths.src + '**/*.ts', paths.test + '**/*.ts', '!' + paths.jspmPackages])
    .pipe(tslint({formatter: 'verbose'}))
    .pipe(tslint.report({emitError: false}))
})

gulp.task('lint:css', function (done) {
  if (production) {
    util.log('Skipping \'' + util.colors.cyan('gulp-stylelint') + '\'')
    done()
    return
  }

  var consoleFormatter = function (results) {
    results.forEach(function (element) {
      var file = path.relative(path.join(process.cwd(), paths.src), element.source)
      element.warnings.forEach(function (warning) {
        var message = '[' + util.colors.cyan('gulp-stylelint') + '] ' +
          util.colors.red(warning.severity) + ' ' + file +
          '[' + warning.line + ', ' + warning.column + ']: ' + warning.text
        util.log(message)
      })
    })
  }

  var stylelint = require('gulp-stylelint')
  return gulp.src([paths.src + '**/*.css', '!' + paths.jspmPackages])
    .pipe(stylelint({
      failAfterError: false,
      reporters: [
        {formatter: consoleFormatter}
      ]
    }))
})

gulp.task('lint:html', function (done) {
  if (production) {
    util.log('Skipping \'' + util.colors.cyan('gulp-htmlhint') + '\'')
    done()
    return
  }

  var consoleReporter = function (results) {
    results.htmlhint.messages.forEach(function (warning) {
      var file = path.relative(path.join(process.cwd(), paths.src), warning.file)
      var message = '[' + util.colors.cyan('gulp-htmlhint') + '] ' +
              util.colors.red(warning.error.type) + ' ' + file +
              '[' + warning.error.line + ', ' + warning.error.col + ']: ' + warning.error.message
      util.log(message)
    })
  }

  var htmlhint = require('gulp-htmlhint')
  return gulp.src([paths.src + '**/*.html', '!' + paths.jspmPackages])
    .pipe(htmlhint())
    .pipe(htmlhint.reporter(consoleReporter))
})

gulp.task('lint', ['lint:ts', 'lint:css', 'lint:html'])

// -- Compile/bundle

gulp.task('tscompile', ['clean:js'], function () {
  var tsResult = tsProject.src()
    .pipe(iif(!production, sourcemaps.init()))
    .pipe(ts(tsProject))

  return tsResult.js
    .pipe(iif(!production, sourcemaps.write('.', {
      mapSources: function (sourcePath) {
        var truncatedSourcePath = sourcePath.substr(sourcePath.lastIndexOf('/') + 1)
        util.log('SourcePath within source map truncated to:', util.colors.cyan(truncatedSourcePath))
        return truncatedSourcePath
      }
    })))
    .pipe(gulp.dest('.'))
})

gulp.task('bundle:app', ['tscompile'], function () {
  return gulp.src(paths.src + './app.js', { base: '.' })
    .pipe(iif(!production, sourcemaps.init({loadMaps: true})))
    .pipe(jspm({selfExecutingBundle: true, minify: true, fileName: 'app-bundle'}))
    .pipe(iif(production, hash({'format': '{hash}{ext}'})))
    .pipe(filenames('appbundle'))
    .pipe(iif(!production, sourcemaps.write('.')))
    .pipe(flatten())
    .pipe(gulp.dest('wwwroot/'))
})

gulp.task('min:html', ['bundle:app'], function () {
  var appbundle = filenames.get('appbundle')[0].substr(filenames.get('appbundle')[0].indexOf('/') + 1)

  return gulp.src([paths.src + '**/*.html', '!' + paths.jspmPackages])
    .pipe(htmlreplace({
      'appbundle': appbundle
    }))
    .pipe(htmlmin({
      collapseWhitespace: production,
      removeComments: production,
      sortAttributes: production,
      sortClassName: production
    }))
    .pipe(gulp.dest(paths.wwwroot))
})

gulp.task('min:image', function () {
  return gulp.src([paths.src + '**/*.{png,jpg,gif,svg}', '!' + paths.jspmPackages])
    .pipe(image({
      optimizationLevel: 3,
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest(paths.wwwroot))
})

gulp.task('assets', function () {
  return gulp.src([paths.src + '**/*.ico', '!' + paths.jspmPackages])
    .pipe(gulp.dest(paths.wwwroot))
})

gulp.task('vendorassets', function () {
  return gulp.src(paths.jspmPackages + '**/*.{eot,svg,ttf,woff,woff2}')
    .pipe(gulp.dest(paths.wwwroot + '/jspm_packages'))
})

gulp.task('build', function (done) {
  run('clean:dest', ['lint', 'bundle:app', 'min:html', 'min:image', 'assets', 'vendorassets'], done)
})

gulp.task('production', function (done) {
  production = true
  run('build', done)
})

gulp.task('default', ['build'])
<commit_msg>Restore browsersync.<commit_after>'use strict'

var gulp = require('gulp')
var run = require('run-sequence')
var iif = require('gulp-if')
var ts = require('gulp-typescript')
var jspm = require('gulp-jspm')
var sourcemaps = require('gulp-sourcemaps')
var htmlreplace = require('gulp-html-replace')
var filenames = require('gulp-filenames')
var htmlmin = require('gulp-htmlmin')
var image = require('gulp-image-optimization')
var flatten = require('gulp-flatten')
var hash = require('gulp-hash-filename')
var util = require('gulp-util')
var del = require('del')
var path = require('path')

var paths = {
  wwwroot: './wwwroot/',
  src: './src/',
  test: './test/',
  jspmPackages: './src/jspm_packages/**/*'
}

var tsProject = ts.createProject('tsconfig.json')
var production = false

gulp.task('clean:dest', function () {
  return del(paths.wwwroot)
})

gulp.task('clean:js', function () {
  return del([paths.src + '**/*.{js,js.map}', '!' + paths.src + 'jspm.conf.js',
    paths.test + '**/*.{js,js.map}', '!' + paths.jspmPackages])
})

// -- Linting --

gulp.task('lint:ts', function (done) {
  if (production) {
    util.log('Skipping \'' + util.colors.cyan('gulp-tslint') + '\'')
    done()
    return
  }

  var tslint = require('gulp-tslint')
  return gulp.src([paths.src + '**/*.ts', paths.test + '**/*.ts', '!' + paths.jspmPackages])
    .pipe(tslint({formatter: 'verbose'}))
    .pipe(tslint.report({emitError: false}))
})

gulp.task('lint:css', function (done) {
  if (production) {
    util.log('Skipping \'' + util.colors.cyan('gulp-stylelint') + '\'')
    done()
    return
  }

  var consoleFormatter = function (results) {
    results.forEach(function (element) {
      var file = path.relative(path.join(process.cwd(), paths.src), element.source)
      element.warnings.forEach(function (warning) {
        var message = '[' + util.colors.cyan('gulp-stylelint') + '] ' +
          util.colors.red(warning.severity) + ' ' + file +
          '[' + warning.line + ', ' + warning.column + ']: ' + warning.text
        util.log(message)
      })
    })
  }

  var stylelint = require('gulp-stylelint')
  return gulp.src([paths.src + '**/*.css', '!' + paths.jspmPackages])
    .pipe(stylelint({
      failAfterError: false,
      reporters: [
        {formatter: consoleFormatter}
      ]
    }))
})

gulp.task('lint:html', function (done) {
  if (production) {
    util.log('Skipping \'' + util.colors.cyan('gulp-htmlhint') + '\'')
    done()
    return
  }

  var consoleReporter = function (results) {
    results.htmlhint.messages.forEach(function (warning) {
      var file = path.relative(path.join(process.cwd(), paths.src), warning.file)
      var message = '[' + util.colors.cyan('gulp-htmlhint') + '] ' +
              util.colors.red(warning.error.type) + ' ' + file +
              '[' + warning.error.line + ', ' + warning.error.col + ']: ' + warning.error.message
      util.log(message)
    })
  }

  var htmlhint = require('gulp-htmlhint')
  return gulp.src([paths.src + '**/*.html', '!' + paths.jspmPackages])
    .pipe(htmlhint())
    .pipe(htmlhint.reporter(consoleReporter))
})

gulp.task('lint', ['lint:ts', 'lint:css', 'lint:html'])

// -- Compile/bundle

gulp.task('tscompile', ['clean:js'], function () {
  var tsResult = tsProject.src()
    .pipe(iif(!production, sourcemaps.init()))
    .pipe(ts(tsProject))

  return tsResult.js
    .pipe(iif(!production, sourcemaps.write('.', {
      mapSources: function (sourcePath) {
        var truncatedSourcePath = sourcePath.substr(sourcePath.lastIndexOf('/') + 1)
        util.log('SourcePath within source map truncated to:', util.colors.cyan(truncatedSourcePath))
        return truncatedSourcePath
      }
    })))
    .pipe(gulp.dest('.'))
})

gulp.task('bundle:app', ['tscompile'], function () {
  return gulp.src(paths.src + './app.js', { base: '.' })
    .pipe(iif(!production, sourcemaps.init({loadMaps: true})))
    .pipe(jspm({selfExecutingBundle: true, minify: true, fileName: 'app-bundle'}))
    .pipe(iif(production, hash({'format': '{hash}{ext}'})))
    .pipe(filenames('appbundle'))
    .pipe(iif(!production, sourcemaps.write('.')))
    .pipe(flatten())
    .pipe(gulp.dest('wwwroot/'))
})

gulp.task('min:html', ['bundle:app'], function () {
  var appbundle = filenames.get('appbundle')[0].substr(filenames.get('appbundle')[0].indexOf('/') + 1)

  return gulp.src([paths.src + '**/*.html', '!' + paths.jspmPackages])
    .pipe(htmlreplace({
      'appbundle': appbundle
    }))
    .pipe(htmlmin({
      collapseWhitespace: production,
      removeComments: production,
      sortAttributes: production,
      sortClassName: production
    }))
    .pipe(gulp.dest(paths.wwwroot))
})

gulp.task('min:image', function () {
  return gulp.src([paths.src + '**/*.{png,jpg,gif,svg}', '!' + paths.jspmPackages])
    .pipe(image({
      optimizationLevel: 3,
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest(paths.wwwroot))
})

gulp.task('assets', function () {
  return gulp.src([paths.src + '**/*.ico', '!' + paths.jspmPackages])
    .pipe(gulp.dest(paths.wwwroot))
})

gulp.task('vendorassets', function () {
  return gulp.src(paths.jspmPackages + '**/*.{eot,svg,ttf,woff,woff2}')
    .pipe(gulp.dest(paths.wwwroot + '/jspm_packages'))
})

gulp.task('build', function (done) {
  run('clean:dest', ['lint', 'bundle:app', 'min:html', 'min:image', 'assets', 'vendorassets'], done)
})

gulp.task('production', function (done) {
  production = true
  run('build', done)
})

gulp.task('default', ['build'])

// -- Watch

gulp.task('watch:ts', function () {
  var watch = require('gulp-watch')
  var batch = require('gulp-batch')

  watch(paths.src + '**/*.ts', batch(function (events, done) {
    gulp.start('tscompile', done)
  }))
})

gulp.task('watch', function () {
  var browserSync = require('browser-sync').create()
  var proxy = require('proxy-middleware')
  var url = require('url')
  var watch = require('gulp-watch')
  var batch = require('gulp-batch')

  var proxyOptions = url.parse('http://localhost:5000/api')
  proxyOptions.route = '/api'

  browserSync.init({
    server: {
      baseDir: paths.src,
      middleware: [proxy(proxyOptions)]
    }
  })

  var sync = function (vinyl) {
    if (vinyl.event === 'add' || vinyl.event === 'change') {
      return gulp.src(vinyl.path)
        .pipe(browserSync.stream())
    }
  }

  watch(paths.src + '**/*.js', sync)
  watch(paths.src + '**/*.css', sync)
  watch(paths.src + '**/*.{html,png,jpg,gif,svg,ico}',
    batch(function (events, done) {
      browserSync.reload()
      done()
    }
  ))

  gulp.start('watch:ts')
})
<|endoftext|>


<commit_before>// extends src/nodes/time.js which extends src/node-box-native-view.js

$(function(){

// Thanks https://raw.github.com/BrianHicks/Markov-Generator/master/markov.js

/*sample regexes:

 /./g - every letter
 /../g - every two letter
 /[.,?"();\-!':—^\w]+ /g - every word
 /([.,?"();\-!':—^\w]+ ){2}/g - every two words

*/
var markov = function(input, type, reg) {
  var data;
  if (reg===undefined) {
    reg = /[.,?"();\-!':—^\w]+ /g;
  }
  if (type == "string" || type === undefined) {
    data = {};
    s = input.match(reg);
    for (var i = 0; i < s.length-1; i++) {
      if(s[i] in data) {
        if (s[i+1] in data[s[i]]) {
          data[s[i]][s[i+1]]++;
        } else {
          data[s[i]][s[i+1]] = 1;
        }
      } else {
        data[s[i]] = {};
        data[s[i]][s[i+1]] = 1;
      }
    }
  } else if (type == "json") {
    data = JSON.parse(input);
  }
  this.data = data;

  var gen = function(l) {
    var sanitycheck = false;
    var out = [];
    while (sanitycheck === false) {
      sanitycheck = true;
      var rProperty = findRandomProperty(data);
      var rList = expand(rProperty);
      var l1 = rList.length;
      out[0] = rList[Math.round(Math.random() * l1)];
      if (typeof out[0] == "undefined") { sanitycheck = false; }
      if (sanitycheck) {
        for (var i = 0; i < l-1; i++) {
          var usableLength = expand(data[out[i]]).length-1;
          var randomInt = Math.round(Math.random() * usableLength);
          var nextLetter = expand(data[out[i]])[randomInt];
          out.push(nextLetter);
        }
      }
    }
    return out.join("");
  };
  this.gen = gen;

  var findRandomProperty = function(o) {
    var l1 = 0;
    var i;
    for (i in o) {
      l1++;
    }
    var r1 = Math.round(Math.random() * l1);
    var l2 = 0;
    for (i in o) {
      l2++;
      if (l2 == r1) {
        return o[i];
      }
    }
  };

  var expand = function(obj) {
    oArray = [];
    for (var prop in obj) {
      for (var i = 0; i < obj[prop]; i++) {
        oArray.push(prop);
      }
    }
    return oArray;
  };

  var getJson = function() {
    if (typeof JSON === "object") {
      return JSON.stringify(data);
    }
  };
  this.getJson = getJson;
};

  var template =
    '

'+
    '<button class="gen">generate</button>'+
    '';

  Iframework.NativeNodes["string-markov"] = Iframework.NativeNodes["string"].extend({

    template: _.template(template),
    info: {
      title: "markov",
      description: "makes a markov chain based "
    },
    events: {
      "click .gen":  "inputgenerate"
    },
    initializeModule: function(){
    },
    inputstring: function (string) {
      string = string.toLowerCase();
      string = string.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/g,"");
      this.markov = new markov(string);
    },
    inputgenerate: function () {
      if (!this.markov) { return; }
      var out = this.markov.gen(this._len);
      this.$(".chain").text(out);
      this.$(".info").text("(" + this._len + " words, " + out.length + " characters)");
      this.send("chain", out);
    },
    inputs: {
      string: {
        type: "string",
        description: "the string that seeds the chain"
      },
      len: {
        type: "int",
        description: "how many words in the chain",
        "default": 20
      },
      generate: {
        type: "bang",
        description: "make a chain"
      }
    },
    outputs: {
      chain: {
        type: "string",
        description: "the generated markov chain"
      }
    }

  });

});
<commit_msg>leave punctuation<commit_after>// extends src/nodes/time.js which extends src/node-box-native-view.js

$(function(){

// Thanks https://raw.github.com/BrianHicks/Markov-Generator/master/markov.js

/*sample regexes:

 /./g - every letter
 /../g - every two letter
 /[.,?"();\-!':—^\w]+ /g - every word
 /([.,?"();\-!':—^\w]+ ){2}/g - every two words

*/
var markov = function(input, type, reg) {
  var data;
  if (reg===undefined) {
    reg = /[.,?"();\-!':—^\w]+ /g;
  }
  if (type == "string" || type === undefined) {
    data = {};
    s = input.match(reg);
    for (var i = 0; i < s.length-1; i++) {
      if(s[i] in data) {
        if (s[i+1] in data[s[i]]) {
          data[s[i]][s[i+1]]++;
        } else {
          data[s[i]][s[i+1]] = 1;
        }
      } else {
        data[s[i]] = {};
        data[s[i]][s[i+1]] = 1;
      }
    }
  } else if (type == "json") {
    data = JSON.parse(input);
  }
  this.data = data;

  var gen = function(l) {
    var sanitycheck = false;
    var out = [];
    while (sanitycheck === false) {
      sanitycheck = true;
      var rProperty = findRandomProperty(data);
      var rList = expand(rProperty);
      var l1 = rList.length;
      out[0] = rList[Math.round(Math.random() * l1)];
      if (typeof out[0] == "undefined") { sanitycheck = false; }
      if (sanitycheck) {
        for (var i = 0; i < l-1; i++) {
          var usableLength = expand(data[out[i]]).length-1;
          var randomInt = Math.round(Math.random() * usableLength);
          var nextLetter = expand(data[out[i]])[randomInt];
          out.push(nextLetter);
        }
      }
    }
    return out.join("");
  };
  this.gen = gen;

  var findRandomProperty = function(o) {
    var l1 = 0;
    var i;
    for (i in o) {
      l1++;
    }
    var r1 = Math.round(Math.random() * l1);
    var l2 = 0;
    for (i in o) {
      l2++;
      if (l2 == r1) {
        return o[i];
      }
    }
  };

  var expand = function(obj) {
    oArray = [];
    for (var prop in obj) {
      for (var i = 0; i < obj[prop]; i++) {
        oArray.push(prop);
      }
    }
    return oArray;
  };

  var getJson = function() {
    if (typeof JSON === "object") {
      return JSON.stringify(data);
    }
  };
  this.getJson = getJson;
};

  var template =
    '

'+
    '<button class="gen">generate</button>'+
    '';

  Iframework.NativeNodes["string-markov"] = Iframework.NativeNodes["string"].extend({

    template: _.template(template),
    info: {
      title: "markov",
      description: "makes a markov chain based "
    },
    events: {
      "click .gen":  "inputgenerate"
    },
    initializeModule: function(){
    },
    inputstring: function (string) {
      string = string.toLowerCase();
      // string = string.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/g,"");
      this.markov = new markov(string);
    },
    inputgenerate: function () {
      if (!this.markov) { return; }
      var out = this.markov.gen(this._len);
      this.$(".chain").text(out);
      this.$(".info").text("(" + this._len + " words, " + out.length + " characters)");
      this.send("chain", out);
    },
    inputs: {
      string: {
        type: "string",
        description: "the string that seeds the chain"
      },
      len: {
        type: "int",
        description: "how many words in the chain",
        "default": 20
      },
      generate: {
        type: "bang",
        description: "make a chain"
      }
    },
    outputs: {
      chain: {
        type: "string",
        description: "the generated markov chain"
      }
    }

  });

});
<|endoftext|>


<commit_before>function FindProxyForURL(url, host) {
	function matchDomain(a) {
		return dnsDomainIs(host, a);
	}
	function B(a) {
		return shExpMatch(url, '*' + a + '*');
	}
	function matchList(list){
		for(var i=0;i < list.length;i++){
			if(matchDomain(list[i])){
				return true;
			}
		}
		return false;
	}
	var domainWhiteList = {{domainWhiteListJson}};
	var domainList = {{domainListJson}};
	if(matchList(domainWhiteList)){
		return "DIRECT";
	}
	if(matchList(domainList)){
		return "SOCKS5 {{proxy_ddr}};PROXY {{proxy_ddr}};";
	}
	if(matchList(["status.dddproxy.com"])){
		return "PROXY {{proxy_ddr}};";
	}
	return "DIRECT";
}
<commit_msg>add socks for safari<commit_after>function FindProxyForURL(url, host) {
	function matchDomain(a) {
		return dnsDomainIs(host, a);
	}
	function B(a) {
		return shExpMatch(url, '*' + a + '*');
	}
	function matchList(list){
		for(var i=0;i < list.length;i++){
			if(matchDomain(list[i])){
				return true;
			}
		}
		return false;
	}
	var domainWhiteList = {{domainWhiteListJson}};
	var domainList = {{domainListJson}};
	if(matchList(domainWhiteList)){
		return "DIRECT";
	}
	if(matchList(domainList)){
		return "SOCKS5 {{proxy_ddr}};SOCKS {{proxy_ddr}};PROXY {{proxy_ddr}};";
	}
	if(matchList(["status.dddproxy.com"])){
		return "PROXY {{proxy_ddr}};";
	}
	return "DIRECT";
}
<|endoftext|>


<commit_before>'use strict';

import { assert } from 'chai';

let primesLessThan100 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];

describe('Problem 3 - Largest prime factor', function () {

    it(`

    The prime factors of 13195 are 5, 7, 13 and 29.
    What is the largest prime factor of the number 600851475143 ?

  `, function () {
        assert.deepEqual(getPrimes(100), primesLessThan100);
        assert.deepEqual(solution(13195), 29);

        assert.deepEqual(solution(600851475143), 6857);
    });

});

//let getPrimesMemoized = _.memoize(getPrimes);

function solution(input, limit = 100, start = 2, result = 1) {
    let basicPrimes = getPrimes(limit, start);

    basicPrimes.forEach(function(prime) {
       if (input % prime === 0) {
           result = prime;
           input = input / result;
       }
    });

    if (input / 2 > result) {
        return solution(input, limit * 2, limit, result);
    }

    return result;
}

function getPrimes(limit, start = 2) {

    let primes = [];

    let count = 0;
    for (let i = start; i < limit; i++) {
        let candidate = i;
        let test = 2;
        let isPrime = true;
        while (test < i) {
            count++;
            if (test !== candidate && candidate % test === 0) {
                isPrime = false;
                break;
            }
            test++;
        }

        if (isPrime) {
            primes.push(candidate);
        }
    }

    return primes;
}

<commit_msg>Problem 3 - Largest prime factor, edit: code cleanup<commit_after>'use strict';

import { assert } from 'chai';

let primesLessThan100 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];

describe('Problem 3 - Largest prime factor', function () {

    it(`

    The prime factors of 13195 are 5, 7, 13 and 29.
    What is the largest prime factor of the number 600851475143 ?

  `, function () {
        assert.deepEqual(getPrimes(100), primesLessThan100);
        assert.deepEqual(solution(13195), 29);

        assert.deepEqual(solution(600851475143), 6857);
    });

});

//let getPrimesMemoized = _.memoize(getPrimes);

function solution(input, limit = 100, start = 2, result = 1) {
    let basicPrimes = getPrimes(limit, start);

    basicPrimes.forEach(function(prime) {
       if (input % prime === 0) {
           result = prime;
           input = input / result;
       }
    });

    if (input / 2 > result) {
        return solution(input, limit * 2, limit, result);
    }

    return result;
}

function getPrimes(limit, start = 2) {

    let primes = [];

    for (let i = start; i < limit; i++) {
        let candidate = i;
        let test = 2;
        let isPrime = true;
        while (test < i) {
            if (test !== candidate && candidate % test === 0) {
                isPrime = false;
                break;
            }
            test++;
        }

        if (isPrime) {
            primes.push(candidate);
        }
    }

    return primes;
}

<|endoftext|>