diff --git a/src/LiveDevelopment/Agents/CSSAgent.js b/src/LiveDevelopment/impls/default/Agents/CSSAgent.js similarity index 99% rename from src/LiveDevelopment/Agents/CSSAgent.js rename to src/LiveDevelopment/impls/default/Agents/CSSAgent.js index eb5dd98a94a..9e306692b43 100644 --- a/src/LiveDevelopment/Agents/CSSAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/CSSAgent.js @@ -39,7 +39,7 @@ define(function CSSAgent(require, exports, module) { var _ = require("thirdparty/lodash"); - var Inspector = require("LiveDevelopment/Inspector/Inspector"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); /** * Stylesheet details diff --git a/src/LiveDevelopment/Agents/ConsoleAgent.js b/src/LiveDevelopment/impls/default/Agents/ConsoleAgent.js similarity index 97% rename from src/LiveDevelopment/Agents/ConsoleAgent.js rename to src/LiveDevelopment/impls/default/Agents/ConsoleAgent.js index e0d479cc294..40db86612f4 100644 --- a/src/LiveDevelopment/Agents/ConsoleAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/ConsoleAgent.js @@ -32,7 +32,7 @@ define(function ConsoleAgent(require, exports, module) { "use strict"; - var Inspector = require("LiveDevelopment/Inspector/Inspector"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); var _lastMessage; // {Console.ConsoleMessage} the last received message diff --git a/src/LiveDevelopment/Agents/DOMAgent.js b/src/LiveDevelopment/impls/default/Agents/DOMAgent.js similarity index 97% rename from src/LiveDevelopment/Agents/DOMAgent.js rename to src/LiveDevelopment/impls/default/Agents/DOMAgent.js index f27ec6f621c..f55ee5e9fcc 100644 --- a/src/LiveDevelopment/Agents/DOMAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/DOMAgent.js @@ -40,10 +40,10 @@ define(function DOMAgent(require, exports, module) { var $exports = $(exports); - var Inspector = require("LiveDevelopment/Inspector/Inspector"); - var EditAgent = require("LiveDevelopment/Agents/EditAgent"); - var DOMNode = require("LiveDevelopment/Agents/DOMNode"); - var DOMHelpers = require("LiveDevelopment/Agents/DOMHelpers"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); + var EditAgent = require("LiveDevelopment/impls/default/Agents/EditAgent"); + var DOMNode = require("LiveDevelopment/impls/default/Agents/DOMNode"); + var DOMHelpers = require("LiveDevelopment/impls/default/Agents/DOMHelpers"); var _load; // {$.Deferred} load promise var _idToNode; // {nodeId -> node} diff --git a/src/LiveDevelopment/Agents/DOMHelpers.js b/src/LiveDevelopment/impls/default/Agents/DOMHelpers.js similarity index 100% rename from src/LiveDevelopment/Agents/DOMHelpers.js rename to src/LiveDevelopment/impls/default/Agents/DOMHelpers.js diff --git a/src/LiveDevelopment/Agents/DOMNode.js b/src/LiveDevelopment/impls/default/Agents/DOMNode.js similarity index 99% rename from src/LiveDevelopment/Agents/DOMNode.js rename to src/LiveDevelopment/impls/default/Agents/DOMNode.js index 31927e6c135..682fcf7e9a5 100644 --- a/src/LiveDevelopment/Agents/DOMNode.js +++ b/src/LiveDevelopment/impls/default/Agents/DOMNode.js @@ -35,7 +35,7 @@ define(function DOMNodeModule(require, exports, module) { "use strict"; - var DOMHelpers = require("LiveDevelopment/Agents/DOMHelpers"); + var DOMHelpers = require("LiveDevelopment/impls/default/Agents/DOMHelpers"); /** Fill a string to the given length (used for debug output) * @param {string} source string diff --git a/src/LiveDevelopment/Agents/EditAgent.js b/src/LiveDevelopment/impls/default/Agents/EditAgent.js similarity index 93% rename from src/LiveDevelopment/Agents/EditAgent.js rename to src/LiveDevelopment/impls/default/Agents/EditAgent.js index 5d13d9fa602..96e9ee44dd9 100644 --- a/src/LiveDevelopment/Agents/EditAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/EditAgent.js @@ -32,10 +32,10 @@ define(function EditAgent(require, exports, module) { "use strict"; - var Inspector = require("LiveDevelopment/Inspector/Inspector"); - var DOMAgent = require("LiveDevelopment/Agents/DOMAgent"); - var RemoteAgent = require("LiveDevelopment/Agents/RemoteAgent"); - var GotoAgent = require("LiveDevelopment/Agents/GotoAgent"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); + var DOMAgent = require("LiveDevelopment/impls/default/Agents/DOMAgent"); + var RemoteAgent = require("LiveDevelopment/impls/default/Agents/RemoteAgent"); + var GotoAgent = require("LiveDevelopment/impls/default/Agents/GotoAgent"); var EditorManager = require("editor/EditorManager"); diff --git a/src/LiveDevelopment/Agents/GotoAgent.js b/src/LiveDevelopment/impls/default/Agents/GotoAgent.js similarity index 95% rename from src/LiveDevelopment/Agents/GotoAgent.js rename to src/LiveDevelopment/impls/default/Agents/GotoAgent.js index 9107a86d279..d94746fc587 100644 --- a/src/LiveDevelopment/Agents/GotoAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/GotoAgent.js @@ -33,10 +33,10 @@ define(function GotoAgent(require, exports, module) { require("utils/Global"); - var Inspector = require("LiveDevelopment/Inspector/Inspector"), - DOMAgent = require("LiveDevelopment/Agents/DOMAgent"), - ScriptAgent = require("LiveDevelopment/Agents/ScriptAgent"), - RemoteAgent = require("LiveDevelopment/Agents/RemoteAgent"), + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"), + DOMAgent = require("LiveDevelopment/impls/default/Agents/DOMAgent"), + ScriptAgent = require("LiveDevelopment/impls/default/Agents/ScriptAgent"), + RemoteAgent = require("LiveDevelopment/impls/default/Agents/RemoteAgent"), EditorManager = require("editor/EditorManager"), CommandManager = require("command/CommandManager"), Commands = require("command/Commands"); diff --git a/src/LiveDevelopment/Agents/HighlightAgent.js b/src/LiveDevelopment/impls/default/Agents/HighlightAgent.js similarity index 93% rename from src/LiveDevelopment/Agents/HighlightAgent.js rename to src/LiveDevelopment/impls/default/Agents/HighlightAgent.js index 08f978b6365..280d5a44226 100644 --- a/src/LiveDevelopment/Agents/HighlightAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/HighlightAgent.js @@ -34,10 +34,10 @@ define(function HighlightAgent(require, exports, module) { "use strict"; - var DOMAgent = require("LiveDevelopment/Agents/DOMAgent"), - Inspector = require("LiveDevelopment/Inspector/Inspector"), - LiveDevelopment = require("LiveDevelopment/LiveDevelopment"), - RemoteAgent = require("LiveDevelopment/Agents/RemoteAgent"), + var DOMAgent = require("LiveDevelopment/impls/default/Agents/DOMAgent"), + Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"), + LiveDevelopment = require("LiveDevelopment/impls/default/LiveDevelopment"), + RemoteAgent = require("LiveDevelopment/impls/default/Agents/RemoteAgent"), _ = require("thirdparty/lodash"); var _highlight = {}; // active highlight diff --git a/src/LiveDevelopment/Agents/NetworkAgent.js b/src/LiveDevelopment/impls/default/Agents/NetworkAgent.js similarity index 97% rename from src/LiveDevelopment/Agents/NetworkAgent.js rename to src/LiveDevelopment/impls/default/Agents/NetworkAgent.js index db1fa022d71..be11ade2351 100644 --- a/src/LiveDevelopment/Agents/NetworkAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/NetworkAgent.js @@ -32,7 +32,7 @@ define(function NetworkAgent(require, exports, module) { "use strict"; - var Inspector = require("LiveDevelopment/Inspector/Inspector"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); var _urlRequested = {}; // url -> request info diff --git a/src/LiveDevelopment/Agents/RemoteAgent.js b/src/LiveDevelopment/impls/default/Agents/RemoteAgent.js similarity index 95% rename from src/LiveDevelopment/Agents/RemoteAgent.js rename to src/LiveDevelopment/impls/default/Agents/RemoteAgent.js index 031768969e4..19796d2323b 100644 --- a/src/LiveDevelopment/Agents/RemoteAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/RemoteAgent.js @@ -37,9 +37,9 @@ define(function RemoteAgent(require, exports, module) { var $exports = $(exports); - var LiveDevelopment = require("LiveDevelopment/LiveDevelopment"), - Inspector = require("LiveDevelopment/Inspector/Inspector"), - RemoteFunctions = require("text!LiveDevelopment/Agents/RemoteFunctions.js"); + var LiveDevelopment = require("LiveDevelopment/impls/default/LiveDevelopment"), + Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"), + RemoteFunctions = require("text!LiveDevelopment/impls/default/Agents/RemoteFunctions.js"); var _load; // deferred load var _objectId; // the object id of the remote object diff --git a/src/LiveDevelopment/Agents/RemoteFunctions.js b/src/LiveDevelopment/impls/default/Agents/RemoteFunctions.js similarity index 100% rename from src/LiveDevelopment/Agents/RemoteFunctions.js rename to src/LiveDevelopment/impls/default/Agents/RemoteFunctions.js diff --git a/src/LiveDevelopment/Agents/ScriptAgent.js b/src/LiveDevelopment/impls/default/Agents/ScriptAgent.js similarity index 97% rename from src/LiveDevelopment/Agents/ScriptAgent.js rename to src/LiveDevelopment/impls/default/Agents/ScriptAgent.js index 26604535d7d..7b64e7c6b04 100644 --- a/src/LiveDevelopment/Agents/ScriptAgent.js +++ b/src/LiveDevelopment/impls/default/Agents/ScriptAgent.js @@ -32,8 +32,8 @@ define(function ScriptAgent(require, exports, module) { "use strict"; - var Inspector = require("LiveDevelopment/Inspector/Inspector"); - var DOMAgent = require("LiveDevelopment/Agents/DOMAgent"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); + var DOMAgent = require("LiveDevelopment/impls/default/Agents/DOMAgent"); var _load; // the load promise var _urlToScript; // url -> script info diff --git a/src/LiveDevelopment/Documents/CSSDocument.js b/src/LiveDevelopment/impls/default/Documents/CSSDocument.js similarity index 97% rename from src/LiveDevelopment/Documents/CSSDocument.js rename to src/LiveDevelopment/impls/default/Documents/CSSDocument.js index 86a1ca6095b..35dd55d8a3e 100644 --- a/src/LiveDevelopment/Documents/CSSDocument.js +++ b/src/LiveDevelopment/impls/default/Documents/CSSDocument.js @@ -50,11 +50,11 @@ define(function CSSDocumentModule(require, exports, module) { "use strict"; var _ = require("thirdparty/lodash"), - CSSAgent = require("LiveDevelopment/Agents/CSSAgent"), + CSSAgent = require("LiveDevelopment/impls/default/Agents/CSSAgent"), CSSUtils = require("language/CSSUtils"), EditorManager = require("editor/EditorManager"), - HighlightAgent = require("LiveDevelopment/Agents/HighlightAgent"), - Inspector = require("LiveDevelopment/Inspector/Inspector"); + HighlightAgent = require("LiveDevelopment/impls/default/Agents/HighlightAgent"), + Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); /** * @constructor diff --git a/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js b/src/LiveDevelopment/impls/default/Documents/CSSPreprocessorDocument.js similarity index 96% rename from src/LiveDevelopment/Documents/CSSPreprocessorDocument.js rename to src/LiveDevelopment/impls/default/Documents/CSSPreprocessorDocument.js index 5c74ed48cea..0aeae0a674a 100644 --- a/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js +++ b/src/LiveDevelopment/impls/default/Documents/CSSPreprocessorDocument.js @@ -40,8 +40,8 @@ define(function CSSPreprocessorDocumentModule(require, exports, module) { var _ = require("thirdparty/lodash"), CSSUtils = require("language/CSSUtils"), EditorManager = require("editor/EditorManager"), - HighlightAgent = require("LiveDevelopment/Agents/HighlightAgent"), - Inspector = require("LiveDevelopment/Inspector/Inspector"); + HighlightAgent = require("LiveDevelopment/impls/default/Agents/HighlightAgent"), + Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); /** * @constructor diff --git a/src/LiveDevelopment/Documents/HTMLDocument.js b/src/LiveDevelopment/impls/default/Documents/HTMLDocument.js similarity index 97% rename from src/LiveDevelopment/Documents/HTMLDocument.js rename to src/LiveDevelopment/impls/default/Documents/HTMLDocument.js index 9ced712d038..8b279a51305 100644 --- a/src/LiveDevelopment/Documents/HTMLDocument.js +++ b/src/LiveDevelopment/impls/default/Documents/HTMLDocument.js @@ -45,12 +45,12 @@ define(function HTMLDocumentModule(require, exports, module) { "use strict"; var EditorManager = require("editor/EditorManager"), - HighlightAgent = require("LiveDevelopment/Agents/HighlightAgent"), + HighlightAgent = require("LiveDevelopment/impls/default/Agents/HighlightAgent"), HTMLInstrumentation = require("language/HTMLInstrumentation"), - Inspector = require("LiveDevelopment/Inspector/Inspector"), - LiveDevelopment = require("LiveDevelopment/LiveDevelopment"), + Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"), + LiveDevelopment = require("LiveDevelopment/impls/default/LiveDevelopment"), PerfUtils = require("utils/PerfUtils"), - RemoteAgent = require("LiveDevelopment/Agents/RemoteAgent"), + RemoteAgent = require("LiveDevelopment/impls/default/Agents/RemoteAgent"), _ = require("thirdparty/lodash"); /** diff --git a/src/LiveDevelopment/Documents/JSDocument.js b/src/LiveDevelopment/impls/default/Documents/JSDocument.js similarity index 95% rename from src/LiveDevelopment/Documents/JSDocument.js rename to src/LiveDevelopment/impls/default/Documents/JSDocument.js index 715bba53a89..c04ae4b9c08 100644 --- a/src/LiveDevelopment/Documents/JSDocument.js +++ b/src/LiveDevelopment/impls/default/Documents/JSDocument.js @@ -45,9 +45,9 @@ define(function JSDocumentModule(require, exports, module) { "use strict"; - var Inspector = require("LiveDevelopment/Inspector/Inspector"); - var ScriptAgent = require("LiveDevelopment/Agents/ScriptAgent"); - var HighlightAgent = require("LiveDevelopment/Agents/HighlightAgent"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); + var ScriptAgent = require("LiveDevelopment/impls/default/Agents/ScriptAgent"); + var HighlightAgent = require("LiveDevelopment/impls/default/Agents/HighlightAgent"); /** * @constructor diff --git a/src/LiveDevelopment/Inspector/Inspector.js b/src/LiveDevelopment/impls/default/Inspector/Inspector.js similarity index 99% rename from src/LiveDevelopment/Inspector/Inspector.js rename to src/LiveDevelopment/impls/default/Inspector/Inspector.js index fa36e1bb974..39818db8ab3 100644 --- a/src/LiveDevelopment/Inspector/Inspector.js +++ b/src/LiveDevelopment/impls/default/Inspector/Inspector.js @@ -392,7 +392,7 @@ define(function Inspector(require, exports, module) { function init(theConfig) { exports.config = theConfig; - var InspectorText = require("text!LiveDevelopment/Inspector/Inspector.json"), + var InspectorText = require("text!LiveDevelopment/impls/default/Inspector/Inspector.json"), InspectorJSON = JSON.parse(InspectorText); var i, j, domain, command; diff --git a/src/LiveDevelopment/Inspector/Inspector.json b/src/LiveDevelopment/impls/default/Inspector/Inspector.json similarity index 100% rename from src/LiveDevelopment/Inspector/Inspector.json rename to src/LiveDevelopment/impls/default/Inspector/Inspector.json diff --git a/src/LiveDevelopment/Inspector/inspector.html b/src/LiveDevelopment/impls/default/Inspector/inspector.html similarity index 100% rename from src/LiveDevelopment/Inspector/inspector.html rename to src/LiveDevelopment/impls/default/Inspector/inspector.html diff --git a/src/LiveDevelopment/Inspector/jsdoc.rb b/src/LiveDevelopment/impls/default/Inspector/jsdoc.rb similarity index 100% rename from src/LiveDevelopment/Inspector/jsdoc.rb rename to src/LiveDevelopment/impls/default/Inspector/jsdoc.rb diff --git a/src/LiveDevelopment/LiveDevelopment.js b/src/LiveDevelopment/impls/default/LiveDevelopment.js similarity index 97% rename from src/LiveDevelopment/LiveDevelopment.js rename to src/LiveDevelopment/impls/default/LiveDevelopment.js index 342ba5fb853..92340122790 100644 --- a/src/LiveDevelopment/LiveDevelopment.js +++ b/src/LiveDevelopment/impls/default/LiveDevelopment.js @@ -94,30 +94,30 @@ define(function LiveDevelopment(require, exports, module) { UserServer = require("LiveDevelopment/Servers/UserServer").UserServer; // Inspector - var Inspector = require("LiveDevelopment/Inspector/Inspector"); + var Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"); // Documents - var CSSDocument = require("LiveDevelopment/Documents/CSSDocument"), - CSSPreprocessorDocument = require("LiveDevelopment/Documents/CSSPreprocessorDocument"), - HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument"), - JSDocument = require("LiveDevelopment/Documents/JSDocument"); + var CSSDocument = require("LiveDevelopment/impls/default/Documents/CSSDocument"), + CSSPreprocessorDocument = require("LiveDevelopment/impls/default/Documents/CSSPreprocessorDocument"), + HTMLDocument = require("LiveDevelopment/impls/default/Documents/HTMLDocument"), + JSDocument = require("LiveDevelopment/impls/default/Documents/JSDocument"); // Document errors var SYNC_ERROR_CLASS = "live-preview-sync-error"; // Agents - var CSSAgent = require("LiveDevelopment/Agents/CSSAgent"); + var CSSAgent = require("LiveDevelopment/impls/default/Agents/CSSAgent"); var agents = { - "console" : require("LiveDevelopment/Agents/ConsoleAgent"), - "remote" : require("LiveDevelopment/Agents/RemoteAgent"), - "network" : require("LiveDevelopment/Agents/NetworkAgent"), - "dom" : require("LiveDevelopment/Agents/DOMAgent"), + "console" : require("LiveDevelopment/impls/default/Agents/ConsoleAgent"), + "remote" : require("LiveDevelopment/impls/default/Agents/RemoteAgent"), + "network" : require("LiveDevelopment/impls/default/Agents/NetworkAgent"), + "dom" : require("LiveDevelopment/impls/default/Agents/DOMAgent"), "css" : CSSAgent, - "script" : require("LiveDevelopment/Agents/ScriptAgent"), - "highlight" : require("LiveDevelopment/Agents/HighlightAgent"), - "goto" : require("LiveDevelopment/Agents/GotoAgent"), - "edit" : require("LiveDevelopment/Agents/EditAgent") + "script" : require("LiveDevelopment/impls/default/Agents/ScriptAgent"), + "highlight" : require("LiveDevelopment/impls/default/Agents/HighlightAgent"), + "goto" : require("LiveDevelopment/impls/default/Agents/GotoAgent"), + "edit" : require("LiveDevelopment/impls/default/Agents/EditAgent") }; // construct path to launch.html @@ -133,7 +133,7 @@ define(function LiveDevelopment(require, exports, module) { // baseUrl is configured dynamically launcherUrl = launcherUrl.replace("/test/SpecRunner.html", "/src/index.html"); - launcherUrl = launcherUrl.substr(0, launcherUrl.lastIndexOf("/")) + "/LiveDevelopment/launch.html"; + launcherUrl = launcherUrl.substr(0, launcherUrl.lastIndexOf("/")) + "/LiveDevelopment/impls/default/launch.html"; launcherUrl = window.location.origin + launcherUrl; // Some agents are still experimental, so we don't enable them all by default diff --git a/src/LiveDevelopment/launch.html b/src/LiveDevelopment/impls/default/launch.html similarity index 100% rename from src/LiveDevelopment/launch.html rename to src/LiveDevelopment/impls/default/launch.html diff --git a/src/LiveDevelopment/impls/default/main.js b/src/LiveDevelopment/impls/default/main.js new file mode 100644 index 00000000000..3854e6b9a92 --- /dev/null +++ b/src/LiveDevelopment/impls/default/main.js @@ -0,0 +1,288 @@ +/* + * 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, $, less, window */ + +/** + * main integrates LiveDevelopment into Brackets + * + * This module creates two menu items: + * + * "Go Live": open or close a Live Development session and visualize the status + * "Highlight": toggle source highlighting + */ +define(function main(require, exports, module) { + "use strict"; + + var DocumentManager = require("document/DocumentManager"), + Commands = require("command/Commands"), + AppInit = require("utils/AppInit"), + LiveDevelopment = require("LiveDevelopment/impls/default/LiveDevelopment"), + Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"), + CommandManager = require("command/CommandManager"), + PreferencesManager = require("preferences/PreferencesManager"), + Dialogs = require("widgets/Dialogs"), + DefaultDialogs = require("widgets/DefaultDialogs"), + UrlParams = require("utils/UrlParams").UrlParams, + Strings = require("strings"), + ExtensionUtils = require("utils/ExtensionUtils"), + StringUtils = require("utils/StringUtils"); + + var params = new UrlParams(); + var config = { + experimental: false, // enable experimental features + debug: true, // enable debug output and helpers + autoconnect: false, // go live automatically after startup? + highlight: true, // enable highlighting? + highlightConfig: { // the highlight configuration for the Inspector + borderColor: {r: 255, g: 229, b: 153, a: 0.66}, + contentColor: {r: 111, g: 168, b: 220, a: 0.55}, + marginColor: {r: 246, g: 178, b: 107, a: 0.66}, + paddingColor: {r: 147, g: 196, b: 125, a: 0.66}, + showInfo: true + } + }; + // Status labels/styles are ordered: error, not connected, progress1, progress2, connected. + var _statusTooltip = [ + Strings.LIVE_DEV_STATUS_TIP_NOT_CONNECTED, + Strings.LIVE_DEV_STATUS_TIP_NOT_CONNECTED, + Strings.LIVE_DEV_STATUS_TIP_PROGRESS1, + Strings.LIVE_DEV_STATUS_TIP_PROGRESS2, + Strings.LIVE_DEV_STATUS_TIP_CONNECTED, + Strings.LIVE_DEV_STATUS_TIP_OUT_OF_SYNC, + Strings.LIVE_DEV_STATUS_TIP_SYNC_ERROR + ]; + + var _statusStyle = ["warning", "", "info", "info", "success", "out-of-sync", "sync-error"]; // Status indicator's CSS class + var _allStatusStyles = _statusStyle.join(" "); + + var _$btnGoLive; // reference to the GoLive button + + /** Load Live Development LESS Style */ + function _loadStyles() { + var lessText = require("text!LiveDevelopment/impls/default/main.less"), + parser = new less.Parser(); + + parser.parse(lessText, function onParse(err, tree) { + console.assert(!err, err); + ExtensionUtils.addEmbeddedStyleSheet(tree.toCSS()); + }); + } + + /** + * Change the appearance of a button. Omit text to remove any extra text; omit style to return to default styling; + * omit tooltip to leave tooltip unchanged. + */ + function _setLabel($btn, text, style, tooltip) { + // Clear text/styles from previous status + $("span", $btn).remove(); + $btn.removeClass(_allStatusStyles); + + // Set text/styles for new status + if (text && text.length > 0) { + $("") + .addClass(style) + .text(text) + .appendTo($btn); + } else { + $btn.addClass(style); + } + + if (tooltip) { + $btn.attr("title", tooltip); + } + } + + /** + * Toggles LiveDevelopment and synchronizes the state of UI elements that reports LiveDevelopment status + * + * Stop Live Dev when in an active state (ACTIVE, OUT_OF_SYNC, SYNC_ERROR). + * Start Live Dev when in an inactive state (ERROR, INACTIVE). + * Do nothing when in a connecting state (CONNECTING, LOADING_AGENTS). + */ + function _handleGoLiveCommand() { + if (LiveDevelopment.status >= LiveDevelopment.STATUS_ACTIVE) { + LiveDevelopment.close(); + } else if (LiveDevelopment.status <= LiveDevelopment.STATUS_INACTIVE) { + if (!params.get("skipLiveDevelopmentInfo") && !PreferencesManager.getViewState("livedev.afterFirstLaunch")) { + PreferencesManager.setViewState("livedev.afterFirstLaunch", "true"); + Dialogs.showModalDialog( + DefaultDialogs.DIALOG_ID_INFO, + Strings.LIVE_DEVELOPMENT_INFO_TITLE, + Strings.LIVE_DEVELOPMENT_INFO_MESSAGE + ).done(function (id) { + LiveDevelopment.open(); + }); + } else { + LiveDevelopment.open(); + } + } + } + + /** Called on status change */ + function _showStatusChangeReason(reason) { + // Destroy the previous twipsy (options are not updated otherwise) + _$btnGoLive.twipsy("hide").removeData("twipsy"); + + // If there was no reason or the action was an explicit request by the user, don't show a twipsy + if (!reason || reason === "explicit_close") { + return; + } + + // Translate the reason + var translatedReason = Strings["LIVE_DEV_" + reason.toUpperCase()]; + if (!translatedReason) { + translatedReason = StringUtils.format(Strings.LIVE_DEV_CLOSED_UNKNOWN_REASON, reason); + } + + // Configure the twipsy + var options = { + placement: "left", + trigger: "manual", + autoHideDelay: 5000, + title: function () { + return translatedReason; + } + }; + + // Show the twipsy with the explanation + _$btnGoLive.twipsy(options).twipsy("show"); + } + + /** Create the menu item "Go Live" */ + function _setupGoLiveButton() { + _$btnGoLive = $("#toolbar-go-live"); + _$btnGoLive.click(function onGoLive() { + _handleGoLiveCommand(); + }); + $(LiveDevelopment).on("statusChange", function statusChange(event, status, reason) { + // status starts at -1 (error), so add one when looking up name and style + // See the comments at the top of LiveDevelopment.js for details on the + // various status codes. + _setLabel(_$btnGoLive, null, _statusStyle[status + 1], _statusTooltip[status + 1]); + _showStatusChangeReason(reason); + if (config.autoconnect) { + window.sessionStorage.setItem("live.enabled", status === 3); + } + }); + + // Initialize tooltip for 'not connected' state + _setLabel(_$btnGoLive, null, _statusStyle[1], _statusTooltip[1]); + } + + /** Maintains state of the Live Preview menu item */ + function _setupGoLiveMenu() { + $(LiveDevelopment).on("statusChange", function statusChange(event, status) { + // Update the checkmark next to 'Live Preview' menu item + // Add checkmark when status is STATUS_ACTIVE; otherwise remove it + CommandManager.get(Commands.FILE_LIVE_FILE_PREVIEW).setChecked(status === LiveDevelopment.STATUS_ACTIVE); + CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setEnabled(status === LiveDevelopment.STATUS_ACTIVE); + }); + } + + function _updateHighlightCheckmark() { + CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setChecked(config.highlight); + } + + function _handlePreviewHighlightCommand() { + config.highlight = !config.highlight; + _updateHighlightCheckmark(); + if (config.highlight) { + LiveDevelopment.showHighlight(); + } else { + LiveDevelopment.hideHighlight(); + } + PreferencesManager.setViewState("livedev.highlight", config.highlight); + } + + /** Setup window references to useful LiveDevelopment modules */ + function _setupDebugHelpers() { + window.ld = LiveDevelopment; + window.i = Inspector; + window.report = function report(params) { window.params = params; console.info(params); }; + } + + /** force reload the live preview */ + function _handleReloadLivePreviewCommand() { + if (LiveDevelopment.status >= LiveDevelopment.STATUS_ACTIVE) { + LiveDevelopment.reload(); + } + } + + /** Initialize LiveDevelopment */ + function init() { + params.parse(); + + Inspector.init(config); + LiveDevelopment.init(config); + _loadStyles(); + _setupGoLiveButton(); + _setupGoLiveMenu(); + + _updateHighlightCheckmark(); + + if (config.debug) { + _setupDebugHelpers(); + } + + // trigger autoconnect + if (config.autoconnect && + window.sessionStorage.getItem("live.enabled") === "true" && + DocumentManager.getCurrentDocument()) { + _handleGoLiveCommand(); + } + + // Redraw highlights when window gets focus. This ensures that the highlights + // will be in sync with any DOM changes that may have occurred. + $(window).focus(function () { + if (Inspector.connected() && config.highlight) { + LiveDevelopment.redrawHighlight(); + } + }); + } + + // init prefs + PreferencesManager.stateManager.definePreference("livedev.highlight", "boolean", true) + .on("change", function () { + config.highlight = PreferencesManager.getViewState("livedev.highlight"); + _updateHighlightCheckmark(); + }); + + PreferencesManager.convertPreferences(module, { + "highlight": "user livedev.highlight", + "afterFirstLaunch": "user livedev.afterFirstLaunch" + }, true); + + config.highlight = PreferencesManager.getViewState("livedev.highlight"); + + // init commands + CommandManager.register(Strings.CMD_LIVE_FILE_PREVIEW, Commands.FILE_LIVE_FILE_PREVIEW, _handleGoLiveCommand); + CommandManager.register(Strings.CMD_LIVE_HIGHLIGHT, Commands.FILE_LIVE_HIGHLIGHT, _handlePreviewHighlightCommand); + CommandManager.register(Strings.CMD_RELOAD_LIVE_PREVIEW, Commands.CMD_RELOAD_LIVE_PREVIEW, _handleReloadLivePreviewCommand); + CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setEnabled(false); + + // Export public functions + exports.init = init; +}); diff --git a/src/LiveDevelopment/main.less b/src/LiveDevelopment/impls/default/main.less similarity index 100% rename from src/LiveDevelopment/main.less rename to src/LiveDevelopment/impls/default/main.less diff --git a/src/LiveDevelopment/impls/livedev2/LiveDevelopment.js b/src/LiveDevelopment/impls/livedev2/LiveDevelopment.js new file mode 100644 index 00000000000..b7b4b24ef8c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/LiveDevelopment.js @@ -0,0 +1,911 @@ +/* + * 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, $, brackets, window, open */ + +/** + * LiveDevelopment allows Brackets to launch a browser with a "live preview" that's + * connected to the current editor. + * + * # STARTING + * + * To start a session call `open`. This will read the currentDocument from brackets, + * launch it in the default browser, and connect to it for live editing. + * + * # STOPPING + * + * To stop a session call `close`. This will close the connection to the browser + * (but will not close the browser tab). + * + * # STATUS + * + * (TODO: some of these are likely obsolete in the new architecture) + * Status updates are dispatched as `statusChange` jQuery events. The status + * is passed as the first parameter and the reason for the change as the second + * parameter. Currently only the "Inactive" status supports the reason parameter. + * The status codes are: + * + * -1: Error + * 0: Inactive + * 1: Connecting to the remote debugger + * 2: Loading agents + * 3: Active + * 4: Out of sync + * + * The reason codes are: + * - null (Unknown reason) + * - "explicit_close" (LiveDevelopment.close() was called) + * - "navigated_away" (The browser changed to a location outside of the project) + * - "detached_target_closed" (The tab or window was closed) + * - "detached_replaced_with_devtools" (The developer tools were opened in the browser) + */ +define(function (require, exports, module) { + "use strict"; + + // Status Codes + var STATUS_ERROR = exports.STATUS_ERROR = -1; + var STATUS_INACTIVE = exports.STATUS_INACTIVE = 0; + var STATUS_CONNECTING = exports.STATUS_CONNECTING = 1; + var STATUS_ACTIVE = exports.STATUS_ACTIVE = 2; + var STATUS_OUT_OF_SYNC = exports.STATUS_OUT_OF_SYNC = 3; + var STATUS_SYNC_ERROR = exports.STATUS_SYNC_ERROR = 4; + var STATUS_RELOADING = exports.STATUS_RELOADING = 5; + var STATUS_RESTARTING = exports.STATUS_RESTARTING = 6; + + var Async = require("utils/Async"), + Dialogs = require("widgets/Dialogs"), + DefaultDialogs = require("widgets/DefaultDialogs"), + DocumentManager = require("document/DocumentManager"), + EditorManager = require("editor/EditorManager"), + ExtensionUtils = require("utils/ExtensionUtils"), + FileSystemError = require("filesystem/FileSystemError"), + FileUtils = require("file/FileUtils"), + PreferencesDialogs = require("preferences/PreferencesDialogs"), + ProjectManager = require("project/ProjectManager"), + Strings = require("strings"), + _ = require("thirdparty/lodash"), + LiveDevServerManager = require("LiveDevelopment/LiveDevServerManager"), + NodeSocketTransport = require("LiveDevelopment/impls/livedev2/transports/NodeSocketTransport"), + LiveDevProtocol = require("LiveDevelopment/impls/livedev2/protocol/LiveDevProtocol"); + + // Documents + var LiveCSSDocument = require("LiveDevelopment/impls/livedev2/documents/LiveCSSDocument"), + LiveHTMLDocument = require("LiveDevelopment/impls/livedev2/documents/LiveHTMLDocument"); + + /** + * @private + * The live HTML document for the currently active preview. + * @type {LiveHTMLDocument} + */ + var _liveDocument; + + /** + * @private + * Live documents related to the active HTML document - for example, CSS files + * that are used by the document. + * TODO: this is not yet maintained in the new architecture - will need to be reimplemented. + * @type {Object.} + */ + var _relatedDocuments = {}; + + /** + * @private + * Current transport for communicating with browser instances. See setTransport(). + * @type {{launch: function(string), send: function(number|Array., string), close: function(number)}} + */ + var _transport; + + /** + * @private + * Protocol handler that provides the actual live development API on top of the current transport. + */ + var _protocol = LiveDevProtocol; + + /** + * @private + * Current live preview server + * @type {BaseServer} + */ + var _server; + + /** + * @private + * Returns true if we think the given extension is for an HTML file. + * @param {string} ext The extension to check. + * @return {boolean} true if this is an HTML extension + */ + function _isHtmlFileExt(ext) { + return (FileUtils.isStaticHtmlFileExt(ext) || + (ProjectManager.getBaseUrl() && FileUtils.isServerHtmlFileExt(ext))); + } + + /** + * @private + * Get the current active document from the document manager. + * TODO: might no longer be necessary - there used to be more stuff in here but I think it was + * removed awhile ago. + * @return {?Document} The currently active document, or null for no document. + */ + function _getCurrentDocument() { + return DocumentManager.getCurrentDocument(); + } + + /** + * @private + * Determine which live document class should be used for a given document + * @param {Document} document The document we want to create a live document for. + * @return {function} The constructor for the live document class; will be a subclass of LiveDocument. + */ + function _classForDocument(doc) { + if (doc.getLanguage().getId() === "css") { + return LiveCSSDocument; + } + + if (_isHtmlFileExt(doc.file.fullPath)) { + return LiveHTMLDocument; + } + + return null; + } + + /** + * Returns true if the global Live Development mode is on (might be in the middle of connecting). + * @return {boolean} + */ + function isActive() { + return exports.status > STATUS_INACTIVE; + } + + /** + * Returns the live document for a given path, or null if there is no live document for it. + * @param {string} path + * @return {?LiveDocument} + */ + function getLiveDocForPath(path) { + if (!_server) { + return undefined; + } + + return _server.get(path); + } + + /** + * Returns the live document for a given editor, or null if there is no live document for it. + * @param {Editor} editor + * @return {?LiveDocument} + */ + function getLiveDocForEditor(editor) { + if (!editor) { + return null; + } + return getLiveDocForPath(editor.document.file.fullPath); + } + + /** + * @private + * Close a live document. + * @param {LiveDocument} + */ + function _closeDocument(liveDocument) { + $(liveDocument).off(".livedev"); + liveDocument.close(); + } + + /** + * 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). + * @param {$.Event} event + * @param {LiveDocument} liveDoc + */ + function _handleRelatedDocumentDeleted(url) { + var liveDoc = _relatedDocuments[url]; + if (liveDoc) { + delete _relatedDocuments[url]; + } + + if (_server) { + _server.remove(liveDoc); + } + + _closeDocument(liveDoc); + } + + /** + * Update the status. Triggers a statusChange event. + * @param {number} status new status + * @param {?string} closeReason Optional string key suffix to display to + * user when closing the live development connection (see LIVE_DEV_* keys) + */ + function _setStatus(status, closeReason) { + // Don't send a notification when the status didn't actually change + if (status === exports.status) { + return; + } + + exports.status = status; + + var reason = status === STATUS_INACTIVE ? closeReason : null; + $(exports).triggerHandler("statusChange", [status, reason]); + } + + /** + * @private + * Close all live documents. + */ + function _closeDocuments() { + if (_liveDocument) { + _closeDocument(_liveDocument); + _liveDocument = undefined; + } + + Object.keys(_relatedDocuments).forEach(function (url) { + _closeDocument(_relatedDocuments[url]); + delete _relatedDocuments[url]; + }); + + // Clear all documents from request filtering + if (_server) { + _server.clear(); + } + } + + /** + * @private + * Returns the URL that we would serve the given path at. + * @param {string} path + * @return {string} + */ + function _resolveUrl(path) { + return _server && _server.pathToUrl(path); + } + + /** + * @private + * Create a LiveDocument for a Brackets editor/document to manage communication between the + * editor and the browser. + * @param {Document} doc + * @param {Editor} editor + * @param {roots} roots + * @return {?LiveDocument} The live document, or null if this type of file doesn't support live editing. + */ + function _createLiveDocument(doc, editor, roots) { + var DocClass = _classForDocument(doc), + liveDocument = new DocClass(_protocol, _resolveUrl, doc, editor, roots); + + if (!DocClass) { + return null; + } + + $(liveDocument).on("errorStatusChanged.livedev", function (event, hasErrors) { + if (isActive()) { + _setStatus(hasErrors ? STATUS_SYNC_ERROR : STATUS_ACTIVE); + } + }); + + return liveDocument; + } + + /** + * Documents are considered to be out-of-sync if they are dirty and + * do not have "update while editing" support + * @param {Document} doc + * @return {boolean} + */ + function _docIsOutOfSync(doc) { + var docClass = _classForDocument(doc), + liveDoc = _server && _server.get(doc.file.fullPath), + isLiveEditingEnabled = liveDoc && liveDoc.isLiveEditingEnabled(); + + return doc.isDirty && !isLiveEditingEnabled; + } + + /** + * Handles a notification from the browser that a stylesheet was loaded into + * the live HTML document. If the stylesheet maps to a file in the project, then + * creates a live document for the stylesheet and adds it to _relatedDocuments. + * TODO: this isn't implemented in the prototype yet. We'll need to implement + * this notification on the browser side. + * @param {$.Event} event + * @param {string} url The URL of the stylesheet that was added. + * @param {array} roots The URLs of the roots of the stylesheet (the css files loaded through ) + */ + function _styleSheetAdded(event, url, roots) { + var path = _server && _server.urlToPath(url), + alreadyAdded = !!_relatedDocuments[url]; + + // path may be null if loading an external stylesheet. + // Also, the stylesheet may already exist and be reported as added twice + // due to Chrome reporting added/removed events after incremental changes + // are pushed to the browser + if (!path || alreadyAdded) { + return; + } + + var docPromise = DocumentManager.getDocumentForPath(path); + + docPromise.done(function (doc) { + if ((_classForDocument(doc) === LiveCSSDocument) && + (!_liveDocument || (doc !== _liveDocument.doc))) { + var liveDoc = _createLiveDocument(doc, null, roots); + if (liveDoc) { + _server.add(liveDoc); + _relatedDocuments[doc.url] = liveDoc; + $(liveDoc).on("updateDoc", function (event, url) { + var path = _server.urlToPath(url), + doc = getLiveDocForPath(path); + doc._updateBrowser(); + }); + } + } + }); + } + + /** + * @private + * Determine an index file that can be used to start Live Development. + * This function will inspect all files in a project to find the closest index file + * available for currently opened document. We are searching for these files: + * - index.html + * - index.htm + * + * If the project is configured with a custom base url for live developmment, then + * the list of possible index files is extended to contain these index files too: + * - index.php + * - index.php3 + * - index.php4 + * - index.php5 + * - index.phtm + * - index.phtml + * - index.cfm + * - index.cfml + * - index.asp + * - index.aspx + * - index.jsp + * - index.jspx + * - index.shm + * - index.shml + * + * If a file was found, the promise will be resolved with the full path to this file. If no file + * was found in the whole project tree, the promise will be resolved with null. + * + * @return {jQuery.Promise} A promise that is resolved with a full path + * to a file if one could been determined, or null if there was no suitable index + * file. + */ + function _getInitialDocFromCurrent() { + var doc = _getCurrentDocument(), + refPath, + i; + + // TODO: FileUtils.getParentFolder() + function getParentFolder(path) { + return path.substring(0, path.lastIndexOf('/', path.length - 2) + 1); + } + + function getFilenameWithoutExtension(filename) { + var index = filename.lastIndexOf("."); + return index === -1 ? filename : filename.slice(0, index); + } + + // Is the currently opened document already a file we can use for Live Development? + if (doc) { + refPath = doc.file.fullPath; + if (FileUtils.isStaticHtmlFileExt(refPath) || FileUtils.isServerHtmlFileExt(refPath)) { + return new $.Deferred().resolve(doc); + } + } + + var result = new $.Deferred(); + + var baseUrl = ProjectManager.getBaseUrl(), + hasOwnServerForLiveDevelopment = (baseUrl && baseUrl.length); + + ProjectManager.getAllFiles().done(function (allFiles) { + var projectRoot = ProjectManager.getProjectRoot().fullPath, + containingFolder, + indexFileFound = false, + stillInProjectTree = true; + + if (refPath) { + containingFolder = FileUtils.getDirectoryPath(refPath); + } else { + containingFolder = projectRoot; + } + + var filteredFiltered = allFiles.filter(function (item) { + var parent = getParentFolder(item.fullPath); + + return (containingFolder.indexOf(parent) === 0); + }); + + var filterIndexFile = function (fileInfo) { + if (fileInfo.fullPath.indexOf(containingFolder) === 0) { + if (getFilenameWithoutExtension(fileInfo.name) === "index") { + if (hasOwnServerForLiveDevelopment) { + if ((FileUtils.isServerHtmlFileExt(fileInfo.name)) || + (FileUtils.isStaticHtmlFileExt(fileInfo.name))) { + return true; + } + } else if (FileUtils.isStaticHtmlFileExt(fileInfo.name)) { + return true; + } + } else { + return false; + } + } + }; + + while (!indexFileFound && stillInProjectTree) { + i = _.findIndex(filteredFiltered, filterIndexFile); + + // We found no good match + if (i === -1) { + // traverse the directory tree up one level + containingFolder = getParentFolder(containingFolder); + // Are we still inside the project? + if (containingFolder.indexOf(projectRoot) === -1) { + stillInProjectTree = false; + } + } else { + indexFileFound = true; + } + } + + if (i !== -1) { + DocumentManager.getDocumentForPath(filteredFiltered[i].fullPath).then(result.resolve, result.resolve); + return; + } + + result.resolve(null); + }); + + return result.promise(); + } + + /** + * @private + * Close the connection and the associated window + * @param {boolean} doCloseWindow Use true to close the window/tab in the browser + * @param {?string} reason Optional string key suffix to display to user (see LIVE_DEV_* keys) + */ + function _close(doCloseWindow, reason) { + if (exports.status !== STATUS_INACTIVE) { + // Close live documents + _closeDocuments(); + // Close all active connections + _protocol.closeAllConnections(); + + if (_server) { + // Stop listening for requests when disconnected + _server.stop(); + + // Dispose server + _server = null; + } + } + + // TODO: don't have a way to close windows in the new architecture +// if (doCloseWindow) { +// } + + _setStatus(STATUS_INACTIVE, reason || "explicit_close"); + } + + /** + * Close the connection and the associated window asynchronously + * @return {jQuery.Promise} Resolves once the connection is closed + */ + function close() { + return _close(true); + } + + /** + * @private + * Displays an error when no HTML file can be found to preview. + */ + function _showWrongDocError() { + Dialogs.showModalDialog( + DefaultDialogs.DIALOG_ID_ERROR, + Strings.LIVE_DEVELOPMENT_ERROR_TITLE, + Strings.LIVE_DEV_NEED_HTML_MESSAGE + ); + } + + /** + * @private + * Displays an error when the server for live development files can't be started. + */ + function _showLiveDevServerNotReadyError() { + Dialogs.showModalDialog( + DefaultDialogs.DIALOG_ID_ERROR, + Strings.LIVE_DEVELOPMENT_ERROR_TITLE, + Strings.LIVE_DEV_SERVER_NOT_READY_MESSAGE + ); + } + + /** + * @private + * Creates the main live document for a given HTML document and notifies the server it exists. + * TODO: we should really maintain the list of live documents, not the server. + * @param {Document} doc + */ + function _createLiveDocumentForFrame(doc) { + // create live document + doc._ensureMasterEditor(); + _liveDocument = _createLiveDocument(doc, doc._masterEditor); + _server.add(_liveDocument); + } + + /** + * @private + * Launches the given document in the browser, given that a live document has already + * been created for it. + * @param {Document} doc + */ + function _open(doc) { + if (doc && _liveDocument && doc === _liveDocument.doc) { + if (_server) { + // Launch the URL in the browser. If it's the first one to connect back to us, + // our status will transition to ACTIVE once it does so. + if (exports.status < STATUS_ACTIVE) { + _protocol.launch(_server.pathToUrl(doc.file.fullPath)); + } + if (exports.status === STATUS_RESTARTING) { + // change page in browser + _protocol.navigate(_server.pathToUrl(doc.file.fullPath)); + } + + $(_protocol) + // TODO: timeout if we don't get a connection within a certain time + .on("Connection.connect.livedev", function (event, msg) { + // check for the first connection + if (_protocol.getConnectionIds().length === 1) { + var doc = _getCurrentDocument(); + // check the page that connection comes from matches the current live document session + if (_liveDocument && (msg.url === _resolveUrl(_liveDocument.doc.file.fullPath))) { + _setStatus(STATUS_ACTIVE); + } + } + }) + .on("Connection.close.livedev", function (event, msg) { + // close session when the last connection was closed + if (_protocol.getConnectionIds().length === 0) { + if (exports.status <= STATUS_ACTIVE) { + close("detached_target_closed"); + } + } + }) + // extract stylesheets and create related LiveCSSDocument instances + .on("Document.Related.livedev", function (event, msg) { + var relatedDocs = msg.related; + var docs = Object.keys(relatedDocs.stylesheets); + docs.forEach(function (url) { + _styleSheetAdded(null, url, relatedDocs.stylesheets[url]); + }); + }) + // create new LiveCSSDocument if a new stylesheet is added + .on("Stylesheet.Added.livedev", function (event, msg) { + _styleSheetAdded(null, msg.href, msg.roots); + }) + // remove LiveCSSDocument instance when stylesheet is removed + .on("Stylesheet.Removed.livedev", function (event, msg) { + _handleRelatedDocumentDeleted(msg.href); + }); + } else { + console.error("LiveDevelopment._open(): No server active"); + } + } else { + // Unlikely that we would get to this state where + // a connection is in process but there is no current + // document + close(); + } + } + + /** + * @private + * Creates the live document in preparation for launching the + * preview of the given document, then launches it. (The live document + * must already exist before we launch it so that the server can + * ask it for the instrumented version of the document when the browser + * requests it.) + * TODO: could probably just consolidate this with _open() + * @param {Document} doc + */ + function _doLaunchAfterServerReady(initialDoc) { + + _createLiveDocumentForFrame(initialDoc); + + // start listening for requests + _server.start(); + + // open browser to the url + _open(initialDoc); + } + + /** + * @private + * Create the server in preparation for opening a live preview. + * @param {Document} doc The document we want the server for. Different servers handle + * different types of project (a static server for when no app server is configured, + * vs. a user server when there is an app server set in File > Project Settings). + */ + function _prepareServer(doc) { + var deferred = new $.Deferred(), + showBaseUrlPrompt = false; + + _server = LiveDevServerManager.getServer(doc.file.fullPath); + + // Optionally prompt for a base URL if no server was found but the + // file is a known server file extension + showBaseUrlPrompt = !_server && FileUtils.isServerHtmlFileExt(doc.file.fullPath); + + if (showBaseUrlPrompt) { + // Prompt for a base URL + PreferencesDialogs.showProjectPreferencesDialog("", Strings.LIVE_DEV_NEED_BASEURL_MESSAGE) + .done(function (id) { + if (id === Dialogs.DIALOG_BTN_OK && ProjectManager.getBaseUrl()) { + // If base url is specifed, then re-invoke _prepareServer() to continue + _prepareServer(doc).then(deferred.resolve, deferred.reject); + } else { + deferred.reject(); + } + }); + } else if (_server) { + // Startup the server + var readyPromise = _server.readyToServe(); + if (!readyPromise) { + _showLiveDevServerNotReadyError(); + deferred.reject(); + } else { + readyPromise.then(deferred.resolve, function () { + _showLiveDevServerNotReadyError(); + deferred.reject(); + }); + } + } else { + // No server found + deferred.reject(); + } + + return deferred.promise(); + } + + /** + * @private + * When switching documents, close the current preview and open a new one. + * TODO: closing the current preview doesn't actually work in the new architecture. + */ + function _onDocumentChange() { + var doc = _getCurrentDocument(); + if (!isActive() || !doc) { + return; + } + + // close the current session and begin a new session + var docUrl = _server && _server.pathToUrl(doc.file.fullPath), + isViewable = _server && _server.canServe(doc.file.fullPath); + + if (_liveDocument.doc.url !== docUrl && isViewable) { + // clear live doc and related docs + _closeDocuments(); + + // create new live doc + _createLiveDocumentForFrame(doc); + _setStatus(STATUS_RESTARTING); + _open(doc); + + } + } + + + /** + * Open a live preview on the current docuemnt. + */ + function open() { + // TODO: need to run _onDocumentChange() after load if doc != currentDocument here? Maybe not, since activeEditorChange + // doesn't trigger it, while inline editors can still cause edits in doc other than currentDoc... + _getInitialDocFromCurrent().done(function (doc) { + var prepareServerPromise = (doc && _prepareServer(doc)) || new $.Deferred().reject(), + otherDocumentsInWorkingFiles; + + if (doc && !doc._masterEditor) { + otherDocumentsInWorkingFiles = DocumentManager.getWorkingSet().length; + DocumentManager.addToWorkingSet(doc.file); + + if (!otherDocumentsInWorkingFiles) { + DocumentManager.setCurrentDocument(doc); + } + } + + // wait for server (StaticServer, Base URL or file:) + prepareServerPromise + .done(function () { + _setStatus(STATUS_CONNECTING); + _doLaunchAfterServerReady(doc); + }) + .fail(function () { + _showWrongDocError(); + }); + }); + } + + /** + * For files that don't support as-you-type live editing, but are loaded by live HTML documents + * (e.g. JS files), we want to reload the full document when they're saved. + * TODO: not implemented, see below. + * @param {$.Event} event + * @param {Document} doc + */ + function _onDocumentSaved(event, doc) { + if (!isActive() || !_server) { + return; + } + + var absolutePath = doc.file.fullPath, + liveDocument = absolutePath && _server.get(absolutePath), + liveEditingEnabled = liveDocument && liveDocument.isLiveEditingEnabled && liveDocument.isLiveEditingEnabled(); + + // Skip reload if the saved document has live editing enabled + if (liveEditingEnabled) { + return; + } + + // reload the page if the given document is a JS file related + // to the current live document. + if (_liveDocument.isRelated(absolutePath)) { + if (doc.getLanguage().getId() === "javascript") { + _setStatus(STATUS_RELOADING); + _protocol.reload(); + } + } + } + + /** + * For files that don't support as-you-type live editing, but are loaded by live HTML documents + * (e.g. JS files), we want to show a dirty indicator on the live development icon when they + * have unsaved changes, so the user knows s/he needs to save in order to have the page reload. + * @param {$.Event} event + * @param {Document} doc + */ + function _onDirtyFlagChange(event, doc) { + if (!isActive() || !_server) { + return; + } + + var absolutePath = doc.file.fullPath; + + if (_liveDocument.isRelated(absolutePath)) { + // Set status to out of sync if dirty. Otherwise, set it to active status. + _setStatus(_docIsOutOfSync(doc) ? STATUS_OUT_OF_SYNC : STATUS_ACTIVE); + } + } + + // TODO: These aren't necessary in the prototype because they're related to servers that are + // registered by the original LiveDevelopment feature when it starts up. +// function getCurrentProjectServerConfig() { +// return { +// baseUrl: ProjectManager.getBaseUrl(), +// pathResolver: ProjectManager.makeProjectRelativeIfPossible, +// root: ProjectManager.getProjectRoot().fullPath +// }; +// } +// +// function _createUserServer() { +// return new UserServer(getCurrentProjectServerConfig()); +// } +// +// function _createFileServer() { +// return new FileServer(getCurrentProjectServerConfig()); +// } + + /** + * Sets the current transport mechanism to be used by the live development protocol + * (e.g. socket server, iframe postMessage, etc.) + * @param {{launch: function(string), send: function(number|Array., string), close: function(number), getRemoteScript: function(): ?string}} transport + * The low-level transport. Must provide the following methods: + * + * launch(url): Opens the url in the target browser. + * send(idOrArray, string): Dispatches the given protocol message (provided as a JSON string) to the given client ID + * or array of client IDs. (See the "connect" message for an explanation of client IDs.) + * close(id): Closes the connection to the given client ID. + * getRemoteScript(): Returns a script that should be injected into the page's HTML in order to handle the remote side + * of the transport. Should include the "\n"; + } + + /** + * Returns a script that should be injected into the HTML that's launched in the + * browser in order to handle protocol requests. Includes the \n" + + remoteFunctionsScript; + + } + + /** + * Launches the given URL in the browser. Proxies to the transport. + * @param {string} url + */ + function launch(url) { + _transport.launch(url); + } + + /** + * Protocol method. Evaluates the given script in the browser (in global context), and returns a promise + * that will be fulfilled with the result of the script, if any. + * @param {number|Array.} clients A client ID or array of client IDs that should evaluate + * the script. + * @param {string} script The script to evalute. + * @return {$.Promise} A promise that's resolved with the return value from the first client that responds + * to the evaluation. + * TODO: we should probably have a way of returning the results from all clients, not just the first? + */ + function evaluate(script, clients) { + return _send( + { + method: "Runtime.evaluate", + params: { + expression: script + } + }, + clients + ); + } + + /** + * Protocol method. Reloads the page that is currently loaded into the browser, optionally ignoring cache. + * @param {number|Array.} clients A client ID or array of client IDs that should reload the page. + * @param {boolean} ignoreCache If true, browser cache is ignored. + * @return {$.Promise} A promise that's resolved with the return value from the first client that responds + * to the method. + * TODO: we should probably have a way of returning the results from all clients, not just the first? + */ + function reload(ignoreCache, clients) { + return _send( + { + method: "Page.reload", + params: { + ignoreCache: true + } + }, + clients + ); + } + + /** + * Protocol method. Navigates current page to the given URL. + * @param {number|Array.} clients A client ID or array of client IDs that should navigate to the given URL. + * @param {string} url URL to navigate the page to. + * @return {$.Promise} A promise that's resolved with the return value from the first client that responds + * to the method. + */ + function navigate(url, clients) { + return _send( + { + method: "Page.navigate", + params: { + url: url + } + }, + clients + ); + } + + /** + * Protocol method. Rretrieves the content of a given stylesheet + * @param {number|Array.} clients A client ID or array of client IDs that should navigate to the given URL. + * @param {string} url Absolute URL that identifies the stylesheet. + * @return {$.Promise} A promise that's resolved with the return value from the first client that responds + * to the method. + */ + function getStyleSheetText(url, clients) { + return _send( + { + method: "CSS.getStyleSheetText", + params: { + url: url + } + }, + clients + ); + } + + /** + * Closes the connection to the given client. Proxies to the transport. + * @param {number} clientId + */ + function close(clientId) { + _transport.close(clientId); + } + + function closeAllConnections() { + getConnectionIds().forEach(function (clientId) { + close(clientId); + }); + _connections = {}; + } + + + // public API + exports.setTransport = setTransport; + exports.getRemoteScript = getRemoteScript; + exports.launch = launch; + exports.evaluate = evaluate; + exports.reload = reload; + exports.navigate = navigate; + exports.getStyleSheetText = getStyleSheetText; + exports.close = close; + exports.getConnectionIds = getConnectionIds; + exports.closeAllConnections = closeAllConnections; +}); diff --git a/src/LiveDevelopment/impls/livedev2/protocol/remote/DocumentObserver.js b/src/LiveDevelopment/impls/livedev2/protocol/remote/DocumentObserver.js new file mode 100644 index 00000000000..254c6e3d7e6 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/protocol/remote/DocumentObserver.js @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2014 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. + * + */ + +(function (global) { + "use strict"; + + var ProtocolManager = global._Brackets_LiveDev_ProtocolManager; + + var _document = null; + var _transport; + + + /** + * Common functions. + */ + var Utils = { + + isExternalStylesheet: function (node) { + return (node.nodeName.toUpperCase() === "LINK" && node.rel === "stylesheet" && node.href); + }, + isExternalScript: function (node) { + return (node.nodeName.toUpperCase() === "SCRIPT" && node.src); + } + }; + + /** + * CSS related commands and notifications + */ + var CSS = { + + /** + * Maintains a map of stylesheets loaded thorugh @import rules and their parents. + * Populated by extractImports, consumed by notifyImportsAdded / notifyImportsRemoved. + * @type { + */ + stylesheets : {}, + + /** + * Check the stylesheet that was just added be really loaded + * to be able to extract potential import-ed stylesheets. + * It invokes notifyStylesheetAdded once the sheet is loaded. + * @param {string} href Absolute URL of the stylesheet. + */ + checkForStylesheetLoaded : function (href) { + var self = this; + + + // Inspect CSSRules for @imports: + // styleSheet obejct is required to scan CSSImportRules but + // browsers differ on the implementation of MutationObserver interface. + // Webkit triggers notifications before stylesheets are loaded, + // Firefox does it after loading. + // There are also differences on when 'load' event is triggered for + // the 'link' nodes. Webkit triggers it before stylesheet is loaded. + // Some references to check: + // http://www.phpied.com/when-is-a-stylesheet-really-loaded/ + // http://stackoverflow.com/questions/17747616/webkit-dynamically-created-stylesheet-when-does-it-really-load + // http://stackoverflow.com/questions/11425209/are-dom-mutation-observers-slower-than-dom-mutation-events + // + // TODO: This is just a temporary 'cross-browser' solution, it needs optimization. + var loadInterval = setInterval(function () { + var i; + for (i = 0; i < document.styleSheets.length; i++) { + if (document.styleSheets[i].href === href) { + //clear interval + clearInterval(loadInterval); + // notify stylesheets added + self.notifyStylesheetAdded(href); + break; + } + } + }, 50); + }, + /** + * Send a notification for the stylesheet added and + * its import-ed styleshets based on document.stylesheets diff + * from previous status. It also updates stylesheets status. + */ + notifyStylesheetAdded : function () { + var i, + added = {}, + current, + newStatus; + + current = this.stylesheets; + newStatus = related().stylesheets; + + Object.keys(newStatus).forEach(function (v, i) { + if (!current[v]) { + added[v] = newStatus[v]; + } + }); + + Object.keys(added).forEach(function (v, i) { + _transport.send(JSON.stringify({ + method: "Stylesheet.Added", + href: v, + roots: added[v] + })); + }); + + this.stylesheets = newStatus; + }, + + /** + * Send a notification for the removed stylesheet and + * its import-ed styleshets based on document.stylesheets diff + * from previous status. It also updates stylesheets status. + */ + notifyStylesheetRemoved : function () { + var i, + removed = {}, + newStatus, + current; + + current = this.stylesheets; + newStatus = related().stylesheets; + + Object.keys(current).forEach(function (v, i) { + if (!newStatus[v]) { + removed[v] = current[v]; + } + }); + + Object.keys(removed).forEach(function (v, i) { + _transport.send(JSON.stringify({ + method: "Stylesheet.Removed", + href: v, + roots: removed[v] + })); + }); + + this.stylesheets = newStatus; + } + }; + + + /* process related docs added */ + function _onNodesAdded(nodes) { + var i; + for (i = 0; i < nodes.length; i++) { + //check for Javascript files + if (Utils.isExternalScript(nodes[i])) { + _transport.send(JSON.stringify({ + method: 'Script.Added', + src: nodes[i].src + })); + } + //check for stylesheets + if (Utils.isExternalStylesheet(nodes[i])) { + CSS.checkForStylesheetLoaded(nodes[i].href); + } + } + } + /* process related docs removed */ + function _onNodesRemoved(nodes) { + var i; + //iterate on removed nodes + for (i = 0; i < nodes.length; i++) { + + // check for external JS files + if (Utils.isExternalScript(nodes[i])) { + _transport.send(JSON.stringify({ + method: 'Script.Removed', + src: nodes[i].src + })); + } + //check for external StyleSheets + if (Utils.isExternalStylesheet(nodes[i])) { + CSS.notifyStylesheetRemoved(nodes[i].href); + } + } + } + + function _enableListeners() { + // enable MutationOberver if it's supported + var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; + if (MutationObserver) { + var observer = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + if (mutation.addedNodes.length > 0) { + _onNodesAdded(mutation.addedNodes); + } + if (mutation.removedNodes.length > 0) { + _onNodesRemoved(mutation.removedNodes); + } + }); + }); + observer.observe(_document, { + childList: true, + subtree: true + }); + } else { + // use MutationEvents as fallback + document.addEventListener('DOMNodeInserted', function niLstnr(e) { + _onNodesAdded([e.target]); + }); + document.addEventListener('DOMNodeRemoved', function nrLstnr(e) { + _onNodesRemoved([e.target]); + }); + } + } + + /** + * Retrieves related documents (external CSS and JS files) + * + * @return {{scripts: object, stylesheets: object}} Related scripts and stylesheets + */ + function related() { + + var rel = { + scripts: {}, + stylesheets: {} + }; + var i; + // iterate on document scripts (HTMLCollection doesn't provide forEach iterator). + for (i = 0; i < _document.scripts.length; i++) { + // add only external scripts + if (_document.scripts[i].src) { + rel.scripts[_document.scripts[i].src] = true; + } + } + + var s, j; + //traverse @import rules + var traverseRules = function _traverseRules(sheet, base) { + var i; + if (sheet.href && sheet.cssRules) { + if (rel.stylesheets[sheet.href] === undefined) { + rel.stylesheets[sheet.href] = []; + } + rel.stylesheets[sheet.href].push(base); + + + for (i = 0; i < sheet.cssRules.length; i++) { + if (sheet.cssRules[i].href) { + traverseRules(sheet.cssRules[i].styleSheet, base); + } + } + } + }; + //iterate on document.stylesheets (StyleSheetList doesn't provide forEach iterator). + for (j = 0; j < document.styleSheets.length; j++) { + s = document.styleSheets[j]; + traverseRules(s, s.href); + } + return rel; + } + + /** + * Start listening for events and send initial related documents message. + * + * @param {HTMLDocument} document + * @param {object} transport Live development transport connection + */ + function start(document, transport) { + _transport = transport; + _document = document; + // start listening to node changes + _enableListeners(); + + var rel = related(); + + // send the current status of related docs. + _transport.send(JSON.stringify({ + method: "Document.Related", + related: rel + })); + // initialize stylesheets with current status for further notifications. + CSS.stylesheets = rel.stylesheets; + } + + /** + * Stop listening. + * TODO currently a no-op. + */ + function stop() { + + } + + var DocumentObserver = { + start: start, + stop: stop, + related: related + }; + + ProtocolManager.setDocumentObserver(DocumentObserver); + +}(this)); \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/protocol/remote/ExtendedRemoteFunctions.js b/src/LiveDevelopment/impls/livedev2/protocol/remote/ExtendedRemoteFunctions.js new file mode 100644 index 00000000000..76cf2e2b305 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/protocol/remote/ExtendedRemoteFunctions.js @@ -0,0 +1,63 @@ +/* + * 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, browser: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ +/*global define, $, window, navigator, Node, console */ + +/** + * ExtendRemoteFunctions defines the addtional functions to be executed in the browser. + */ +function ExtendRemoteFunctions(obj) { + "use strict"; + + var ExtendedObj = function () {}; + ExtendedObj.prototype = obj; + + ExtendedObj.prototype.reloadCSS = function reloadCSS(url, text) { + var i, + node; + + var head = document.getElementsByTagName('head')[0]; + // create an style element to replace the one loaded with + var s = document.createElement('style'); + s.type = 'text/css'; + s.appendChild(document.createTextNode(text)); + + for (i = 0; i < document.styleSheets.length; i++) { + node = document.styleSheets[i]; + if (node.ownerNode.id === url) { + head.insertBefore(s, node.ownerNode); // insert the style element here + // now can remove the style element previously created (if any) + node.ownerNode.parentNode.removeChild(node.ownerNode); + } else if (node.href === url && !node.disabled) { + // if the link element to change + head.insertBefore(s, node.ownerNode); // insert the style element here + node.disabled = true; + i++; // since we have just inserted a stylesheet + } + } + s.id = url; + }; + return new ExtendedObj(); +} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/protocol/remote/LiveDevProtocolRemote.js b/src/LiveDevelopment/impls/livedev2/protocol/remote/LiveDevProtocolRemote.js new file mode 100644 index 00000000000..986492e85ce --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/protocol/remote/LiveDevProtocolRemote.js @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2014 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 evil: true */ + +// This is the script that Brackets live development injects into HTML pages in order to +// establish and maintain the live development socket connection. Note that Brackets may +// also inject other scripts via "evaluate" once this has connected back to Brackets. + +(function (global) { + "use strict"; + + // This protocol handler assumes that there is also an injected transport script that + // has the following methods: + // setCallbacks(obj) - a method that takes an object with a "message" callback that + // will be called with the message string whenever a message is received by the transport. + // send(msgStr) - sends the given message string over the transport. + var transport = global._Brackets_LiveDev_Transport; + + + /** + * Manage messaging between Editor and Browser at the protocol layer. + * Handle messages that arrives through the current transport and dispatch them + * to subscribers. Subscribers are handlers that implements remote commands/functions. + * Property 'method' of messages body is used as the 'key' to identify message types. + * Provide a 'send' operation that allows remote commands sending messages to the Editor. + */ + var MessageBroker = { + + /** + * Collection of handlers (subscribers) per each method. + * To be pushed by 'on' and consumed by 'trigger' stored this way: + * handlers[method] = [handler1, handler2, ...] + */ + handlers: {}, + + /** + * Dispatch messages to handlers according to msg.method value. + * @param {Object} msg Message to be dispatched. + */ + trigger: function (msg) { + var msgHandlers; + if (!msg.method) { + // no message type, ignoring it + // TODO: should we trigger a generic event? + console.log("[Brackets LiveDev] Received message without method."); + return; + } + // get handlers for msg.method + msgHandlers = this.handlers[msg.method]; + + if (msgHandlers && msgHandlers.length > 0) { + // invoke handlers with the received message + msgHandlers.forEach(function (handler) { + try { + // TODO: check which context should be used to call handlers here. + handler(msg); + return; + } catch (e) { + console.log("[Brackets LiveDev] Error executing a handler for " + msg.method); + console.log(e.stack); + return; + } + }); + } else { + // no subscribers, ignore it. + // TODO: any other default handling? (eg. specific respond, trigger as a generic event, etc.); + console.log("[Brackets LiveDev] No subscribers for message " + msg.method); + return; + } + }, + + /** + * Send a response of a particular message to the Editor. + * Original message must provide an 'id' property + * @param {Object} orig Original message. + * @param {Object} response Message to be sent as the response. + */ + respond: function (orig, response) { + if (!orig.id) { + console.log("[Brackets LiveDev] Trying to send a response for a message with no ID"); + return; + } + response.id = orig.id; + this.send(response); + }, + + /** + * Subscribe handlers to specific messages. + * @param {string} method Message type. + * @param {function} handler. + * TODO: add handler name or any identification mechanism to then implement 'off'? + */ + on: function (method, handler) { + if (!method || !handler) { + return; + } + if (!this.handlers[method]) { + //initialize array + this.handlers[method] = []; + } + // add handler to the stack + this.handlers[method].push(handler); + }, + + /** + * Send a message to the Editor. + * @param {string} msgStr Message to be sent. + */ + send: function (msgStr) { + transport.send(JSON.stringify(msgStr)); + } + }; + + /** + * Runtime Domain. Implements remote commands for "Runtime.*" + */ + var Runtime = { + /** + * Evaluate an expresion and return its result. + */ + evaluate: function (msg) { + console.log("Runtime.evaluate"); + var result = eval(msg.params.expression); + MessageBroker.respond(msg, { + result: result // TODO: in original protocol this is an object handle + }); + } + }; + + // subscribe handler to method Runtime.evaluate + MessageBroker.on("Runtime.evaluate", Runtime.evaluate); + + /** + * Page Domain. + */ + var Page = { + /** + * Reload the current page optionally ignoring cache. + * @param {Object} msg + */ + reload: function (msg) { + // just reload the page + window.location.reload(msg.params.ignoreCache); + }, + + /** + * Navigate to a different page. + * @param {Object} msg + */ + navigate: function (msg) { + if (msg.params.url) { + // navigate to a new page. + window.location.replace(msg.params.url); + } + } + }; + + // subscribe handler to method Page.reload + MessageBroker.on("Page.reload", Page.reload); + MessageBroker.on("Page.navigate", Page.navigate); + MessageBroker.on("Connection.close", Page.close); + + + + // By the time this executes, there must already be an active transport. + if (!transport) { + console.error("[Brackets LiveDev] No transport set"); + return; + } + + var ProtocolManager = { + + _documentObserver: {}, + + _protocolHandler: {}, + + enable: function () { + transport.setCallbacks(this._protocolHandler); + transport.enable(); + }, + + onConnect: function () { + this._documentObserver.start(window.document, transport); + }, + + onClose: function () { + // TODO: This is absolutely temporary solution. It shows a message + // when the connection has been closed. UX decision to be taken on what to do when + // the session is explicitly closed from the Editor side. If the browser can't be closed, + // this could be an alternative. A better alternative to this could be a redirection + // to a custom static page being served by StaticServer + var body = document.getElementsByTagName("body")[0]; + body.style.opacity = 0.5; + var status = document.createElement("div"); + status.textContent = "Live Development Session has Ended"; + status.style.width = "100%"; + status.style.color = "#fff"; + status.style.backgroundColor = "#ff0000"; + status.style.position = "absolute"; + status.style.top = 0; + status.style.left = 0; + status.style.padding = "0.2em"; + status.style.zIndex = 2227; + body.appendChild(status); + }, + + setDocumentObserver: function (documentOberver) { + if (!documentOberver) { + return; + } + this._documentObserver = documentOberver; + }, + + setProtocolHandler: function (protocolHandler) { + if (!protocolHandler) { + return; + } + this._protocolHandler = protocolHandler; + } + }; + + // exposing ProtocolManager + global._Brackets_LiveDev_ProtocolManager = ProtocolManager; + + /** + * CSS Domain. + */ + var CSS = { + /** + * retrieves the content of the stylesheet + * TODO: it now depends on reloadCSS implementation + */ + getStyleSheetText: function (msg) { + var i, + sheet, + text; + for (i = 0; i < document.styleSheets.length; i++) { + sheet = document.styleSheets[i]; + // if it was not 'reloaded' + if ((!sheet.disabled) && (sheet.href === msg.params.url)) { + var j, + rules = document.styleSheets[i].cssRules; + text = ""; + for (j = 0; j < rules.length; j++) { + text += rules[j].cssText + '\n'; + } + } else if (sheet.ownerNode.id === msg.params.url) { // if it was already 'reloaded' + text = sheet.ownerNode.innerText; + } + } + MessageBroker.respond(msg, { + text: text + }); + } + }; + + MessageBroker.on("CSS.getStyleSheetText", CSS.getStyleSheetText); + + /** + * The remote handler for the protocol. + */ + var ProtocolHandler = { + /** + * Handles a message from the transport. Parses it as JSON and delegates + * to MessageBroker who is in charge of routing them to handlers. + * @param {string} msgStr The protocol message as stringified JSON. + */ + message: function (msgStr) { + var msg; + try { + msg = JSON.parse(msgStr); + } catch (e) { + console.log("[Brackets LiveDev] Invalid Message Received"); + // TODO: we should probably send back an error message here? + return; + } + // delegates handling/routing to MessageBroker. + MessageBroker.trigger(msg); + }, + + close: function (evt) { + ProtocolManager.onClose(); + }, + + connect: function (evt) { + ProtocolManager.onConnect(); + } + }; + + ProtocolManager.setProtocolHandler(ProtocolHandler); + + window.addEventListener('load', function () { + ProtocolManager.enable(); + }); + +}(this)); diff --git a/src/LiveDevelopment/impls/livedev2/styles/images/live_development_sprites.svg b/src/LiveDevelopment/impls/livedev2/styles/images/live_development_sprites.svg new file mode 100644 index 00000000000..7e1c824cf6b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/styles/images/live_development_sprites.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/LiveDevelopment/impls/livedev2/styles/styles.css b/src/LiveDevelopment/impls/livedev2/styles/styles.css new file mode 100644 index 00000000000..cfe7f8d26aa --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/styles/styles.css @@ -0,0 +1,41 @@ +/* + * 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. + * + */ + +#toolbar-go-live-new { + content: ""; + background: url("images/live_development_sprites.svg") 0 0 no-repeat; + width: 24px; + height: 24px; +} +#toolbar-go-live-new.success { + background-position: 0 -24px; +} +#toolbar-go-live-new.info { + background-position: 0 -48px; +} +#toolbar-go-live-new.out-of-sync { + background-position: 0 -72px; +} +#toolbar-go-live-new.sync-error { + background-position: 0 -96px; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/NodeSocketTransport.js b/src/LiveDevelopment/impls/livedev2/transports/NodeSocketTransport.js new file mode 100644 index 00000000000..3d7329e32c6 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/NodeSocketTransport.js @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014 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, $, brackets, window, open */ + +// This transport provides a WebSocket connection between Brackets and a live browser preview. +// This is just a thin wrapper around the Node extension (NodeSocketTransportDomain) that actually +// provides the WebSocket server and handles the communication. We also rely on an injected script in +// the browser for the other end of the transport. + +define(function (require, exports, module) { + "use strict"; + + var FileUtils = require("file/FileUtils"), + NodeDomain = require("utils/NodeDomain"); + + // The script that will be injected into the previewed HTML to handle the other side of the socket connection. + var NodeSocketTransportRemote = require("text!LiveDevelopment/impls/livedev2/transports/remote/NodeSocketTransportRemote.js"); + + // The node extension that actually provides the WebSocket server. + + var domainPath = FileUtils.getNativeBracketsDirectoryPath() + "/" + FileUtils.getNativeModuleDirectoryPath(module) + "/node/NodeSocketTransportDomain"; + + var NodeSocketTransportDomain = new NodeDomain("nodeSocketTransport", domainPath); + + // This must match the port declared in NodeSocketTransportDomain.js. + // TODO: randomize this? + var SOCKET_PORT = 8123; + + /** + * Returns the script that should be injected into the browser to handle the other end of the transport. + * @return {string} + */ + function getRemoteScript() { + return "\n"; + } + + // Events + + // We can simply retrigger the events we receive from the node domain directly, since they're in + // the same format expected by clients of the transport. + ["connect", "message", "close"].forEach(function (type) { + $(NodeSocketTransportDomain).on(type, function () { + console.log("NodeSocketTransport - event - " + type + " - " + JSON.stringify(Array.prototype.slice.call(arguments, 1))); + // Remove the event object from the argument list. + $(exports).triggerHandler(type, Array.prototype.slice.call(arguments, 1)); + }); + }); + + // Exports + + exports.getRemoteScript = getRemoteScript; + + // Proxy the node domain methods directly through, since they have exactly the same + // signatures as the ones we're supposed to provide. + ["launch", "send", "close"].forEach(function (method) { + exports[method] = function () { + var args = Array.prototype.slice.call(arguments); + args.unshift(method); + console.log("NodeSocketTransport - " + args); + NodeSocketTransportDomain.exec.apply(NodeSocketTransportDomain, args); + }; + }); + +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/NodeSocketTransportDomain.js b/src/LiveDevelopment/impls/livedev2/transports/node/NodeSocketTransportDomain.js new file mode 100644 index 00000000000..33c22c78cba --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/NodeSocketTransportDomain.js @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2014 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, maxerr: 50, node: true */ + +(function () { + "use strict"; + + var WebSocketServer = require("ws").Server, + open = require("open"), + _ = require("lodash"); + + /** + * @private + * The WebSocket server we listen for incoming connections on. + * @type {?WebSocketServer} + */ + var _wsServer; + + /** + * @private + * The Brackets domain manager for registering node extensions. + * @type {?DomainManager} + */ + var _domainManager; + + /** + * @private + * The ID that should be allocated to the next client that connects to the transport. + * @type {number} + */ + var _nextClientId = 1; + + /** + * @private + * A map of client IDs to the URL and WebSocket for the given ID. + * @type {Object.} + */ + var _clients = {}; + + // This must match the port declared in NodeSocketTransport.js. + // TODO: randomize this? + var SOCKET_PORT = 8123; + + /** + * @private + * Returns the client info for a given WebSocket, or null if that socket isn't registered. + * @param {WebSocket} ws + * @return {?{id: number, url: string, socket: WebSocket}} + */ + function _clientForSocket(ws) { + return _.find(_clients, function (client) { + return (client.socket === ws); + }); + } + + /** + * @private + * Creates the WebSocketServer and handles incoming connections. + */ + function _createServer() { + if (!_wsServer) { + // TODO: make port configurable, or use random port + _wsServer = new WebSocketServer({port: SOCKET_PORT}); + _wsServer.on("connection", function (ws) { + ws.on("message", function (msg) { + console.log("WebSocketServer - received - " + msg); + var msgObj; + try { + msgObj = JSON.parse(msg); + } catch (e) { + console.error("nodeSocketTransport: Error parsing message: " + msg); + return; + } + + // See the comment in NodeSocketTransportRemote.connect() for why we have an extra + // layer of transport-layer message objects surrounding the protocol messaging. + + if (msgObj.type === "connect") { + if (!msgObj.url) { + console.error("nodeSocketTransport: Malformed connect message: " + msg); + return; + } + var clientId = _nextClientId++; + _clients[clientId] = { + id: clientId, + url: msgObj.url, + socket: ws + }; + console.log("emitting connect event"); + _domainManager.emitEvent("nodeSocketTransport", "connect", [clientId, msgObj.url]); + } else if (msgObj.type === "message") { + var client = _clientForSocket(ws); + if (client) { + _domainManager.emitEvent("nodeSocketTransport", "message", [client.id, msgObj.message]); + } else { + console.error("nodeSocketTransport: Couldn't locate client for message: " + msg); + } + } else { + console.error("nodeSocketTransport: Got bad socket message type: " + msg); + } + }).on("error", function (e) { + // TODO: emit error event + var client = _clientForSocket(ws); + console.error("nodeSocketTransport: Error on socket for client " + JSON.stringify(client) + ": " + e); + }).on("close", function () { + var client = _clientForSocket(ws); + if (client) { + _domainManager.emitEvent("nodeSocketTransport", "close", [client.id]); + delete _clients[client.id]; + } else { + console.error("nodeSocketTransport: Socket closed, but couldn't locate client"); + } + }); + }); + } + } + + /** + * Initializes the socket server, then launches the given URL in the system default browser. + * @param {string} url + */ + function _cmdLaunch(url) { + _createServer(); + open(url); + } + + /** + * Sends a transport-layer message over the socket. + * @param {number|Array.} idOrArray A client ID or array of client IDs to send the message to. + * @param {string} msgStr The message to send as a JSON string. + */ + function _cmdSend(idOrArray, msgStr) { + if (!Array.isArray(idOrArray)) { + idOrArray = [idOrArray]; + } + idOrArray.forEach(function (id) { + var client = _clients[id]; + if (!client) { + console.error("nodeSocketTransport: Couldn't find client ID: " + id); + } else { + client.socket.send(msgStr); + } + }); + } + + /** + * Closes the connection for a given client ID. + * @param {number} clientId + */ + function _cmdClose(clientId) { + var client = _clients[clientId]; + if (client) { + client.socket.close(); + delete _clients[clientId]; + } + } + + /** + * Initializes the domain and registers commands. + * @param {DomainManager} domainManager The DomainManager for the server + */ + function init(domainManager) { + _domainManager = domainManager; + if (!domainManager.hasDomain("nodeSocketTransport")) { + domainManager.registerDomain("nodeSocketTransport", {major: 0, minor: 1}); + } + domainManager.registerCommand( + "nodeSocketTransport", // domain name + "launch", // command name + _cmdLaunch, // command handler function + false, // this command is synchronous in Node + "Launches a given HTML file in the browser for live development", + [{name: "url", // parameters + type: "string", + description: "file:// url to the HTML file"}], + [] + ); + domainManager.registerCommand( + "nodeSocketTransport", // domain name + "send", // command name + _cmdSend, // command handler function + false, // this command is synchronous in Node + "Sends a message to a given client or list of clients", + [ + {name: "idOrArray", type: "number|Array.", description: "id or array of ids to send the message to"}, + {name: "message", type: "string", description: "JSON message to send"} + ], + [] + ); + domainManager.registerCommand( + "nodeSocketTransport", // domain name + "close", // command name + _cmdClose, // command handler function + false, // this command is synchronous in Node + "Closes the connection to a given client", + [ + {name: "id", type: "number", description: "id of connection to close"} + ], + [] + ); + domainManager.registerEvent( + "nodeSocketTransport", + "connect", + [ + {name: "clientID", type: "number", description: "ID of live preview page connecting to live development"}, + {name: "url", type: "string", description: "URL of page that live preview is connecting from"} + ] + ); + domainManager.registerEvent( + "nodeSocketTransport", + "message", + [ + {name: "clientID", type: "number", description: "ID of live preview page sending message"}, + {name: "msg", type: "string", description: "JSON message from client page"} + ] + ); + domainManager.registerEvent( + "nodeSocketTransport", + "close", + [ + {name: "clientID", type: "number", description: "ID of live preview page being closed"} + ] + ); + } + + exports.init = init; + +}()); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/browser-launcher b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/browser-launcher new file mode 100644 index 00000000000..34faf6082bc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/browser-launcher @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=`dirname "$0"` + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../browser-launcher/bin/cmd.js" "$@" + ret=$? +else + node "$basedir/../browser-launcher/bin/cmd.js" "$@" + ret=$? +fi +exit $ret diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/browser-launcher.cmd b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/browser-launcher.cmd new file mode 100644 index 00000000000..2bc5a169e3b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/browser-launcher.cmd @@ -0,0 +1,5 @@ +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\browser-launcher\bin\cmd.js" %* +) ELSE ( + node "%~dp0\..\browser-launcher\bin\cmd.js" %* +) \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/win-detect-browsers b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/win-detect-browsers new file mode 100644 index 00000000000..712354c26d8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/win-detect-browsers @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=`dirname "$0"` + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../win-detect-browsers/bin/detect-browsers" "$@" + ret=$? +else + node "$basedir/../win-detect-browsers/bin/detect-browsers" "$@" + ret=$? +fi +exit $ret diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/win-detect-browsers.cmd b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/win-detect-browsers.cmd new file mode 100644 index 00000000000..789c3b5fff4 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/win-detect-browsers.cmd @@ -0,0 +1,5 @@ +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\win-detect-browsers\bin\detect-browsers" %* +) ELSE ( + node "%~dp0\..\win-detect-browsers\bin\detect-browsers" %* +) \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/wscat b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/wscat new file mode 100644 index 00000000000..06c3b744e48 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/.bin/wscat @@ -0,0 +1 @@ +../ws/bin/wscat \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/.npmignore new file mode 100644 index 00000000000..9046dde51c6 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/.npmignore @@ -0,0 +1,12 @@ +*.markdown +*.md +.git* +Makefile +benchmarks/ +docs/ +examples/ +install.sh +support/ +test/ +.DS_Store +coverage.html diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/.travis.yml new file mode 100644 index 00000000000..a12e3f0fdeb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/LICENSE new file mode 100644 index 00000000000..0c5d22d96df --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2010 Sencha Inc. +Copyright (c) 2011 LearnBoost +Copyright (c) 2011 TJ Holowaychuk + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/Readme.md new file mode 100644 index 00000000000..2cbc066c9b5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/Readme.md @@ -0,0 +1,84 @@ +# Connect [![build status](https://secure.travis-ci.org/senchalabs/connect.png)](http://travis-ci.org/senchalabs/connect) + + Connect is an extensible HTTP server framework for [node](http://nodejs.org), providing high performance "plugins" known as _middleware_. + + Connect is bundled with over _20_ commonly used middleware, including + a logger, session support, cookie parser, and [more](http://senchalabs.github.com/connect). Be sure to view the 2.x [documentation](http://www.senchalabs.org/connect/). + +```js +var connect = require('connect') + , http = require('http'); + +var app = connect() + .use(connect.favicon()) + .use(connect.logger('dev')) + .use(connect.static('public')) + .use(connect.directory('public')) + .use(connect.cookieParser()) + .use(connect.session({ secret: 'my secret here' })) + .use(function(req, res){ + res.end('Hello from Connect!\n'); + }); + +http.createServer(app).listen(3000); +``` + +## Middleware + + - [basicAuth](http://www.senchalabs.org/connect/basicAuth.html) + - [bodyParser](http://www.senchalabs.org/connect/bodyParser.html) + - [compress](http://www.senchalabs.org/connect/compress.html) + - [cookieParser](http://www.senchalabs.org/connect/cookieParser.html) + - [cookieSession](http://www.senchalabs.org/connect/cookieSession.html) + - [csrf](http://www.senchalabs.org/connect/csrf.html) + - [directory](http://www.senchalabs.org/connect/directory.html) + - [errorHandler](http://www.senchalabs.org/connect/errorHandler.html) + - [favicon](http://www.senchalabs.org/connect/favicon.html) + - [json](http://www.senchalabs.org/connect/json.html) + - [limit](http://www.senchalabs.org/connect/limit.html) + - [logger](http://www.senchalabs.org/connect/logger.html) + - [methodOverride](http://www.senchalabs.org/connect/methodOverride.html) + - [multipart](http://www.senchalabs.org/connect/multipart.html) + - [urlencoded](http://www.senchalabs.org/connect/urlencoded.html) + - [query](http://www.senchalabs.org/connect/query.html) + - [responseTime](http://www.senchalabs.org/connect/responseTime.html) + - [session](http://www.senchalabs.org/connect/session.html) + - [static](http://www.senchalabs.org/connect/static.html) + - [staticCache](http://www.senchalabs.org/connect/staticCache.html) + - [subdomains](http://www.senchalabs.org/connect/subdomains.html) + - [vhost](http://www.senchalabs.org/connect/vhost.html) + +## Running Tests + +first: + + $ npm install -d + +then: + + $ make test + +## Contributors + + https://github.com/senchalabs/connect/graphs/contributors + +## Node Compatibility + + Connect `< 1.x` is compatible with node 0.2.x + + + Connect `1.x` is compatible with node 0.4.x + + + Connect `2.x` is compatible with node 0.6.x + + + Connect (_master_) is compatible with node 0.8.x + +## CLA + + [http://sencha.com/cla](http://sencha.com/cla) + +## License + +View the [LICENSE](https://github.com/senchalabs/connect/blob/master/LICENSE) file. The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons used by the `directory` middleware created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/). diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/index.js new file mode 100644 index 00000000000..23240eedaa5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/index.js @@ -0,0 +1,4 @@ + +module.exports = process.env.CONNECT_COV + ? require('./lib-cov/connect') + : require('./lib/connect'); \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/cache.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/cache.js new file mode 100644 index 00000000000..052fcdb3d5c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/cache.js @@ -0,0 +1,81 @@ + +/*! + * Connect - Cache + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Expose `Cache`. + */ + +module.exports = Cache; + +/** + * LRU cache store. + * + * @param {Number} limit + * @api private + */ + +function Cache(limit) { + this.store = {}; + this.keys = []; + this.limit = limit; +} + +/** + * Touch `key`, promoting the object. + * + * @param {String} key + * @param {Number} i + * @api private + */ + +Cache.prototype.touch = function(key, i){ + this.keys.splice(i,1); + this.keys.push(key); +}; + +/** + * Remove `key`. + * + * @param {String} key + * @api private + */ + +Cache.prototype.remove = function(key){ + delete this.store[key]; +}; + +/** + * Get the object stored for `key`. + * + * @param {String} key + * @return {Array} + * @api private + */ + +Cache.prototype.get = function(key){ + return this.store[key]; +}; + +/** + * Add a cache `key`. + * + * @param {String} key + * @return {Array} + * @api private + */ + +Cache.prototype.add = function(key){ + // initialize store + var len = this.keys.push(key); + + // limit reached, invalidate LRU + if (len > this.limit) this.remove(this.keys.shift()); + + var arr = this.store[key] = []; + arr.createdAt = new Date; + return arr; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/connect.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/connect.js new file mode 100644 index 00000000000..72961dca712 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/connect.js @@ -0,0 +1,92 @@ +/*! + * Connect + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter + , proto = require('./proto') + , utils = require('./utils') + , path = require('path') + , basename = path.basename + , fs = require('fs'); + +// node patches + +require('./patch'); + +// expose createServer() as the module + +exports = module.exports = createServer; + +/** + * Framework version. + */ + +exports.version = '2.7.11'; + +/** + * Expose mime module. + */ + +exports.mime = require('./middleware/static').mime; + +/** + * Expose the prototype. + */ + +exports.proto = proto; + +/** + * Auto-load middleware getters. + */ + +exports.middleware = {}; + +/** + * Expose utilities. + */ + +exports.utils = utils; + +/** + * Create a new connect server. + * + * @return {Function} + * @api public + */ + +function createServer() { + function app(req, res, next){ app.handle(req, res, next); } + utils.merge(app, proto); + utils.merge(app, EventEmitter.prototype); + app.route = '/'; + app.stack = []; + for (var i = 0; i < arguments.length; ++i) { + app.use(arguments[i]); + } + return app; +}; + +/** + * Support old `.createServer()` method. + */ + +createServer.createServer = createServer; + +/** + * Auto-load bundled middleware with getters. + */ + +fs.readdirSync(__dirname + '/middleware').forEach(function(filename){ + if (!/\.js$/.test(filename)) return; + var name = basename(filename, '.js'); + function load(){ return require('./middleware/' + name); } + exports.middleware.__defineGetter__(name, load); + exports.__defineGetter__(name, load); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/index.js new file mode 100644 index 00000000000..afc44d91d49 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/index.js @@ -0,0 +1,50 @@ + +/** + * Connect is a middleware framework for node, + * shipping with over 18 bundled middleware and a rich selection of + * 3rd-party middleware. + * + * var app = connect() + * .use(connect.logger('dev')) + * .use(connect.static('public')) + * .use(function(req, res){ + * res.end('hello world\n'); + * }) + * + * http.createServer(app).listen(3000); + * + * Installation: + * + * $ npm install connect + * + * Middleware: + * + * - [basicAuth](https://github.com/expressjs/basic-auth-connect) basic http authentication + * - [cookieParser](https://github.com/expressjs/cookie-parser) cookie parser + * - [compress](https://github.com/expressjs/compression) Gzip compression middleware + * - [csrf](https://github.com/expressjs/csurf) Cross-site request forgery protection + * - [directory](https://github.com/expressjs/serve-index) directory listing middleware + * - [errorHandler](https://github.com/expressjs/errorhandler) flexible error handler + * - [favicon](https://github.com/expressjs/favicon) efficient favicon server (with default icon) + * - [logger](https://github.com/expressjs/morgan) request logger with custom format support + * - [methodOverride](https://github.com/expressjs/method-override) faux HTTP method support + * - [responseTime](https://github.com/expressjs/response-time) calculates response-time and exposes via X-Response-Time + * - [session](https://github.com/expressjs/session) session management support with bundled MemoryStore + * - [static](https://github.com/expressjs/serve-static) streaming static file server supporting `Range` and more + * - [timeout](https://github.com/expressjs/timeout) request timeouts + * - [vhost](https://github.com/expressjs/vhost) virtual host sub-domain mapping middleware + * - [bodyParser](bodyParser.html) extensible request body parser + * - [json](json.html) application/json parser + * - [urlencoded](urlencoded.html) application/x-www-form-urlencoded parser + * - [multipart](multipart.html) multipart/form-data parser + * - [cookieSession](cookieSession.html) cookie-based session support + * - [staticCache](staticCache.html) memory cache layer for the static() middleware + * - [limit](limit.html) limit the bytesize of request bodies + * - [query](query.html) automatic querystring parser, populating `req.query` + * + * Links: + * + * - list of [3rd-party](https://github.com/senchalabs/connect/wiki) middleware + * - GitHub [repository](http://github.com/senchalabs/connect) + * + */ \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/basicAuth.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/basicAuth.js new file mode 100644 index 00000000000..5fbe33ac521 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/basicAuth.js @@ -0,0 +1,24 @@ +/*! + * Connect - basicAuth + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Basic Auth: + * + * Enfore basic authentication by providing a `callback(user, pass)`, + * which must return `true` in order to gain access. Alternatively an async + * method is provided as well, invoking `callback(user, pass, callback)`. Populates + * `req.user`. The final alternative is simply passing username / password + * strings. + * + * See [basic-auth-connect](https://github.com/expressjs/basic-auth-connect) + * + * @param {Function|String} callback or username + * @param {String} realm + * @api public + */ + +module.exports = require('basic-auth-connect'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/bodyParser.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/bodyParser.js new file mode 100644 index 00000000000..14481f56a4e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/bodyParser.js @@ -0,0 +1,68 @@ + +/*! + * Connect - bodyParser + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var multipart = require('./multipart') + , urlencoded = require('./urlencoded') + , json = require('./json'); + +/** + * Body parser: + * + * Status: the multipart body parser will be removed in Connect 3. + * + * Parse request bodies, supports _application/json_, + * _application/x-www-form-urlencoded_, and _multipart/form-data_. + * + * This is equivalent to: + * + * app.use(connect.json()); + * app.use(connect.urlencoded()); + * app.use(connect.multipart()); + * + * Examples: + * + * connect() + * .use(connect.bodyParser()) + * .use(function(req, res) { + * res.end('viewing user ' + req.body.user.name); + * }); + * + * $ curl -d 'user[name]=tj' http://local/ + * $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://local/ + * + * View [json](json.html), [urlencoded](urlencoded.html), and [multipart](multipart.html) for more info. + * + * If you wish to create your own body parser, you may be interested in: + * + * - [raw-body](https://github.com/stream-utils/raw-body) + * - [body](https://github.com/raynos/body) + * + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function bodyParser(options){ + var _urlencoded = urlencoded(options) + , _multipart = multipart(options) + , _json = json(options); + + return function bodyParser(req, res, next) { + _json(req, res, function(err){ + if (err) return next(err); + _urlencoded(req, res, function(err){ + if (err) return next(err); + _multipart(req, res, next); + }); + }); + } +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/compress.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/compress.js new file mode 100644 index 00000000000..5b62e551a4d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/compress.js @@ -0,0 +1,20 @@ +/*! + * Connect - compress + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Compress: + * + * Compress response data with gzip/deflate. + * + * See [compression](https://github.com/expressjs/compression) + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = require('compression'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/cookieParser.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/cookieParser.js new file mode 100644 index 00000000000..80a06e1e4ff --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/cookieParser.js @@ -0,0 +1,19 @@ + +/*! + * Connect - cookieParser + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Cookie parser: + * + * See [cookie-parser](https://github.com/expressjs/cookie-parser) + * + * @param {String} secret + * @return {Function} + * @api public + */ + +module.exports = require('cookie-parser'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/cookieSession.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/cookieSession.js new file mode 100644 index 00000000000..88382a49ea7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/cookieSession.js @@ -0,0 +1,121 @@ +/*! + * Connect - cookieSession + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./../utils') + , Cookie = require('express-session').Cookie + , debug = require('debug')('connect:cookieSession') + , signature = require('cookie-signature') + , url = require('url'); + +/** + * Cookie Session: + * + * Cookie session middleware. + * + * var app = connect(); + * app.use(connect.cookieParser()); + * app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }})); + * + * Options: + * + * - `key` cookie name defaulting to `connect.sess` + * - `secret` prevents cookie tampering + * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` + * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") + * + * Clearing sessions: + * + * To clear the session simply set its value to `null`, + * `cookieSession()` will then respond with a 1970 Set-Cookie. + * + * req.session = null; + * + * If you are interested in more sophisticated solutions, + * you may be interested in: + * + * - [client-sessions](https://github.com/mozilla/node-client-sessions) + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function cookieSession(options){ + // TODO: utilize Session/Cookie to unify API + options = options || {}; + var key = options.key || 'connect.sess' + , trustProxy = options.proxy; + + return function cookieSession(req, res, next) { + + // req.secret is for backwards compatibility + var secret = options.secret || req.secret; + if (!secret) throw new Error('`secret` option required for cookie sessions'); + + // default session + req.session = {}; + var cookie = req.session.cookie = new Cookie(options.cookie); + + // pathname mismatch + var originalPath = url.parse(req.originalUrl).pathname; + if (0 != originalPath.indexOf(cookie.path)) return next(); + + // cookieParser secret + if (!options.secret && req.secret) { + req.session = req.signedCookies[key] || {}; + req.session.cookie = cookie; + } else { + // TODO: refactor + var rawCookie = req.cookies[key]; + if (rawCookie) { + var unsigned = utils.parseSignedCookie(rawCookie, secret); + if (unsigned) { + var original = unsigned; + req.session = utils.parseJSONCookie(unsigned) || {}; + req.session.cookie = cookie; + } + } + } + + res.on('header', function(){ + // removed + if (!req.session) { + debug('clear session'); + cookie.expires = new Date(0); + res.setHeader('Set-Cookie', cookie.serialize(key, '')); + return; + } + + delete req.session.cookie; + + // check security + var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase() + , tls = req.connection.encrypted || (trustProxy && 'https' == proto.split(/\s*,\s*/)[0]); + + // only send secure cookies via https + if (cookie.secure && !tls) return debug('not secured'); + + // serialize + debug('serializing %j', req.session); + var val = 'j:' + JSON.stringify(req.session); + + // compare data, no need to set-cookie if unchanged + if (original == val) return debug('unmodified session'); + + // set-cookie + val = 's:' + signature.sign(val, secret); + val = cookie.serialize(key, val); + debug('set-cookie %j', cookie); + res.setHeader('Set-Cookie', val); + }); + + next(); + }; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/csrf.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/csrf.js new file mode 100644 index 00000000000..360601f2b63 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/csrf.js @@ -0,0 +1,18 @@ +/*! + * Connect - csrf + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Anti CSRF: + * + * CSRF protection middleware. + * + * See [csurf](https://github.com/expressjs/csurf) + * + * @param {Object} options + * @api public + */ + +module.exports = require('csurf'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/directory.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/directory.js new file mode 100644 index 00000000000..01cc7f5921f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/directory.js @@ -0,0 +1,20 @@ + +/*! + * Connect - directory + * Copyright(c) 2011 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Directory: + * + * See [serve-index](https://github.com/expressjs/serve-index) + * + * @param {String} root + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = require('serve-index'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/errorHandler.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/errorHandler.js new file mode 100644 index 00000000000..4df43aef6d4 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/errorHandler.js @@ -0,0 +1,17 @@ +/*! + * Connect - errorHandler + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Error handler: + * + * See [errorHandler](https://github.com/expressjs/errorhandler) + * + * @return {Function} + * @api public + */ + +module.exports = require('errorhandler'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/favicon.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/favicon.js new file mode 100644 index 00000000000..570f5bc2b90 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/favicon.js @@ -0,0 +1,22 @@ +/*! + * Connect - favicon + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Favicon: + * + * By default serves the connect favicon, or the favicon + * located by the given `path`. + * + * See [static-favicon](https://github.com/expressjs/favicon) + * + * @param {String} path + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = require('static-favicon'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/json.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/json.js new file mode 100644 index 00000000000..ef489852049 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/json.js @@ -0,0 +1,87 @@ + +/*! + * Connect - json + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils'); +var getBody = require('raw-body'); + +/** + * JSON: + * + * Parse JSON request bodies, providing the + * parsed object as `req.body`. + * + * Options: + * + * - `strict` when `false` anything `JSON.parse()` accepts will be parsed + * - `reviver` used as the second "reviver" argument for JSON.parse + * - `limit` byte limit [1mb] + * + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function(options){ + options = options || {}; + var strict = options.strict !== false; + var verify = typeof options.verify === 'function' && options.verify; + + return function json(req, res, next) { + if (req._body) return next(); + req.body = req.body || {}; + + if (!utils.hasBody(req)) return next(); + + // check Content-Type + if (!exports.regexp.test(utils.mime(req))) return next(); + + // flag as parsed + req._body = true; + + // parse + getBody(req, { + limit: options.limit || '1mb', + length: req.headers['content-length'], + encoding: 'utf8' + }, function (err, buf) { + if (err) return next(err); + + if (verify) { + try { + verify(req, res, buf) + } catch (err) { + if (!err.status) err.status = 403; + return next(err); + } + } + + var first = buf.trim()[0]; + + if (0 == buf.length) { + return next(utils.error(400, 'invalid json, empty body')); + } + + if (strict && '{' != first && '[' != first) return next(utils.error(400, 'invalid json')); + try { + req.body = JSON.parse(buf, options.reviver); + } catch (err){ + err.body = buf; + err.status = 400; + return next(err); + } + next(); + }) + }; +}; + +exports.regexp = /^application\/([\w!#\$%&\*`\-\.\^~]*\+)?json$/i; + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/limit.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/limit.js new file mode 100644 index 00000000000..2b895f97be8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/limit.js @@ -0,0 +1,89 @@ + +/*! + * Connect - limit + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils'), + brokenPause = utils.brokenPause; + +/** + * Limit: + * + * Status: Deprecated. This middleware will be removed in Connect 3.0. + * If you still wish to use some type of limit middleware, + * you may be interested in: + * + * - [raw-body](https://github.com/stream-utils/raw-body) + * + * Limit request bodies to the given size in `bytes`. + * + * A string representation of the bytesize may also be passed, + * for example "5mb", "200kb", "1gb", etc. + * + * connect() + * .use(connect.limit('5.5mb')) + * .use(handleImageUpload) + * + * @param {Number|String} bytes + * @return {Function} + * @api public + */ + +module.exports = function limit(bytes){ + if ('string' == typeof bytes) bytes = utils.parseBytes(bytes); + if ('number' != typeof bytes) throw new Error('limit() bytes required'); + + if (process.env.NODE_ENV !== 'test') { + console.warn('connect.limit() will be removed in connect 3.0'); + } + + return function limit(req, res, next){ + var received = 0 + , len = req.headers['content-length'] + ? parseInt(req.headers['content-length'], 10) + : null; + + // self-awareness + if (req._limit) return next(); + req._limit = true; + + // limit by content-length + if (len && len > bytes) return next(utils.error(413)); + + // limit + if (brokenPause) { + listen(); + } else { + req.on('newListener', function handler(event) { + if (event !== 'data') return; + + req.removeListener('newListener', handler); + // Start listening at the end of the current loop + // otherwise the request will be consumed too early. + // Sideaffect is `limit` will miss the first chunk, + // but that's not a big deal. + // Unfortunately, the tests don't have large enough + // request bodies to test this. + process.nextTick(listen); + }); + }; + + next(); + + function listen() { + req.on('data', function(chunk) { + received += Buffer.isBuffer(chunk) + ? chunk.length : + Buffer.byteLength(chunk); + + if (received > bytes) req.destroy(); + }); + }; + }; +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/logger.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/logger.js new file mode 100644 index 00000000000..d304100ae08 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/logger.js @@ -0,0 +1,20 @@ +/*! + * Connect - logger + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Logger: + * + * Log requests with the given `options` or a `format` string. + * + * See [morgan](https://github.com/expressjs/morgan) + * + * @param {String|Function|Object} format or options + * @return {Function} + * @api public + */ + +module.exports = require('morgan'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/methodOverride.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/methodOverride.js new file mode 100644 index 00000000000..39006e5c535 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/methodOverride.js @@ -0,0 +1,18 @@ +/*! + * Connect - methodOverride + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Method Override: + * + * See [method-override](https://github.com/expressjs/method-override) + * + * @param {String} key + * @return {Function} + * @api public + */ + +module.exports = require('method-override'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/multipart.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/multipart.js new file mode 100644 index 00000000000..8bf66389282 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/multipart.js @@ -0,0 +1,171 @@ +/*! + * Connect - multipart + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var multiparty = require('multiparty') + , _limit = require('./limit') + , utils = require('../utils') + , qs = require('qs'); + +/** + * Multipart: + * + * Status: Deprecated. The multipart parser will be removed in Connect 3.0. + * Please use one of the following parsers/middleware directly: + * + * - [formidable](https://github.com/felixge/node-formidable) + * - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) or [multiparty] + * - [connect-busboy](https://github.com/mscdex/connect-busboy) or [busboy](https://github.com/mscdex/busboy) + * + * Parse multipart/form-data request bodies, + * providing the parsed object as `req.body` + * and `req.files`. + * + * Configuration: + * + * The options passed are merged with [multiparty](https://github.com/superjoe30/node-multiparty)'s + * `Form` object, allowing you to configure the upload directory, + * size limits, etc. For example if you wish to change the upload dir do the following. + * + * app.use(connect.multipart({ uploadDir: path })); + * + * Options: + * + * - `limit` byte limit defaulting to [100mb] + * - `defer` defers processing and exposes the multiparty form object as `req.form`. + * `next()` is called without waiting for the form's "end" event. + * This option is useful if you need to bind to the "progress" or "part" events, for example. + * + * Temporary Files: + * + * By default temporary files are used, stored in `os.tmpDir()`. These + * are not automatically garbage collected, you are in charge of moving them + * or deleting them. When `defer` is not used and these files are created you + * may refernce them via the `req.files` object. + * + * req.files.images.forEach(function(file){ + * console.log(' uploaded : %s %skb : %s', file.originalFilename, file.size / 1024 | 0, file.path); + * }); + * + * It is highly recommended to monitor and clean up tempfiles in any production + * environment, you may use tools like [reap](https://github.com/visionmedia/reap) + * to do so. + * + * Streaming: + * + * When `defer` is used files are _not_ streamed to tmpfiles, you may + * access them via the "part" events and stream them accordingly: + * + * req.form.on('part', function(part){ + * // transfer to s3 etc + * console.log('upload %s %s', part.name, part.filename); + * var out = fs.createWriteStream('/tmp/' + part.filename); + * part.pipe(out); + * }); + * + * req.form.on('close', function(){ + * res.end('uploaded!'); + * }); + * + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function(options){ + options = options || {}; + + if (process.env.NODE_ENV !== 'test') { + console.warn('connect.multipart() will be removed in connect 3.0'); + console.warn('visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives'); + } + + var limit = _limit(options.limit || '100mb'); + + return function multipart(req, res, next) { + if (req._body) return next(); + req.body = req.body || {}; + req.files = req.files || {}; + + if (!utils.hasBody(req)) return next(); + + // ignore GET + if ('GET' == req.method || 'HEAD' == req.method) return next(); + + // check Content-Type + if ('multipart/form-data' != utils.mime(req)) return next(); + + // flag as parsed + req._body = true; + + // parse + limit(req, res, function(err){ + if (err) return next(err); + + var form = new multiparty.Form(options) + , data = {} + , files = {} + , done; + + Object.keys(options).forEach(function(key){ + form[key] = options[key]; + }); + + function ondata(name, val, data){ + if (Array.isArray(data[name])) { + data[name].push(val); + } else if (data[name]) { + data[name] = [data[name], val]; + } else { + data[name] = val; + } + } + + form.on('field', function(name, val){ + ondata(name, val, data); + }); + + if (!options.defer) { + form.on('file', function(name, val){ + val.name = val.originalFilename; + val.type = val.headers['content-type'] || null; + ondata(name, val, files); + }); + } + + form.on('error', function(err){ + if (!options.defer) { + err.status = 400; + next(err); + } + done = true; + }); + + form.on('close', function(){ + if (done) return; + try { + req.body = qs.parse(data); + req.files = qs.parse(files); + } catch (err) { + form.emit('error', err); + return; + } + if (!options.defer) next(); + }); + + form.parse(req); + + if (options.defer) { + req.form = form; + next(); + } + }); + } +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/query.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/query.js new file mode 100644 index 00000000000..f0fb50fc5c9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/query.js @@ -0,0 +1,47 @@ +/*! + * Connect - query + * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var qs = require('qs') + , parse = require('../utils').parseUrl; + +/** + * Query: + * + * Automatically parse the query-string when available, + * populating the `req.query` object using + * [qs](https://github.com/visionmedia/node-querystring). + * + * Examples: + * + * connect() + * .use(connect.query()) + * .use(function(req, res){ + * res.end(JSON.stringify(req.query)); + * }); + * + * The `options` passed are provided to qs.parse function. + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function query(options){ + return function query(req, res, next){ + if (!req.query) { + req.query = ~req.url.indexOf('?') + ? qs.parse(parse(req).query, options) + : {}; + } + + next(); + }; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/responseTime.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/responseTime.js new file mode 100644 index 00000000000..c8168ccc001 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/responseTime.js @@ -0,0 +1,17 @@ + +/*! + * Connect - responseTime + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Reponse time: + * + * See [response-time](https://github.com/expressjs/response-time) + * + * @return {Function} + * @api public + */ + +module.exports = require('response-time'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/session.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/session.js new file mode 100644 index 00000000000..a3c6331a864 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/session.js @@ -0,0 +1,20 @@ +/*! + * Connect - session + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Session: + * + * Setup session store with the given `options`. + * + * See [express-session](https://github.com/expressjs/session) + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = require('express-session'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/static.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/static.js new file mode 100644 index 00000000000..aef56ae8285 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/static.js @@ -0,0 +1,19 @@ +/*! + * Connect - static + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Static: + * + * See [serve-static](https://github.com/expressjs/serve-static) + * + * @param {String} root + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = require('serve-static'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/staticCache.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/staticCache.js new file mode 100644 index 00000000000..66d3c1f6286 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/staticCache.js @@ -0,0 +1,238 @@ + +/*! + * Connect - staticCache + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , Cache = require('../cache') + , fresh = require('fresh'); + +/** + * Static cache: + * + * Status: Deprecated. This middleware will be removed in + * Connect 3.0. You may be interested in: + * + * - [st](https://github.com/isaacs/st) + * + * Enables a memory cache layer on top of + * the `static()` middleware, serving popular + * static files. + * + * By default a maximum of 128 objects are + * held in cache, with a max of 256k each, + * totalling ~32mb. + * + * A Least-Recently-Used (LRU) cache algo + * is implemented through the `Cache` object, + * simply rotating cache objects as they are + * hit. This means that increasingly popular + * objects maintain their positions while + * others get shoved out of the stack and + * garbage collected. + * + * Benchmarks: + * + * static(): 2700 rps + * node-static: 5300 rps + * static() + staticCache(): 7500 rps + * + * Options: + * + * - `maxObjects` max cache objects [128] + * - `maxLength` max cache object length 256kb + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function staticCache(options){ + var options = options || {} + , cache = new Cache(options.maxObjects || 128) + , maxlen = options.maxLength || 1024 * 256; + + if (process.env.NODE_ENV !== 'test') { + console.warn('connect.staticCache() is deprecated and will be removed in 3.0'); + console.warn('use varnish or similar reverse proxy caches.'); + } + + return function staticCache(req, res, next){ + var key = cacheKey(req) + , ranges = req.headers.range + , hasCookies = req.headers.cookie + , hit = cache.get(key); + + // cache static + // TODO: change from staticCache() -> cache() + // and make this work for any request + req.on('static', function(stream){ + var headers = res._headers + , cc = utils.parseCacheControl(headers['cache-control'] || '') + , contentLength = headers['content-length'] + , hit; + + // dont cache set-cookie responses + if (headers['set-cookie']) return hasCookies = true; + + // dont cache when cookies are present + if (hasCookies) return; + + // ignore larger files + if (!contentLength || contentLength > maxlen) return; + + // don't cache partial files + if (headers['content-range']) return; + + // dont cache items we shouldn't be + // TODO: real support for must-revalidate / no-cache + if ( cc['no-cache'] + || cc['no-store'] + || cc['private'] + || cc['must-revalidate']) return; + + // if already in cache then validate + if (hit = cache.get(key)){ + if (headers.etag == hit[0].etag) { + hit[0].date = new Date; + return; + } else { + cache.remove(key); + } + } + + // validation notifiactions don't contain a steam + if (null == stream) return; + + // add the cache object + var arr = []; + + // store the chunks + stream.on('data', function(chunk){ + arr.push(chunk); + }); + + // flag it as complete + stream.on('end', function(){ + var cacheEntry = cache.add(key); + delete headers['x-cache']; // Clean up (TODO: others) + cacheEntry.push(200); + cacheEntry.push(headers); + cacheEntry.push.apply(cacheEntry, arr); + }); + }); + + if (req.method == 'GET' || req.method == 'HEAD') { + if (ranges) { + next(); + } else if (!hasCookies && hit && !mustRevalidate(req, hit)) { + res.setHeader('X-Cache', 'HIT'); + respondFromCache(req, res, hit); + } else { + res.setHeader('X-Cache', 'MISS'); + next(); + } + } else { + next(); + } + } +}; + +/** + * Respond with the provided cached value. + * TODO: Assume 200 code, that's iffy. + * + * @param {Object} req + * @param {Object} res + * @param {Object} cacheEntry + * @return {String} + * @api private + */ + +function respondFromCache(req, res, cacheEntry) { + var status = cacheEntry[0] + , headers = utils.merge({}, cacheEntry[1]) + , content = cacheEntry.slice(2); + + headers.age = (new Date - new Date(headers.date)) / 1000 || 0; + + switch (req.method) { + case 'HEAD': + res.writeHead(status, headers); + res.end(); + break; + case 'GET': + if (utils.conditionalGET(req) && fresh(req.headers, headers)) { + headers['content-length'] = 0; + res.writeHead(304, headers); + res.end(); + } else { + res.writeHead(status, headers); + + function write() { + while (content.length) { + if (false === res.write(content.shift())) { + res.once('drain', write); + return; + } + } + res.end(); + } + + write(); + } + break; + default: + // This should never happen. + res.writeHead(500, ''); + res.end(); + } +} + +/** + * Determine whether or not a cached value must be revalidated. + * + * @param {Object} req + * @param {Object} cacheEntry + * @return {String} + * @api private + */ + +function mustRevalidate(req, cacheEntry) { + var cacheHeaders = cacheEntry[1] + , reqCC = utils.parseCacheControl(req.headers['cache-control'] || '') + , cacheCC = utils.parseCacheControl(cacheHeaders['cache-control'] || '') + , cacheAge = (new Date - new Date(cacheHeaders.date)) / 1000 || 0; + + if ( cacheCC['no-cache'] + || cacheCC['must-revalidate'] + || cacheCC['proxy-revalidate']) return true; + + if (reqCC['no-cache']) return true; + + if (null != reqCC['max-age']) return reqCC['max-age'] < cacheAge; + + if (null != cacheCC['max-age']) return cacheCC['max-age'] < cacheAge; + + return false; +} + +/** + * The key to use in the cache. For now, this is the URL path and query. + * + * 'http://example.com?key=value' -> '/?key=value' + * + * @param {Object} req + * @return {String} + * @api private + */ + +function cacheKey(req) { + return utils.parseUrl(req).path; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/timeout.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/timeout.js new file mode 100644 index 00000000000..ec5edc3bb5a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/timeout.js @@ -0,0 +1,23 @@ +/*! + * Connect - timeout + * Ported from https://github.com/LearnBoost/connect-timeout + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var debug = require('debug')('connect:timeout'); + +/** + * Timeout: + * + * See [connect-timeout](https://github.com/expressjs/timeout) + * + * @param {Number} ms + * @return {Function} + * @api public + */ + +module.exports = require('connect-timeout'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/urlencoded.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/urlencoded.js new file mode 100644 index 00000000000..b94868d869b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/urlencoded.js @@ -0,0 +1,76 @@ +/*! + * Connect - urlencoded + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils'); +var getBody = require('raw-body'); +var qs = require('qs'); + +/** + * Urlencoded: + * + * Parse x-ww-form-urlencoded request bodies, + * providing the parsed object as `req.body` using + * [qs](https://github.com/visionmedia/node-querystring). + * + * Options: + * + * - `limit` byte limit [1mb] + * + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function(options){ + options = options || {}; + var verify = typeof options.verify === 'function' && options.verify; + + return function urlencoded(req, res, next) { + if (req._body) return next(); + req.body = req.body || {}; + + if (!utils.hasBody(req)) return next(); + + // check Content-Type + if ('application/x-www-form-urlencoded' != utils.mime(req)) return next(); + + // flag as parsed + req._body = true; + + // parse + getBody(req, { + limit: options.limit || '1mb', + length: req.headers['content-length'], + encoding: 'utf8' + }, function (err, buf) { + if (err) return next(err); + + if (verify) { + try { + verify(req, res, buf) + } catch (err) { + if (!err.status) err.status = 403; + return next(err); + } + } + + try { + req.body = buf.length + ? qs.parse(buf) + : {}; + } catch (err){ + err.body = buf; + return next(err); + } + next(); + }) + } +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/vhost.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/vhost.js new file mode 100644 index 00000000000..e193bd6b3ab --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/middleware/vhost.js @@ -0,0 +1,20 @@ + +/*! + * Connect - vhost + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Vhost: + * + * See [vhost](https://github.com/expressjs/vhost) + * + * @param {String} hostname + * @param {Server} server + * @return {Function} + * @api public + */ + +module.exports = require('vhost'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/patch.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/patch.js new file mode 100644 index 00000000000..22bcbc62c04 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/patch.js @@ -0,0 +1,89 @@ + +/*! + * Connect + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , res = http.ServerResponse.prototype + , setHeader = res.setHeader + , _renderHeaders = res._renderHeaders + , writeHead = res.writeHead; + +// apply only once + +if (!res._hasConnectPatch) { + + /** + * Provide a public "header sent" flag + * until node does. + * + * @return {Boolean} + * @api public + */ + + res.__defineGetter__('headerSent', function(){ + return this._header; + }); + + /** + * Set header `field` to `val`, special-casing + * the `Set-Cookie` field for multiple support. + * + * @param {String} field + * @param {String} val + * @api public + */ + + res.setHeader = function(field, val){ + var key = field.toLowerCase() + , prev; + + // special-case Set-Cookie + if (this._headers && 'set-cookie' == key) { + if (prev = this.getHeader(field)) { + if (Array.isArray(prev)) { + val = prev.concat(val); + } else if (Array.isArray(val)) { + val = val.concat(prev); + } else { + val = [prev, val]; + } + } + // charset + } else if ('content-type' == key && this.charset) { + val += '; charset=' + this.charset; + } + + return setHeader.call(this, field, val); + }; + + /** + * Proxy to emit "header" event. + */ + + res._renderHeaders = function(){ + if (!this._emittedHeader) this.emit('header'); + this._emittedHeader = true; + return _renderHeaders.call(this); + }; + + res.writeHead = function(statusCode, reasonPhrase, headers){ + if (typeof reasonPhrase === 'object') headers = reasonPhrase; + if (typeof headers === 'object') { + Object.keys(headers).forEach(function(key){ + this.setHeader(key, headers[key]); + }, this); + } + if (!this._emittedHeader) this.emit('header'); + this._emittedHeader = true; + return writeHead.call(this, statusCode, reasonPhrase); + }; + + res._hasConnectPatch = true; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/proto.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/proto.js new file mode 100644 index 00000000000..a945bc28b1d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/proto.js @@ -0,0 +1,233 @@ +/*! + * Connect - HTTPServer + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , utils = require('./utils') + , debug = require('debug')('connect:dispatcher'); + +// prototype + +var app = module.exports = {}; + +// environment + +var env = process.env.NODE_ENV || 'development'; + +/** + * Utilize the given middleware `handle` to the given `route`, + * defaulting to _/_. This "route" is the mount-point for the + * middleware, when given a value other than _/_ the middleware + * is only effective when that segment is present in the request's + * pathname. + * + * For example if we were to mount a function at _/admin_, it would + * be invoked on _/admin_, and _/admin/settings_, however it would + * not be invoked for _/_, or _/posts_. + * + * Examples: + * + * var app = connect(); + * app.use(connect.favicon()); + * app.use(connect.logger()); + * app.use(connect.static(__dirname + '/public')); + * + * If we wanted to prefix static files with _/public_, we could + * "mount" the `static()` middleware: + * + * app.use('/public', connect.static(__dirname + '/public')); + * + * This api is chainable, so the following is valid: + * + * connect() + * .use(connect.favicon()) + * .use(connect.logger()) + * .use(connect.static(__dirname + '/public')) + * .listen(3000); + * + * @param {String|Function|Server} route, callback or server + * @param {Function|Server} callback or server + * @return {Server} for chaining + * @api public + */ + +app.use = function(route, fn){ + // default route to '/' + if ('string' != typeof route) { + fn = route; + route = '/'; + } + + // wrap sub-apps + if ('function' == typeof fn.handle) { + var server = fn; + fn.route = route; + fn = function(req, res, next){ + server.handle(req, res, next); + }; + } + + // wrap vanilla http.Servers + if (fn instanceof http.Server) { + fn = fn.listeners('request')[0]; + } + + // strip trailing slash + if ('/' == route[route.length - 1]) { + route = route.slice(0, -1); + } + + // add the middleware + debug('use %s %s', route || '/', fn.name || 'anonymous'); + this.stack.push({ route: route, handle: fn }); + + return this; +}; + +/** + * Handle server requests, punting them down + * the middleware stack. + * + * @api private + */ + +app.handle = function(req, res, out) { + var stack = this.stack + , search = 1 + req.url.indexOf('?') + , pathlength = search ? search - 1 : req.url.length + , fqdn = 1 + req.url.substr(0, pathlength).indexOf('://') + , protohost = fqdn ? req.url.substr(0, req.url.indexOf('/', 2 + fqdn)) : '' + , removed = '' + , slashAdded = false + , index = 0; + + function next(err) { + var layer, path, c; + + if (slashAdded) { + req.url = req.url.substr(1); + slashAdded = false; + } + + req.url = protohost + removed + req.url.substr(protohost.length); + req.originalUrl = req.originalUrl || req.url; + removed = ''; + + // next callback + layer = stack[index++]; + + // all done + if (!layer || res.headerSent) { + // delegate to parent + if (out) return out(err); + + // unhandled error + if (err) { + // default to 500 + if (res.statusCode < 400) res.statusCode = 500; + debug('default %s', res.statusCode); + + // respect err.status + if (err.status) res.statusCode = err.status; + + // production gets a basic error message + var msg = 'production' == env + ? http.STATUS_CODES[res.statusCode] + : err.stack || err.toString(); + msg = utils.escape(msg); + + // log to stderr in a non-test env + if ('test' != env) console.error(err.stack || err.toString()); + if (res.headerSent) return req.socket.destroy(); + res.setHeader('Content-Type', 'text/html'); + res.setHeader('Content-Length', Buffer.byteLength(msg)); + if ('HEAD' == req.method) return res.end(); + res.end(msg); + } else { + debug('default 404'); + res.statusCode = 404; + res.setHeader('Content-Type', 'text/html'); + if ('HEAD' == req.method) return res.end(); + res.end('Cannot ' + utils.escape(req.method) + ' ' + utils.escape(req.originalUrl) + '\n'); + } + return; + } + + try { + path = utils.parseUrl(req).pathname; + if (undefined == path) path = '/'; + + // skip this layer if the route doesn't match. + if (0 != path.toLowerCase().indexOf(layer.route.toLowerCase())) return next(err); + + c = path[layer.route.length]; + if (c && '/' != c && '.' != c) return next(err); + + // Call the layer handler + // Trim off the part of the url that matches the route + removed = layer.route; + req.url = protohost + req.url.substr(protohost.length + removed.length); + + // Ensure leading slash + if (!fqdn && '/' != req.url[0]) { + req.url = '/' + req.url; + slashAdded = true; + } + + debug('%s %s : %s', layer.handle.name || 'anonymous', layer.route, req.originalUrl); + var arity = layer.handle.length; + if (err) { + if (arity === 4) { + layer.handle(err, req, res, next); + } else { + next(err); + } + } else if (arity < 4) { + layer.handle(req, res, next); + } else { + next(); + } + } catch (e) { + next(e); + } + } + next(); +}; + +/** + * Listen for connections. + * + * This method takes the same arguments + * as node's `http.Server#listen()`. + * + * HTTP and HTTPS: + * + * If you run your application both as HTTP + * and HTTPS you may wrap them individually, + * since your Connect "server" is really just + * a JavaScript `Function`. + * + * var connect = require('connect') + * , http = require('http') + * , https = require('https'); + * + * var app = connect(); + * + * http.createServer(app).listen(80); + * https.createServer(options, app).listen(443); + * + * @return {http.Server} + * @api public + */ + +app.listen = function(){ + var server = http.createServer(this); + return server.listen.apply(server, arguments); +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/utils.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/utils.js new file mode 100644 index 00000000000..d79f15dc73b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/lib/utils.js @@ -0,0 +1,409 @@ + +/*! + * Connect - utils + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , crypto = require('crypto') + , parse = require('url').parse + , sep = require('path').sep + , signature = require('cookie-signature') + , nodeVersion = process.versions.node.split('.'); + +// pause is broken in node < 0.10 +exports.brokenPause = parseInt(nodeVersion[0], 10) === 0 + && parseInt(nodeVersion[1], 10) < 10; + +/** + * Return `true` if the request has a body, otherwise return `false`. + * + * @param {IncomingMessage} req + * @return {Boolean} + * @api private + */ + +exports.hasBody = function(req) { + var encoding = 'transfer-encoding' in req.headers; + var length = 'content-length' in req.headers && req.headers['content-length'] !== '0'; + return encoding || length; +}; + +/** + * Extract the mime type from the given request's + * _Content-Type_ header. + * + * @param {IncomingMessage} req + * @return {String} + * @api private + */ + +exports.mime = function(req) { + var str = req.headers['content-type'] || '' + , i = str.indexOf(';'); + return ~i ? str.slice(0, i) : str; +}; + +/** + * Generate an `Error` from the given status `code` + * and optional `msg`. + * + * @param {Number} code + * @param {String} msg + * @return {Error} + * @api private + */ + +exports.error = function(code, msg){ + var err = new Error(msg || http.STATUS_CODES[code]); + err.status = code; + return err; +}; + +/** + * Return md5 hash of the given string and optional encoding, + * defaulting to hex. + * + * utils.md5('wahoo'); + * // => "e493298061761236c96b02ea6aa8a2ad" + * + * @param {String} str + * @param {String} encoding + * @return {String} + * @api private + */ + +exports.md5 = function(str, encoding){ + return crypto + .createHash('md5') + .update(str, 'utf8') + .digest(encoding || 'hex'); +}; + +/** + * Merge object b with object a. + * + * var a = { foo: 'bar' } + * , b = { bar: 'baz' }; + * + * utils.merge(a, b); + * // => { foo: 'bar', bar: 'baz' } + * + * @param {Object} a + * @param {Object} b + * @return {Object} + * @api private + */ + +exports.merge = function(a, b){ + if (a && b) { + for (var key in b) { + a[key] = b[key]; + } + } + return a; +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Sign the given `val` with `secret`. + * + * @param {String} val + * @param {String} secret + * @return {String} + * @api private + */ + +exports.sign = function(val, secret){ + console.warn('do not use utils.sign(), use https://github.com/visionmedia/node-cookie-signature') + return val + '.' + crypto + .createHmac('sha256', secret) + .update(val) + .digest('base64') + .replace(/=+$/, ''); +}; + +/** + * Unsign and decode the given `val` with `secret`, + * returning `false` if the signature is invalid. + * + * @param {String} val + * @param {String} secret + * @return {String|Boolean} + * @api private + */ + +exports.unsign = function(val, secret){ + console.warn('do not use utils.unsign(), use https://github.com/visionmedia/node-cookie-signature') + var str = val.slice(0, val.lastIndexOf('.')); + return exports.sign(str, secret) == val + ? str + : false; +}; + +/** + * Parse signed cookies, returning an object + * containing the decoded key/value pairs, + * while removing the signed key from `obj`. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.parseSignedCookies = function(obj, secret){ + var ret = {}; + Object.keys(obj).forEach(function(key){ + var val = obj[key]; + if (0 == val.indexOf('s:')) { + val = signature.unsign(val.slice(2), secret); + if (val) { + ret[key] = val; + delete obj[key]; + } + } + }); + return ret; +}; + +/** + * Parse a signed cookie string, return the decoded value + * + * @param {String} str signed cookie string + * @param {String} secret + * @return {String} decoded value + * @api private + */ + +exports.parseSignedCookie = function(str, secret){ + return 0 == str.indexOf('s:') + ? signature.unsign(str.slice(2), secret) + : str; +}; + +/** + * Parse JSON cookies. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.parseJSONCookies = function(obj){ + Object.keys(obj).forEach(function(key){ + var val = obj[key]; + var res = exports.parseJSONCookie(val); + if (res) obj[key] = res; + }); + return obj; +}; + +/** + * Parse JSON cookie string + * + * @param {String} str + * @return {Object} Parsed object or null if not json cookie + * @api private + */ + +exports.parseJSONCookie = function(str) { + if (0 == str.indexOf('j:')) { + try { + return JSON.parse(str.slice(2)); + } catch (err) { + // no op + } + } +}; + +/** + * Pause `data` and `end` events on the given `obj`. + * Middleware performing async tasks _should_ utilize + * this utility (or similar), to re-emit data once + * the async operation has completed, otherwise these + * events may be lost. Pause is only required for + * node versions less than 10, and is replaced with + * noop's otherwise. + * + * var pause = utils.pause(req); + * fs.readFile(path, function(){ + * next(); + * pause.resume(); + * }); + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.pause = exports.brokenPause + ? require('pause') + : function () { + return { + end: noop, + resume: noop + } + } + +/** + * Strip `Content-*` headers from `res`. + * + * @param {ServerResponse} res + * @api private + */ + +exports.removeContentHeaders = function(res){ + if (!res._headers) return; + Object.keys(res._headers).forEach(function(field){ + if (0 == field.indexOf('content')) { + res.removeHeader(field); + } + }); +}; + +/** + * Check if `req` is a conditional GET request. + * + * @param {IncomingMessage} req + * @return {Boolean} + * @api private + */ + +exports.conditionalGET = function(req) { + return req.headers['if-modified-since'] + || req.headers['if-none-match']; +}; + +/** + * Respond with 401 "Unauthorized". + * + * @param {ServerResponse} res + * @param {String} realm + * @api private + */ + +exports.unauthorized = function(res, realm) { + res.statusCode = 401; + res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"'); + res.end('Unauthorized'); +}; + +/** + * Respond with 304 "Not Modified". + * + * @param {ServerResponse} res + * @param {Object} headers + * @api private + */ + +exports.notModified = function(res) { + exports.removeContentHeaders(res); + res.statusCode = 304; + res.end(); +}; + +/** + * Return an ETag in the form of `"-"` + * from the given `stat`. + * + * @param {Object} stat + * @return {String} + * @api private + */ + +exports.etag = function(stat) { + return '"' + stat.size + '-' + Number(stat.mtime) + '"'; +}; + +/** + * Parse the given Cache-Control `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +exports.parseCacheControl = function(str){ + var directives = str.split(',') + , obj = {}; + + for(var i = 0, len = directives.length; i < len; i++) { + var parts = directives[i].split('=') + , key = parts.shift().trim() + , val = parseInt(parts.shift(), 10); + + obj[key] = isNaN(val) ? true : val; + } + + return obj; +}; + +/** + * Parse the `req` url with memoization. + * + * @param {ServerRequest} req + * @return {Object} + * @api private + */ + +exports.parseUrl = function(req){ + var parsed = req._parsedUrl; + if (parsed && parsed.href == req.url) { + return parsed; + } else { + parsed = parse(req.url); + + if (parsed.auth && !parsed.protocol && ~parsed.href.indexOf('//')) { + // This parses pathnames, and a strange pathname like //r@e should work + parsed = parse(req.url.replace(/@/g, '%40')); + } + + return req._parsedUrl = parsed; + } +}; + +/** + * Parse byte `size` string. + * + * @param {String} size + * @return {Number} + * @api private + */ + +exports.parseBytes = require('bytes'); + +/** + * Normalizes the path separator from system separator + * to URL separator, aka `/`. + * + * @param {String} path + * @return {String} + * @api private + */ + +exports.normalizeSlashes = function normalizeSlashes(path) { + return path.split(sep).join('/'); +}; + +function noop() {} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/.npmignore new file mode 100644 index 00000000000..602eb8e1b2f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/.npmignore @@ -0,0 +1 @@ +test.js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/.travis.yml new file mode 100644 index 00000000000..c6f70dbfdcd --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/.travis.yml @@ -0,0 +1,3 @@ +node_js: +- "0.10" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/Makefile new file mode 100644 index 00000000000..a450a16f3e3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/Makefile @@ -0,0 +1,8 @@ +BIN = ./node_modules/.bin/ + +test: + @NODE_ENV=test $(BIN)mocha \ + --require should \ + --reporter spec + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/README.md new file mode 100644 index 00000000000..0543437ee12 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/README.md @@ -0,0 +1,60 @@ +# simgr - Simple Image Resizer [![Build Status](https://travis-ci.org/expressjs/basic-auth-connect.png)](https://travis-ci.org/expressjs/basic-auth-connect) + +Connect's Basic Auth middleware in its own module. This module is considered deprecated. You should instead create your own middleware with [basic-auth](https://github.com/visionmedia/node-basic-auth). + +## API + +```js +var basicAuth = require('basic-auth-connect'); +``` + +Sorry, couldn't think of a more clever name. + +Simple username and password + +```js +connect() +.use(basicAuth('username', 'password')); +``` + +Callback verification + +```js +connect() +.use(basicAuth(function(user, pass){ + return 'tj' == user && 'wahoo' == pass; +})) +``` + +Async callback verification, accepting `fn(err, user)`. + +``` +connect() +.use(basicAuth(function(user, pass, fn){ + User.authenticate({ user: user, pass: pass }, fn); +})) +``` + +## License + +The MIT License (MIT) + +Copyright (c) 2013 Jonathan Ong me@jongleberry.com + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/index.js new file mode 100644 index 00000000000..f5e847f9246 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/index.js @@ -0,0 +1,128 @@ +var http = require('http'); + +/*! + * Connect - basicAuth + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Basic Auth: + * + * Status: Deprecated. No bug reports or pull requests are welcomed + * for this middleware. However, this middleware will not be removed. + * Instead, you should use [basic-auth](https://github.com/visionmedia/node-basic-auth). + * + * Enfore basic authentication by providing a `callback(user, pass)`, + * which must return `true` in order to gain access. Alternatively an async + * method is provided as well, invoking `callback(user, pass, callback)`. Populates + * `req.user`. The final alternative is simply passing username / password + * strings. + * + * Simple username and password + * + * connect(connect.basicAuth('username', 'password')); + * + * Callback verification + * + * connect() + * .use(connect.basicAuth(function(user, pass){ + * return 'tj' == user && 'wahoo' == pass; + * })) + * + * Async callback verification, accepting `fn(err, user)`. + * + * connect() + * .use(connect.basicAuth(function(user, pass, fn){ + * User.authenticate({ user: user, pass: pass }, fn); + * })) + * + * @param {Function|String} callback or username + * @param {String} realm + * @api public + */ + +module.exports = function basicAuth(callback, realm) { + var username, password; + + // user / pass strings + if ('string' == typeof callback) { + username = callback; + password = realm; + if ('string' != typeof password) throw new Error('password argument required'); + realm = arguments[2]; + callback = function(user, pass){ + return user == username && pass == password; + } + } + + realm = realm || 'Authorization Required'; + + return function(req, res, next) { + var authorization = req.headers.authorization; + + if (req.user) return next(); + if (!authorization) return unauthorized(res, realm); + + var parts = authorization.split(' '); + + if (parts.length !== 2) return next(error(400)); + + var scheme = parts[0] + , credentials = new Buffer(parts[1], 'base64').toString() + , index = credentials.indexOf(':'); + + if ('Basic' != scheme || index < 0) return next(error(400)); + + var user = credentials.slice(0, index) + , pass = credentials.slice(index + 1); + + // async + if (callback.length >= 3) { + callback(user, pass, function(err, user){ + if (err || !user) return unauthorized(res, realm); + req.user = req.remoteUser = user; + next(); + }); + // sync + } else { + if (callback(user, pass)) { + req.user = req.remoteUser = user; + next(); + } else { + unauthorized(res, realm); + } + } + } +}; + +/** + * Respond with 401 "Unauthorized". + * + * @param {ServerResponse} res + * @param {String} realm + * @api private + */ + +function unauthorized(res, realm) { + res.statusCode = 401; + res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"'); + res.end('Unauthorized'); +}; + +/** + * Generate an `Error` from the given status `code` + * and optional `msg`. + * + * @param {Number} code + * @param {String} msg + * @return {Error} + * @api private + */ + +function error(code, msg){ + var err = new Error(msg || http.STATUS_CODES[code]); + err.status = code; + return err; +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/package.json new file mode 100644 index 00000000000..a8f15c72c08 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/basic-auth-connect/package.json @@ -0,0 +1,35 @@ +{ + "name": "basic-auth-connect", + "description": "Basic auth middleware for node and connect", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/basic-auth-connect.git" + }, + "bugs": { + "url": "https://github.com/expressjs/basic-auth-connect/issues" + }, + "devDependencies": { + "mocha": "*", + "should": "*", + "supertest": "*", + "connect": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# simgr - Simple Image Resizer [![Build Status](https://travis-ci.org/expressjs/basic-auth-connect.png)](https://travis-ci.org/expressjs/basic-auth-connect)\n\nConnect's Basic Auth middleware in its own module. This module is considered deprecated. You should instead create your own middleware with [basic-auth](https://github.com/visionmedia/node-basic-auth).\n\n## API\n\n```js\nvar basicAuth = require('basic-auth-connect');\n```\n\nSorry, couldn't think of a more clever name.\n\nSimple username and password\n\n```js\nconnect()\n.use(basicAuth('username', 'password'));\n```\n\nCallback verification\n\n```js\nconnect()\n.use(basicAuth(function(user, pass){\n return 'tj' == user && 'wahoo' == pass;\n}))\n```\n\nAsync callback verification, accepting `fn(err, user)`.\n\n```\nconnect()\n.use(basicAuth(function(user, pass, fn){\n User.authenticate({ user: user, pass: pass }, fn);\n}))\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.", + "readmeFilename": "README.md", + "_id": "basic-auth-connect@1.0.0", + "dist": { + "shasum": "fdb0b43962ca7b40456a7c2bb48fe173da2d2122" + }, + "_from": "basic-auth-connect@1.0.0", + "_resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/.npmignore new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/.npmignore @@ -0,0 +1 @@ +test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/History.md new file mode 100644 index 00000000000..f233ed160b3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/History.md @@ -0,0 +1,15 @@ + +0.2.1 / 2013-04-01 +================== + + * add .component + +0.2.0 / 2012-10-28 +================== + + * bytes(200).should.eql('200b') + +0.1.0 / 2012-07-04 +================== + + * add bytes to string conversion [yields] diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/Makefile new file mode 100644 index 00000000000..8e8640f2e6d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/Makefile @@ -0,0 +1,7 @@ + +test: + @./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/Readme.md new file mode 100644 index 00000000000..9325d5bf419 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/Readme.md @@ -0,0 +1,51 @@ +# node-bytes + + Byte string parser / formatter. + +## Example: + +```js +bytes('1kb') +// => 1024 + +bytes('2mb') +// => 2097152 + +bytes('1gb') +// => 1073741824 + +bytes(1073741824) +// => 1gb +``` + +## Installation + +``` +$ npm install bytes +$ component install visionmedia/bytes.js +``` + +## License + +(The MIT License) + +Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/component.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/component.json new file mode 100644 index 00000000000..2929c25d615 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/component.json @@ -0,0 +1,7 @@ +{ + "name": "bytes", + "description": "byte size string parser / serializer", + "keywords": ["bytes", "utility"], + "version": "0.2.1", + "scripts": ["index.js"] +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/index.js new file mode 100644 index 00000000000..70b2e01a41b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/index.js @@ -0,0 +1,39 @@ + +/** + * Parse byte `size` string. + * + * @param {String} size + * @return {Number} + * @api public + */ + +module.exports = function(size) { + if ('number' == typeof size) return convert(size); + var parts = size.match(/^(\d+(?:\.\d+)?) *(kb|mb|gb)$/) + , n = parseFloat(parts[1]) + , type = parts[2]; + + var map = { + kb: 1 << 10 + , mb: 1 << 20 + , gb: 1 << 30 + }; + + return map[type] * n; +}; + +/** + * convert bytes into string. + * + * @param {Number} b - bytes to convert + * @return {String} + * @api public + */ + +function convert (b) { + var gb = 1 << 30, mb = 1 << 20, kb = 1 << 10; + if (b >= gb) return (Math.round(b / gb * 100) / 100) + 'gb'; + if (b >= mb) return (Math.round(b / mb * 100) / 100) + 'mb'; + if (b >= kb) return (Math.round(b / kb * 100) / 100) + 'kb'; + return b + 'b'; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/package.json new file mode 100644 index 00000000000..601b1102c6b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/bytes/package.json @@ -0,0 +1,29 @@ +{ + "name": "bytes", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "description": "byte size string parser / serializer", + "version": "0.2.1", + "main": "index.js", + "dependencies": {}, + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "component": { + "scripts": { + "bytes/index.js": "index.js" + } + }, + "readme": "# node-bytes\n\n Byte string parser / formatter.\n\n## Example:\n\n```js\nbytes('1kb')\n// => 1024\n\nbytes('2mb')\n// => 2097152\n\nbytes('1gb')\n// => 1073741824\n\nbytes(1073741824)\n// => 1gb\n```\n\n## Installation\n\n```\n$ npm install bytes\n$ component install visionmedia/bytes.js\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "Readme.md", + "_id": "bytes@0.2.1", + "dist": { + "shasum": "586572818c283774f959f5c5762ece7bdf522f03" + }, + "_from": "bytes@0.2.1", + "_resolved": "https://registry.npmjs.org/bytes/-/bytes-0.2.1.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/.npmignore new file mode 100644 index 00000000000..602eb8e1b2f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/.npmignore @@ -0,0 +1 @@ +test.js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/.travis.yml new file mode 100644 index 00000000000..87f8cd91a50 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/Makefile new file mode 100644 index 00000000000..7fbd904cad2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/Makefile @@ -0,0 +1,6 @@ +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter spec + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/README.md new file mode 100644 index 00000000000..1680f322b77 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/README.md @@ -0,0 +1,51 @@ +# compression [![Build Status](https://travis-ci.org/expressjs/compression.png)](https://travis-ci.org/expressjs/compression) + +Connect's compress middleware as its own module. Works with and without Connect. + +```js +var compress = require('compression')() + +http.createServer(function (req, res) { + compress(req, res, function (err) { + if (err) throw err + + res.end('hello world') + }) +}) + +var app = require('connect')() +app.use(compress) +``` + +## API + +### var middleware = compress([options]) + +In addition to `zlib` options, additional options are: + +- `threshold` <1kb> - only compress the response if the byte size is at or above a threshold +- `filter` - a filter callback function + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/index.js new file mode 100644 index 00000000000..634f182c980 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/index.js @@ -0,0 +1,196 @@ +/*! + * Connect - compress + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var zlib = require('zlib'); +var bytes = require('bytes'); +var Negotiator = require('negotiator'); +var compressible = require('compressible'); + +/** + * Supported content-encoding methods. + */ + +exports.methods = { + gzip: zlib.createGzip + , deflate: zlib.createDeflate +}; + +/** + * Default filter function. + */ + +exports.filter = function(req, res){ + return compressible(res.getHeader('Content-Type')); +}; + +/** + * Compress: + * + * Compress response data with gzip/deflate. + * + * Filter: + * + * A `filter` callback function may be passed to + * replace the default logic of: + * + * exports.filter = function(req, res){ + * return /json|text|javascript/.test(res.getHeader('Content-Type')); + * }; + * + * Threshold: + * + * Only compress the response if the byte size is at or above a threshold. + * Always compress while streaming. + * + * - `threshold` - string representation of size or bytes as an integer. + * + * Options: + * + * All remaining options are passed to the gzip/deflate + * creation functions. Consult node's docs for additional details. + * + * - `chunkSize` (default: 16*1024) + * - `windowBits` + * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression + * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more + * - `strategy`: compression strategy + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function compress(options) { + options = options || {}; + var filter = options.filter || exports.filter; + var threshold; + + if (false === options.threshold || 0 === options.threshold) { + threshold = 0 + } else if ('string' === typeof options.threshold) { + threshold = bytes(options.threshold) + } else { + threshold = options.threshold || 1024 + } + + return function compress(req, res, next){ + var accept = req.headers['accept-encoding'] + , writeHead = res.writeHead + , write = res.write + , end = res.end + , compress = true + , stream; + + // see #724 + req.on('close', function(){ + res.write = res.end = function(){}; + }); + + // flush is noop by default + res.flush = noop; + + // proxy + + res.write = function(chunk, encoding){ + if (!this.headerSent) { + // if content-length is set and is lower + // than the threshold, don't compress + var length = res.getHeader('content-length'); + if (!isNaN(length) && length < threshold) compress = false; + this._implicitHeader(); + } + return stream + ? stream.write(new Buffer(chunk, encoding)) + : write.call(res, chunk, encoding); + }; + + res.end = function(chunk, encoding){ + if (chunk) { + if (!this.headerSent && getSize(chunk) < threshold) compress = false; + this.write(chunk, encoding); + } else if (!this.headerSent) { + // response size === 0 + compress = false; + } + return stream + ? stream.end() + : end.call(res); + }; + + res.writeHead = function(){ + // default request filter + if (!filter(req, res)) return writeHead.apply(res, arguments); + + // vary + var vary = res.getHeader('Vary'); + if (!vary) { + res.setHeader('Vary', 'Accept-Encoding'); + } else if (!~vary.indexOf('Accept-Encoding')) { + res.setHeader('Vary', vary + ', Accept-Encoding'); + } + + if (!compress) return writeHead.apply(res, arguments); + + var encoding = res.getHeader('Content-Encoding') || 'identity'; + + // already encoded + if ('identity' != encoding) return writeHead.apply(res, arguments); + + // SHOULD use identity + if (!accept) return writeHead.apply(res, arguments); + + // head + if ('HEAD' == req.method) return writeHead.apply(res, arguments); + + // compression method + var method = new Negotiator(req).preferredEncoding(['gzip', 'deflate', 'identity']); + // negotiation failed + if (method === 'identity') return writeHead.apply(res, arguments); + + // compression stream + stream = exports.methods[method](options); + + // overwrite the flush method + res.flush = function(){ + stream.flush(); + } + + // header fields + res.setHeader('Content-Encoding', method); + res.removeHeader('Content-Length'); + + // compression + stream.on('data', function(chunk){ + write.call(res, chunk); + }); + + stream.on('end', function(){ + end.call(res); + }); + + stream.on('drain', function() { + res.emit('drain'); + }); + + writeHead.apply(res, arguments); + }; + + next(); + }; +}; + +function getSize(chunk) { + return Buffer.isBuffer(chunk) + ? chunk.length + : Buffer.byteLength(chunk); +} + +function noop(){} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/.npmignore new file mode 100644 index 00000000000..497c2ecf248 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/.npmignore @@ -0,0 +1,63 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store* +# Icon? +ehthumbs.db +Thumbs.db + +# Node.js # +########### +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +node_modules +npm-debug.log + +# Components # +############## + +/build +/components + +# Sublime Text # +############## +*.sublime-project +*.sublime-workspace \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/.travis.yml new file mode 100644 index 00000000000..c6f70dbfdcd --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/.travis.yml @@ -0,0 +1,3 @@ +node_js: +- "0.10" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/README.md new file mode 100644 index 00000000000..9d102aea346 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/README.md @@ -0,0 +1,51 @@ +# Compressible [![Build Status](https://travis-ci.org/expressjs/compressible.png)](https://travis-ci.org/expressjs/compressible) + +Compressible `Content-Type` / `mime` checking. + +## API + +### compressible(type) + +```js +var compressible = require('compressible') +compressible('text/html') // -> true +compressible('image/png') // -> false +``` + +### compressible.get(type) + +Returns the specifications object associated with the given `Content-Type`. +Generates an object using the regex if none is found. + +### compressible.specs + +Exports `specifications.json`. + +### compressible.regex + +The regular expression that checks the `Content-Type`. +However, you should use `compressible(type)` instead of this regular expression due to additional non-regex checks. + +## License + +The MIT License (MIT) + +Copyright (c) 2013 Jonathan Ong me@jongleberry.com + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/bench.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/bench.js new file mode 100644 index 00000000000..c18dded2757 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/bench.js @@ -0,0 +1,53 @@ +var assert = require('assert') + , Benchmark = require('benchmark') + , suite = new Benchmark.Suite + , mime = require('mime') + , keys = Object.keys(mime.types) + , compressible = require('./index.js') + , benchmarks = require('beautify-benchmark') + +function getRandomType () { + var type = mime.types[keys[Math.floor(Math.random() * keys.length)]] + return type + mime.charsets.lookup(type) +} + +function legacy (type) { + if (!type || typeof type !== "string") return false + var spec = compressible.specs[type.split(';')] + return spec ? spec.compressible : compressible.regex.test(type) +} + +function previous (type) { + if (!type || typeof type !== "string") return false + var i = type.indexOf(';') + , spec = compressible.specs[i < 0 ? type : type.slice(0, i)] + return spec ? spec.compressible : compressible.regex.test(type) +} + +describe('Compressible performance benchmarks.', function () { + it('Performance of `current` should be within the top 95%', function () { + suite.add('current', function() { + compressible(getRandomType()) + }) + .add('previous', function () { + previous(getRandomType()) + }) + .add('legacy', function () { + legacy(getRandomType()) + }) + .on('cycle', function (event) { + benchmarks.add(event.target) + }) + .on('start', function (event) { + console.log('\n Starting...') + }) + .on('complete', function done () { + console.log('\n Done!') + var result = benchmarks.getPercent('current') + benchmarks.log() + if (result < 95) + assert.fail('' + result + '%', '95%`', null, '>=', done) + }) + .run({ 'async': false }) + }) +}) \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/index.js new file mode 100644 index 00000000000..9dd506d4309 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/index.js @@ -0,0 +1,30 @@ +module.exports = compressible + +compressible.specs = +compressible.specifications = require('./specifications.json') + +compressible.regex = +compressible.regexp = /json|text|javascript|dart|ecmascript|xml/ + +compressible.get = get + +function compressible(type) { + if (!type || typeof type !== "string") return false + var i = type.indexOf(';') + , spec = compressible.specs[~i ? type.slice(0, i) : type] + return spec ? spec.compressible : compressible.regex.test(type) +} + +function get(type) { + if (!type || typeof type !== "string") return { + compressible: false, + sources: [], + notes: "Invalid type." + } + var spec = compressible.specs[type.split(';')[0]] + return spec ? spec : { + compressible: compressible.regex.test(type), + sources: ["compressible.regex"], + notes: "Automatically generated via regex." + } +} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/package.json new file mode 100644 index 00000000000..99e511df612 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/package.json @@ -0,0 +1,48 @@ +{ + "name": "compressible", + "description": "Compressible Content-Type / mime checking", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "contributors": { + "name": "Jeremiah Senkpiel", + "email": "fishrock123@rocketmail.com", + "url": "https://searchbeam.jit.su", + "twitter": "https://twitter.com/fishrock123" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/compressible.git" + }, + "bugs": { + "url": "https://github.com/expressjs/compressible/issues" + }, + "keywords": [ + "compress", + "gzip", + "mime", + "content-type" + ], + "devDependencies": { + "mocha": "*", + "benchmark": "*", + "beautify-benchmark": "~0.2.4", + "mime": "*" + }, + "scripts": { + "test": "mocha --reporter spec", + "posttest": "mocha --reporter spec bench.js" + }, + "readme": "# Compressible [![Build Status](https://travis-ci.org/expressjs/compressible.png)](https://travis-ci.org/expressjs/compressible)\n\nCompressible `Content-Type` / `mime` checking.\n\n## API\n\n### compressible(type)\n\n```js\nvar compressible = require('compressible')\ncompressible('text/html') // -> true\ncompressible('image/png') // -> false\n```\n\n### compressible.get(type)\n\nReturns the specifications object associated with the given `Content-Type`.\nGenerates an object using the regex if none is found.\n\n### compressible.specs\n\nExports `specifications.json`.\n\n### compressible.regex\n\nThe regular expression that checks the `Content-Type`.\nHowever, you should use `compressible(type)` instead of this regular expression due to additional non-regex checks.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.", + "readmeFilename": "README.md", + "_id": "compressible@1.0.0", + "dist": { + "shasum": "f83e49c1cb61421753545125a8011d68b492427d" + }, + "_from": "compressible@1.0.0", + "_resolved": "https://registry.npmjs.org/compressible/-/compressible-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/specifications.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/specifications.json new file mode 100644 index 00000000000..ef8dd8958f7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/specifications.json @@ -0,0 +1,695 @@ +{ + "application/atom+xml": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/Atom_(standard)" + ], + "notes": "" + }, + "application/dart": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/EDI-X12": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/EDIFACT": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/ecmascript": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/font-woff": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/gzip": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/java-archive": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/java-serialized-object": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/java-vm": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/javascript": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/json": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/msword": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/octet-stream": { + "compressible": false, + "sources": [ + "https://github.com/broofa/node-mime/blob/master/types/mime.types#L154" + ], + "notes": "" + }, + "application/ogg": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/pdf": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/pgp-encrypted": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/postscript": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/rdf+xml": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/RDF/XML" + ], + "notes": "" + }, + "application/rss+xml": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/rtf": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/soap+xml": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/SOAP" + ], + "notes": "" + }, + "application/tar": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/vnd.android.package-archive": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.dart": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/vnd.google-earth.kml+xml": { + "compressible": true, + "sources": [ + "https://developers.google.com/kml/documentation/kml_tut" + ], + "notes": "" + }, + "application/vnd.google-earth.kmz": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.mozilla.xul+xml": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/XUL" + ], + "notes": "" + }, + "application/vnd.ms-excel": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.ms-fontobject": { + "compressible": true, + "sources": [ + "http://www.phpied.com/gzip-your-font-face-files/" + ], + "notes": "" + }, + "application/vnd.ms-opentype": { + "compressible": true, + "sources": [ + "http://www.phpied.com/gzip-your-font-face-files/" + ], + "notes": "" + }, + "application/vnd.ms-powerpoint": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.ms-xpsdocument": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.oasis.opendocument.graphics": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.oasis.opendocument.presentation": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.oasis.opendocument.spreadsheet": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.oasis.opendocument.text": { + "compressible": false, + "sources": [ + "http://en.wikipedia.org/wiki/OpenDocument_technical_specification#File_types" + ], + "notes": "" + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-7z-compressed": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-bzip": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-bzip2": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-deb": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-dvi": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-font-otf": { + "compressible": true, + "sources": [ + "http://www.phpied.com/gzip-your-font-face-files/" + ], + "notes": "" + }, + "application/x-font-ttf": { + "compressible": true, + "sources": [ + "http://www.phpied.com/gzip-your-font-face-files/" + ], + "notes": "" + }, + "application/x-java-jnlp-file": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-javascript": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/x-latex": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-mpegURL": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-pkcs12": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-rar-compressed": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-sh": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/x-shockwave-flash": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-stuffit": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-tar": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/x-www-form-urlencode": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/x-xpinstall": { + "compressible": false, + "sources": [], + "notes": "" + }, + "application/xhtml+xml": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/xml": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/xml-dtd": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/Document_type_definition" + ], + "notes": "" + }, + "application/xop+xml": { + "compressible": true, + "sources": [], + "notes": "" + }, + "application/zip": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/L24": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/basic": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/mp4": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/mpeg": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/ogg": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/vnd.rn-realaudio": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/vnd.wave": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/vorbis": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/webm": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/x-aac": { + "compressible": false, + "sources": [], + "notes": "" + }, + "audio/x-caf": { + "compressible": false, + "sources": [], + "notes": "" + }, + "font/opentype": { + "compressible": true, + "sources": [ + "http://www.phpied.com/gzip-your-font-face-files/" + ], + "notes": "" + }, + "image/bmp": { + "compressible": true, + "sources": [ + "http://stackoverflow.com/a/12770116" + ], + "notes": "" + }, + "image/gif": { + "compressible": false, + "sources": [], + "notes": "" + }, + "image/jpeg": { + "compressible": false, + "sources": [], + "notes": "" + }, + "image/pjpeg": { + "compressible": false, + "sources": [], + "notes": "" + }, + "image/png": { + "compressible": false, + "sources": [], + "notes": "" + }, + "image/svg+xml": { + "compressible": true, + "sources": [], + "notes": "" + }, + "image/tiff": { + "compressible": false, + "sources": [ + "http://stackoverflow.com/a/12770116" + ], + "notes": "Gains insignificant in testing." + }, + "image/vnd.adobe.photoshop": { + "compressible": true, + "sources": [], + "notes": "" + }, + "image/x-icon": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/ICO_(file_format)" + ], + "notes": "Usually a wrapper for .bmp formated images." + }, + "image/x-xcf": { + "compressible": false, + "sources": [], + "notes": "" + }, + "message/http": { + "compressible": false, + "sources": [ + "http://stackoverflow.com/a/1450163" + ], + "notes": "It is safest to leave these uncompressed." + }, + "message/imdn+xml": { + "compressible": true, + "sources": [ + "http://tools.ietf.org/html/rfc5438" + ], + "notes": "" + }, + "message/partial": { + "compressible": false, + "sources": [], + "notes": "" + }, + "message/rfc822": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/MIME#Multipart_subtypes" + ], + "notes": "" + }, + "model/example": { + "compressible": false, + "sources": [], + "notes": "" + }, + "model/iges": { + "compressible": false, + "sources": [], + "notes": "" + }, + "model/mesh": { + "compressible": false, + "sources": [], + "notes": "" + }, + "model/vrml": { + "compressible": false, + "sources": [], + "notes": "" + }, + "model/x3d+binary": { + "compressible": false, + "sources": [], + "notes": "" + }, + "model/x3d+vrml": { + "compressible": false, + "sources": [], + "notes": "" + }, + "model/x3d+xml": { + "compressible": true, + "sources": [ + "http://edutechwiki.unige.ch/en/X3D_file_structure" + ], + "notes": "" + }, + "multipart/alternative": { + "compressible": false, + "sources": [], + "notes": "" + }, + "multipart/encrypted": { + "compressible": false, + "sources": [], + "notes": "" + }, + "multipart/form-data": { + "compressible": false, + "sources": [], + "notes": "" + }, + "multipart/mixed": { + "compressible": false, + "sources": [], + "notes": "" + }, + "multipart/related": { + "compressible": false, + "sources": [], + "notes": "" + }, + "multipart/signed": { + "compressible": false, + "sources": [], + "notes": "" + }, + "text/cache-manifest": { + "compressible": true, + "sources": [ + "https://bugzilla.mozilla.org/show_bug.cgi?id=715191#c2" + ], + "notes": "I think so." + }, + "text/calender": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/ICalendar" + ], + "notes": "Probably needs to be uncompressed before sent to iCalender, though." + }, + "text/cmd": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/css": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/csv": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/html": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/javascript": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/n3": { + "compressible": true, + "sources": [ + "http://en.wikipedia.org/wiki/Notation3" + ], + "notes": "" + }, + "text/plain": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/richtext": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/tab-separated-values": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/uri-list": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/vcard": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/x-gwt-rpc": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/x-jquery-tmpl": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/x-markdown": { + "compressible": true, + "sources": [], + "notes": "" + }, + "text/xml": { + "compressible": true, + "sources": [], + "notes": "" + }, + "video/mp4": { + "compressible": false, + "sources": [], + "notes": "" + }, + "video/mpeg": { + "compressible": false, + "sources": [], + "notes": "" + }, + "video/ogg": { + "compressible": false, + "sources": [], + "notes": "" + }, + "video/quicktime": { + "compressible": false, + "sources": [], + "notes": "" + }, + "video/webm": { + "compressible": false, + "sources": [], + "notes": "" + }, + "video/x-flv": { + "compressible": false, + "sources": [], + "notes": "" + }, + "video/x-matroska": { + "compressible": false, + "sources": [], + "notes": "" + }, + "video/x-ms-wmv": { + "compressible": false, + "sources": [], + "notes": "" + }, + "x-shader/x-fragment": { + "compressible": true, + "sources": [ + "https://bugzilla.mozilla.org/show_bug.cgi?id=715191#c2" + ], + "notes": "" + } +} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/test.js new file mode 100644 index 00000000000..d52b801dc8d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/compressible/test.js @@ -0,0 +1,92 @@ +var assert = require('assert') + +var specifications = require('./specifications.json') +var compressible = require('./') + +// None of these should be actual types so that the lookup will never include them. +var example_types = [ + { type: 'something/text', should: true }, + { type: 'thingie/dart', should: true }, + { type: 'type/json', should: true }, + { type: 'ecmascript/6', should: true }, + { type: 'data/beans+xml', should: true }, + { type: 'asdf/nope', should: false }, + { type: 'cats', should: false } +] + +var invalid_types = [ + undefined, + null, + 0, + 1, + false, + true +] + +var object_true = { + compressible: true, + sources: ["compressible.regex"], + notes: "Automatically generated via regex." +}, object_false = { + compressible: false, + sources: ["compressible.regex"], + notes: "Automatically generated via regex." +} + +describe('Testing if spec lookups are correct.', function () { + for (var type in specifications) { + var value = specifications[type].compressible + it(type + ' should' + (value ? ' ' : ' not ') + 'be compressible', function () { + assert.equal(compressible(type), value) + }) + } +}) + +describe('Testing if the regex works as intended.', function () { + example_types.forEach(function (example) { + it(example.type + ' should' + (example.should ? ' ' : ' not ') + 'be compressible', function () { + assert.equal(compressible(example.type), example.should) + }) + }) +}) + +describe('Testing if getter returns the correct objects.', function () { + it('All spec objects should be get-able', function () { + for (var type in specifications) { + assert.equal(compressible.get(type), specifications[type]) + } + }) + example_types.forEach(function (example) { + it(example.type + ' should generate a ' + (example.should ? 'true' : 'false') + ' object', function () { + assert.deepEqual(compressible.get(example.type), example.should ? object_true: object_false) + }) + }) +}) + +describe('Testing if charsets are handled correctly.', function () { + it('Charsets should be stripped off without issue', function () { + for (var type in specifications) { + var value = specifications[type].compressible + assert.equal(compressible(type + '; charset=utf-8'), value) + } + }) + it('Types with charsets should be get-able', function () { + for (var type in specifications) { + assert.equal(compressible.get(type + '; charset=utf-8'), specifications[type]) + } + }) +}) + +describe('Ensuring invalid types do not cause errors.', function () { + it('No arguments should return false without error', function () { + assert.equal(compressible(), false) + }) + + invalid_types.forEach(function (invalid) { + it(invalid + ' should return false without error', function () { + assert.doesNotThrow(function () { + assert.equal(compressible(invalid), false) + }) + }) + }) +}) \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/LICENSE new file mode 100644 index 00000000000..42ca2e7d7bb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/LICENSE @@ -0,0 +1,27 @@ +Original "Negotiator" program Copyright Federico Romero +Port to JavaScript Copyright Isaac Z. Schlueter + +All rights reserved. + +MIT License + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/accept.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/accept.js new file mode 100644 index 00000000000..2a1803918dd --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/accept.js @@ -0,0 +1,47 @@ +(function() { + var Negotiator, availableMediaTypes, http, key, representations, server, val; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + representations = { + 'text/html': '

Hello world!

', + 'text/plain': 'Hello World!', + 'application/json': JSON.stringify({ + hello: 'world!' + }) + }; + + availableMediaTypes = (function() { + var _results; + _results = []; + for (key in representations) { + val = representations[key]; + _results.push(key); + } + return _results; + })(); + + server = http.createServer(function(req, res) { + var mediaType, negotiator; + negotiator = new Negotiator(req); + console.log("Accept: " + req.headers['accept']); + console.log("Preferred: " + (negotiator.preferredMediaTypes())); + console.log("Possible: " + (negotiator.preferredMediaTypes(availableMediaTypes))); + mediaType = negotiator.preferredMediaType(availableMediaTypes); + console.log("Selected: " + mediaType); + if (mediaType) { + res.writeHead(200, { + 'Content-Type': mediaType + }); + return res.end(representations[mediaType]); + } else { + res.writeHead(406); + return res.end(); + } + }); + + server.listen(8080); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/charset.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/charset.js new file mode 100644 index 00000000000..6455effaffd --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/charset.js @@ -0,0 +1,52 @@ +(function() { + var Buffer, Iconv, Negotiator, availableCharsets, http, iconv, key, message, messages, server, val; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + Buffer = require('buffer').Buffer; + + Iconv = require('iconv').Iconv; + + iconv = new Iconv('UTF-8', 'ISO-8859-1'); + + message = "ë"; + + messages = { + 'utf-8': message, + 'iso-8859-1': iconv.convert(new Buffer(message)) + }; + + availableCharsets = (function() { + var _results; + _results = []; + for (key in messages) { + val = messages[key]; + _results.push(key); + } + return _results; + })(); + + server = http.createServer(function(req, res) { + var charset, negotiator; + negotiator = new Negotiator(req); + console.log("Accept-Charset: " + req.headers['accept-charset']); + console.log("Preferred: " + (negotiator.preferredCharsets())); + console.log("Possible: " + (negotiator.preferredCharsets(availableCharsets))); + charset = negotiator.preferredCharset(availableCharsets); + console.log("Selected: " + charset); + if (charset) { + res.writeHead(200, { + 'Content-Type': "text/html; charset=" + charset + }); + return res.end(messages[charset]); + } else { + res.writeHead(406); + return res.end(); + } + }); + + server.listen(8080); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/encoding.js new file mode 100644 index 00000000000..a02d0f46d96 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/encoding.js @@ -0,0 +1,48 @@ +(function() { + var Negotiator, gbuf, http, messages; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + gbuf = require('gzip-buffer'); + + messages = { + identity: 'Hello World' + }; + + gbuf.gzip(messages.identity, function(zipped) { + var availableEncodings, key, server, val; + messages.gzip = zipped; + availableEncodings = (function() { + var _results; + _results = []; + for (key in messages) { + val = messages[key]; + _results.push(key); + } + return _results; + })(); + console.log(availableEncodings); + server = http.createServer(function(req, res) { + var encoding, negotiator; + negotiator = new Negotiator(req); + console.log("Accept-Encoding: " + req.headers['accept-encoding']); + console.log("Preferred: " + (negotiator.preferredEncodings())); + console.log("Possible: " + (negotiator.preferredEncodings(availableEncodings))); + encoding = negotiator.preferredEncoding(availableEncodings); + console.log("Selected: " + encoding); + if (encoding) { + res.writeHead(200, { + 'Content-Encoding': encoding + }); + return res.end(messages[encoding]); + } else { + res.writeHead(406); + return res.end(); + } + }); + return server.listen(8080); + }); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/language.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/language.js new file mode 100644 index 00000000000..f161743f9e0 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/examples/language.js @@ -0,0 +1,44 @@ +(function() { + var Negotiator, availableLanguages, http, key, messages, server, val; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + messages = { + es: "¡Hola Mundo!", + en: "Hello World!" + }; + + availableLanguages = (function() { + var _results; + _results = []; + for (key in messages) { + val = messages[key]; + _results.push(key); + } + return _results; + })(); + + server = http.createServer(function(req, res) { + var language, negotiator; + negotiator = new Negotiator(req); + console.log("Accept-Language: " + req.headers['accept-language']); + console.log("Preferred: " + (negotiator.preferredLanguages())); + console.log("Possible: " + (negotiator.preferredLanguages(availableLanguages))); + language = negotiator.preferredLanguage(availableLanguages); + console.log("Selected: " + language); + if (language) { + res.writeHead(200, { + 'Content-Language': language + }); + return res.end(messages[language]); + } else { + res.writeHead(406); + return res.end(); + } + }); + + server.listen(8080); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/charset.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/charset.js new file mode 100644 index 00000000000..3300457226d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/charset.js @@ -0,0 +1,71 @@ +module.exports = preferredCharsets; +preferredCharsets.preferredCharsets = preferredCharsets; + +function parseAcceptCharset(accept) { + return accept.split(',').map(function(e) { + return parseCharset(e.trim()); + }).filter(function(e) { + return e && e.q > 0; + }); +} + +function parseCharset(s) { + var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/); + if (!match) return null; + + var charset = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(';') + for (var i = 0; i < params.length; i ++) { + var p = params[i].trim().split('='); + if (p[0] === 'q') { + q = parseFloat(p[1]); + break; + } + } + } + + return { + charset: charset, + q: q + }; +} + +function getCharsetPriority(charset, accepted) { + return (accepted.filter(function(a) { + return specify(charset, a); + }).sort(function (a, b) { + // revsort + return a.q === b.q ? 0 : a.q > b.q ? -1 : 1; + })[0] || {q:0}).q; +} + +function specify(charset, spec) { + if (spec.charset === '*' || spec.charset === charset) { + return spec; + } +}; + +function preferredCharsets(accept, provided) { + accept = parseAcceptCharset(accept || ''); + if (provided) { + return provided.map(function(type) { + return [type, getCharsetPriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).map(function(type) { + return type.charset; + }); + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/encoding.js new file mode 100644 index 00000000000..b4fc889f79e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/encoding.js @@ -0,0 +1,89 @@ +module.exports = preferredEncodings; +preferredEncodings.preferredEncodings = preferredEncodings; + +function parseAcceptEncoding(accept) { + var acceptableEncodings; + + if (accept) { + acceptableEncodings = accept.split(',').map(function(e) { + return parseEncoding(e.trim()); + }); + } else { + acceptableEncodings = []; + } + + if (!acceptableEncodings.some(function(e) { + return e && e.encoding === 'identity'; + })) { + acceptableEncodings.push({ + encoding: 'identity', + q: 0.1 + }); + } + + return acceptableEncodings.filter(function(e) { + return e && e.q > 0; + }); +} + +function parseEncoding(s) { + var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/); + + if (!match) return null; + + var encoding = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(';'); + for (var i = 0; i < params.length; i ++) { + var p = params[i].trim().split('='); + if (p[0] === 'q') { + q = parseFloat(p[1]); + break; + } + } + } + + return { + encoding: encoding, + q: q + }; +} + +function getEncodingPriority(encoding, accepted) { + return (accepted.filter(function(a) { + return specify(encoding, a); + }).sort(function (a, b) { + // revsort + return a.q === b.q ? 0 : a.q > b.q ? -1 : 1; + })[0] || {q:0}).q; +} + +function specify(encoding, spec) { + if (spec.encoding === '*' || spec.encoding === encoding) { + return spec; + } +} + +function preferredEncodings(accept, provided) { + accept = parseAcceptEncoding(accept || ''); + if (provided) { + return provided.map(function(type) { + return [type, getEncodingPriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).map(function(type) { + return type.encoding; + }); + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/language.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/language.js new file mode 100644 index 00000000000..432b7026f9a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/language.js @@ -0,0 +1,92 @@ +module.exports = preferredLanguages; +preferredLanguages.preferredLanguages = preferredLanguages; + +function parseAcceptLanguage(accept) { + return accept.split(',').map(function(e) { + return parseLanguage(e.trim()); + }).filter(function(e) { + return e && e.q > 0; + }); +} + +function parseLanguage(s) { + var match = s.match(/^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/); + if (!match) return null; + + var prefix = match[1], + suffix = match[2], + full = prefix; + + if (suffix) full += "-" + suffix; + + var q = 1; + if (match[3]) { + var params = match[3].split(';') + for (var i = 0; i < params.length; i ++) { + var p = params[i].split('='); + if (p[0] === 'q') q = parseFloat(p[1]); + } + } + + return { + prefix: prefix, + suffix: suffix, + q: q, + full: full + }; +} + +function getLanguagePriority(language, accepted) { + var match = getClosestMatch(language, accepted); + return match ? match.q : 0; +} + +function getClosestMatch(language, accepted) { + var parsed = parseLanguage(language); + + var matches = accepted.filter(function(a) { + return a.full === parsed.full; + }); + if (matches.length) return matches[0]; + + matches = accepted.filter(function(a) { + return a.prefix === parsed.prefix && !a.suffix; + }); + if (matches.length) return matches[0]; + + matches = accepted.filter(function(a) { + return a.prefix === parsed.prefix; + }); + if (matches.length) return matches[0]; + + matches = accepted.filter(function(a) { + return a.prefix === '*'; + }); + return matches[0]; +} + +function preferredLanguages(accept, provided) { + accept = parseAcceptLanguage(accept || ''); + if (provided) { + + var ret = provided.map(function(type) { + return [type, getLanguagePriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + return ret; + + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).map(function(type) { + return type.full; + }); + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/mediaType.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/mediaType.js new file mode 100644 index 00000000000..3dc017fd169 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/mediaType.js @@ -0,0 +1,101 @@ +module.exports = preferredMediaTypes; +preferredMediaTypes.preferredMediaTypes = preferredMediaTypes; + +function parseAccept(accept) { + return accept.split(',').map(function(e) { + return parseMediaType(e.trim()); + }).filter(function(e) { + return e && e.q > 0; + }); +}; + +function parseMediaType(s) { + var match = s.match(/\s*(\S+)\/([^;\s]+)\s*(?:;(.*))?/); + if (!match) return null; + + var type = match[1], + subtype = match[2], + full = "" + type + "/" + subtype, + params = {}, + q = 1; + + if (match[3]) { + params = match[3].split(';').map(function(s) { + return s.trim().split('='); + }).reduce(function (set, p) { + set[p[0]] = p[1]; + return set + }, params); + + if (params.q != null) { + q = parseFloat(params.q); + delete params.q; + } + } + + return { + type: type, + subtype: subtype, + params: params, + q: q, + full: full + }; +} + +function getMediaTypePriority(type, accepted) { + return (accepted.filter(function(a) { + return specify(type, a); + }).sort(function (a, b) { + // revsort + return a.q > b.q ? -1 : 1; + })[0] || {q:0}).q; +} + +function specifies(spec, type) { + return spec === '*' || spec === type; +} + +function specify(type, spec) { + var p = parseMediaType(type); + + if (spec.params) { + var keys = Object.keys(spec.params); + if (keys.some(function (k) { + return !specifies(spec.params[k], p.params[k]); + })) { + // some didn't specify. + return null; + } + } + + if (specifies(spec.type, p.type) && + specifies(spec.subtype, p.subtype)) { + return spec; + } +} + +function preferredMediaTypes(accept, provided) { + accept = parseAccept(accept || ''); + if (provided) { + return provided.map(function(type) { + return [type, getMediaTypePriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).map(function(type) { + return type.full; + }); + } +} + + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/negotiator.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/negotiator.js new file mode 100644 index 00000000000..fe0e58a572e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/lib/negotiator.js @@ -0,0 +1,29 @@ +module.exports = Negotiator; +Negotiator.Negotiator = Negotiator; + +function Negotiator(request) { + if (!(this instanceof Negotiator)) return new Negotiator(request); + this.request = request; +} + +var set = { preferredCharset: [require('./charset.js'), 'accept-charset'], + preferredEncoding: [require('./encoding.js'), 'accept-encoding'], + preferredLanguage: [require('./language.js'), 'accept-language'], + preferredMediaType: [require('./mediaType.js'), 'accept'] }; + +Object.keys(set).forEach(function (k) { + var mh = set[k], + method = mh[0], + header = mh[1], + singular = k, + plural = k + 's'; + + Negotiator.prototype[plural] = function (available) { + return method(this.request.headers[header], available); + }; + + Negotiator.prototype[singular] = function(available) { + var set = this[plural](available); + if (set) return set[0]; + }; +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/package.json new file mode 100644 index 00000000000..419af140088 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/package.json @@ -0,0 +1,49 @@ +{ + "name": "negotiator", + "description": "HTTP content negotiation", + "version": "0.3.0", + "author": { + "name": "Federico Romero", + "email": "federico.romero@outboxlabs.com" + }, + "contributors": [ + { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/federomero/negotiator.git" + }, + "keywords": [ + "http", + "content negotiation", + "accept", + "accept-language", + "accept-encoding", + "accept-charset" + ], + "engine": "node >= 0.6", + "license": "MIT", + "devDependencies": { + "nodeunit": "0.6.x" + }, + "scripts": { + "test": "nodeunit test" + }, + "optionalDependencies": {}, + "engines": { + "node": "*" + }, + "main": "lib/negotiator.js", + "readme": "# Negotiator\n\nAn HTTP content negotiator for node.js written in javascript.\n\n# Accept Negotiation\n\n Negotiator = require('negotiator')\n\n availableMediaTypes = ['text/html', 'text/plain', 'application/json']\n\n // The negotiator constructor receives a request object\n negotiator = new Negotiator(request)\n\n // Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'\n\n negotiator.preferredMediaTypes()\n // -> ['text/html', 'image/jpeg', 'application/*']\n\n negotiator.preferredMediaTypes(availableMediaTypes)\n // -> ['text/html', 'application/json']\n\n negotiator.preferredMediaType(availableMediaTypes)\n // -> 'text/html'\n\nYou can check a working example at `examples/accept.js`.\n\n## Methods\n\n`preferredMediaTypes(availableMediaTypes)`:\n\nReturns an array of preferred media types ordered by priority from a list of available media types.\n\n`preferredMediaType(availableMediaType)`:\n\nReturns the top preferred media type from a list of available media types.\n\n# Accept-Language Negotiation\n\n Negotiator = require('negotiator')\n\n negotiator = new Negotiator(request)\n\n availableLanguages = 'en', 'es', 'fr'\n\n // Let's say Accept-Language header is 'en;q=0.8, es, pt'\n\n negotiator.preferredLanguages()\n // -> ['es', 'pt', 'en']\n\n negotiator.preferredLanguages(availableLanguages)\n // -> ['es', 'en']\n\n language = negotiator.preferredLanguage(availableLanguages)\n // -> 'es'\n\nYou can check a working example at `examples/language.js`.\n\n## Methods\n\n`preferredLanguages(availableLanguages)`:\n\nReturns an array of preferred languages ordered by priority from a list of available languages.\n\n`preferredLanguage(availableLanguages)`:\n\nReturns the top preferred language from a list of available languages.\n\n# Accept-Charset Negotiation\n\n Negotiator = require('negotiator')\n\n availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']\n\n negotiator = new Negotiator(request)\n\n // Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'\n\n negotiator.preferredCharsets()\n // -> ['utf-8', 'iso-8859-1', 'utf-7']\n\n negotiator.preferredCharsets(availableCharsets)\n // -> ['utf-8', 'iso-8859-1']\n\n negotiator.preferredCharset(availableCharsets)\n // -> 'utf-8'\n\nYou can check a working example at `examples/charset.js`.\n\n## Methods\n\n`preferredCharsets(availableCharsets)`:\n\nReturns an array of preferred charsets ordered by priority from a list of available charsets.\n\n`preferredCharset(availableCharsets)`:\n\nReturns the top preferred charset from a list of available charsets.\n\n# Accept-Encoding Negotiation\n\n Negotiator = require('negotiator').Negotiator\n\n availableEncodings = ['identity', 'gzip']\n\n negotiator = new Negotiator(request)\n\n // Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'\n\n negotiator.preferredEncodings()\n // -> ['gzip', 'identity', 'compress']\n\n negotiator.preferredEncodings(availableEncodings)\n // -> ['gzip', 'identity']\n\n negotiator.preferredEncoding(availableEncodings)\n // -> 'gzip'\n\nYou can check a working example at `examples/encoding.js`.\n\n## Methods\n\n`preferredEncodings(availableEncodings)`:\n\nReturns an array of preferred encodings ordered by priority from a list of available encodings.\n\n`preferredEncoding(availableEncodings)`:\n\nReturns the top preferred encoding from a list of available encodings.\n\n# License\n\nMIT\n", + "readmeFilename": "readme.md", + "bugs": { + "url": "https://github.com/federomero/negotiator/issues" + }, + "dependencies": {}, + "_id": "negotiator@0.3.0", + "_from": "negotiator@0.3.0" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/readme.md new file mode 100644 index 00000000000..0a077bbeb8c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/readme.md @@ -0,0 +1,132 @@ +# Negotiator + +An HTTP content negotiator for node.js written in javascript. + +# Accept Negotiation + + Negotiator = require('negotiator') + + availableMediaTypes = ['text/html', 'text/plain', 'application/json'] + + // The negotiator constructor receives a request object + negotiator = new Negotiator(request) + + // Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8' + + negotiator.preferredMediaTypes() + // -> ['text/html', 'image/jpeg', 'application/*'] + + negotiator.preferredMediaTypes(availableMediaTypes) + // -> ['text/html', 'application/json'] + + negotiator.preferredMediaType(availableMediaTypes) + // -> 'text/html' + +You can check a working example at `examples/accept.js`. + +## Methods + +`preferredMediaTypes(availableMediaTypes)`: + +Returns an array of preferred media types ordered by priority from a list of available media types. + +`preferredMediaType(availableMediaType)`: + +Returns the top preferred media type from a list of available media types. + +# Accept-Language Negotiation + + Negotiator = require('negotiator') + + negotiator = new Negotiator(request) + + availableLanguages = 'en', 'es', 'fr' + + // Let's say Accept-Language header is 'en;q=0.8, es, pt' + + negotiator.preferredLanguages() + // -> ['es', 'pt', 'en'] + + negotiator.preferredLanguages(availableLanguages) + // -> ['es', 'en'] + + language = negotiator.preferredLanguage(availableLanguages) + // -> 'es' + +You can check a working example at `examples/language.js`. + +## Methods + +`preferredLanguages(availableLanguages)`: + +Returns an array of preferred languages ordered by priority from a list of available languages. + +`preferredLanguage(availableLanguages)`: + +Returns the top preferred language from a list of available languages. + +# Accept-Charset Negotiation + + Negotiator = require('negotiator') + + availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5'] + + negotiator = new Negotiator(request) + + // Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2' + + negotiator.preferredCharsets() + // -> ['utf-8', 'iso-8859-1', 'utf-7'] + + negotiator.preferredCharsets(availableCharsets) + // -> ['utf-8', 'iso-8859-1'] + + negotiator.preferredCharset(availableCharsets) + // -> 'utf-8' + +You can check a working example at `examples/charset.js`. + +## Methods + +`preferredCharsets(availableCharsets)`: + +Returns an array of preferred charsets ordered by priority from a list of available charsets. + +`preferredCharset(availableCharsets)`: + +Returns the top preferred charset from a list of available charsets. + +# Accept-Encoding Negotiation + + Negotiator = require('negotiator').Negotiator + + availableEncodings = ['identity', 'gzip'] + + negotiator = new Negotiator(request) + + // Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5' + + negotiator.preferredEncodings() + // -> ['gzip', 'identity', 'compress'] + + negotiator.preferredEncodings(availableEncodings) + // -> ['gzip', 'identity'] + + negotiator.preferredEncoding(availableEncodings) + // -> 'gzip' + +You can check a working example at `examples/encoding.js`. + +## Methods + +`preferredEncodings(availableEncodings)`: + +Returns an array of preferred encodings ordered by priority from a list of available encodings. + +`preferredEncoding(availableEncodings)`: + +Returns the top preferred encoding from a list of available encodings. + +# License + +MIT diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/charset.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/charset.js new file mode 100644 index 00000000000..79224a7544e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/charset.js @@ -0,0 +1,62 @@ +(function() { + var configuration, preferredCharsets, testConfigurations, testCorrectCharset, _i, _len, + _this = this; + + preferredCharsets = require('../lib/charset').preferredCharsets; + + this["Should not return a charset when no charset is provided"] = function(test) { + test.deepEqual(preferredCharsets('*', []), []); + return test.done(); + }; + + this["Should not return a charset when no charset is acceptable"] = function(test) { + test.deepEqual(preferredCharsets('ISO-8859-1', ['utf-8']), []); + return test.done(); + }; + + this["Should not return a charset with q = 0"] = function(test) { + test.deepEqual(preferredCharsets('utf-8;q=0', ['utf-8']), []); + return test.done(); + }; + + testCorrectCharset = function(c) { + return _this["Should return " + c.selected + " for accept-charset header " + c.accept + " with provided charset " + c.provided] = function(test) { + test.deepEqual(preferredCharsets(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'utf-8', + provided: ['utf-8'], + selected: ['utf-8'] + }, { + accept: '*', + provided: ['utf-8'], + selected: ['utf-8'] + }, { + accept: 'utf-8', + provided: ['utf-8', 'ISO-8859-1'], + selected: ['utf-8'] + }, { + accept: 'utf-8, ISO-8859-1', + provided: ['utf-8'], + selected: ['utf-8'] + }, { + accept: 'utf-8;q=0.8, ISO-8859-1', + provided: ['utf-8', 'ISO-8859-1'], + selected: ['ISO-8859-1', 'utf-8'] + }, { + accept: 'utf-8;q=0.8, ISO-8859-1', + provided: null, + selected: ['ISO-8859-1', 'utf-8'] + } + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectCharset(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/encoding.js new file mode 100644 index 00000000000..7859d5e45fb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/encoding.js @@ -0,0 +1,70 @@ +(function() { + var configuration, preferredEncodings, testConfigurations, testCorrectEncoding, _i, _len, + _this = this; + + preferredEncodings = require('../lib/encoding').preferredEncodings; + + this["Should return identity encoding when no encoding is provided"] = function(test) { + test.deepEqual(preferredEncodings(null), ['identity']); + return test.done(); + }; + + this["Should include the identity encoding even if not explicity listed"] = function(test) { + test.ok(preferredEncodings('gzip').indexOf('identity') !== -1); + return test.done(); + }; + + this["Should not return identity encoding if q = 0"] = function(test) { + test.ok(preferredEncodings('identity;q=0').indexOf('identity') === -1); + return test.done(); + }; + + testCorrectEncoding = function(c) { + return _this["Should return " + c.selected + " for accept-encoding header " + c.accept + " with provided encoding " + c.provided] = function(test) { + test.deepEqual(preferredEncodings(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'gzip', + provided: ['identity', 'gzip'], + selected: ['gzip', 'identity'] + }, { + accept: 'gzip, compress', + provided: ['compress'], + selected: ['compress'] + }, { + accept: 'deflate', + provided: ['gzip', 'identity'], + selected: ['identity'] + }, { + accept: '*', + provided: ['identity', 'gzip'], + selected: ['identity', 'gzip'] + }, { + accept: 'gzip, compress', + provided: ['compress', 'identity'], + selected: ['compress', 'identity'] + }, { + accept: 'gzip;q=0.8, identity;q=0.5, *;q=0.3', + provided: ['identity', 'gzip', 'compress'], + selected: ['gzip', 'identity', 'compress'] + }, { + accept: 'gzip;q=0.8, compress', + provided: ['gzip', 'compress'], + selected: ['compress', 'gzip'] + }, { + accept: 'gzip;q=0.8, compress', + provided: null, + selected: ['compress', 'gzip', 'identity'] + } + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectEncoding(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/language.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/language.js new file mode 100644 index 00000000000..d98f26de275 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/language.js @@ -0,0 +1,70 @@ +(function() { + var configuration, preferredLanguages, testConfigurations, testCorrectType, _i, _len, + _this = this; + + preferredLanguages = require('../lib/language').preferredLanguages; + + this["Should not return a language when no is provided"] = function(test) { + test.deepEqual(preferredLanguages('*', []), []); + return test.done(); + }; + + this["Should not return a language when no language is acceptable"] = function(test) { + test.deepEqual(preferredLanguages('en', ['es']), []); + return test.done(); + }; + + this["Should not return a language with q = 0"] = function(test) { + test.deepEqual(preferredLanguages('en;q=0', ['en']), []); + return test.done(); + }; + + testCorrectType = function(c) { + return _this["Should return " + c.selected + " for accept-language header " + c.accept + " with provided language " + c.provided] = function(test) { + test.deepEqual(preferredLanguages(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'en', + provided: ['en'], + selected: ['en'] + }, { + accept: '*', + provided: ['en'], + selected: ['en'] + }, { + accept: 'en-US, en;q=0.8', + provided: ['en-US', 'en-GB'], + selected: ['en-US', 'en-GB'] + }, { + accept: 'en-US, en-GB', + provided: ['en-US'], + selected: ['en-US'] + }, { + accept: 'en', + provided: ['en-US'], + selected: ['en-US'] + }, { + accept: 'en;q=0.8, es', + provided: ['en', 'es'], + selected: ['es', 'en'] + }, { + accept: 'en-US;q=0.8, es', + provided: ['en', 'es'], + selected: ['es', 'en'] + }, { + accept: 'en-US;q=0.8, es', + provided: null, + selected: ['es', 'en-US'] + } + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectType(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/mediaType.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/mediaType.js new file mode 100644 index 00000000000..08e49231127 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/node_modules/negotiator/test/mediaType.js @@ -0,0 +1,70 @@ +(function() { + var configuration, preferredMediaTypes, testConfigurations, testCorrectType, _i, _len, + _this = this; + + preferredMediaTypes = require('../lib/mediaType').preferredMediaTypes; + + this["Should not return a media type when no media type provided"] = function(test) { + test.deepEqual(preferredMediaTypes('*/*', []), []); + return test.done(); + }; + + this["Should not return a media type when no media type is acceptable"] = function(test) { + test.deepEqual(preferredMediaTypes('application/json', ['text/html']), []); + return test.done(); + }; + + this["Should not return a media type with q = 0"] = function(test) { + test.deepEqual(preferredMediaTypes('text/html;q=0', ['text/html']), []); + return test.done(); + }; + + testCorrectType = function(c) { + return _this["Should return " + c.selected + " for access header " + c.accept + " with provided types " + c.provided] = function(test) { + test.deepEqual(preferredMediaTypes(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'text/html', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: '*/*', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'text/*', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'application/json, text/html', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'text/html;q=0.1', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'application/json, text/html', + provided: ['application/json', 'text/html'], + selected: ['application/json', 'text/html'] + }, { + accept: 'application/json;q=0.2, text/html', + provided: ['application/json', 'text/html'], + selected: ['text/html', 'application/json'] + }, { + accept: 'application/json;q=0.2, text/html', + provided: null, + selected: ['text/html', 'application/json'] + } + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectType(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/package.json new file mode 100644 index 00000000000..fea3a6860e5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/compression/package.json @@ -0,0 +1,40 @@ +{ + "name": "compression", + "description": "Compression middleware for connect and node.js", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/compression.git" + }, + "bugs": { + "url": "https://github.com/expressjs/compression/issues" + }, + "dependencies": { + "bytes": "0.2.1", + "negotiator": "0.3.0", + "compressible": "1.0.0" + }, + "devDependencies": { + "supertest": "*", + "connect": "*", + "mocha": "*", + "should": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# compression [![Build Status](https://travis-ci.org/expressjs/compression.png)](https://travis-ci.org/expressjs/compression)\n\nConnect's compress middleware as its own module. Works with and without Connect.\n\n```js\nvar compress = require('compression')()\n\nhttp.createServer(function (req, res) {\n compress(req, res, function (err) {\n if (err) throw err\n\n res.end('hello world')\n })\n})\n\nvar app = require('connect')()\napp.use(compress)\n```\n\n## API\n\n### var middleware = compress([options])\n\nIn addition to `zlib` options, additional options are:\n\n- `threshold` <1kb> - only compress the response if the byte size is at or above a threshold\n- `filter` - a filter callback function\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.", + "readmeFilename": "README.md", + "_id": "compression@1.0.0", + "dist": { + "shasum": "8aeb85d48db5145d38bc8b181b6352d8eab26020" + }, + "_from": "compression@1.0.0", + "_resolved": "https://registry.npmjs.org/compression/-/compression-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/.npmignore new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/.travis.yml new file mode 100644 index 00000000000..3e3646a12ca --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/.travis.yml @@ -0,0 +1,4 @@ +node_js: +- "0.10" +- "0.11" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/Makefile new file mode 100644 index 00000000000..083aa531ac9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/Makefile @@ -0,0 +1,6 @@ +test: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/README.md new file mode 100644 index 00000000000..13436351995 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/README.md @@ -0,0 +1,40 @@ +# Timeout + +Previously `connect.timeout()`. + +Usage: + +```js +var app = require('connect'); +app.use(require('timeout')(300)) +``` + +## API + +### fn = timeout(ms) + +Returns middleware that times out in `ms` milliseconds. + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/index.js new file mode 100644 index 00000000000..e6b7aed531c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/index.js @@ -0,0 +1,57 @@ +/*! + * Connect - timeout + * Ported from https://github.com/LearnBoost/connect-timeout + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var debug = require('debug')('connect:timeout'); + +/** + * Timeout: + * + * Times out the request in `ms`, defaulting to `5000`. The + * method `req.clearTimeout()` is added to revert this behaviour + * programmatically within your application's middleware, routes, etc. + * + * The timeout error is passed to `next()` so that you may customize + * the response behaviour. This error has the `.timeout` property as + * well as `.status == 503`. + * + * @param {Number} ms + * @return {Function} + * @api public + */ + +module.exports = function timeout(ms) { + ms = ms || 5000; + + return function(req, res, next) { + var id = setTimeout(function(){ + req.emit('timeout', ms); + }, ms); + + req.on('timeout', function(){ + if (res.headersSent) return debug('response started, cannot timeout'); + var err = new Error('Response timeout'); + err.timeout = ms; + err.status = 503; + next(err); + }); + + req.clearTimeout = function(){ + clearTimeout(id); + }; + + var writeHead = res.writeHead; + res.writeHead = function(){ + clearTimeout(id); + writeHead.apply(res, arguments); + } + + next(); + }; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/package.json new file mode 100644 index 00000000000..d14b579fb07 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/connect-timeout/package.json @@ -0,0 +1,38 @@ +{ + "name": "connect-timeout", + "description": "timeout middleware", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/timeout.git" + }, + "bugs": { + "url": "https://github.com/expressjs/timeout/issues" + }, + "dependencies": { + "debug": "*" + }, + "devDependencies": { + "mocha": "^1.17.0", + "should": "^3.0.0", + "supertest": "*", + "connect": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# Timeout\n\nPreviously `connect.timeout()`.\n\nUsage:\n\n```js\nvar app = require('connect');\napp.use(require('timeout')(300))\n```\n\n## API\n\n### fn = timeout(ms)\n\nReturns middleware that times out in `ms` milliseconds.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", + "readmeFilename": "README.md", + "_id": "connect-timeout@1.0.0", + "dist": { + "shasum": "12054799f90bb9566f8b274efe7842d6465d10bb" + }, + "_from": "connect-timeout@1.0.0", + "_resolved": "https://registry.npmjs.org/connect-timeout/-/connect-timeout-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/.npmignore new file mode 100644 index 00000000000..3c3629e647f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/README.md new file mode 100644 index 00000000000..ffca3fd7b53 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/README.md @@ -0,0 +1,25 @@ +# cookie-parser + +Parse _Cookie_ header and populate `req.cookies` with an object keyed by the cookie +names. Optionally you may enabled signed cookie support by passing a `secret` string, +which assigns `req.secret` so it may be used by other middleware. + +```js +var cookieParser = require('cookie-parser'); + +connect() + .use(cookieParser('optional secret string')) + .use(function(req, res, next){ + res.end(JSON.stringify(req.cookies)); + }) +``` + +## install + +```shell +npm install cookie-parser +``` + +## License + +MIT diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/index.js new file mode 100644 index 00000000000..7f63d5b0756 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/index.js @@ -0,0 +1,48 @@ +var cookie = require('cookie'); +var parse = require('./lib/parse'); + +/** + * Parse _Cookie_ header and populate `req.cookies` + * with an object keyed by the cookie names. Optionally + * you may enabled signed cookie support by passing + * a `secret` string, which assigns `req.secret` so + * it may be used by other middleware. + * + * Examples: + * + * connect() + * .use(connect.cookieParser('optional secret string')) + * .use(function(req, res, next){ + * res.end(JSON.stringify(req.cookies)); + * }) + * + * @param {String} secret + * @return {Function} + * @api public + */ + +module.exports = function cookieParser(secret, opt){ + return function cookieParser(req, res, next) { + if (req.cookies) return next(); + var cookies = req.headers.cookie; + + req.secret = secret; + req.cookies = {}; + req.signedCookies = {}; + + if (cookies) { + try { + req.cookies = cookie.parse(cookies, opt); + if (secret) { + req.signedCookies = parse.signedCookies(req.cookies, secret); + req.signedCookies = parse.JSONCookies(req.signedCookies); + } + req.cookies = parse.JSONCookies(req.cookies); + } catch (err) { + err.status = 400; + return next(err); + } + } + next(); + }; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/lib/parse.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/lib/parse.js new file mode 100644 index 00000000000..7991ab74bb9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/lib/parse.js @@ -0,0 +1,61 @@ +var signature = require('cookie-signature'); + +/** + * Parse signed cookies, returning an object + * containing the decoded key/value pairs, + * while removing the signed key from `obj`. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.signedCookies = function(obj, secret){ + var ret = {}; + Object.keys(obj).forEach(function(key){ + var val = obj[key]; + if (0 == val.indexOf('s:')) { + val = signature.unsign(val.slice(2), secret); + if (val) { + ret[key] = val; + delete obj[key]; + } + } + }); + return ret; +}; + +/** + * Parse JSON cookies. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.JSONCookies = function(obj){ + Object.keys(obj).forEach(function(key){ + var val = obj[key]; + var res = exports.JSONCookie(val); + if (res) obj[key] = res; + }); + return obj; +}; + +/** + * Parse JSON cookie string + * + * @param {String} str + * @return {Object} Parsed object or null if not json cookie + * @api private + */ + +exports.JSONCookie = function(str) { + if (0 == str.indexOf('j:')) { + try { + return JSON.parse(str.slice(2)); + } catch (err) { + // no op + } + } +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/.npmignore new file mode 100644 index 00000000000..3c3629e647f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/.travis.yml new file mode 100644 index 00000000000..9400c1188eb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.6" + - "0.8" + - "0.10" diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/LICENSE new file mode 100644 index 00000000000..249d9def928 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/LICENSE @@ -0,0 +1,9 @@ +// MIT License + +Copyright (C) Roman Shtylman + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/README.md new file mode 100644 index 00000000000..5187ed1ccad --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/README.md @@ -0,0 +1,44 @@ +# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) # + +cookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers. + +See [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies. + +## how? + +``` +npm install cookie +``` + +```javascript +var cookie = require('cookie'); + +var hdr = cookie.serialize('foo', 'bar'); +// hdr = 'foo=bar'; + +var cookies = cookie.parse('foo=bar; cat=meow; dog=ruff'); +// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' }; +``` + +## more + +The serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values. + +### path +> cookie path + +### expires +> absolute expiration date for the cookie (Date object) + +### maxAge +> relative max age of the cookie from when the client receives it (seconds) + +### domain +> domain for the cookie + +### secure +> true or false + +### httpOnly +> true or false + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/index.js new file mode 100644 index 00000000000..16bdb65dda8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/index.js @@ -0,0 +1,70 @@ + +/// Serialize the a name value pair into a cookie string suitable for +/// http headers. An optional options object specified cookie parameters +/// +/// serialize('foo', 'bar', { httpOnly: true }) +/// => "foo=bar; httpOnly" +/// +/// @param {String} name +/// @param {String} val +/// @param {Object} options +/// @return {String} +var serialize = function(name, val, opt){ + opt = opt || {}; + var enc = opt.encode || encode; + var pairs = [name + '=' + enc(val)]; + + if (opt.maxAge) pairs.push('Max-Age=' + opt.maxAge); + if (opt.domain) pairs.push('Domain=' + opt.domain); + if (opt.path) pairs.push('Path=' + opt.path); + if (opt.expires) pairs.push('Expires=' + opt.expires.toUTCString()); + if (opt.httpOnly) pairs.push('HttpOnly'); + if (opt.secure) pairs.push('Secure'); + + return pairs.join('; '); +}; + +/// Parse the given cookie header string into an object +/// The object has the various cookies as keys(names) => values +/// @param {String} str +/// @return {Object} +var parse = function(str, opt) { + opt = opt || {}; + var obj = {} + var pairs = str.split(/[;,] */); + var dec = opt.decode || decode; + + pairs.forEach(function(pair) { + var eq_idx = pair.indexOf('=') + + // skip things that don't look like key=value + if (eq_idx < 0) { + return; + } + + var key = pair.substr(0, eq_idx).trim() + var val = pair.substr(++eq_idx, pair.length).trim(); + + // quoted values + if ('"' == val[0]) { + val = val.slice(1, -1); + } + + // only assign once + if (undefined == obj[key]) { + try { + obj[key] = dec(val); + } catch (e) { + obj[key] = val; + } + } + }); + + return obj; +}; + +var encode = encodeURIComponent; +var decode = decodeURIComponent; + +module.exports.serialize = serialize; +module.exports.parse = parse; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/package.json new file mode 100644 index 00000000000..99a390f7ed4 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/package.json @@ -0,0 +1,36 @@ +{ + "author": { + "name": "Roman Shtylman", + "email": "shtylman@gmail.com" + }, + "name": "cookie", + "description": "cookie parsing and serialization", + "version": "0.1.0", + "repository": { + "type": "git", + "url": "git://github.com/shtylman/node-cookie.git" + }, + "keywords": [ + "cookie", + "cookies" + ], + "main": "index.js", + "scripts": { + "test": "mocha" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "1.x.x" + }, + "optionalDependencies": {}, + "engines": { + "node": "*" + }, + "readme": "# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) #\n\ncookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers.\n\nSee [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies.\n\n## how?\n\n```\nnpm install cookie\n```\n\n```javascript\nvar cookie = require('cookie');\n\nvar hdr = cookie.serialize('foo', 'bar');\n// hdr = 'foo=bar';\n\nvar cookies = cookie.parse('foo=bar; cat=meow; dog=ruff');\n// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' };\n```\n\n## more\n\nThe serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values.\n\n### path\n> cookie path\n\n### expires\n> absolute expiration date for the cookie (Date object)\n\n### maxAge\n> relative max age of the cookie from when the client receives it (seconds)\n\n### domain\n> domain for the cookie\n\n### secure\n> true or false\n\n### httpOnly\n> true or false\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/shtylman/node-cookie/issues" + }, + "_id": "cookie@0.1.0", + "_from": "cookie@0.1.0" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/mocha.opts b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/mocha.opts new file mode 100644 index 00000000000..e2bfcc5ac3f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/mocha.opts @@ -0,0 +1 @@ +--ui qunit diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/parse.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/parse.js new file mode 100644 index 00000000000..c6c27a20bb5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/parse.js @@ -0,0 +1,44 @@ + +var assert = require('assert'); + +var cookie = require('..'); + +suite('parse'); + +test('basic', function() { + assert.deepEqual({ foo: 'bar' }, cookie.parse('foo=bar')); + assert.deepEqual({ foo: '123' }, cookie.parse('foo=123')); +}); + +test('ignore spaces', function() { + assert.deepEqual({ FOO: 'bar', baz: 'raz' }, + cookie.parse('FOO = bar; baz = raz')); +}); + +test('escaping', function() { + assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, + cookie.parse('foo="bar=123456789&name=Magic+Mouse"')); + + assert.deepEqual({ email: ' ",;/' }, + cookie.parse('email=%20%22%2c%3b%2f')); +}); + +test('ignore escaping error and return original value', function() { + assert.deepEqual({ foo: '%1', bar: 'bar' }, cookie.parse('foo=%1;bar=bar')); +}); + +test('ignore non values', function() { + assert.deepEqual({ foo: '%1', bar: 'bar' }, cookie.parse('foo=%1;bar=bar;HttpOnly;Secure')); +}); + +test('unencoded', function() { + assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, + cookie.parse('foo="bar=123456789&name=Magic+Mouse"',{ + decode: function(value) { return value; } + })); + + assert.deepEqual({ email: '%20%22%2c%3b%2f' }, + cookie.parse('email=%20%22%2c%3b%2f',{ + decode: function(value) { return value; } + })); +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/serialize.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/serialize.js new file mode 100644 index 00000000000..86bb8c935c6 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/node_modules/cookie/test/serialize.js @@ -0,0 +1,64 @@ +// builtin +var assert = require('assert'); + +var cookie = require('..'); + +suite('serialize'); + +test('basic', function() { + assert.equal('foo=bar', cookie.serialize('foo', 'bar')); + assert.equal('foo=bar%20baz', cookie.serialize('foo', 'bar baz')); +}); + +test('path', function() { + assert.equal('foo=bar; Path=/', cookie.serialize('foo', 'bar', { + path: '/' + })); +}); + +test('secure', function() { + assert.equal('foo=bar; Secure', cookie.serialize('foo', 'bar', { + secure: true + })); + + assert.equal('foo=bar', cookie.serialize('foo', 'bar', { + secure: false + })); +}); + +test('domain', function() { + assert.equal('foo=bar; Domain=example.com', cookie.serialize('foo', 'bar', { + domain: 'example.com' + })); +}); + +test('httpOnly', function() { + assert.equal('foo=bar; HttpOnly', cookie.serialize('foo', 'bar', { + httpOnly: true + })); +}); + +test('maxAge', function() { + assert.equal('foo=bar; Max-Age=1000', cookie.serialize('foo', 'bar', { + maxAge: 1000 + })); +}); + +test('escaping', function() { + assert.deepEqual('cat=%2B%20', cookie.serialize('cat', '+ ')); +}); + +test('parse->serialize', function() { + + assert.deepEqual({ cat: 'foo=123&name=baz five' }, cookie.parse( + cookie.serialize('cat', 'foo=123&name=baz five'))); + + assert.deepEqual({ cat: ' ";/' }, cookie.parse( + cookie.serialize('cat', ' ";/'))); +}); + +test('unencoded', function() { + assert.deepEqual('cat=+ ', cookie.serialize('cat', '+ ', { + encode: function(value) { return value; } + })); +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/package.json new file mode 100644 index 00000000000..5c01b071139 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/package.json @@ -0,0 +1,46 @@ +{ + "name": "cookie-parser", + "version": "1.0.1", + "description": "cookie parsing with signatures", + "keywords": [ + "cookie", + "middleware" + ], + "repository": { + "type": "git", + "url": "git://github.com/expressjs/cookie-parser.git" + }, + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "dependencies": { + "cookie": "0.1.0", + "cookie-signature": "1.0.3" + }, + "devDependencies": { + "mocha": "~1.17.0", + "connect": "2.13.0", + "supertest": "0.9.0" + }, + "licenses": "MIT", + "main": "./index.js", + "engines": { + "node": ">= 0.10.0" + }, + "scripts": { + "test": "mocha --ui bdd --reporter list -- test/*.js" + }, + "readme": "# cookie-parser\n\nParse _Cookie_ header and populate `req.cookies` with an object keyed by the cookie\nnames. Optionally you may enabled signed cookie support by passing a `secret` string,\nwhich assigns `req.secret` so it may be used by other middleware.\n\n```js\nvar cookieParser = require('cookie-parser');\n\nconnect()\n .use(cookieParser('optional secret string'))\n .use(function(req, res, next){\n res.end(JSON.stringify(req.cookies));\n })\n```\n\n## install\n\n```shell\nnpm install cookie-parser\n```\n\n## License\n\nMIT\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/expressjs/cookie-parser/issues" + }, + "_id": "cookie-parser@1.0.1", + "dist": { + "shasum": "17bd622c9717cd0858a912a9fef4c0362360a7b0" + }, + "_from": "cookie-parser@1.0.1", + "_resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.0.1.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/test/cookieParser.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/test/cookieParser.js new file mode 100644 index 00000000000..657c2b9bd1e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-parser/test/cookieParser.js @@ -0,0 +1,72 @@ +var connect = require('connect') + , request = require('supertest') + , signature = require('cookie-signature'); + +var app = connect(); + +app.use(connect.cookieParser('keyboard cat')); + +app.use(function(req, res, next){ + if ('/signed' != req.url) return next(); + res.end(JSON.stringify(req.signedCookies)); +}); + +app.use(function(req, res, next){ + res.end(JSON.stringify(req.cookies)); +}); + +describe('connect.cookieParser()', function(){ + describe('when no cookies are sent', function(){ + it('should default req.cookies to {}', function(done){ + request(app) + .get('/') + .expect('{}', done); + }) + + it('should default req.signedCookies to {}', function(done){ + request(app) + .get('/signed') + .expect('{}', done); + }) + }) + + describe('when cookies are sent', function(){ + it('should populate req.cookies', function(done){ + request(app) + .get('/') + .set('Cookie', 'foo=bar; bar=baz') + .expect('{"foo":"bar","bar":"baz"}', done); + }) + }) + + describe('when a secret is given', function(){ + var val = signature.sign('foobarbaz', 'keyboard cat'); + // TODO: "bar" fails... + + it('should populate req.signedCookies', function(done){ + request(app) + .get('/signed') + .set('Cookie', 'foo=s:' + val) + .expect('{"foo":"foobarbaz"}', done); + }) + + it('should remove the signed value from req.cookies', function(done){ + request(app) + .get('/') + .set('Cookie', 'foo=s:' + val) + .expect('{}', done); + }) + + it('should omit invalid signatures', function(done){ + request(app) + .get('/signed') + .set('Cookie', 'foo=' + val + '3') + .expect('{}', function(){ + request(app) + .get('/') + .set('Cookie', 'foo=' + val + '3') + .expect('{"foo":"foobarbaz.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3"}', done); + }); + }) + }) +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/.npmignore new file mode 100644 index 00000000000..f1250e584c9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/History.md new file mode 100644 index 00000000000..7aacdf0c01f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/History.md @@ -0,0 +1,21 @@ +1.0.3 / 2014-01-28 +================== + + * fix for timing attacks + +1.0.2 / 2014-01-28 +================== + + * fix missing repository warning + * fix typo in test + +1.0.1 / 2013-04-15 +================== + + * Revert "Changed underlying HMAC algo. to sha512." + * Revert "Fix for timing attacks on MAC verification." + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/Makefile new file mode 100644 index 00000000000..4e9c8d36ebc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/Makefile @@ -0,0 +1,7 @@ + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter spec + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/Readme.md new file mode 100644 index 00000000000..2559e841b02 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/Readme.md @@ -0,0 +1,42 @@ + +# cookie-signature + + Sign and unsign cookies. + +## Example + +```js +var cookie = require('cookie-signature'); + +var val = cookie.sign('hello', 'tobiiscool'); +val.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI'); + +var val = cookie.sign('hello', 'tobiiscool'); +cookie.unsign(val, 'tobiiscool').should.equal('hello'); +cookie.unsign(val, 'luna').should.be.false; +``` + +## License + +(The MIT License) + +Copyright (c) 2012 LearnBoost <tj@learnboost.com> + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/index.js new file mode 100644 index 00000000000..32419feae2e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/index.js @@ -0,0 +1,43 @@ +/** + * Module dependencies. + */ + +var crypto = require('crypto'); + +/** + * Sign the given `val` with `secret`. + * + * @param {String} val + * @param {String} secret + * @return {String} + * @api private + */ + +exports.sign = function(val, secret){ + if ('string' != typeof val) throw new TypeError('cookie required'); + if ('string' != typeof secret) throw new TypeError('secret required'); + return val + '.' + crypto + .createHmac('sha256', secret) + .update(val) + .digest('base64') + .replace(/\=+$/, ''); +}; + +/** + * Unsign and decode the given `val` with `secret`, + * returning `false` if the signature is invalid. + * + * @param {String} val + * @param {String} secret + * @return {String|Boolean} + * @api private + */ + +exports.unsign = function(val, secret){ + if ('string' != typeof val) throw new TypeError('cookie required'); + if ('string' != typeof secret) throw new TypeError('secret required'); + var str = val.slice(0, val.lastIndexOf('.')) + , mac = exports.sign(str, secret); + + return exports.sign(mac, secret) == exports.sign(val, secret) ? str : false; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/package.json new file mode 100644 index 00000000000..aa7582b0551 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/cookie-signature/package.json @@ -0,0 +1,35 @@ +{ + "name": "cookie-signature", + "version": "1.0.3", + "description": "Sign and unsign cookies", + "keywords": [ + "cookie", + "sign", + "unsign" + ], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@learnboost.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/visionmedia/node-cookie-signature.git" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "main": "index", + "readme": "\n# cookie-signature\n\n Sign and unsign cookies.\n\n## Example\n\n```js\nvar cookie = require('cookie-signature');\n\nvar val = cookie.sign('hello', 'tobiiscool');\nval.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI');\n\nvar val = cookie.sign('hello', 'tobiiscool');\ncookie.unsign(val, 'tobiiscool').should.equal('hello');\ncookie.unsign(val, 'luna').should.be.false;\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 LearnBoost <tj@learnboost.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/node-cookie-signature/issues" + }, + "_id": "cookie-signature@1.0.3", + "dist": { + "shasum": "91cd997cc51fb641595738c69cda020328f50ff9" + }, + "_from": "cookie-signature@1.0.3", + "_resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/.npmignore new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/.travis.yml new file mode 100644 index 00000000000..3e3646a12ca --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/.travis.yml @@ -0,0 +1,4 @@ +node_js: +- "0.10" +- "0.11" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/Makefile new file mode 100644 index 00000000000..083aa531ac9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/Makefile @@ -0,0 +1,6 @@ +test: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/index.js new file mode 100644 index 00000000000..b6a4ef3b206 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/index.js @@ -0,0 +1,158 @@ +/*! + * Connect - csrf + * Copyright(c) 2011 Sencha Inc. + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var uid = require('uid2'); +var crypto = require('crypto'); + +/** + * Anti CSRF: + * + * CSRF protection middleware. + * + * This middleware adds a `req.csrfToken()` function to make a token + * which should be added to requests which mutate + * state, within a hidden form field, query-string etc. This + * token is validated against the visitor's session. + * + * The default `value` function checks `req.body` generated + * by the `bodyParser()` middleware, `req.query` generated + * by `query()`, and the "X-CSRF-Token" header field. + * + * This middleware requires session support, thus should be added + * somewhere _below_ `session()` and `cookieParser()`. + * + * Options: + * + * - `value` a function accepting the request, returning the token + * + * @param {Object} options + * @api public + */ + +module.exports = function csrf(options) { + options = options || {}; + var value = options.value || defaultValue; + + return function(req, res, next){ + + // already have one + var secret = req.session.csrfSecret; + if (secret) return createToken(secret); + + // generate secret + uid(24, function(err, secret){ + if (err) return next(err); + req.session.csrfSecret = secret; + createToken(secret); + }); + + // generate the token + function createToken(secret) { + var token; + + // lazy-load token + req.csrfToken = function csrfToken() { + return token || (token = saltedToken(secret)); + }; + + // ignore these methods + if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next(); + + // determine user-submitted value + var val = value(req); + + // check + if (!checkToken(val, secret)) { + var err = new Error('invalid csrf token'); + err.status = 403; + next(err); + return; + } + + next(); + } + } +}; + +/** + * Default value function, checking the `req.body` + * and `req.query` for the CSRF token. + * + * @param {IncomingMessage} req + * @return {String} + * @api private + */ + +function defaultValue(req) { + return (req.body && req.body._csrf) + || (req.query && req.query._csrf) + || (req.headers['x-csrf-token']) + || (req.headers['x-xsrf-token']); +} + +/** + * Return salted token. + * + * @param {String} secret + * @return {String} + * @api private + */ + +function saltedToken(secret) { + return createToken(generateSalt(10), secret); +} + +/** + * Creates a CSRF token from a given salt and secret. + * + * @param {String} salt (should be 10 characters) + * @param {String} secret + * @return {String} + * @api private + */ + +function createToken(salt, secret) { + return salt + crypto + .createHash('sha1') + .update(salt + secret) + .digest('base64'); +} + +/** + * Checks if a given CSRF token matches the given secret. + * + * @param {String} token + * @param {String} secret + * @return {Boolean} + * @api private + */ + +function checkToken(token, secret) { + if ('string' != typeof token) return false; + return token === createToken(token.slice(0, 10), secret); +} + +/** + * Generates a random salt, using a fast non-blocking PRNG (Math.random()). + * + * @param {Number} length + * @return {String} + * @api private + */ + +function generateSalt(length) { + var i, r = []; + for (i = 0; i < length; ++i) { + r.push(SALTCHARS[Math.floor(Math.random() * SALTCHARS.length)]); + } + return r.join(''); +} + +var SALTCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/LICENSE new file mode 100644 index 00000000000..bdfab69b588 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Marco Aurelio + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/index.js new file mode 100644 index 00000000000..6240b30832f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/index.js @@ -0,0 +1,55 @@ +/** + * Module dependencies + */ + +var crypto = require('crypto'); + +/** + * 62 characters in the ascii range that can be used in URLs without special + * encoding. + */ +var UIDCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + +/** + * Make a Buffer into a string ready for use in URLs + * + * @param {String} + * @returns {String} + * @api private + */ +function tostr(bytes) { + var chars, r, i; + + r = []; + for (i = 0; i < bytes.length; i++) { + r.push(UIDCHARS[bytes[i] % UIDCHARS.length]); + } + + return r.join(''); +} + +/** + * Generate an Unique Id + * + * @param {Number} length The number of chars of the uid + * @param {Number} cb (optional) Callback for async uid generation + * @api public + */ + +function uid(length, cb) { + + if (typeof cb === 'undefined') { + return tostr(crypto.pseudoRandomBytes(length)); + } else { + crypto.pseudoRandomBytes(length, function(err, bytes) { + if (err) return cb(err); + cb(null, tostr(bytes)); + }) + } +} + +/** + * Exports + */ + +module.exports = uid; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/package.json new file mode 100644 index 00000000000..f877925b676 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/node_modules/uid2/package.json @@ -0,0 +1,16 @@ +{ + "name": "uid2", + "description": "strong uid", + "tags": [ + "uid" + ], + "version": "0.0.3", + "dependencies": {}, + "readme": "ERROR: No README data found!", + "_id": "uid2@0.0.3", + "dist": { + "shasum": "837bfbe18583ae394e1e2b803f8bc13c47f942ef" + }, + "_from": "uid2@~0.0.2", + "_resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/package.json new file mode 100644 index 00000000000..0bc38c65847 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/csurf/package.json @@ -0,0 +1,39 @@ +{ + "name": "csurf", + "description": "CSRF token middleware", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/csurf.git" + }, + "bugs": { + "url": "https://github.com/expressjs/csurf/issues" + }, + "dependencies": { + "uid2": "~0.0.2" + }, + "devDependencies": { + "cookie-session": "*", + "body-parser": "*", + "mocha": "^1.17.0", + "should": "^3.0.0", + "supertest": "*", + "connect": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "ERROR: No README data found!", + "_id": "csurf@1.0.0", + "dist": { + "shasum": "a68d5718b988032e270abf1f4b34f272753d745b" + }, + "_from": "csurf@1.0.0", + "_resolved": "https://registry.npmjs.org/csurf/-/csurf-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/Readme.md new file mode 100644 index 00000000000..c5a34e8b89e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/Readme.md @@ -0,0 +1,115 @@ +# debug + + tiny node.js debugging utility modelled after node core's debugging technique. + +## Installation + +``` +$ npm install debug +``` + +## Usage + + With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility. + +Example _app.js_: + +```js +var debug = require('debug')('http') + , http = require('http') + , name = 'My App'; + +// fake app + +debug('booting %s', name); + +http.createServer(function(req, res){ + debug(req.method + ' ' + req.url); + res.end('hello\n'); +}).listen(3000, function(){ + debug('listening'); +}); + +// fake worker of some kind + +require('./worker'); +``` + +Example _worker.js_: + +```js +var debug = require('debug')('worker'); + +setInterval(function(){ + debug('doing some work'); +}, 1000); +``` + + The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: + + ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png) + + ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png) + +## Millisecond diff + + When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. + + ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png) + + When stderr is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below: + _(NOTE: Debug now uses stderr instead of stdout, so the correct shell command for this example is actually `DEBUG=* node example/worker 2> out &`)_ + + ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png) + +## Conventions + + If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". + +## Wildcards + + The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. + + You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:". + +## Browser support + + Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. + +```js +a = debug('worker:a'); +b = debug('worker:b'); + +setInterval(function(){ + a('doing some work'); +}, 1000); + +setInterval(function(){ + a('doing some work'); +}, 1200); +``` + +## License + +(The MIT License) + +Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/debug.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/debug.js new file mode 100644 index 00000000000..509dc0dedd1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/debug.js @@ -0,0 +1,137 @@ + +/** + * Expose `debug()` as the module. + */ + +module.exports = debug; + +/** + * Create a debugger with the given `name`. + * + * @param {String} name + * @return {Type} + * @api public + */ + +function debug(name) { + if (!debug.enabled(name)) return function(){}; + + return function(fmt){ + fmt = coerce(fmt); + + var curr = new Date; + var ms = curr - (debug[name] || curr); + debug[name] = curr; + + fmt = name + + ' ' + + fmt + + ' +' + debug.humanize(ms); + + // This hackery is required for IE8 + // where `console.log` doesn't have 'apply' + window.console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); + } +} + +/** + * The currently active debug mode names. + */ + +debug.names = []; +debug.skips = []; + +/** + * Enables a debug mode by name. This can include modes + * separated by a colon and wildcards. + * + * @param {String} name + * @api public + */ + +debug.enable = function(name) { + try { + localStorage.debug = name; + } catch(e){} + + var split = (name || '').split(/[\s,]+/) + , len = split.length; + + for (var i = 0; i < len; i++) { + name = split[i].replace('*', '.*?'); + if (name[0] === '-') { + debug.skips.push(new RegExp('^' + name.substr(1) + '$')); + } + else { + debug.names.push(new RegExp('^' + name + '$')); + } + } +}; + +/** + * Disable debug output. + * + * @api public + */ + +debug.disable = function(){ + debug.enable(''); +}; + +/** + * Humanize the given `ms`. + * + * @param {Number} m + * @return {String} + * @api private + */ + +debug.humanize = function(ms) { + var sec = 1000 + , min = 60 * 1000 + , hour = 60 * min; + + if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; + if (ms >= min) return (ms / min).toFixed(1) + 'm'; + if (ms >= sec) return (ms / sec | 0) + 's'; + return ms + 'ms'; +}; + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +debug.enabled = function(name) { + for (var i = 0, len = debug.skips.length; i < len; i++) { + if (debug.skips[i].test(name)) { + return false; + } + } + for (var i = 0, len = debug.names.length; i < len; i++) { + if (debug.names[i].test(name)) { + return true; + } + } + return false; +}; + +/** + * Coerce `val`. + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +// persist + +try { + if (window.localStorage) debug.enable(localStorage.debug); +} catch(e){} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/index.js new file mode 100644 index 00000000000..e02c13b7f6a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/index.js @@ -0,0 +1,5 @@ +if ('undefined' == typeof window) { + module.exports = require('./lib/debug'); +} else { + module.exports = require('./debug'); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/lib/debug.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/lib/debug.js new file mode 100644 index 00000000000..3b0a9183d5a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/lib/debug.js @@ -0,0 +1,147 @@ +/** + * Module dependencies. + */ + +var tty = require('tty'); + +/** + * Expose `debug()` as the module. + */ + +module.exports = debug; + +/** + * Enabled debuggers. + */ + +var names = [] + , skips = []; + +(process.env.DEBUG || '') + .split(/[\s,]+/) + .forEach(function(name){ + name = name.replace('*', '.*?'); + if (name[0] === '-') { + skips.push(new RegExp('^' + name.substr(1) + '$')); + } else { + names.push(new RegExp('^' + name + '$')); + } + }); + +/** + * Colors. + */ + +var colors = [6, 2, 3, 4, 5, 1]; + +/** + * Previous debug() call. + */ + +var prev = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Is stdout a TTY? Colored output is disabled when `true`. + */ + +var isatty = tty.isatty(2); + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function color() { + return colors[prevColor++ % colors.length]; +} + +/** + * Humanize the given `ms`. + * + * @param {Number} m + * @return {String} + * @api private + */ + +function humanize(ms) { + var sec = 1000 + , min = 60 * 1000 + , hour = 60 * min; + + if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; + if (ms >= min) return (ms / min).toFixed(1) + 'm'; + if (ms >= sec) return (ms / sec | 0) + 's'; + return ms + 'ms'; +} + +/** + * Create a debugger with the given `name`. + * + * @param {String} name + * @return {Type} + * @api public + */ + +function debug(name) { + function disabled(){} + disabled.enabled = false; + + var match = skips.some(function(re){ + return re.test(name); + }); + + if (match) return disabled; + + match = names.some(function(re){ + return re.test(name); + }); + + if (!match) return disabled; + var c = color(); + + function colored(fmt) { + fmt = coerce(fmt); + + var curr = new Date; + var ms = curr - (prev[name] || curr); + prev[name] = curr; + + fmt = ' \u001b[9' + c + 'm' + name + ' ' + + '\u001b[3' + c + 'm\u001b[90m' + + fmt + '\u001b[3' + c + 'm' + + ' +' + humanize(ms) + '\u001b[0m'; + + console.error.apply(this, arguments); + } + + function plain(fmt) { + fmt = coerce(fmt); + + fmt = new Date().toUTCString() + + ' ' + name + ' ' + fmt; + console.error.apply(this, arguments); + } + + colored.enabled = plain.enabled = true; + + return isatty || process.env.DEBUG_COLORS + ? colored + : plain; +} + +/** + * Coerce `val`. + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/package.json new file mode 100644 index 00000000000..912d7321d9a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/debug/package.json @@ -0,0 +1,45 @@ +{ + "name": "debug", + "version": "0.7.4", + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/debug.git" + }, + "description": "small debugging utility", + "keywords": [ + "debug", + "log", + "debugger" + ], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "*" + }, + "main": "lib/debug.js", + "browser": "./debug.js", + "engines": { + "node": "*" + }, + "files": [ + "lib/debug.js", + "debug.js", + "index.js" + ], + "component": { + "scripts": { + "debug/index.js": "index.js", + "debug/debug.js": "debug.js" + } + }, + "readme": "# debug\n\n tiny node.js debugging utility modelled after node core's debugging technique.\n\n## Installation\n\n```\n$ npm install debug\n```\n\n## Usage\n\n With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.\n \nExample _app.js_:\n\n```js\nvar debug = require('debug')('http')\n , http = require('http')\n , name = 'My App';\n\n// fake app\n\ndebug('booting %s', name);\n\nhttp.createServer(function(req, res){\n debug(req.method + ' ' + req.url);\n res.end('hello\\n');\n}).listen(3000, function(){\n debug('listening');\n});\n\n// fake worker of some kind\n\nrequire('./worker');\n```\n\nExample _worker.js_:\n\n```js\nvar debug = require('debug')('worker');\n\nsetInterval(function(){\n debug('doing some work');\n}, 1000);\n```\n\n The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:\n\n ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)\n\n ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)\n\n## Millisecond diff\n\n When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the \"+NNNms\" will show you how much time was spent between calls.\n\n ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)\n\n When stderr is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:\n _(NOTE: Debug now uses stderr instead of stdout, so the correct shell command for this example is actually `DEBUG=* node example/worker 2> out &`)_\n \n ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)\n \n## Conventions\n\n If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use \":\" to separate features. For example \"bodyParser\" from Connect would then be \"connect:bodyParser\". \n\n## Wildcards\n\n The \"*\" character may be used as a wildcard. Suppose for example your library has debuggers named \"connect:bodyParser\", \"connect:compress\", \"connect:session\", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.\n\n You can also exclude specific debuggers by prefixing them with a \"-\" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with \"connect:\".\n\n## Browser support\n\n Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. \n\n```js\na = debug('worker:a');\nb = debug('worker:b');\n\nsetInterval(function(){\n a('doing some work');\n}, 1000);\n\nsetInterval(function(){\n a('doing some work');\n}, 1200);\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/debug/issues" + }, + "_id": "debug@0.7.4", + "_from": "debug@>= 0.7.3 < 1" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/.npmignore new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/.travis.yml new file mode 100644 index 00000000000..3e3646a12ca --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/.travis.yml @@ -0,0 +1,4 @@ +node_js: +- "0.10" +- "0.11" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/Makefile new file mode 100644 index 00000000000..083aa531ac9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/Makefile @@ -0,0 +1,6 @@ +test: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/README.md new file mode 100644 index 00000000000..79f549dd24e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/README.md @@ -0,0 +1,34 @@ +# Error Handler + +Previously `connect.errorHandler()`. + +Usage: + +```js +var app = require('connect'); +app.use(require('errorhandler')()) +``` + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/index.js new file mode 100644 index 00000000000..5943d01d2bb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/index.js @@ -0,0 +1,107 @@ +/*! + * Connect - errorHandler + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var fs; +try { + fs = require('graceful-fs'); +} catch (_) { + fs = require('fs'); +} + +// environment + +var env = process.env.NODE_ENV || 'development'; + +/** + * Error handler: + * + * Development error handler, providing stack traces + * and error message responses for requests accepting text, html, + * or json. + * + * Text: + * + * By default, and when _text/plain_ is accepted a simple stack trace + * or error message will be returned. + * + * JSON: + * + * When _application/json_ is accepted, connect will respond with + * an object in the form of `{ "error": error }`. + * + * HTML: + * + * When accepted connect will output a nice html stack trace. + * + * @return {Function} + * @api public + */ + +exports = module.exports = function errorHandler(){ + return function errorHandler(err, req, res, next){ + if (err.status) res.statusCode = err.status; + if (res.statusCode < 400) res.statusCode = 500; + if ('test' != env) console.error(err.stack); + var accept = req.headers.accept || ''; + // html + if (~accept.indexOf('html')) { + fs.readFile(__dirname + '/public/style.css', 'utf8', function(e, style){ + fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){ + var stack = (err.stack || '') + .split('\n').slice(1) + .map(function(v){ return '
  • ' + v + '
  • '; }).join(''); + html = html + .replace('{style}', style) + .replace('{stack}', stack) + .replace('{title}', exports.title) + .replace('{statusCode}', res.statusCode) + .replace(/\{error\}/g, escapeHTML(err.toString().replace(/\n/g, '
    '))); + res.setHeader('Content-Type', 'text/html; charset=utf-8'); + res.end(html); + }); + }); + // json + } else if (~accept.indexOf('json')) { + var error = { message: err.message, stack: err.stack }; + for (var prop in err) error[prop] = err[prop]; + var json = JSON.stringify({ error: error }); + res.setHeader('Content-Type', 'application/json'); + res.end(json); + // plain text + } else { + res.setHeader('Content-Type', 'text/plain'); + res.end(err.stack); + } + }; +}; + +/** + * Template title, framework authors may override this value. + */ + +exports.title = 'Connect'; + + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +function escapeHTML(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/package.json new file mode 100644 index 00000000000..cd9d53bcbde --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/package.json @@ -0,0 +1,35 @@ +{ + "name": "errorhandler", + "description": "connect's default error handler page", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/errorhandler.git" + }, + "bugs": { + "url": "https://github.com/expressjs/errorhandler/issues" + }, + "devDependencies": { + "mocha": "^1.17.0", + "should": "^3.0.0", + "supertest": "*", + "connect": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# Error Handler\n\nPreviously `connect.errorHandler()`.\n\nUsage:\n\n```js\nvar app = require('connect');\napp.use(require('errorhandler')())\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", + "readmeFilename": "README.md", + "_id": "errorhandler@1.0.0", + "dist": { + "shasum": "d74b37e8dc38c99afb3f5a79edcebaea022d042a" + }, + "_from": "errorhandler@1.0.0", + "_resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/public/error.html b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/public/error.html new file mode 100644 index 00000000000..a6d3fafd873 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/public/error.html @@ -0,0 +1,14 @@ + + + + {error} + + + +
    +

    {title}

    +

    {statusCode} {error}

    +
      {stack}
    +
    + + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/public/style.css b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/public/style.css new file mode 100644 index 00000000000..0709908a666 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/errorhandler/public/style.css @@ -0,0 +1,257 @@ +* { + margin: 0; + padding: 0; + outline: 0; +} + +body { + padding: 80px 100px; + font: 13px "Helvetica Neue", "Lucida Grande", "Arial"; + background: #ECE9E9 -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ECE9E9)); + background: #ECE9E9 -moz-linear-gradient(top, #fff, #ECE9E9); + background-repeat: no-repeat; + color: #555; + -webkit-font-smoothing: antialiased; +} +h1, h2, h3 { + font-size: 22px; + color: #343434; +} +h1 em, h2 em { + padding: 0 5px; + font-weight: normal; +} +h1 { + font-size: 60px; +} +h2 { + margin-top: 10px; +} +h3 { + margin: 5px 0 10px 0; + padding-bottom: 5px; + border-bottom: 1px solid #eee; + font-size: 18px; +} +ul li { + list-style: none; +} +ul li:hover { + cursor: pointer; + color: #2e2e2e; +} +ul li .path { + padding-left: 5px; + font-weight: bold; +} +ul li .line { + padding-right: 5px; + font-style: italic; +} +ul li:first-child .path { + padding-left: 0; +} +p { + line-height: 1.5; +} +a { + color: #555; + text-decoration: none; +} +a:hover { + color: #303030; +} +#stacktrace { + margin-top: 15px; +} +.directory h1 { + margin-bottom: 15px; + font-size: 18px; +} +ul#files { + width: 100%; + height: 100%; + overflow: hidden; +} +ul#files li { + float: left; + width: 30%; + line-height: 25px; + margin: 1px; +} +ul#files li a { + display: block; + height: 25px; + border: 1px solid transparent; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + overflow: hidden; + white-space: nowrap; +} +ul#files li a:focus, +ul#files li a:hover { + background: rgba(255,255,255,0.65); + border: 1px solid #ececec; +} +ul#files li a.highlight { + -webkit-transition: background .4s ease-in-out; + background: #ffff4f; + border-color: #E9DC51; +} +#search { + display: block; + position: fixed; + top: 20px; + right: 20px; + width: 90px; + -webkit-transition: width ease 0.2s, opacity ease 0.4s; + -moz-transition: width ease 0.2s, opacity ease 0.4s; + -webkit-border-radius: 32px; + -moz-border-radius: 32px; + -webkit-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); + -moz-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); + -webkit-font-smoothing: antialiased; + text-align: left; + font: 13px "Helvetica Neue", Arial, sans-serif; + padding: 4px 10px; + border: none; + background: transparent; + margin-bottom: 0; + outline: none; + opacity: 0.7; + color: #888; +} +#search:focus { + width: 120px; + opacity: 1.0; +} + +/*views*/ +#files span { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + text-indent: 10px; +} +#files .name { + background-repeat: no-repeat; +} +#files .icon .name { + text-indent: 28px; +} + +/*tiles*/ +.view-tiles .name { + width: 100%; + background-position: 8px 5px; +} +.view-tiles .size, +.view-tiles .date { + display: none; +} + +/*details*/ +ul#files.view-details li { + float: none; + display: block; + width: 90%; +} +ul#files.view-details li.header { + height: 25px; + background: #000; + color: #fff; + font-weight: bold; +} +.view-details .header { + border-radius: 5px; +} +.view-details .name { + width: 60%; + background-position: 8px 5px; +} +.view-details .size { + width: 10%; +} +.view-details .date { + width: 30%; +} +.view-details .size, +.view-details .date { + text-align: right; + direction: rtl; +} + +/*mobile*/ +@media (max-width: 768px) { + body { + font-size: 13px; + line-height: 16px; + padding: 0; + } + #search { + position: static; + width: 100%; + font-size: 2em; + line-height: 1.8em; + text-indent: 10px; + border: 0; + border-radius: 0; + padding: 10px 0; + margin: 0; + } + #search:focus { + width: 100%; + border: 0; + opacity: 1; + } + .directory h1 { + font-size: 2em; + line-height: 1.5em; + color: #fff; + background: #000; + padding: 15px 10px; + margin: 0; + } + ul#files { + border-top: 1px solid #cacaca; + } + ul#files li { + float: none; + width: auto !important; + display: block; + border-bottom: 1px solid #cacaca; + font-size: 2em; + line-height: 1.2em; + text-indent: 0; + margin: 0; + } + ul#files li:nth-child(odd) { + background: #e0e0e0; + } + ul#files li a { + height: auto; + border: 0; + border-radius: 0; + padding: 15px 10px; + } + ul#files li a:focus, + ul#files li a:hover { + border: 0; + } + #files .header, + #files .size, + #files .date { + display: none !important; + } + #files .name { + float: none; + display: inline-block; + width: 100%; + text-indent: 0; + background-position: 0 0; + } + #files .icon .name { + text-indent: 41px; + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/.npmignore new file mode 100644 index 00000000000..3c3629e647f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/README.md new file mode 100644 index 00000000000..c5c3d9abe74 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/README.md @@ -0,0 +1,142 @@ +# express-session + +Setup session store with the given `options`. + +Session data is _not_ saved in the cookie itself, however +cookies are used, so we must use the [cookieParser()](cookieParser.html) +middleware _before_ `session()`. + +## Example + +```js + app.use(connect.cookieParser()) + app.use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) +``` + +**Options** + + - `key` cookie name defaulting to `connect.sid` + - `store` session store instance + - `secret` session cookie is signed with this secret to prevent tampering + - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` + - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") + +**Cookie options** + +By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set +so the cookie becomes a browser-session cookie. When the user closes the +browser the cookie (and session) will be removed. + +## req.session + +To store or access session data, simply use the request property `req.session`, +which is (generally) serialized as JSON by the store, so nested objects +are typically fine. For example below is a user-specific view counter: + +```js +app.use(cookieParser()) +app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) + +app.use(function(req, res, next){ + var sess = req.session; + if (sess.views) { + res.setHeader('Content-Type', 'text/html'); + res.write('

    views: ' + sess.views + '

    '); + res.write('

    expires in: ' + (sess.cookie.maxAge / 1000) + 's

    '); + res.end(); + sess.views++; + } else { + sess.views = 1; + res.end('welcome to the session demo. refresh!'); + } +}) +``` + +## Session#regenerate() + +To regenerate the session simply invoke the method, once complete +a new SID and `Session` instance will be initialized at `req.session`. + +```js +req.session.regenerate(function(err){ + // will have a new session here +}); +``` + +## Session#destroy() + +Destroys the session, removing `req.session`, will be re-generated next request. + +```js +req.session.destroy(function(err){ + // cannot access session here +}); +``` + +## Session#reload() + +Reloads the session data. + +```js +req.session.reload(function(err){ + // session updated +}); +``` + +## Session#save() + +Save the session. + +```js +req.session.save(function(err){ + // session saved +}); +``` + +## Session#touch() + +Updates the `.maxAge` property. Typically this is +not necessary to call, as the session middleware does this for you. + +## Session#cookie + +Each session has a unique cookie object accompany it. This allows +you to alter the session cookie per visitor. For example we can +set `req.session.cookie.expires` to `false` to enable the cookie +to remain for only the duration of the user-agent. + +## Session#maxAge + +Alternatively `req.session.cookie.maxAge` will return the time +remaining in milliseconds, which we may also re-assign a new value +to adjust the `.expires` property appropriately. The following +are essentially equivalent + +```js +var hour = 3600000; +req.session.cookie.expires = new Date(Date.now() + hour); +req.session.cookie.maxAge = hour; +``` + +For example when `maxAge` is set to `60000` (one minute), and 30 seconds +has elapsed it will return `30000` until the current request has completed, +at which time `req.session.touch()` is called to reset `req.session.maxAge` +to its original value. + +```js +req.session.cookie.maxAge; +// => 30000 +``` + +## Session Store Implementation + +Every session store _must_ implement the following methods + + - `.get(sid, callback)` + - `.set(sid, session, callback)` + - `.destroy(sid, callback)` + +Recommended methods include, but are not limited to: + + - `.length(callback)` + - `.clear(callback)` diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/index.js new file mode 100644 index 00000000000..7d83b08c741 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/index.js @@ -0,0 +1,369 @@ +/*! + * Connect - session + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var uid = require('uid2') + , crc32 = require('buffer-crc32') + , parse = require('url').parse + , signature = require('cookie-signature') + , debug = require('debug')('session') + +var Session = require('./session/session') + , MemoryStore = require('./session/memory') + , Cookie = require('./session/cookie') + , Store = require('./session/store') + +// environment + +var env = process.env.NODE_ENV; + +/** + * Expose the middleware. + */ + +exports = module.exports = session; + +/** + * Expose constructors. + */ + +exports.Store = Store; +exports.Cookie = Cookie; +exports.Session = Session; +exports.MemoryStore = MemoryStore; + +/** + * Warning message for `MemoryStore` usage in production. + */ + +var warning = 'Warning: connect.session() MemoryStore is not\n' + + 'designed for a production environment, as it will leak\n' + + 'memory, and will not scale past a single process.'; + +/** + * Session: + * + * Setup session store with the given `options`. + * + * Session data is _not_ saved in the cookie itself, however + * cookies are used, so we must use the [cookieParser()](cookieParser.html) + * middleware _before_ `session()`. + * + * Examples: + * + * connect() + * .use(connect.cookieParser()) + * .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) + * + * Options: + * + * - `key` cookie name defaulting to `connect.sid` + * - `store` session store instance + * - `secret` session cookie is signed with this secret to prevent tampering + * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` + * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") + * + * Cookie option: + * + * By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set + * so the cookie becomes a browser-session cookie. When the user closes the + * browser the cookie (and session) will be removed. + * + * ## req.session + * + * To store or access session data, simply use the request property `req.session`, + * which is (generally) serialized as JSON by the store, so nested objects + * are typically fine. For example below is a user-specific view counter: + * + * connect() + * .use(connect.favicon()) + * .use(connect.cookieParser()) + * .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) + * .use(function(req, res, next){ + * var sess = req.session; + * if (sess.views) { + * res.setHeader('Content-Type', 'text/html'); + * res.write('

    views: ' + sess.views + '

    '); + * res.write('

    expires in: ' + (sess.cookie.maxAge / 1000) + 's

    '); + * res.end(); + * sess.views++; + * } else { + * sess.views = 1; + * res.end('welcome to the session demo. refresh!'); + * } + * } + * )).listen(3000); + * + * ## Session#regenerate() + * + * To regenerate the session simply invoke the method, once complete + * a new SID and `Session` instance will be initialized at `req.session`. + * + * req.session.regenerate(function(err){ + * // will have a new session here + * }); + * + * ## Session#destroy() + * + * Destroys the session, removing `req.session`, will be re-generated next request. + * + * req.session.destroy(function(err){ + * // cannot access session here + * }); + * + * ## Session#reload() + * + * Reloads the session data. + * + * req.session.reload(function(err){ + * // session updated + * }); + * + * ## Session#save() + * + * Save the session. + * + * req.session.save(function(err){ + * // session saved + * }); + * + * ## Session#touch() + * + * Updates the `.maxAge` property. Typically this is + * not necessary to call, as the session middleware does this for you. + * + * ## Session#cookie + * + * Each session has a unique cookie object accompany it. This allows + * you to alter the session cookie per visitor. For example we can + * set `req.session.cookie.expires` to `false` to enable the cookie + * to remain for only the duration of the user-agent. + * + * ## Session#maxAge + * + * Alternatively `req.session.cookie.maxAge` will return the time + * remaining in milliseconds, which we may also re-assign a new value + * to adjust the `.expires` property appropriately. The following + * are essentially equivalent + * + * var hour = 3600000; + * req.session.cookie.expires = new Date(Date.now() + hour); + * req.session.cookie.maxAge = hour; + * + * For example when `maxAge` is set to `60000` (one minute), and 30 seconds + * has elapsed it will return `30000` until the current request has completed, + * at which time `req.session.touch()` is called to reset `req.session.maxAge` + * to its original value. + * + * req.session.cookie.maxAge; + * // => 30000 + * + * Session Store Implementation: + * + * Every session store _must_ implement the following methods + * + * - `.get(sid, callback)` + * - `.set(sid, session, callback)` + * - `.destroy(sid, callback)` + * + * Recommended methods include, but are not limited to: + * + * - `.length(callback)` + * - `.clear(callback)` + * + * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. + * + * @param {Object} options + * @return {Function} + * @api public + */ + +function session(options){ + var options = options || {} + , key = options.key || 'connect.sid' + , store = options.store || new MemoryStore + , cookie = options.cookie || {} + , trustProxy = options.proxy + , storeReady = true + , rollingSessions = options.rolling || false; + + // notify user that this store is not + // meant for a production environment + if ('production' == env && store instanceof MemoryStore) { + console.warn(warning); + } + + // generates the new session + store.generate = function(req){ + req.sessionID = uid(24); + req.session = new Session(req); + req.session.cookie = new Cookie(cookie); + }; + + store.on('disconnect', function(){ storeReady = false; }); + store.on('connect', function(){ storeReady = true; }); + + return function session(req, res, next) { + // self-awareness + if (req.session) return next(); + + // Handle connection as if there is no session if + // the store has temporarily disconnected etc + if (!storeReady) return debug('store is disconnected'), next(); + + // pathname mismatch + var originalPath = parse(req.originalUrl).pathname; + if (0 != originalPath.indexOf(cookie.path || '/')) return next(); + + // backwards compatibility for signed cookies + // req.secret is passed from the cookie parser middleware + var secret = options.secret || req.secret; + + // ensure secret is available or bail + if (!secret) throw new Error('`secret` option required for sessions'); + + var originalHash + , originalId; + + // expose store + req.sessionStore = store; + + // grab the session cookie value and check the signature + var rawCookie = req.cookies[key]; + + // get signedCookies for backwards compat with signed cookies + var unsignedCookie = req.signedCookies[key]; + + if (!unsignedCookie && rawCookie) { + unsignedCookie = (0 == rawCookie.indexOf('s:')) + ? signature.unsign(rawCookie.slice(2), secret) + : rawCookie; + } + + // set-cookie + var writeHead = res.writeHead; + res.writeHead = function(){ + if (!req.session) { + debug('no session'); + writeHead.apply(res, arguments); + return; + } + + var cookie = req.session.cookie + , proto = (req.headers['x-forwarded-proto'] || '').split(',')[0].toLowerCase().trim() + , tls = req.connection.encrypted || (trustProxy && 'https' == proto) + , isNew = unsignedCookie != req.sessionID; + + // only send secure cookies via https + if (cookie.secure && !tls) { + debug('not secured'); + writeHead.apply(res, arguments); + return; + } + + // in case of rolling session, always reset the cookie + if (!rollingSessions) { + + // browser-session length cookie + if (null == cookie.expires) { + if (!isNew) { + debug('already set browser-session cookie'); + writeHead.apply(res, arguments); + return + } + // compare hashes and ids + } else if (originalHash == hash(req.session) && originalId == req.session.id) { + debug('unmodified session'); + writeHead.apply(res, arguments); + return + } + + } + + var val = 's:' + signature.sign(req.sessionID, secret); + val = cookie.serialize(key, val); + debug('set-cookie %s', val); + res.setHeader('Set-Cookie', val); + writeHead.apply(res, arguments); + }; + + // proxy end() to commit the session + var end = res.end; + res.end = function(data, encoding){ + res.end = end; + if (!req.session) return res.end(data, encoding); + debug('saving'); + req.session.resetMaxAge(); + req.session.save(function(err){ + if (err) console.error(err.stack); + debug('saved'); + res.end(data, encoding); + }); + }; + + // generate the session + function generate() { + store.generate(req); + } + + // get the sessionID from the cookie + req.sessionID = unsignedCookie; + + // generate a session if the browser doesn't send a sessionID + if (!req.sessionID) { + debug('no SID sent, generating session'); + generate(); + next(); + return; + } + + // generate the session object + debug('fetching %s', req.sessionID); + store.get(req.sessionID, function(err, sess){ + // error handling + if (err) { + debug('error %j', err); + if ('ENOENT' == err.code) { + generate(); + next(); + } else { + next(err); + } + // no session + } else if (!sess) { + debug('no session found'); + generate(); + next(); + // populate req.session + } else { + debug('session found'); + store.createSession(req, sess); + originalId = req.sessionID; + originalHash = hash(sess); + next(); + } + }); + }; +}; + +/** + * Hash the given `sess` object omitting changes + * to `.cookie`. + * + * @param {Object} sess + * @return {String} + * @api private + */ + +function hash(sess) { + return crc32.signed(JSON.stringify(sess, function(key, val){ + if ('cookie' != key) return val; + })); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/.npmignore new file mode 100644 index 00000000000..b512c09d476 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/.npmignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/.travis.yml new file mode 100644 index 00000000000..7a902e8c86d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - 0.6 + - 0.8 +notifications: + email: + recipients: + - brianloveswords@gmail.com \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/README.md new file mode 100644 index 00000000000..0d9d8b83595 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/README.md @@ -0,0 +1,47 @@ +# buffer-crc32 + +[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32) + +crc32 that works with binary data and fancy character sets, outputs +buffer, signed or unsigned data and has tests. + +Derived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix + +# install +``` +npm install buffer-crc32 +``` + +# example +```js +var crc32 = require('buffer-crc32'); +// works with buffers +var buf = Buffer([0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00]) +crc32(buf) // -> + +// has convenience methods for getting signed or unsigned ints +crc32.signed(buf) // -> -1805997238 +crc32.unsigned(buf) // -> 2488970058 + +// will cast to buffer if given a string, so you can +// directly use foreign characters safely +crc32('自動販売機') // -> + +// and works in append mode too +var partialCrc = crc32('hey'); +var partialCrc = crc32(' ', partialCrc); +var partialCrc = crc32('sup', partialCrc); +var partialCrc = crc32(' ', partialCrc); +var finalCrc = crc32('bros', partialCrc); // -> +``` + +# tests +This was tested against the output of zlib's crc32 method. You can run +the tests with`npm test` (requires tap) + +# see also +https://github.com/alexgorbatchev/node-crc, `crc.buffer.crc32` also +supports buffer inputs and return unsigned ints (thanks @tjholowaychuk). + +# license +MIT/X11 diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/index.js new file mode 100644 index 00000000000..e29ce3ebce2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/index.js @@ -0,0 +1,88 @@ +var Buffer = require('buffer').Buffer; + +var CRC_TABLE = [ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d +]; + +function bufferizeInt(num) { + var tmp = Buffer(4); + tmp.writeInt32BE(num, 0); + return tmp; +} + +function _crc32(buf, previous) { + if (!Buffer.isBuffer(buf)) { + buf = Buffer(buf); + } + if (Buffer.isBuffer(previous)) { + previous = previous.readUInt32BE(0); + } + var crc = ~~previous ^ -1; + for (var n = 0; n < buf.length; n++) { + crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8); + } + return (crc ^ -1); +} + +function crc32() { + return bufferizeInt(_crc32.apply(null, arguments)); +} +crc32.signed = function () { + return _crc32.apply(null, arguments); +}; +crc32.unsigned = function () { + return _crc32.apply(null, arguments) >>> 0; +}; + +module.exports = crc32; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/package.json new file mode 100644 index 00000000000..c702600c3a5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/package.json @@ -0,0 +1,43 @@ +{ + "author": { + "name": "Brian J. Brennan", + "email": "brianloveswords@gmail.com", + "url": "http://bjb.io" + }, + "name": "buffer-crc32", + "description": "A pure javascript CRC32 algorithm that plays nice with binary data", + "version": "0.2.1", + "contributors": [ + { + "name": "Vladimir Kuznetsov" + } + ], + "homepage": "https://github.com/brianloveswords/buffer-crc32", + "repository": { + "type": "git", + "url": "git://github.com/brianloveswords/buffer-crc32.git" + }, + "main": "index.js", + "scripts": { + "test": "./node_modules/.bin/tap tests/*.test.js" + }, + "dependencies": {}, + "devDependencies": { + "tap": "~0.2.5" + }, + "optionalDependencies": {}, + "engines": { + "node": "*" + }, + "readme": "# buffer-crc32\n\n[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32)\n\ncrc32 that works with binary data and fancy character sets, outputs\nbuffer, signed or unsigned data and has tests.\n\nDerived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix\n\n# install\n```\nnpm install buffer-crc32\n```\n\n# example\n```js\nvar crc32 = require('buffer-crc32');\n// works with buffers\nvar buf = Buffer([0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00])\ncrc32(buf) // -> \n\n// has convenience methods for getting signed or unsigned ints\ncrc32.signed(buf) // -> -1805997238\ncrc32.unsigned(buf) // -> 2488970058\n\n// will cast to buffer if given a string, so you can\n// directly use foreign characters safely\ncrc32('自動販売機') // -> \n\n// and works in append mode too\nvar partialCrc = crc32('hey');\nvar partialCrc = crc32(' ', partialCrc);\nvar partialCrc = crc32('sup', partialCrc);\nvar partialCrc = crc32(' ', partialCrc);\nvar finalCrc = crc32('bros', partialCrc); // -> \n```\n\n# tests\nThis was tested against the output of zlib's crc32 method. You can run\nthe tests with`npm test` (requires tap)\n\n# see also\nhttps://github.com/alexgorbatchev/node-crc, `crc.buffer.crc32` also\nsupports buffer inputs and return unsigned ints (thanks @tjholowaychuk).\n\n# license\nMIT/X11\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/brianloveswords/buffer-crc32/issues" + }, + "_id": "buffer-crc32@0.2.1", + "dist": { + "shasum": "be3e5382fc02b6d6324956ac1af98aa98b08534c" + }, + "_from": "buffer-crc32@0.2.1", + "_resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/tests/crc.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/tests/crc.test.js new file mode 100644 index 00000000000..bb0f9efccbe --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/buffer-crc32/tests/crc.test.js @@ -0,0 +1,89 @@ +var crc32 = require('..'); +var test = require('tap').test; + +test('simple crc32 is no problem', function (t) { + var input = Buffer('hey sup bros'); + var expected = Buffer([0x47, 0xfa, 0x55, 0x70]); + t.same(crc32(input), expected); + t.end(); +}); + +test('another simple one', function (t) { + var input = Buffer('IEND'); + var expected = Buffer([0xae, 0x42, 0x60, 0x82]); + t.same(crc32(input), expected); + t.end(); +}); + +test('slightly more complex', function (t) { + var input = Buffer([0x00, 0x00, 0x00]); + var expected = Buffer([0xff, 0x41, 0xd9, 0x12]); + t.same(crc32(input), expected); + t.end(); +}); + +test('complex crc32 gets calculated like a champ', function (t) { + var input = Buffer('शीर्षक'); + var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]); + t.same(crc32(input), expected); + t.end(); +}); + +test('casts to buffer if necessary', function (t) { + var input = 'शीर्षक'; + var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]); + t.same(crc32(input), expected); + t.end(); +}); + +test('can do signed', function (t) { + var input = 'ham sandwich'; + var expected = -1891873021; + t.same(crc32.signed(input), expected); + t.end(); +}); + +test('can do unsigned', function (t) { + var input = 'bear sandwich'; + var expected = 3711466352; + t.same(crc32.unsigned(input), expected); + t.end(); +}); + + +test('simple crc32 in append mode', function (t) { + var input = [Buffer('hey'), Buffer(' '), Buffer('sup'), Buffer(' '), Buffer('bros')]; + var expected = Buffer([0x47, 0xfa, 0x55, 0x70]); + for (var crc = 0, i = 0; i < input.length; i++) { + crc = crc32(input[i], crc); + } + t.same(crc, expected); + t.end(); +}); + + +test('can do signed in append mode', function (t) { + var input1 = 'ham'; + var input2 = ' '; + var input3 = 'sandwich'; + var expected = -1891873021; + + var crc = crc32.signed(input1); + crc = crc32.signed(input2, crc); + crc = crc32.signed(input3, crc); + + t.same(crc, expected); + t.end(); +}); + +test('can do unsigned in append mode', function (t) { + var input1 = 'bear san'; + var input2 = 'dwich'; + var expected = 3711466352; + + var crc = crc32.unsigned(input1); + crc = crc32.unsigned(input2, crc); + t.same(crc, expected); + t.end(); +}); + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/.npmignore new file mode 100644 index 00000000000..3c3629e647f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/.travis.yml new file mode 100644 index 00000000000..9400c1188eb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.6" + - "0.8" + - "0.10" diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/LICENSE new file mode 100644 index 00000000000..249d9def928 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/LICENSE @@ -0,0 +1,9 @@ +// MIT License + +Copyright (C) Roman Shtylman + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/README.md new file mode 100644 index 00000000000..5187ed1ccad --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/README.md @@ -0,0 +1,44 @@ +# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) # + +cookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers. + +See [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies. + +## how? + +``` +npm install cookie +``` + +```javascript +var cookie = require('cookie'); + +var hdr = cookie.serialize('foo', 'bar'); +// hdr = 'foo=bar'; + +var cookies = cookie.parse('foo=bar; cat=meow; dog=ruff'); +// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' }; +``` + +## more + +The serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values. + +### path +> cookie path + +### expires +> absolute expiration date for the cookie (Date object) + +### maxAge +> relative max age of the cookie from when the client receives it (seconds) + +### domain +> domain for the cookie + +### secure +> true or false + +### httpOnly +> true or false + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/index.js new file mode 100644 index 00000000000..16bdb65dda8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/index.js @@ -0,0 +1,70 @@ + +/// Serialize the a name value pair into a cookie string suitable for +/// http headers. An optional options object specified cookie parameters +/// +/// serialize('foo', 'bar', { httpOnly: true }) +/// => "foo=bar; httpOnly" +/// +/// @param {String} name +/// @param {String} val +/// @param {Object} options +/// @return {String} +var serialize = function(name, val, opt){ + opt = opt || {}; + var enc = opt.encode || encode; + var pairs = [name + '=' + enc(val)]; + + if (opt.maxAge) pairs.push('Max-Age=' + opt.maxAge); + if (opt.domain) pairs.push('Domain=' + opt.domain); + if (opt.path) pairs.push('Path=' + opt.path); + if (opt.expires) pairs.push('Expires=' + opt.expires.toUTCString()); + if (opt.httpOnly) pairs.push('HttpOnly'); + if (opt.secure) pairs.push('Secure'); + + return pairs.join('; '); +}; + +/// Parse the given cookie header string into an object +/// The object has the various cookies as keys(names) => values +/// @param {String} str +/// @return {Object} +var parse = function(str, opt) { + opt = opt || {}; + var obj = {} + var pairs = str.split(/[;,] */); + var dec = opt.decode || decode; + + pairs.forEach(function(pair) { + var eq_idx = pair.indexOf('=') + + // skip things that don't look like key=value + if (eq_idx < 0) { + return; + } + + var key = pair.substr(0, eq_idx).trim() + var val = pair.substr(++eq_idx, pair.length).trim(); + + // quoted values + if ('"' == val[0]) { + val = val.slice(1, -1); + } + + // only assign once + if (undefined == obj[key]) { + try { + obj[key] = dec(val); + } catch (e) { + obj[key] = val; + } + } + }); + + return obj; +}; + +var encode = encodeURIComponent; +var decode = decodeURIComponent; + +module.exports.serialize = serialize; +module.exports.parse = parse; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/package.json new file mode 100644 index 00000000000..99a390f7ed4 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/package.json @@ -0,0 +1,36 @@ +{ + "author": { + "name": "Roman Shtylman", + "email": "shtylman@gmail.com" + }, + "name": "cookie", + "description": "cookie parsing and serialization", + "version": "0.1.0", + "repository": { + "type": "git", + "url": "git://github.com/shtylman/node-cookie.git" + }, + "keywords": [ + "cookie", + "cookies" + ], + "main": "index.js", + "scripts": { + "test": "mocha" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "1.x.x" + }, + "optionalDependencies": {}, + "engines": { + "node": "*" + }, + "readme": "# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) #\n\ncookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers.\n\nSee [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies.\n\n## how?\n\n```\nnpm install cookie\n```\n\n```javascript\nvar cookie = require('cookie');\n\nvar hdr = cookie.serialize('foo', 'bar');\n// hdr = 'foo=bar';\n\nvar cookies = cookie.parse('foo=bar; cat=meow; dog=ruff');\n// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' };\n```\n\n## more\n\nThe serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values.\n\n### path\n> cookie path\n\n### expires\n> absolute expiration date for the cookie (Date object)\n\n### maxAge\n> relative max age of the cookie from when the client receives it (seconds)\n\n### domain\n> domain for the cookie\n\n### secure\n> true or false\n\n### httpOnly\n> true or false\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/shtylman/node-cookie/issues" + }, + "_id": "cookie@0.1.0", + "_from": "cookie@0.1.0" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/mocha.opts b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/mocha.opts new file mode 100644 index 00000000000..e2bfcc5ac3f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/mocha.opts @@ -0,0 +1 @@ +--ui qunit diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/parse.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/parse.js new file mode 100644 index 00000000000..c6c27a20bb5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/parse.js @@ -0,0 +1,44 @@ + +var assert = require('assert'); + +var cookie = require('..'); + +suite('parse'); + +test('basic', function() { + assert.deepEqual({ foo: 'bar' }, cookie.parse('foo=bar')); + assert.deepEqual({ foo: '123' }, cookie.parse('foo=123')); +}); + +test('ignore spaces', function() { + assert.deepEqual({ FOO: 'bar', baz: 'raz' }, + cookie.parse('FOO = bar; baz = raz')); +}); + +test('escaping', function() { + assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, + cookie.parse('foo="bar=123456789&name=Magic+Mouse"')); + + assert.deepEqual({ email: ' ",;/' }, + cookie.parse('email=%20%22%2c%3b%2f')); +}); + +test('ignore escaping error and return original value', function() { + assert.deepEqual({ foo: '%1', bar: 'bar' }, cookie.parse('foo=%1;bar=bar')); +}); + +test('ignore non values', function() { + assert.deepEqual({ foo: '%1', bar: 'bar' }, cookie.parse('foo=%1;bar=bar;HttpOnly;Secure')); +}); + +test('unencoded', function() { + assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, + cookie.parse('foo="bar=123456789&name=Magic+Mouse"',{ + decode: function(value) { return value; } + })); + + assert.deepEqual({ email: '%20%22%2c%3b%2f' }, + cookie.parse('email=%20%22%2c%3b%2f',{ + decode: function(value) { return value; } + })); +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/serialize.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/serialize.js new file mode 100644 index 00000000000..86bb8c935c6 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/cookie/test/serialize.js @@ -0,0 +1,64 @@ +// builtin +var assert = require('assert'); + +var cookie = require('..'); + +suite('serialize'); + +test('basic', function() { + assert.equal('foo=bar', cookie.serialize('foo', 'bar')); + assert.equal('foo=bar%20baz', cookie.serialize('foo', 'bar baz')); +}); + +test('path', function() { + assert.equal('foo=bar; Path=/', cookie.serialize('foo', 'bar', { + path: '/' + })); +}); + +test('secure', function() { + assert.equal('foo=bar; Secure', cookie.serialize('foo', 'bar', { + secure: true + })); + + assert.equal('foo=bar', cookie.serialize('foo', 'bar', { + secure: false + })); +}); + +test('domain', function() { + assert.equal('foo=bar; Domain=example.com', cookie.serialize('foo', 'bar', { + domain: 'example.com' + })); +}); + +test('httpOnly', function() { + assert.equal('foo=bar; HttpOnly', cookie.serialize('foo', 'bar', { + httpOnly: true + })); +}); + +test('maxAge', function() { + assert.equal('foo=bar; Max-Age=1000', cookie.serialize('foo', 'bar', { + maxAge: 1000 + })); +}); + +test('escaping', function() { + assert.deepEqual('cat=%2B%20', cookie.serialize('cat', '+ ')); +}); + +test('parse->serialize', function() { + + assert.deepEqual({ cat: 'foo=123&name=baz five' }, cookie.parse( + cookie.serialize('cat', 'foo=123&name=baz five'))); + + assert.deepEqual({ cat: ' ";/' }, cookie.parse( + cookie.serialize('cat', ' ";/'))); +}); + +test('unencoded', function() { + assert.deepEqual('cat=+ ', cookie.serialize('cat', '+ ', { + encode: function(value) { return value; } + })); +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/LICENSE new file mode 100644 index 00000000000..bdfab69b588 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Marco Aurelio + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/index.js new file mode 100644 index 00000000000..6240b30832f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/index.js @@ -0,0 +1,55 @@ +/** + * Module dependencies + */ + +var crypto = require('crypto'); + +/** + * 62 characters in the ascii range that can be used in URLs without special + * encoding. + */ +var UIDCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + +/** + * Make a Buffer into a string ready for use in URLs + * + * @param {String} + * @returns {String} + * @api private + */ +function tostr(bytes) { + var chars, r, i; + + r = []; + for (i = 0; i < bytes.length; i++) { + r.push(UIDCHARS[bytes[i] % UIDCHARS.length]); + } + + return r.join(''); +} + +/** + * Generate an Unique Id + * + * @param {Number} length The number of chars of the uid + * @param {Number} cb (optional) Callback for async uid generation + * @api public + */ + +function uid(length, cb) { + + if (typeof cb === 'undefined') { + return tostr(crypto.pseudoRandomBytes(length)); + } else { + crypto.pseudoRandomBytes(length, function(err, bytes) { + if (err) return cb(err); + cb(null, tostr(bytes)); + }) + } +} + +/** + * Exports + */ + +module.exports = uid; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/package.json new file mode 100644 index 00000000000..58fda95a76f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/uid2/package.json @@ -0,0 +1,17 @@ +{ + "name": "uid2", + "description": "strong uid", + "tags": [ + "uid" + ], + "version": "0.0.3", + "dependencies": {}, + "readme": "ERROR: No README data found!", + "_id": "uid2@0.0.3", + "dist": { + "shasum": "837bfbe18583ae394e1e2b803f8bc13c47f942ef" + }, + "_from": "uid2@~0.0.2", + "_resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "scripts": {} +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/.travis.yml new file mode 100644 index 00000000000..af92b021bee --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/.travis.yml @@ -0,0 +1,6 @@ +language: "node_js" +node_js: + - "0.4" + - "0.6" + - "0.8" + - "0.10" diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/LICENSE new file mode 100644 index 00000000000..e33bd10bb4a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/LICENSE @@ -0,0 +1,20 @@ +(The MIT License) + +Copyright (c) 2013 Jared Hanson + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/README.md new file mode 100644 index 00000000000..2f94e9bd2ea --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/README.md @@ -0,0 +1,34 @@ +# utils-merge + +Merges the properties from a source object into a destination object. + +## Install + + $ npm install utils-merge + +## Usage + +```javascript +var a = { foo: 'bar' } + , b = { bar: 'baz' }; + +merge(a, b); +// => { foo: 'bar', bar: 'baz' } +``` + +## Tests + + $ npm install + $ npm test + +[![Build Status](https://secure.travis-ci.org/jaredhanson/utils-merge.png)](http://travis-ci.org/jaredhanson/utils-merge) + +## Credits + + - [Jared Hanson](http://github.com/jaredhanson) + +## License + +[The MIT License](http://opensource.org/licenses/MIT) + +Copyright (c) 2013 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)> diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/index.js new file mode 100644 index 00000000000..4265c694fec --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/index.js @@ -0,0 +1,23 @@ +/** + * Merge object b with object a. + * + * var a = { foo: 'bar' } + * , b = { bar: 'baz' }; + * + * merge(a, b); + * // => { foo: 'bar', bar: 'baz' } + * + * @param {Object} a + * @param {Object} b + * @return {Object} + * @api public + */ + +exports = module.exports = function(a, b){ + if (a && b) { + for (var key in b) { + a[key] = b[key]; + } + } + return a; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/package.json new file mode 100644 index 00000000000..d2122c12633 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/node_modules/utils-merge/package.json @@ -0,0 +1,46 @@ +{ + "name": "utils-merge", + "version": "1.0.0", + "description": "merge() utility function", + "keywords": [ + "util" + ], + "repository": { + "type": "git", + "url": "git://github.com/jaredhanson/utils-merge.git" + }, + "bugs": { + "url": "http://github.com/jaredhanson/utils-merge/issues" + }, + "author": { + "name": "Jared Hanson", + "email": "jaredhanson@gmail.com", + "url": "http://www.jaredhanson.net/" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/MIT" + } + ], + "main": "./index", + "dependencies": {}, + "devDependencies": { + "mocha": "1.x.x", + "chai": "1.x.x" + }, + "scripts": { + "test": "node_modules/.bin/mocha --reporter spec --require test/bootstrap/node test/*.test.js" + }, + "engines": { + "node": ">= 0.4.0" + }, + "readme": "# utils-merge\n\nMerges the properties from a source object into a destination object.\n\n## Install\n\n $ npm install utils-merge\n\n## Usage\n\n```javascript\nvar a = { foo: 'bar' }\n , b = { bar: 'baz' };\n\nmerge(a, b);\n// => { foo: 'bar', bar: 'baz' }\n```\n\n## Tests\n\n $ npm install\n $ npm test\n\n[![Build Status](https://secure.travis-ci.org/jaredhanson/utils-merge.png)](http://travis-ci.org/jaredhanson/utils-merge)\n\n## Credits\n\n - [Jared Hanson](http://github.com/jaredhanson)\n\n## License\n\n[The MIT License](http://opensource.org/licenses/MIT)\n\nCopyright (c) 2013 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>\n", + "readmeFilename": "README.md", + "_id": "utils-merge@1.0.0", + "dist": { + "shasum": "0294fb922bb9375153541c4f7096231f287c8af8" + }, + "_from": "utils-merge@1.0.0", + "_resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/package.json new file mode 100644 index 00000000000..144e054e229 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/package.json @@ -0,0 +1,38 @@ +{ + "name": "express-session", + "version": "1.0.2", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "main": "./index.js", + "dependencies": { + "utils-merge": "1.0.0", + "cookie": "0.1.0", + "cookie-signature": "1.0.3", + "uid2": "0.0.3", + "buffer-crc32": "0.2.1", + "debug": "0.7.4" + }, + "devDependencies": { + "mocha": "~1.17.0", + "connect": "2.13.0", + "supertest": "0.9.0", + "should": "3.1.2", + "cookie-parser": "1.0.0" + }, + "scripts": { + "test": "mocha --bail --ui bdd --reporter list -- test/*.js" + }, + "license": "MIT", + "readme": "# express-session\n\nSetup session store with the given `options`.\n\nSession data is _not_ saved in the cookie itself, however\ncookies are used, so we must use the [cookieParser()](cookieParser.html)\nmiddleware _before_ `session()`.\n\n## Example\n\n```js\n app.use(connect.cookieParser())\n app.use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }}))\n```\n\n**Options**\n\n - `key` cookie name defaulting to `connect.sid`\n - `store` session store instance\n - `secret` session cookie is signed with this secret to prevent tampering\n - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`\n - `proxy` trust the reverse proxy when setting secure cookies (via \"x-forwarded-proto\")\n\n**Cookie options**\n\nBy default `cookie.maxAge` is `null`, meaning no \"expires\" parameter is set\nso the cookie becomes a browser-session cookie. When the user closes the\nbrowser the cookie (and session) will be removed.\n\n## req.session\n\nTo store or access session data, simply use the request property `req.session`,\nwhich is (generally) serialized as JSON by the store, so nested objects\nare typically fine. For example below is a user-specific view counter:\n\n```js\napp.use(cookieParser())\napp.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))\n\napp.use(function(req, res, next){\n var sess = req.session;\n if (sess.views) {\n res.setHeader('Content-Type', 'text/html');\n res.write('

    views: ' + sess.views + '

    ');\n res.write('

    expires in: ' + (sess.cookie.maxAge / 1000) + 's

    ');\n res.end();\n sess.views++;\n } else {\n sess.views = 1;\n res.end('welcome to the session demo. refresh!');\n }\n})\n```\n\n## Session#regenerate()\n\nTo regenerate the session simply invoke the method, once complete\na new SID and `Session` instance will be initialized at `req.session`.\n\n```js\nreq.session.regenerate(function(err){\n // will have a new session here\n});\n```\n\n## Session#destroy()\n\nDestroys the session, removing `req.session`, will be re-generated next request.\n\n```js\nreq.session.destroy(function(err){\n // cannot access session here\n});\n```\n\n## Session#reload()\n\nReloads the session data.\n\n```js\nreq.session.reload(function(err){\n // session updated\n});\n```\n\n## Session#save()\n\nSave the session.\n\n```js\nreq.session.save(function(err){\n // session saved\n});\n```\n\n## Session#touch()\n\nUpdates the `.maxAge` property. Typically this is\nnot necessary to call, as the session middleware does this for you.\n\n## Session#cookie\n\nEach session has a unique cookie object accompany it. This allows\nyou to alter the session cookie per visitor. For example we can\nset `req.session.cookie.expires` to `false` to enable the cookie\nto remain for only the duration of the user-agent.\n\n## Session#maxAge\n\nAlternatively `req.session.cookie.maxAge` will return the time\nremaining in milliseconds, which we may also re-assign a new value\nto adjust the `.expires` property appropriately. The following\nare essentially equivalent\n\n```js\nvar hour = 3600000;\nreq.session.cookie.expires = new Date(Date.now() + hour);\nreq.session.cookie.maxAge = hour;\n```\n\nFor example when `maxAge` is set to `60000` (one minute), and 30 seconds\nhas elapsed it will return `30000` until the current request has completed,\nat which time `req.session.touch()` is called to reset `req.session.maxAge`\nto its original value.\n\n```js\nreq.session.cookie.maxAge;\n// => 30000\n```\n\n## Session Store Implementation\n\nEvery session store _must_ implement the following methods\n\n - `.get(sid, callback)`\n - `.set(sid, session, callback)`\n - `.destroy(sid, callback)`\n\nRecommended methods include, but are not limited to:\n\n - `.length(callback)`\n - `.clear(callback)`\n", + "readmeFilename": "README.md", + "description": "Setup session store with the given `options`.", + "_id": "express-session@1.0.2", + "dist": { + "shasum": "004478c742561774411ceb79733155a56b6d49eb" + }, + "_from": "express-session@1.0.2", + "_resolved": "https://registry.npmjs.org/express-session/-/express-session-1.0.2.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/cookie.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/cookie.js new file mode 100644 index 00000000000..86591de38a3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/cookie.js @@ -0,0 +1,128 @@ + +/*! + * Connect - session - Cookie + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var merge = require('utils-merge') + , cookie = require('cookie'); + +/** + * Initialize a new `Cookie` with the given `options`. + * + * @param {IncomingMessage} req + * @param {Object} options + * @api private + */ + +var Cookie = module.exports = function Cookie(options) { + this.path = '/'; + this.maxAge = null; + this.httpOnly = true; + if (options) merge(this, options); + this.originalMaxAge = undefined == this.originalMaxAge + ? this.maxAge + : this.originalMaxAge; +}; + +/*! + * Prototype. + */ + +Cookie.prototype = { + + /** + * Set expires `date`. + * + * @param {Date} date + * @api public + */ + + set expires(date) { + this._expires = date; + this.originalMaxAge = this.maxAge; + }, + + /** + * Get expires `date`. + * + * @return {Date} + * @api public + */ + + get expires() { + return this._expires; + }, + + /** + * Set expires via max-age in `ms`. + * + * @param {Number} ms + * @api public + */ + + set maxAge(ms) { + this.expires = 'number' == typeof ms + ? new Date(Date.now() + ms) + : ms; + }, + + /** + * Get expires max-age in `ms`. + * + * @return {Number} + * @api public + */ + + get maxAge() { + return this.expires instanceof Date + ? this.expires.valueOf() - Date.now() + : this.expires; + }, + + /** + * Return cookie data object. + * + * @return {Object} + * @api private + */ + + get data() { + return { + originalMaxAge: this.originalMaxAge + , expires: this._expires + , secure: this.secure + , httpOnly: this.httpOnly + , domain: this.domain + , path: this.path + } + }, + + /** + * Return a serialized cookie string. + * + * @return {String} + * @api public + */ + + serialize: function(name, val){ + return cookie.serialize(name, val, this.data); + }, + + /** + * Return JSON representation of this cookie. + * + * @return {Object} + * @api private + */ + + toJSON: function(){ + return this.data; + } +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/memory.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/memory.js new file mode 100644 index 00000000000..b79147f4e9d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/memory.js @@ -0,0 +1,129 @@ + +/*! + * Connect - session - MemoryStore + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Store = require('./store'); + +/** + * Initialize a new `MemoryStore`. + * + * @api public + */ + +var MemoryStore = module.exports = function MemoryStore() { + this.sessions = {}; +}; + +/** + * Inherit from `Store.prototype`. + */ + +MemoryStore.prototype.__proto__ = Store.prototype; + +/** + * Attempt to fetch session by the given `sid`. + * + * @param {String} sid + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.get = function(sid, fn){ + var self = this; + setImmediate(function(){ + var expires + , sess = self.sessions[sid]; + if (sess) { + sess = JSON.parse(sess); + expires = 'string' == typeof sess.cookie.expires + ? new Date(sess.cookie.expires) + : sess.cookie.expires; + if (!expires || new Date < expires) { + fn(null, sess); + } else { + self.destroy(sid, fn); + } + } else { + fn(); + } + }); +}; + +/** + * Commit the given `sess` object associated with the given `sid`. + * + * @param {String} sid + * @param {Session} sess + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.set = function(sid, sess, fn){ + var self = this; + setImmediate(function(){ + self.sessions[sid] = JSON.stringify(sess); + fn && fn(); + }); +}; + +/** + * Destroy the session associated with the given `sid`. + * + * @param {String} sid + * @api public + */ + +MemoryStore.prototype.destroy = function(sid, fn){ + var self = this; + setImmediate(function(){ + delete self.sessions[sid]; + fn && fn(); + }); +}; + +/** + * Invoke the given callback `fn` with all active sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.all = function(fn){ + var arr = [] + , keys = Object.keys(this.sessions); + for (var i = 0, len = keys.length; i < len; ++i) { + arr.push(this.sessions[keys[i]]); + } + fn(null, arr); +}; + +/** + * Clear all sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.clear = function(fn){ + this.sessions = {}; + fn && fn(); +}; + +/** + * Fetch number of sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.length = function(fn){ + fn(null, Object.keys(this.sessions).length); +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/session.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/session.js new file mode 100644 index 00000000000..891f31c7a8d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/session.js @@ -0,0 +1,116 @@ + +/*! + * Connect - session - Session + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var merge = require('utils-merge') + +/** + * Create a new `Session` with the given request and `data`. + * + * @param {IncomingRequest} req + * @param {Object} data + * @api private + */ + +var Session = module.exports = function Session(req, data) { + Object.defineProperty(this, 'req', { value: req }); + Object.defineProperty(this, 'id', { value: req.sessionID }); + if ('object' == typeof data) merge(this, data); +}; + +/** + * Update reset `.cookie.maxAge` to prevent + * the cookie from expiring when the + * session is still active. + * + * @return {Session} for chaining + * @api public + */ + +Session.prototype.touch = function(){ + return this.resetMaxAge(); +}; + +/** + * Reset `.maxAge` to `.originalMaxAge`. + * + * @return {Session} for chaining + * @api public + */ + +Session.prototype.resetMaxAge = function(){ + this.cookie.maxAge = this.cookie.originalMaxAge; + return this; +}; + +/** + * Save the session data with optional callback `fn(err)`. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.save = function(fn){ + this.req.sessionStore.set(this.id, this, fn || function(){}); + return this; +}; + +/** + * Re-loads the session data _without_ altering + * the maxAge properties. Invokes the callback `fn(err)`, + * after which time if no exception has occurred the + * `req.session` property will be a new `Session` object, + * although representing the same session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.reload = function(fn){ + var req = this.req + , store = this.req.sessionStore; + store.get(this.id, function(err, sess){ + if (err) return fn(err); + if (!sess) return fn(new Error('failed to load session')); + store.createSession(req, sess); + fn(); + }); + return this; +}; + +/** + * Destroy `this` session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.destroy = function(fn){ + delete this.req.session; + this.req.sessionStore.destroy(this.id, fn); + return this; +}; + +/** + * Regenerate this request's session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.regenerate = function(fn){ + this.req.sessionStore.regenerate(this.req, fn); + return this; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/store.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/store.js new file mode 100644 index 00000000000..54294cbdf73 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/session/store.js @@ -0,0 +1,84 @@ + +/*! + * Connect - session - Store + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter + , Session = require('./session') + , Cookie = require('./cookie'); + +/** + * Initialize abstract `Store`. + * + * @api private + */ + +var Store = module.exports = function Store(options){}; + +/** + * Inherit from `EventEmitter.prototype`. + */ + +Store.prototype.__proto__ = EventEmitter.prototype; + +/** + * Re-generate the given requests's session. + * + * @param {IncomingRequest} req + * @return {Function} fn + * @api public + */ + +Store.prototype.regenerate = function(req, fn){ + var self = this; + this.destroy(req.sessionID, function(err){ + self.generate(req); + fn(err); + }); +}; + +/** + * Load a `Session` instance via the given `sid` + * and invoke the callback `fn(err, sess)`. + * + * @param {String} sid + * @param {Function} fn + * @api public + */ + +Store.prototype.load = function(sid, fn){ + var self = this; + this.get(sid, function(err, sess){ + if (err) return fn(err); + if (!sess) return fn(); + var req = { sessionID: sid, sessionStore: self }; + sess = self.createSession(req, sess); + fn(null, sess); + }); +}; + +/** + * Create session from JSON `sess` data. + * + * @param {IncomingRequest} req + * @param {Object} sess + * @return {Session} + * @api private + */ + +Store.prototype.createSession = function(req, sess){ + var expires = sess.cookie.expires + , orig = sess.cookie.originalMaxAge; + sess.cookie = new Cookie(sess.cookie); + if ('string' == typeof expires) sess.cookie.expires = new Date(expires); + sess.cookie.originalMaxAge = orig; + req.session = new Session(req, sess); + return req.session; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/test/session.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/test/session.js new file mode 100644 index 00000000000..f93bec52d49 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/express-session/test/session.js @@ -0,0 +1,640 @@ + +var connect = require('connect') + , assert = require('assert') + , request = require('supertest') + , should = require('should') + , cookieParser = require('cookie-parser') + , session = require('../') + +var min = 60 * 1000; + +function respond(req, res) { + res.end(); +} + +function sid(res) { + var val = res.headers['set-cookie']; + if (!val) return ''; + return /^connect\.sid=([^;]+);/.exec(val[0])[1]; +} + +function expires(res) { + return res.headers['set-cookie'][0].match(/Expires=([^;]+)/)[1]; +} + +var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(respond); + +describe('session()', function(){ + it('should export constructors', function(){ + session.Session.should.be.a.Function; + session.Store.should.be.a.Function; + session.MemoryStore.should.be.a.Function; + }) + + describe('proxy option', function(){ + describe('when enabled', function(){ + it('should trust X-Forwarded-Proto when string', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) + .use(respond); + + request(app) + .get('/') + .set('X-Forwarded-Proto', 'https') + .end(function(err, res){ + res.headers.should.have.property('set-cookie'); + done(); + }); + }) + + it('should trust X-Forwarded-Proto when comma-separated list', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) + .use(respond); + + request(app) + .get('/') + .set('X-Forwarded-Proto', 'https,http') + .end(function(err, res){ + res.headers.should.have.property('set-cookie'); + done(); + }); + }) + }) + + describe('when disabled', function(){ + it('should not trust X-Forwarded-Proto', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { secure: true, maxAge: min }})) + .use(respond); + + request(app) + .get('/') + .set('X-Forwarded-Proto', 'https') + .end(function(err, res){ + res.headers.should.not.have.property('set-cookie'); + done(); + }); + }) + }) + }) + + describe('key option', function(){ + it('should default to "connect.sid"', function(done){ + request(app) + .get('/') + .end(function(err, res){ + res.headers['set-cookie'].should.have.length(1); + res.headers['set-cookie'][0].should.match(/^connect\.sid/); + done(); + }); + }) + + it('should allow overriding', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', key: 'sid', cookie: { maxAge: min }})) + .use(respond); + + request(app) + .get('/') + .end(function(err, res){ + res.headers['set-cookie'].should.have.length(1); + res.headers['set-cookie'][0].should.match(/^sid/); + done(); + }); + }) + }) + + it('should retain the sid', function(done){ + var n = 0; + + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(function(req, res){ + req.session.count = ++n; + res.end(); + }) + + request(app) + .get('/') + .end(function(err, res){ + + var id = sid(res); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + id) + .end(function(err, res){ + sid(res).should.equal(id); + done(); + }); + }); + }) + + describe('when an invalid sid is given', function(){ + it('should generate a new one', function(done){ + request(app) + .get('/') + .set('Cookie', 'connect.sid=foobarbaz') + .end(function(err, res){ + sid(res).should.not.equal('foobarbaz'); + done(); + }); + }) + }) + + it('should issue separate sids', function(done){ + var n = 0; + + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(function(req, res){ + req.session.count = ++n; + res.end(); + }) + + request(app) + .get('/') + .end(function(err, res){ + + var id = sid(res); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + id) + .end(function(err, res){ + sid(res).should.equal(id); + + request(app) + .get('/') + .end(function(err, res){ + sid(res).should.not.equal(id); + done(); + }); + }); + }); + }) + + describe('req.session', function(){ + it('should persist', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min, httpOnly: false }})) + .use(function(req, res, next){ + // checks that cookie options persisted + req.session.cookie.httpOnly.should.equal(false); + + req.session.count = req.session.count || 0; + req.session.count++; + res.end(req.session.count.toString()); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.text.should.equal('1'); + + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .end(function(err, res){ + res.text.should.equal('2'); + done(); + }); + }); + }) + + it('should only set-cookie when modified', function(done){ + var modify = true; + + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(function(req, res, next){ + if (modify) { + req.session.count = req.session.count || 0; + req.session.count++; + } + res.end(req.session.count.toString()); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.text.should.equal('1'); + + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .end(function(err, res){ + var id = sid(res); + res.text.should.equal('2'); + modify = false; + + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .end(function(err, res){ + sid(res).should.be.empty; + res.text.should.equal('2'); + modify = true; + + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + id) + .end(function(err, res){ + sid(res).should.not.be.empty; + res.text.should.equal('3'); + done(); + }); + }); + }); + }); + }) + + describe('.destroy()', function(){ + it('should destroy the previous session', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session.destroy(function(err){ + if (err) throw err; + assert(!req.session, 'req.session after destroy'); + res.end(); + }); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.headers.should.not.have.property('set-cookie'); + done(); + }); + }) + }) + + describe('.regenerate()', function(){ + it('should destroy/replace the previous session', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(function(req, res, next){ + var id = req.session.id; + req.session.regenerate(function(err){ + if (err) throw err; + id.should.not.equal(req.session.id); + res.end(); + }); + }); + + request(app) + .get('/') + .end(function(err, res){ + var id = sid(res); + + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + id) + .end(function(err, res){ + sid(res).should.not.equal(''); + sid(res).should.not.equal(id); + done(); + }); + }); + }) + }) + + describe('.cookie', function(){ + describe('.*', function(){ + it('should serialize as parameters', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', proxy: true, cookie: { maxAge: min }})) + .use(function(req, res, next){ + req.session.cookie.httpOnly = false; + req.session.cookie.secure = true; + res.end(); + }); + + request(app) + .get('/') + .set('X-Forwarded-Proto', 'https') + .end(function(err, res){ + res.headers['set-cookie'][0].should.not.include('HttpOnly'); + res.headers['set-cookie'][0].should.include('Secure'); + done(); + }); + }) + + it('should default to a browser-session length cookie', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) + .use(function(req, res, next){ + res.end(); + }); + + request(app) + .get('/admin') + .end(function(err, res){ + var cookie = res.headers['set-cookie'][0]; + cookie.should.not.include('Expires'); + done(); + }); + }) + + it('should Set-Cookie only once for browser-session cookies', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) + .use(function(req, res, next){ + res.end(); + }); + + request(app) + .get('/admin/foo') + .end(function(err, res){ + res.headers.should.have.property('set-cookie'); + + request(app) + .get('/admin') + .set('Cookie', 'connect.sid=' + sid(res)) + .end(function(err, res){ + res.headers.should.not.have.property('set-cookie'); + done(); + }) + }); + }) + + it('should override defaults', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { path: '/admin', httpOnly: false, secure: true, maxAge: 5000 }})) + .use(function(req, res, next){ + req.session.cookie.secure = false; + res.end(); + }); + + request(app) + .get('/admin') + .end(function(err, res){ + var cookie = res.headers['set-cookie'][0]; + cookie.should.not.include('HttpOnly'); + cookie.should.not.include('Secure'); + cookie.should.include('Path=/admin'); + cookie.should.include('Expires'); + done(); + }); + }) + }) + + describe('.secure', function(){ + it('should not set-cookie when insecure', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session.cookie.secure = true; + res.end(); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.headers.should.not.have.property('set-cookie'); + done(); + }); + }) + }) + + describe('when the pathname does not match cookie.path', function(){ + it('should not set-cookie', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) + .use(function(req, res, next){ + if (!req.session) { + return res.end(); + } + req.session.foo = Math.random(); + res.end(); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.status.should.equal(200); + res.headers.should.not.have.property('set-cookie'); + done(); + }); + }) + + it('should not set-cookie even for FQDN', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) + .use(function(req, res, next){ + if (!req.session) { + return res.end(); + } + + req.session.foo = Math.random(); + res.end(); + }); + + request(app) + .get('/') + .set('host', 'http://foo/bar') + .end(function(err, res){ + res.status.should.equal(200); + res.headers.should.not.have.property('set-cookie'); + done(); + }); + }) + }) + + describe('when the pathname does match cookie.path', function(){ + it('should set-cookie', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) + .use(function(req, res, next){ + req.session.foo = Math.random(); + res.end(); + }); + + request(app) + .get('/foo/bar/baz') + .end(function(err, res){ + res.headers.should.have.property('set-cookie'); + done(); + }); + }) + + it('should set-cookie even for FQDN', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) + .use(function(req, res, next){ + req.session.foo = Math.random(); + res.end(); + }); + + request(app) + .get('/foo/bar/baz') + .set('host', 'http://example.com') + .end(function(err, res){ + res.status.should.equal(200); + res.headers.should.have.property('set-cookie'); + done(); + }); + }) + }) + + describe('.maxAge', function(){ + var id; + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: 2000 }})) + .use(function(req, res, next){ + req.session.count = req.session.count || 0; + req.session.count++; + if (req.session.count == 2) req.session.cookie.maxAge = 5000; + if (req.session.count == 3) req.session.cookie.maxAge = 3000000000; + res.end(req.session.count.toString()); + }); + + it('should set relative in milliseconds', function(done){ + request(app) + .get('/') + .end(function(err, res){ + var a = new Date(expires(res)) + , b = new Date; + + id = sid(res); + + a.getYear().should.equal(b.getYear()); + a.getMonth().should.equal(b.getMonth()); + a.getDate().should.equal(b.getDate()); + a.getSeconds().should.not.equal(b.getSeconds()); + var delta = a.valueOf() - b.valueOf(); + (delta > 1000 && delta < 2000).should.be.ok; + res.text.should.equal('1'); + done(); + }); + }); + + it('should modify cookie when changed', function(done){ + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + id) + .end(function(err, res){ + var a = new Date(expires(res)) + , b = new Date; + + id = sid(res); + + a.getYear().should.equal(b.getYear()); + a.getMonth().should.equal(b.getMonth()); + a.getSeconds().should.not.equal(b.getSeconds()); + var delta = a.valueOf() - b.valueOf(); + (delta > 4000 && delta < 5000).should.be.ok; + res.text.should.equal('2'); + done(); + }); + }); + + it('should modify cookie when changed to large value', function(done){ + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + id) + .end(function(err, res){ + var a = new Date(expires(res)) + , b = new Date; + + id = sid(res); + + var delta = a.valueOf() - b.valueOf(); + (delta > 2999999000 && delta < 3000000000).should.be.ok; + res.text.should.equal('3'); + done(); + }); + }); + }) + + describe('.expires', function(){ + describe('when given a Date', function(){ + it('should set absolute', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session.cookie.expires = new Date(0); + res.end(); + }); + + request(app) + .get('/') + .end(function(err, res){ + expires(res).should.equal('Thu, 01 Jan 1970 00:00:00 GMT'); + done(); + }); + }) + }) + + describe('when null', function(){ + it('should be a browser-session cookie', function(done){ + var app = connect() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session.cookie.expires = null; + res.end(); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.headers['set-cookie'][0].should.not.include('Expires='); + done(); + }); + }) + }) + }) + }) + + it('should support req.signedCookies', function(done){ + var app = connect() + .use(cookieParser('keyboard cat')) + .use(session()) + .use(function(req, res, next){ + req.session.count = req.session.count || 0; + req.session.count++; + res.end(req.session.count.toString()); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.text.should.equal('1'); + + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .end(function(err, res){ + res.text.should.equal('2'); + done(); + }); + }); + }) + + }) +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/.npmignore new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/.npmignore @@ -0,0 +1 @@ +test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/History.md new file mode 100644 index 00000000000..12e1b3e2db3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/History.md @@ -0,0 +1,10 @@ + +0.2.1 / 2014-01-29 +================== + + * fix: support max-age=0 for end-to-end revalidation + +0.2.0 / 2013-08-11 +================== + + * fix: return false for no-cache diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/Makefile new file mode 100644 index 00000000000..8e8640f2e6d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/Makefile @@ -0,0 +1,7 @@ + +test: + @./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/Readme.md new file mode 100644 index 00000000000..61366c5777a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/Readme.md @@ -0,0 +1,57 @@ + +# node-fresh + + HTTP response freshness testing + +## fresh(req, res) + + Check freshness of `req` and `res` headers. + + When the cache is "fresh" __true__ is returned, + otherwise __false__ is returned to indicate that + the cache is now stale. + +## Example: + +```js +var req = { 'if-none-match': 'tobi' }; +var res = { 'etag': 'luna' }; +fresh(req, res); +// => false + +var req = { 'if-none-match': 'tobi' }; +var res = { 'etag': 'tobi' }; +fresh(req, res); +// => true +``` + +## Installation + +``` +$ npm install fresh +``` + +## License + +(The MIT License) + +Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/index.js new file mode 100644 index 00000000000..9c3f47d1eae --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/index.js @@ -0,0 +1,53 @@ + +/** + * Expose `fresh()`. + */ + +module.exports = fresh; + +/** + * Check freshness of `req` and `res` headers. + * + * When the cache is "fresh" __true__ is returned, + * otherwise __false__ is returned to indicate that + * the cache is now stale. + * + * @param {Object} req + * @param {Object} res + * @return {Boolean} + * @api public + */ + +function fresh(req, res) { + // defaults + var etagMatches = true; + var notModified = true; + + // fields + var modifiedSince = req['if-modified-since']; + var noneMatch = req['if-none-match']; + var lastModified = res['last-modified']; + var etag = res['etag']; + var cc = req['cache-control']; + + // unconditional request + if (!modifiedSince && !noneMatch) return false; + + // check for no-cache cache request directive + if (cc && cc.indexOf('no-cache') !== -1) return false; + + // parse if-none-match + if (noneMatch) noneMatch = noneMatch.split(/ *, */); + + // if-none-match + if (noneMatch) etagMatches = ~noneMatch.indexOf(etag) || '*' == noneMatch[0]; + + // if-modified-since + if (modifiedSince) { + modifiedSince = new Date(modifiedSince); + lastModified = new Date(lastModified); + notModified = lastModified <= modifiedSince; + } + + return !! (etagMatches && notModified); +} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/package.json new file mode 100644 index 00000000000..c051fe6231f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/fresh/package.json @@ -0,0 +1,37 @@ +{ + "name": "fresh", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "description": "HTTP response freshness testing", + "version": "0.2.2", + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/visionmedia/node-fresh.git" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/visionmedia/node-fresh/blob/master/Readme.md#license" + } + ], + "readme": "\n# node-fresh\n\n HTTP response freshness testing\n\n## fresh(req, res)\n\n Check freshness of `req` and `res` headers.\n\n When the cache is \"fresh\" __true__ is returned,\n otherwise __false__ is returned to indicate that\n the cache is now stale.\n\n## Example:\n\n```js\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'luna' };\nfresh(req, res);\n// => false\n\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'tobi' };\nfresh(req, res);\n// => true\n```\n\n## Installation\n\n```\n$ npm install fresh\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/node-fresh/issues" + }, + "_id": "fresh@0.2.2", + "dist": { + "shasum": "9731dcf5678c7faeb44fb903c4f72df55187fa77" + }, + "_from": "fresh@0.2.2", + "_resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/.npmignore new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/.travis.yml new file mode 100644 index 00000000000..3e3646a12ca --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/.travis.yml @@ -0,0 +1,4 @@ +node_js: +- "0.10" +- "0.11" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/Makefile new file mode 100644 index 00000000000..083aa531ac9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/Makefile @@ -0,0 +1,6 @@ +test: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/README.md new file mode 100644 index 00000000000..e7039f3cd35 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/README.md @@ -0,0 +1,35 @@ +# Method Override + +Previously `connect.methodOverride()`. + +Usage: + +```js +var app = require('connect'); +app.use(require('body-parser')()); +app.use(require('method-override')()) +``` + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/index.js new file mode 100644 index 00000000000..a729d136ca3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/index.js @@ -0,0 +1,58 @@ +/*! + * Connect - methodOverride + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var methods = require('methods'); + +/** + * Method Override: + * + * Provides faux HTTP method support. + * + * Pass an optional `key` to use when checking for + * a method override, otherwise defaults to _\_method_. + * The original method is available via `req.originalMethod`. + * + * @param {String} key + * @return {Function} + * @api public + */ + +module.exports = function methodOverride(key){ + key = key || "_method"; + return function methodOverride(req, res, next) { + var method; + req.originalMethod = req.originalMethod || req.method; + + // req.body + if (req.body && typeof req.body === 'object' && key in req.body) { + method = req.body[key].toLowerCase(); + delete req.body[key]; + } + + // check X-HTTP-Method-Override + if (req.headers['x-http-method-override']) { + method = req.headers['x-http-method-override'].toLowerCase(); + } + + // replace + if (supports(method)) req.method = method.toUpperCase(); + + next(); + }; +}; + +/** + * Check if node supports `method`. + */ + +function supports(method) { + return ~methods.indexOf(method); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/History.md new file mode 100644 index 00000000000..1d0e229fd0b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/History.md @@ -0,0 +1,5 @@ + +0.1.0 / 2013-10-28 +================== + + * add http.METHODS support diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/Readme.md new file mode 100644 index 00000000000..ac0658e21c2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/Readme.md @@ -0,0 +1,4 @@ + +# Methods + + HTTP verbs that node core's parser supports. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/index.js new file mode 100644 index 00000000000..95b93f5fbcd --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/index.js @@ -0,0 +1,37 @@ + +var http = require('http'); + +if (http.METHODS) { + module.exports = http.METHODS.map(function(method){ + return method.toLowerCase(); + }); + + return; +} + +module.exports = [ + 'get', + 'post', + 'put', + 'head', + 'delete', + 'options', + 'trace', + 'copy', + 'lock', + 'mkcol', + 'move', + 'propfind', + 'proppatch', + 'unlock', + 'report', + 'mkactivity', + 'checkout', + 'merge', + 'm-search', + 'notify', + 'subscribe', + 'unsubscribe', + 'patch', + 'search' +]; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/package.json new file mode 100644 index 00000000000..52c99afdc99 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/node_modules/methods/package.json @@ -0,0 +1,28 @@ +{ + "name": "methods", + "version": "0.1.0", + "description": "HTTP methods that node supports", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "http", + "methods" + ], + "author": { + "name": "TJ Holowaychuk" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/node-methods.git" + }, + "readme": "\n# Methods\n\n HTTP verbs that node core's parser supports.\n", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/node-methods/issues" + }, + "_id": "methods@0.1.0", + "_from": "methods@*" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/package.json new file mode 100644 index 00000000000..2664ae11568 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/method-override/package.json @@ -0,0 +1,38 @@ +{ + "name": "method-override", + "description": "method override", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/method-override.git" + }, + "bugs": { + "url": "https://github.com/expressjs/method-override/issues" + }, + "dependencies": { + "methods": "*" + }, + "devDependencies": { + "mocha": "^1.17.0", + "should": "^3.0.0", + "supertest": "*", + "connect": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# Method Override\n\nPreviously `connect.methodOverride()`.\n\nUsage:\n\n```js\nvar app = require('connect');\napp.use(require('body-parser')());\napp.use(require('method-override')())\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", + "readmeFilename": "README.md", + "_id": "method-override@1.0.0", + "dist": { + "shasum": "9e5bfbd80f3b9e043801dd3fe60bbab0f15b5f61" + }, + "_from": "method-override@1.0.0", + "_resolved": "https://registry.npmjs.org/method-override/-/method-override-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/.npmignore new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/Makefile new file mode 100644 index 00000000000..bd17c559a73 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/Makefile @@ -0,0 +1,9 @@ +BIN = ./node_modules/.bin/ + +test: + @$(BIN)mocha \ + --require should \ + --reporter spec \ + --bail + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/README.md new file mode 100644 index 00000000000..89299c2da77 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/README.md @@ -0,0 +1,15 @@ +# Connect Logger + +Connect's logging middleware. Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. You may view the old docs at http://www.senchalabs.org/connect/logger.html. Otherwise, view the source code's JSDocs. + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/index.js new file mode 100644 index 00000000000..75cdd07b550 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/index.js @@ -0,0 +1,349 @@ +/*! + * Connect - logger + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var bytes = require('bytes'); + +/*! + * Log buffer. + */ + +var buf = []; + +/*! + * Default log buffer duration. + */ + +var defaultBufferDuration = 1000; + +/** + * Logger: + * + * Log requests with the given `options` or a `format` string. + * + * Options: + * + * - `format` Format string, see below for tokens + * - `stream` Output stream, defaults to _stdout_ + * - `buffer` Buffer duration, defaults to 1000ms when _true_ + * - `immediate` Write log line on request instead of response (for response times) + * - `skip` Function to determine if logging is skipped, called as + * `skip(req, res)`, defaults to always false. + * + * Tokens: + * + * - `:req[header]` ex: `:req[Accept]` + * - `:res[header]` ex: `:res[Content-Length]` + * - `:http-version` + * - `:response-time` + * - `:remote-addr` + * - `:date` + * - `:method` + * - `:url` + * - `:referrer` + * - `:user-agent` + * - `:status` + * + * Formats: + * + * Pre-defined formats that ship with connect: + * + * - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"' + * - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms' + * - `tiny` ':method :url :status :res[content-length] - :response-time ms' + * - `dev` concise output colored by response status for development use + * + * Examples: + * + * connect.logger() // default + * connect.logger('short') + * connect.logger('tiny') + * connect.logger({ immediate: true, format: 'dev' }) + * connect.logger(':method :url - :referrer') + * connect.logger(':req[content-type] -> :res[content-type]') + * connect.logger(function(tokens, req, res){ return 'some format string' }) + * connect.logger({ format: 'dev', skip: function(req, res){ return res.statusCode === 304; }}) + * + * Defining Tokens: + * + * To define a token, simply invoke `connect.logger.token()` with the + * name and a callback function. The value returned is then available + * as ":type" in this case. + * + * connect.logger.token('type', function(req, res){ return req.headers['content-type']; }) + * + * Defining Formats: + * + * All default formats are defined this way, however it's public API as well: + * + * connect.logger.format('name', 'string or function') + * + * @param {String|Function|Object} format or options + * @return {Function} + * @api public + */ + +exports = module.exports = function logger(options) { + if ('object' == typeof options) { + options = options || {}; + } else if (options) { + options = { format: options }; + } else { + options = {}; + } + + // output on request instead of response + var immediate = options.immediate; + + // check if log entry should be skipped + var skip = options.skip || function () { return false; }; + + // format name + var fmt = exports[options.format] || options.format || exports.default; + + // compile format + if ('function' != typeof fmt) fmt = compile(fmt); + + // options + var stream = options.stream || process.stdout + , buffer = options.buffer; + + // buffering support + if (buffer) { + var realStream = stream + , interval = 'number' == typeof buffer + ? buffer + : defaultBufferDuration; + + // flush interval + setInterval(function(){ + if (buf.length) { + realStream.write(buf.join('')); + buf.length = 0; + } + }, interval); + + // swap the stream + stream = { + write: function(str){ + buf.push(str); + } + }; + } + + return function logger(req, res, next) { + var sock = req.socket; + req._startTime = new Date; + req._remoteAddress = sock.socket ? sock.socket.remoteAddress : sock.remoteAddress; + + function logRequest(){ + res.removeListener('finish', logRequest); + res.removeListener('close', logRequest); + if (skip(req, res)) return; + var line = fmt(exports, req, res); + if (null == line) return; + stream.write(line + '\n'); + }; + + // immediate + if (immediate) { + logRequest(); + // proxy end to output logging + } else { + res.on('finish', logRequest); + res.on('close', logRequest); + } + + + next(); + }; +}; + +/** + * Compile `fmt` into a function. + * + * @param {String} fmt + * @return {Function} + * @api private + */ + +function compile(fmt) { + fmt = fmt.replace(/"/g, '\\"'); + var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){ + return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "'; + }) + '";' + return new Function('tokens, req, res', js); +}; + +/** + * Define a token function with the given `name`, + * and callback `fn(req, res)`. + * + * @param {String} name + * @param {Function} fn + * @return {Object} exports for chaining + * @api public + */ + +exports.token = function(name, fn) { + exports[name] = fn; + return this; +}; + +/** + * Define a `fmt` with the given `name`. + * + * @param {String} name + * @param {String|Function} fmt + * @return {Object} exports for chaining + * @api public + */ + +exports.format = function(name, str){ + exports[name] = str; + return this; +}; + +/** + * Default format. + */ + +exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'); + +/** + * Short format. + */ + +exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'); + +/** + * Tiny format. + */ + +exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms'); + +/** + * dev (colored) + */ + +exports.format('dev', function(tokens, req, res){ + var status = res.statusCode + , len = parseInt(res.getHeader('Content-Length'), 10) + , color = 32; + + if (status >= 500) color = 31 + else if (status >= 400) color = 33 + else if (status >= 300) color = 36; + + len = isNaN(len) + ? '' + : len = ' - ' + bytes(len); + + return '\x1b[90m' + req.method + + ' ' + (req.originalUrl || req.url) + ' ' + + '\x1b[' + color + 'm' + res.statusCode + + ' \x1b[90m' + + (new Date - req._startTime) + + 'ms' + len + + '\x1b[0m'; +}); + +/** + * request url + */ + +exports.token('url', function(req){ + return req.originalUrl || req.url; +}); + +/** + * request method + */ + +exports.token('method', function(req){ + return req.method; +}); + +/** + * response time in milliseconds + */ + +exports.token('response-time', function(req){ + return String(Date.now() - req._startTime); +}); + +/** + * UTC date + */ + +exports.token('date', function(){ + return new Date().toUTCString(); +}); + +/** + * response status code + */ + +exports.token('status', function(req, res){ + return res.headersSent ? res.statusCode : null; +}); + +/** + * normalized referrer + */ + +exports.token('referrer', function(req){ + return req.headers['referer'] || req.headers['referrer']; +}); + +/** + * remote address + */ + +exports.token('remote-addr', function(req){ + if (req.ip) return req.ip; + if (req._remoteAddress) return req._remoteAddress; + var sock = req.socket; + if (sock.socket) return sock.socket.remoteAddress; + return sock.remoteAddress; +}); + +/** + * HTTP version + */ + +exports.token('http-version', function(req){ + return req.httpVersionMajor + '.' + req.httpVersionMinor; +}); + +/** + * UA string + */ + +exports.token('user-agent', function(req){ + return req.headers['user-agent']; +}); + +/** + * request header + */ + +exports.token('req', function(req, res, field){ + return req.headers[field.toLowerCase()]; +}); + +/** + * response header + */ + +exports.token('res', function(req, res, field){ + return (res._headers || {})[field.toLowerCase()]; +}); + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/package.json new file mode 100644 index 00000000000..e3c556b8a05 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/morgan/package.json @@ -0,0 +1,38 @@ +{ + "name": "morgan", + "description": "connect's logger for node.js", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/morgan.git" + }, + "bugs": { + "url": "https://github.com/expressjs/morgan/issues" + }, + "dependencies": { + "bytes": "~0.2.0" + }, + "devDependencies": { + "connect": "*", + "mocha": "*", + "should": "*", + "supertest": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# Connect Logger\n\nConnect's logging middleware. Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. You may view the old docs at http://www.senchalabs.org/connect/logger.html. Otherwise, view the source code's JSDocs.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.", + "readmeFilename": "README.md", + "_id": "morgan@1.0.0", + "dist": { + "shasum": "83cf74b9f2d841901f1a9a6b8fa7a468d2e47a8d" + }, + "_from": "morgan@1.0.0", + "_resolved": "https://registry.npmjs.org/morgan/-/morgan-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.jshintrc b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.jshintrc new file mode 100644 index 00000000000..a93b50cfb4b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.jshintrc @@ -0,0 +1,70 @@ +{ + // Settings + "passfail" : false, // Stop on first error. + "maxerr" : 100, // Maximum errors before stopping. + + + // Predefined globals whom JSHint will ignore. + "browser" : false, // Standard browser globals e.g. `window`, `document`. + + "node" : true, + "rhino" : false, + "couch" : false, + "wsh" : false, // Windows Scripting Host. + + "jquery" : false, + "prototypejs" : false, + "mootools" : false, + "dojo" : false, + + + "predef" : [ + "describe", "it", "before", "after" + ], + + // Development. + "debug" : true, // Allow debugger statements e.g. browser breakpoints. + "devel" : true, // Allow development statements e.g. `console.log();`. + + + // EcmaScript 5. + "es5" : true, // Allow EcmaScript 5 syntax. + "strict" : false, // Require `use strict` pragma in every file. + "globalstrict" : true, // Allow global "use strict" (also enables 'strict'). + + + // The Good Parts. + "asi" : true, // Tolerate Automatic Semicolon Insertion (no semicolons). + "laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. + "laxcomma" : true, + "bitwise" : false, // Prohibit bitwise operators (&, |, ^, etc.). + "boss" : true, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. + "curly" : false, // Require {} for every new block or scope. + "eqeqeq" : true, // Require triple equals i.e. `===`. + "eqnull" : true, // Tolerate use of `== null`. + "evil" : false, // Tolerate use of `eval`. + "expr" : false, // Tolerate `ExpressionStatement` as Programs. + "forin" : false, // Prohibt `for in` loops without `hasOwnProperty`. + "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` + "latedef" : false, // Prohibit variable use before definition. + "loopfunc" : false, // Allow functions to be defined within loops. + "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`. + "regexp" : false, // Prohibit `.` and `[^...]` in regular expressions. + "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`. + "scripturl" : false, // Tolerate script-targeted URLs. + "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`. + "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`. + "undef" : true, // Require all non-global variables be declared before they are used. + + + // Persone styling prefrences. + "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`. + "noempty" : true, // Prohibit use of empty blocks. + "nonew" : true, // Prohibit use of constructors for side-effects. + "nomen" : false, // Prohibit use of initial or trailing underbars in names. + "onevar" : false, // Allow only one `var` statement per function. + "plusplus" : false, // Prohibit use of `++` & `--`. + "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. + "trailing" : true, // Prohibit trailing whitespaces. + "white" : false // Check against strict whitespace and indentation rules. +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.npmignore new file mode 100644 index 00000000000..07e6e472cc7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.npmignore @@ -0,0 +1 @@ +/node_modules diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.travis.yml new file mode 100644 index 00000000000..b1fc4b01501 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.8" + - "0.10" +before_script: + - ulimit -n 500 diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/CHANGELOG.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/CHANGELOG.md new file mode 100644 index 00000000000..ea54d9a13c8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/CHANGELOG.md @@ -0,0 +1,191 @@ +### 2.2.0 + + * additional callback API to support multiple files with same field name + * fix assertion crash when max field count is exceeded + * fix assertion crash when client aborts an invalid request + * (>=v0.10 only) unpipe the request when an error occurs to save resources. + * update readable-stream to ~1.1.9 + * fix assertion crash when EMFILE occurrs + * (no more assertions - only 'error' events) + +### 2.1.9 + + * relax content-type detection regex. (thanks amitaibu) + +### 2.1.8 + + * replace deprecated Buffer.write(). (thanks hueniverse) + +### 2.1.7 + + * add repository field to package.json + +### 2.1.6 + + * expose `hash` as an option to `Form`. (thanks wookiehangover) + +### 2.1.5 + + * fix possible 'close' event before all temp files are done + +### 2.1.4 + + * fix crash for invalid requests + +### 2.1.3 + + * add `file.size` + +### 2.1.2 + + * proper backpressure support + * update s3 example + +### 2.1.1 + + * fix uploads larger than 2KB + * fix both s3 and upload example + * add part.byteCount and part.byteOffset + +### 2.1.0 (recalled) + + * Complete rewrite. See README for changes and new API. + +### v1.0.13 + +* Only update hash if update method exists (Sven Lito) +* According to travis v0.10 needs to go quoted (Sven Lito) +* Bumping build node versions (Sven Lito) +* Additional fix for empty requests (Eugene Girshov) +* Change the default to 1000, to match the new Node behaviour. (OrangeDog) +* Add ability to control maxKeys in the querystring parser. (OrangeDog) +* Adjust test case to work with node 0.9.x (Eugene Girshov) +* Update package.json (Sven Lito) +* Path adjustment according to eb4468b (Markus Ast) + +### v1.0.12 + +* Emit error on aborted connections (Eugene Girshov) +* Add support for empty requests (Eugene Girshov) +* Fix name/filename handling in Content-Disposition (jesperp) +* Tolerate malformed closing boundary in multipart (Eugene Girshov) +* Ignore preamble in multipart messages (Eugene Girshov) +* Add support for application/json (Mike Frey, Carlos Rodriguez) +* Add support for Base64 encoding (Elmer Bulthuis) +* Add File#toJSON (TJ Holowaychuk) +* Remove support for Node.js 0.4 & 0.6 (Andrew Kelley) +* Documentation improvements (Sven Lito, Andre Azevedo) +* Add support for application/octet-stream (Ion Lupascu, Chris Scribner) +* Use os.tmpDir() to get tmp directory (Andrew Kelley) +* Improve package.json (Andrew Kelley, Sven Lito) +* Fix benchmark script (Andrew Kelley) +* Fix scope issue in incoming_forms (Sven Lito) +* Fix file handle leak on error (OrangeDog) + +### v1.0.11 + +* Calculate checksums for incoming files (sreuter) +* Add definition parameters to "IncomingForm" as an argument (Math-) + +### v1.0.10 + +* Make parts to be proper Streams (Matt Robenolt) + +### v1.0.9 + +* Emit progress when content length header parsed (Tim Koschützki) +* Fix Readme syntax due to GitHub changes (goob) +* Replace references to old 'sys' module in Readme with 'util' (Peter Sugihara) + +### v1.0.8 + +* Strip potentially unsafe characters when using `keepExtensions: true`. +* Switch to utest / urun for testing +* Add travis build + +### v1.0.7 + +* Remove file from package that was causing problems when installing on windows. (#102) +* Fix typos in Readme (Jason Davies). + +### v1.0.6 + +* Do not default to the default to the field name for file uploads where + filename="". + +### v1.0.5 + +* Support filename="" in multipart parts +* Explain unexpected end() errors in parser better + +**Note:** Starting with this version, formidable emits 'file' events for empty +file input fields. Previously those were incorrectly emitted as regular file +input fields with value = "". + +### v1.0.4 + +* Detect a good default tmp directory regardless of platform. (#88) + +### v1.0.3 + +* Fix problems with utf8 characters (#84) / semicolons in filenames (#58) +* Small performance improvements +* New test suite and fixture system + +### v1.0.2 + +* Exclude node\_modules folder from git +* Implement new `'aborted'` event +* Fix files in example folder to work with recent node versions +* Make gently a devDependency + +[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2) + +### v1.0.1 + +* Fix package.json to refer to proper main directory. (#68, Dean Landolt) + +[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1) + +### v1.0.0 + +* Add support for multipart boundaries that are quoted strings. (Jeff Craig) + +This marks the beginning of development on version 2.0 which will include +several architectural improvements. + +[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0) + +### v0.9.11 + +* Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki) +* Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class + +**Important:** The old property names of the File class will be removed in a +future release. + +[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11) + +### Older releases + +These releases were done before starting to maintain the above Changelog: + +* [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10) +* [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9) +* [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8) +* [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7) +* [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6) +* [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5) +* [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4) +* [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3) +* [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2) +* [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) +* [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/LICENSE new file mode 100644 index 00000000000..8488a4056d3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/LICENSE @@ -0,0 +1,7 @@ +Copyright (C) 2011-2013 Felix Geisendörfer, Andrew Kelley + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/README.md new file mode 100644 index 00000000000..f149ac04662 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/README.md @@ -0,0 +1,177 @@ +[![Build Status](https://travis-ci.org/superjoe30/node-multiparty.png?branch=master)](https://travis-ci.org/superjoe30/node-multiparty) +# multiparty + +Parse http requests with content-type `multipart/form-data`, also known as file uploads. + +See also [busboy](https://github.com/mscdex/busboy) - a +[faster](https://github.com/mscdex/dicer/wiki/Benchmarks) alternative +which may be worth looking into. + +### Why the fork? + + * This module uses the Node.js v0.10 streams properly, *even in Node.js v0.8* + * It will not create a temp file for you unless you want it to. + * Counts bytes and does math to help you figure out the `Content-Length` of + each part. + * You can easily stream uploads to s3 with + [knox](https://github.com/LearnBoost/knox), for [example](examples/s3.js). + * Less bugs. This code is simpler, has all deprecated functionality removed, + has cleaner tests, and does not try to do anything beyond multipart stream + parsing. + +## Installation + +``` +npm install multiparty +``` + +## Usage + + * See [examples](examples). + +Parse an incoming `multipart/form-data` request. + +```js +var multiparty = require('multiparty') + , http = require('http') + , util = require('util') + +http.createServer(function(req, res) { + if (req.url === '/upload' && req.method === 'POST') { + // parse a file upload + var form = new multiparty.Form(); + + form.parse(req, function(err, fields, files) { + res.writeHead(200, {'content-type': 'text/plain'}); + res.write('received upload:\n\n'); + res.end(util.inspect({fields: fields, files: files})); + }); + + return; + } + + // show a file upload form + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); +}).listen(8080); +``` + +## API + +### multiparty.Form +```js +var form = new multiparty.Form(options) +``` +Creates a new form. Options: + + * `encoding` - sets encoding for the incoming form fields. Defaults to `utf8`. + * `maxFieldSize` - Limits the amount of memory a field (not a file) can + allocate in bytes. If this value is exceeded, an `error` event is emitted. + The default size is 2MB. + * `maxFields` - Limits the number of fields that will be parsed before + emitting an `error` event. A file counts as a field in this case. + Defaults to 1000. + * `autoFields` - Enables `field` events. This is automatically set to `true` + if you add a `field` listener. + * `autoFiles` - Enables `file` events. This is automatically set to `true` + if you add a `file` listener. + * `uploadDir` - Only relevant when `autoFiles` is `true`. The directory for + placing file uploads in. You can move them later using `fs.rename()`. + Defaults to `os.tmpDir()`. + * `hash` - Only relevant when `autoFiles` is `true`. If you want checksums + calculated for incoming files, set this to either `sha1` or `md5`. + Defaults to off. + +#### form.parse(request, [cb]) + +Parses an incoming node.js `request` containing form data. If `cb` is +provided, `autoFields` and `autoFiles` are set to `true` and all fields and +files are collected and passed to the callback: + +```js +form.parse(req, function(err, fieldsObject, filesObject, fieldsList, filesList) { + // ... +}); +``` + +It is often convenient to access a field or file by name. In this situation, +use `fieldsObject` or `filesObject`. However sometimes, as in the case of a +`` the multipart stream will contain +multiple files of the same input name, and you are interested in all of them. +In this case, use `filesList`. + +Another example is when you do not care what the field name of a file is; you +are merely interested in a single upload. In this case, set `maxFields` to 1 +(assuming no other fields expected besides the file) and use `filesList[0]`. + +#### form.bytesReceived + +The amount of bytes received for this form so far. + +#### form.bytesExpected + +The expected number of bytes in this form. + +### Events + +#### 'error' (err) + +You definitely want to handle this event. If not your server *will* crash when +users submit bogus multipart requests! + +#### 'part' (part) + +Emitted when a part is encountered in the request. `part` is a +`ReadableStream`. It also has the following properties: + + * `headers` - the headers for this part. For example, you may be interested + in `content-type`. + * `name` - the field name for this part + * `filename` - only if the part is an incoming file + * `byteOffset` - the byte offset of this part in the request body + * `byteCount` - assuming that this is the last part in the request, + this is the size of this part in bytes. You could use this, for + example, to set the `Content-Length` header if uploading to S3. + If the part had a `Content-Length` header then that value is used + here instead. + +#### 'aborted' + +Emitted when the request is aborted. This event will be followed shortly +by an `error` event. In practice you do not need to handle this event. + +#### 'progress' (bytesReceived, bytesExpected) + +#### 'close' + +Emitted after all parts have been parsed and emitted. Not emitted if an `error` +event is emitted. This is typically when you would send your response. + +#### 'file' (name, file) + +**By default multiparty will not touch your hard drive.** But if you add this +listener, multiparty automatically sets `form.autoFiles` to `true` and will +stream uploads to disk for you. + + * `name` - the field name for this file + * `file` - an object with these properties: + - `fieldName` - same as `name` - the field name for this file + - `originalFilename` - the filename that the user reports for the file + - `path` - the absolute path of the uploaded file on disk + - `headers` - the HTTP headers that were sent along with this file + - `size` - size of the file in bytes + +If you set the `form.hash` option, then `file` will also contain a `hash` +property which is the checksum of the file. + +#### 'field' (name, value) + + * `name` - field name + * `value` - string field value + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/azureblobstorage.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/azureblobstorage.js new file mode 100644 index 00000000000..273c3321ab2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/azureblobstorage.js @@ -0,0 +1,41 @@ +var http = require('http') + , util = require('util') + , multiparty = require('../') + , azure = require('azure') + , PORT = process.env.PORT || 27372 + +var server = http.createServer(function(req, res) { + if (req.url === '/') { + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + } else if (req.url === '/upload') { + + var blobService = azure.createBlobService(); + var form = new multiparty.Form(); + form.on('part', function(part) { + if (!part.filename) return; + + var size = part.byteCount - part.byteOffset; + var name = part.filename; + var container = 'blobContainerName'; + + blobService.createBlockBlobFromStream(container, name, part, size, function(error) { + if (error) { + // error handling + } + }); + }); + form.parse(req); + + res.send('File uploaded successfully'); + } +}); +server.listen(PORT, function() { + console.info('listening on http://0.0.0.0:'+PORT+'/'); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/s3.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/s3.js new file mode 100644 index 00000000000..60617ba2ccd --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/s3.js @@ -0,0 +1,74 @@ +var http = require('http') + , util = require('util') + , multiparty = require('../') + , knox = require('knox') + , Batch = require('batch') + , PORT = process.env.PORT || 27372 + +var s3Client = knox.createClient({ + secure: false, + key: process.env.S3_KEY, + secret: process.env.S3_SECRET, + bucket: process.env.S3_BUCKET, +}); + +var server = http.createServer(function(req, res) { + if (req.url === '/') { + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + } else if (req.url === '/upload') { + var headers = { + 'x-amz-acl': 'public-read', + }; + var form = new multiparty.Form(); + var batch = new Batch(); + batch.push(function(cb) { + form.on('field', function(name, value) { + if (name === 'path') { + var destPath = value; + if (destPath[0] !== '/') destPath = '/' + destPath; + cb(null, destPath); + } + }); + }); + batch.push(function(cb) { + form.on('part', function(part) { + if (! part.filename) return; + cb(null, part); + }); + }); + batch.end(function(err, results) { + if (err) throw err; + form.removeListener('close', onEnd); + var destPath = results[0] + , part = results[1]; + + headers['Content-Length'] = part.byteCount; + s3Client.putStream(part, destPath, headers, function(err, s3Response) { + if (err) throw err; + res.statusCode = s3Response.statusCode; + s3Response.pipe(res); + console.log("https://s3.amazonaws.com/" + process.env.S3_BUCKET + destPath); + }); + }); + form.on('close', onEnd); + form.parse(req); + + } else { + res.writeHead(404, {'content-type': 'text/plain'}); + res.end('404'); + } + + function onEnd() { + throw new Error("no uploaded file"); + } +}); +server.listen(PORT, function() { + console.info('listening on http://0.0.0.0:'+PORT+'/'); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/upload.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/upload.js new file mode 100644 index 00000000000..5dd39268473 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/examples/upload.js @@ -0,0 +1,37 @@ +var http = require('http') + , util = require('util') + , multiparty = require('../') + , PORT = process.env.PORT || 27372 + +var server = http.createServer(function(req, res) { + if (req.url === '/') { + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + } else if (req.url === '/upload') { + var form = new multiparty.Form(); + + form.parse(req, function(err, fields, files) { + if (err) { + res.writeHead(400, {'content-type': 'text/plain'}); + res.end("invalid request: " + err.message); + return; + } + res.writeHead(200, {'content-type': 'text/plain'}); + res.write('received fields:\n\n '+util.inspect(fields)); + res.write('\n\n'); + res.end('received files:\n\n '+util.inspect(files)); + }); + } else { + res.writeHead(404, {'content-type': 'text/plain'}); + res.end('404'); + } +}); +server.listen(PORT, function() { + console.info('listening on http://0.0.0.0:'+PORT+'/'); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/index.js new file mode 100644 index 00000000000..71c88ae3713 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/index.js @@ -0,0 +1,618 @@ +exports.Form = Form; + +var stream = require('readable-stream') + , util = require('util') + , fs = require('fs') + , crypto = require('crypto') + , path = require('path') + , os = require('os') + , StringDecoder = require('string_decoder').StringDecoder + , StreamCounter = require('stream-counter') + +var START = 0 + , START_BOUNDARY = 1 + , HEADER_FIELD_START = 2 + , HEADER_FIELD = 3 + , HEADER_VALUE_START = 4 + , HEADER_VALUE = 5 + , HEADER_VALUE_ALMOST_DONE = 6 + , HEADERS_ALMOST_DONE = 7 + , PART_DATA_START = 8 + , PART_DATA = 9 + , PART_END = 10 + , END = 11 + + , LF = 10 + , CR = 13 + , SPACE = 32 + , HYPHEN = 45 + , COLON = 58 + , A = 97 + , Z = 122 + +var CONTENT_TYPE_RE = /^multipart\/(form-data|related);\s*boundary=(?:"([^"]+)"|([^;]+))$/i; +var FILE_EXT_RE = /(\.[_\-a-zA-Z0-9]{0,16}).*/; +var LAST_BOUNDARY_SUFFIX_LEN = 4; // --\r\n + +util.inherits(Form, stream.Writable); +function Form(options) { + var self = this; + stream.Writable.call(self); + + options = options || {}; + + self.error = null; + self.finished = false; + + self.autoFields = !!options.autoFields; + self.autoFiles = !!options.autoFields; + + self.maxFields = options.maxFields || 1000; + self.maxFieldsSize = options.maxFieldsSize || 2 * 1024 * 1024; + self.uploadDir = options.uploadDir || os.tmpDir(); + self.encoding = options.encoding || 'utf8'; + self.hash = options.hash || false; + + self.bytesReceived = 0; + self.bytesExpected = null; + + self.openedFiles = []; + self.totalFieldSize = 0; + self.totalFieldCount = 0; + self.flushing = 0; + + self.backpressure = false; + self.writeCbs = []; + + if (options.boundary) setUpParser(self, options.boundary); + + self.on('newListener', function(eventName) { + if (eventName === 'file') { + self.autoFiles = true; + } else if (eventName === 'field') { + self.autoFields = true; + } + }); +} + +Form.prototype.parse = function(req, cb) { + var self = this; + + // if the user supplies a callback, this implies autoFields and autoFiles + if (cb) { + self.autoFields = true; + self.autoFiles = true; + } + + self.handleError = handleError; + self.bytesExpected = getBytesExpected(req.headers); + + req.on('error', handleError); + req.on('aborted', onReqAborted); + + var contentType = req.headers['content-type']; + if (!contentType) { + handleError(new Error('missing content-type header')); + return; + } + + var m = contentType.match(CONTENT_TYPE_RE); + if (!m) { + handleError(new Error('unrecognized content-type: ' + contentType)); + return; + } + var boundary = m[2] || m[3]; + setUpParser(self, boundary); + req.pipe(self); + + if (cb) { + var fieldsTable = {}; + var filesTable = {}; + var fieldsList = []; + var filesList = []; + self.on('error', function(err) { + cb(err); + }); + self.on('field', function(name, value) { + fieldsTable[name] = value; + fieldsList.push({name: name, value: value}); + }); + self.on('file', function(name, file) { + filesTable[name] = file; + filesList.push(file); + }); + self.on('close', function() { + cb(null, fieldsTable, filesTable, fieldsList, filesList); + }); + } + + function onReqAborted() { + self.emit('aborted'); + handleError(new Error("Request aborted")); + } + + function handleError(err) { + var first = !self.error; + if (first) { + self.error = err; + req.removeListener('aborted', onReqAborted); + + // welp. 0.8 doesn't support unpipe, too bad so sad. + // let's drop support for 0.8 soon. + if (req.unpipe) { + req.unpipe(self); + } + } + + self.openedFiles.forEach(function(file) { + file.ws.destroy(); + fs.unlink(file.path, function(err) { + // this is already an error condition, ignore 2nd error + }); + }); + self.openedFiles = []; + + if (first) { + self.emit('error', err); + } + } + +}; + +Form.prototype._write = function(buffer, encoding, cb) { + var self = this + , i = 0 + , len = buffer.length + , prevIndex = self.index + , index = self.index + , state = self.state + , lookbehind = self.lookbehind + , boundary = self.boundary + , boundaryChars = self.boundaryChars + , boundaryLength = self.boundary.length + , boundaryEnd = boundaryLength - 1 + , bufferLength = buffer.length + , c + , cl + + for (i = 0; i < len; i++) { + c = buffer[i]; + switch (state) { + case START: + index = 0; + state = START_BOUNDARY; + /* falls through */ + case START_BOUNDARY: + if (index === boundaryLength - 2) { + if (c !== CR) return self.handleError(new Error("Expected CR Received " + c)); + index++; + break; + } else if (index === boundaryLength - 1) { + if (c !== LF) return self.handleError(new Error("Expected LF Received " + c)); + index = 0; + self.onParsePartBegin(); + state = HEADER_FIELD_START; + break; + } + + if (c !== boundary[index+2]) index = -2; + if (c === boundary[index+2]) index++; + break; + case HEADER_FIELD_START: + state = HEADER_FIELD; + self.headerFieldMark = i; + index = 0; + /* falls through */ + case HEADER_FIELD: + if (c === CR) { + self.headerFieldMark = null; + state = HEADERS_ALMOST_DONE; + break; + } + + index++; + if (c === HYPHEN) break; + + if (c === COLON) { + if (index === 1) { + // empty header field + self.handleError(new Error("Empty header field")); + return; + } + self.onParseHeaderField(buffer.slice(self.headerFieldMark, i)); + self.headerFieldMark = null; + state = HEADER_VALUE_START; + break; + } + + cl = lower(c); + if (cl < A || cl > Z) { + self.handleError(new Error("Expected alphabetic character, received " + c)); + return; + } + break; + case HEADER_VALUE_START: + if (c === SPACE) break; + + self.headerValueMark = i; + state = HEADER_VALUE; + /* falls through */ + case HEADER_VALUE: + if (c === CR) { + self.onParseHeaderValue(buffer.slice(self.headerValueMark, i)); + self.headerValueMark = null; + self.onParseHeaderEnd(); + state = HEADER_VALUE_ALMOST_DONE; + } + break; + case HEADER_VALUE_ALMOST_DONE: + if (c !== LF) return self.handleError(new Error("Expected LF Received " + c)); + state = HEADER_FIELD_START; + break; + case HEADERS_ALMOST_DONE: + if (c !== LF) return self.handleError(new Error("Expected LF Received " + c)); + var err = self.onParseHeadersEnd(i + 1); + if (err) return self.handleError(err); + state = PART_DATA_START; + break; + case PART_DATA_START: + state = PART_DATA; + self.partDataMark = i; + /* falls through */ + case PART_DATA: + prevIndex = index; + + if (index === 0) { + // boyer-moore derrived algorithm to safely skip non-boundary data + i += boundaryEnd; + while (i < bufferLength && !(buffer[i] in boundaryChars)) { + i += boundaryLength; + } + i -= boundaryEnd; + c = buffer[i]; + } + + if (index < boundaryLength) { + if (boundary[index] === c) { + if (index === 0) { + self.onParsePartData(buffer.slice(self.partDataMark, i)); + self.partDataMark = null; + } + index++; + } else { + index = 0; + } + } else if (index === boundaryLength) { + index++; + if (c === CR) { + // CR = part boundary + self.partBoundaryFlag = true; + } else if (c === HYPHEN) { + // HYPHEN = end boundary + self.lastBoundaryFlag = true; + } else { + index = 0; + } + } else if (index - 1 === boundaryLength) { + if (self.partBoundaryFlag) { + index = 0; + if (c === LF) { + self.partBoundaryFlag = false; + self.onParsePartEnd(); + self.onParsePartBegin(); + state = HEADER_FIELD_START; + break; + } + } else if (self.lastBoundaryFlag) { + if (c === HYPHEN) { + self.onParsePartEnd(); + self.end(); + state = END; + } else { + index = 0; + } + } else { + index = 0; + } + } + + if (index > 0) { + // when matching a possible boundary, keep a lookbehind reference + // in case it turns out to be a false lead + lookbehind[index-1] = c; + } else if (prevIndex > 0) { + // if our boundary turned out to be rubbish, the captured lookbehind + // belongs to partData + self.onParsePartData(lookbehind.slice(0, prevIndex)); + prevIndex = 0; + self.partDataMark = i; + + // reconsider the current character even so it interrupted the sequence + // it could be the beginning of a new sequence + i--; + } + + break; + case END: + break; + default: + self.handleError(new Error("Parser has invalid state.")); + return; + } + } + + if (self.headerFieldMark != null) { + self.onParseHeaderField(buffer.slice(self.headerFieldMark)); + self.headerFieldMark = 0; + } + if (self.headerValueMark != null) { + self.onParseHeaderValue(buffer.slice(self.headerValueMark)); + self.headerValueMark = 0; + } + if (self.partDataMark != null) { + self.onParsePartData(buffer.slice(self.partDataMark)); + self.partDataMark = 0; + } + + self.index = index; + self.state = state; + + self.bytesReceived += buffer.length; + self.emit('progress', self.bytesReceived, self.bytesExpected); + + if (self.backpressure) { + self.writeCbs.push(cb); + } else { + cb(); + } +}; + +Form.prototype.onParsePartBegin = function() { + clearPartVars(this); +} + +Form.prototype.onParseHeaderField = function(b) { + this.headerField += this.headerFieldDecoder.write(b); +} + +Form.prototype.onParseHeaderValue = function(b) { + this.headerValue += this.headerValueDecoder.write(b); +} + +Form.prototype.onParseHeaderEnd = function() { + this.headerField = this.headerField.toLowerCase(); + this.partHeaders[this.headerField] = this.headerValue; + + var m; + if (this.headerField === 'content-disposition') { + if (m = this.headerValue.match(/\bname="([^"]+)"/i)) { + this.partName = m[1]; + } + this.partFilename = parseFilename(this.headerValue); + } else if (this.headerField === 'content-transfer-encoding') { + this.partTransferEncoding = this.headerValue.toLowerCase(); + } + + this.headerFieldDecoder = new StringDecoder(this.encoding); + this.headerField = ''; + this.headerValueDecoder = new StringDecoder(this.encoding); + this.headerValue = ''; +} + +Form.prototype.onParsePartData = function(b) { + if (this.partTransferEncoding === 'base64') { + this.backpressure = ! this.destStream.write(b.toString('ascii'), 'base64'); + } else { + this.backpressure = ! this.destStream.write(b); + } +} + +Form.prototype.onParsePartEnd = function() { + if (this.destStream) { + flushWriteCbs(this); + var s = this.destStream; + process.nextTick(function() { + s.end(); + }); + } + clearPartVars(this); +} + +Form.prototype.onParseHeadersEnd = function(offset) { + var self = this; + switch(self.partTransferEncoding){ + case 'binary': + case '7bit': + case '8bit': + self.partTransferEncoding = 'binary'; + break; + + case 'base64': break; + default: + return new Error("unknown transfer-encoding: " + self.partTransferEncoding); + } + + self.totalFieldCount += 1; + if (self.totalFieldCount >= self.maxFields) { + return new Error("maxFields " + self.maxFields + " exceeded."); + } + + self.destStream = new stream.PassThrough(); + self.destStream.on('drain', function() { + flushWriteCbs(self); + }); + self.destStream.headers = self.partHeaders; + self.destStream.name = self.partName; + self.destStream.filename = self.partFilename; + self.destStream.byteOffset = self.bytesReceived + offset; + var partContentLength = self.destStream.headers['content-length']; + self.destStream.byteCount = partContentLength ? + parseInt(partContentLength, 10) : + (self.bytesExpected - self.destStream.byteOffset - + self.boundary.length - LAST_BOUNDARY_SUFFIX_LEN); + + self.emit('part', self.destStream); + if (self.destStream.filename == null && self.autoFields) { + handleField(self, self.destStream); + } else if (self.destStream.filename != null && self.autoFiles) { + handleFile(self, self.destStream); + } +} + +function flushWriteCbs(self) { + self.writeCbs.forEach(function(cb) { + process.nextTick(cb); + }); + self.writeCbs = []; + self.backpressure = false; +} + +function getBytesExpected(headers) { + var contentLength = headers['content-length']; + if (contentLength) { + return parseInt(contentLength, 10); + } else if (headers['transfer-encoding'] == null) { + return 0; + } else { + return null; + } +} + +function beginFlush(self) { + self.flushing += 1; +} + +function endFlush(self) { + self.flushing -= 1; + maybeClose(self); +} + +function maybeClose(self) { + if (!self.flushing && self.finished && !self.error) { + self.emit('close'); + } +} + +function handleFile(self, fileStream) { + beginFlush(self); + var file = { + fieldName: fileStream.name, + originalFilename: fileStream.filename, + path: uploadPath(self.uploadDir, fileStream.filename), + headers: fileStream.headers, + }; + file.ws = fs.createWriteStream(file.path); + self.openedFiles.push(file); + fileStream.pipe(file.ws); + var counter = new StreamCounter(); + fileStream.pipe(counter); + var hashWorkaroundStream + , hash = null; + if (self.hash) { + // workaround stream because https://github.com/joyent/node/issues/5216 + hashWorkaroundStream = stream.Writable(); + hash = crypto.createHash(self.hash); + hashWorkaroundStream._write = function(buffer, encoding, callback) { + hash.update(buffer); + callback(); + }; + fileStream.pipe(hashWorkaroundStream); + } + file.ws.on('error', function(err) { + if (!self.error) self.handleError(err); + }); + file.ws.on('close', function() { + if (hash) file.hash = hash.digest('hex'); + file.size = counter.bytes; + self.emit('file', fileStream.name, file); + endFlush(self); + }); +} + +function handleField(self, fieldStream) { + var value = ''; + var decoder = new StringDecoder(self.encoding); + + beginFlush(self); + fieldStream.on('readable', function() { + var buffer = fieldStream.read(); + if (!buffer) return; + + self.totalFieldSize += buffer.length; + if (self.totalFieldSize > self.maxFieldsSize) { + self.handleError(new Error("maxFieldsSize " + self.maxFieldsSize + " exceeded")); + return; + } + value += decoder.write(buffer); + }); + + fieldStream.on('end', function() { + self.emit('field', fieldStream.name, value); + endFlush(self); + }); +} + +function clearPartVars(self) { + self.partHeaders = {}; + self.partName = null; + self.partFilename = null; + self.partTransferEncoding = 'binary'; + self.destStream = null; + + self.headerFieldDecoder = new StringDecoder(self.encoding); + self.headerField = ""; + self.headerValueDecoder = new StringDecoder(self.encoding); + self.headerValue = ""; +} + +function setUpParser(self, boundary) { + self.boundary = new Buffer(boundary.length + 4); + self.boundary.write('\r\n--', 0, boundary.length + 4, 'ascii'); + self.boundary.write(boundary, 4, boundary.length, 'ascii'); + self.lookbehind = new Buffer(self.boundary.length + 8); + self.state = START; + self.boundaryChars = {}; + for (var i = 0; i < self.boundary.length; i++) { + self.boundaryChars[self.boundary[i]] = true; + } + + self.index = null; + self.partBoundaryFlag = false; + self.lastBoundaryFlag = false; + + self.on('finish', function() { + if ((self.state === HEADER_FIELD_START && self.index === 0) || + (self.state === PART_DATA && self.index === self.boundary.length)) + { + self.onParsePartEnd(); + } else if (self.state !== END) { + self.handleError(new Error('stream ended unexpectedly')); + } + self.finished = true; + maybeClose(self); + }); +} + +function uploadPath(baseDir, filename) { + var ext = path.extname(filename).replace(FILE_EXT_RE, '$1'); + var name = process.pid + '-' + + (Math.random() * 0x100000000 + 1).toString(36) + ext; + return path.join(baseDir, name); +} + +function parseFilename(headerValue) { + var m = headerValue.match(/\bfilename="(.*?)"($|; )/i); + if (!m) return; + + var filename = m[1].substr(m[1].lastIndexOf('\\') + 1); + filename = filename.replace(/%22/g, '"'); + filename = filename.replace(/&#([\d]{4});/g, function(m, code) { + return String.fromCharCode(code); + }); + return filename; +} + +function lower(c) { + return c | 0x20; +} + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/.npmignore new file mode 100644 index 00000000000..38344f87a62 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/.npmignore @@ -0,0 +1,5 @@ +build/ +test/ +examples/ +fs.js +zlib.js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/LICENSE new file mode 100644 index 00000000000..e3d4e695a4c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/LICENSE @@ -0,0 +1,18 @@ +Copyright Joyent, Inc. and other Node contributors. 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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/README.md new file mode 100644 index 00000000000..34c11897927 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/README.md @@ -0,0 +1,15 @@ +# readable-stream + +***Node-core streams for userland*** + +[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true)](https://nodei.co/npm/readable-stream/) +[![NPM](https://nodei.co/npm-dl/readable-stream.png)](https://nodei.co/npm/readable-stream/) + +This package is a mirror of the Streams2 and Streams3 implementations in Node-core. + +If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core. + +**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12. + +**readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `"~1.1.0"` + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/duplex.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/duplex.js new file mode 100644 index 00000000000..ca807af8762 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/duplex.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_duplex.js") diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/float.patch b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/float.patch new file mode 100644 index 00000000000..b984607a41c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/float.patch @@ -0,0 +1,923 @@ +diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js +index c5a741c..a2e0d8e 100644 +--- a/lib/_stream_duplex.js ++++ b/lib/_stream_duplex.js +@@ -26,8 +26,8 @@ + + module.exports = Duplex; + var util = require('util'); +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('./_stream_readable'); ++var Writable = require('./_stream_writable'); + + util.inherits(Duplex, Readable); + +diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js +index a5e9864..330c247 100644 +--- a/lib/_stream_passthrough.js ++++ b/lib/_stream_passthrough.js +@@ -25,7 +25,7 @@ + + module.exports = PassThrough; + +-var Transform = require('_stream_transform'); ++var Transform = require('./_stream_transform'); + var util = require('util'); + util.inherits(PassThrough, Transform); + +diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js +index 0c3fe3e..90a8298 100644 +--- a/lib/_stream_readable.js ++++ b/lib/_stream_readable.js +@@ -23,10 +23,34 @@ module.exports = Readable; + Readable.ReadableState = ReadableState; + + var EE = require('events').EventEmitter; ++if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { ++ return emitter.listeners(type).length; ++}; ++ ++if (!global.setImmediate) global.setImmediate = function setImmediate(fn) { ++ return setTimeout(fn, 0); ++}; ++if (!global.clearImmediate) global.clearImmediate = function clearImmediate(i) { ++ return clearTimeout(i); ++}; ++ + var Stream = require('stream'); + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + var StringDecoder; +-var debug = util.debuglog('stream'); ++var debug; ++if (util.debuglog) ++ debug = util.debuglog('stream'); ++else try { ++ debug = require('debuglog')('stream'); ++} catch (er) { ++ debug = function() {}; ++} + + util.inherits(Readable, Stream); + +@@ -380,7 +404,7 @@ function chunkInvalid(state, chunk) { + + + function onEofChunk(stream, state) { +- if (state.decoder && !state.ended) { ++ if (state.decoder && !state.ended && state.decoder.end) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); +diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js +index b1f9fcc..b0caf57 100644 +--- a/lib/_stream_transform.js ++++ b/lib/_stream_transform.js +@@ -64,8 +64,14 @@ + + module.exports = Transform; + +-var Duplex = require('_stream_duplex'); ++var Duplex = require('./_stream_duplex'); + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + util.inherits(Transform, Duplex); + + +diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js +index ba2e920..f49288b 100644 +--- a/lib/_stream_writable.js ++++ b/lib/_stream_writable.js +@@ -27,6 +27,12 @@ module.exports = Writable; + Writable.WritableState = WritableState; + + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + var Stream = require('stream'); + + util.inherits(Writable, Stream); +@@ -119,7 +125,7 @@ function WritableState(options, stream) { + function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. +- if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) ++ if (!(this instanceof Writable) && !(this instanceof require('./_stream_duplex'))) + return new Writable(options); + + this._writableState = new WritableState(options, this); +diff --git a/test/simple/test-stream-big-push.js b/test/simple/test-stream-big-push.js +index e3787e4..8cd2127 100644 +--- a/test/simple/test-stream-big-push.js ++++ b/test/simple/test-stream-big-push.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + var str = 'asdfasdfasdfasdfasdf'; + + var r = new stream.Readable({ +diff --git a/test/simple/test-stream-end-paused.js b/test/simple/test-stream-end-paused.js +index bb73777..d40efc7 100644 +--- a/test/simple/test-stream-end-paused.js ++++ b/test/simple/test-stream-end-paused.js +@@ -25,7 +25,7 @@ var gotEnd = false; + + // Make sure we don't miss the end event for paused 0-length streams + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var stream = new Readable(); + var calledRead = false; + stream._read = function() { +diff --git a/test/simple/test-stream-pipe-after-end.js b/test/simple/test-stream-pipe-after-end.js +index b46ee90..0be8366 100644 +--- a/test/simple/test-stream-pipe-after-end.js ++++ b/test/simple/test-stream-pipe-after-end.js +@@ -22,8 +22,8 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var util = require('util'); + + util.inherits(TestReadable, Readable); +diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js +deleted file mode 100644 +index f689358..0000000 +--- a/test/simple/test-stream-pipe-cleanup.js ++++ /dev/null +@@ -1,122 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// 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. +- +-// This test asserts that Stream.prototype.pipe does not leave listeners +-// hanging on the source or dest. +- +-var common = require('../common'); +-var stream = require('stream'); +-var assert = require('assert'); +-var util = require('util'); +- +-function Writable() { +- this.writable = true; +- this.endCalls = 0; +- stream.Stream.call(this); +-} +-util.inherits(Writable, stream.Stream); +-Writable.prototype.end = function() { +- this.endCalls++; +-}; +- +-Writable.prototype.destroy = function() { +- this.endCalls++; +-}; +- +-function Readable() { +- this.readable = true; +- stream.Stream.call(this); +-} +-util.inherits(Readable, stream.Stream); +- +-function Duplex() { +- this.readable = true; +- Writable.call(this); +-} +-util.inherits(Duplex, Writable); +- +-var i = 0; +-var limit = 100; +- +-var w = new Writable(); +- +-var r; +- +-for (i = 0; i < limit; i++) { +- r = new Readable(); +- r.pipe(w); +- r.emit('end'); +-} +-assert.equal(0, r.listeners('end').length); +-assert.equal(limit, w.endCalls); +- +-w.endCalls = 0; +- +-for (i = 0; i < limit; i++) { +- r = new Readable(); +- r.pipe(w); +- r.emit('close'); +-} +-assert.equal(0, r.listeners('close').length); +-assert.equal(limit, w.endCalls); +- +-w.endCalls = 0; +- +-r = new Readable(); +- +-for (i = 0; i < limit; i++) { +- w = new Writable(); +- r.pipe(w); +- w.emit('close'); +-} +-assert.equal(0, w.listeners('close').length); +- +-r = new Readable(); +-w = new Writable(); +-var d = new Duplex(); +-r.pipe(d); // pipeline A +-d.pipe(w); // pipeline B +-assert.equal(r.listeners('end').length, 2); // A.onend, A.cleanup +-assert.equal(r.listeners('close').length, 2); // A.onclose, A.cleanup +-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup +-assert.equal(d.listeners('close').length, 3); // A.cleanup, B.onclose, B.cleanup +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 1); // B.cleanup +- +-r.emit('end'); +-assert.equal(d.endCalls, 1); +-assert.equal(w.endCalls, 0); +-assert.equal(r.listeners('end').length, 0); +-assert.equal(r.listeners('close').length, 0); +-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup +-assert.equal(d.listeners('close').length, 2); // B.onclose, B.cleanup +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 1); // B.cleanup +- +-d.emit('end'); +-assert.equal(d.endCalls, 1); +-assert.equal(w.endCalls, 1); +-assert.equal(r.listeners('end').length, 0); +-assert.equal(r.listeners('close').length, 0); +-assert.equal(d.listeners('end').length, 0); +-assert.equal(d.listeners('close').length, 0); +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 0); +diff --git a/test/simple/test-stream-pipe-error-handling.js b/test/simple/test-stream-pipe-error-handling.js +index c5d724b..c7d6b7d 100644 +--- a/test/simple/test-stream-pipe-error-handling.js ++++ b/test/simple/test-stream-pipe-error-handling.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var Stream = require('stream').Stream; ++var Stream = require('../../').Stream; + + (function testErrorListenerCatches() { + var source = new Stream(); +diff --git a/test/simple/test-stream-pipe-event.js b/test/simple/test-stream-pipe-event.js +index cb9d5fe..56f8d61 100644 +--- a/test/simple/test-stream-pipe-event.js ++++ b/test/simple/test-stream-pipe-event.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common'); +-var stream = require('stream'); ++var stream = require('../../'); + var assert = require('assert'); + var util = require('util'); + +diff --git a/test/simple/test-stream-push-order.js b/test/simple/test-stream-push-order.js +index f2e6ec2..a5c9bf9 100644 +--- a/test/simple/test-stream-push-order.js ++++ b/test/simple/test-stream-push-order.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var assert = require('assert'); + + var s = new Readable({ +diff --git a/test/simple/test-stream-push-strings.js b/test/simple/test-stream-push-strings.js +index 06f43dc..1701a9a 100644 +--- a/test/simple/test-stream-push-strings.js ++++ b/test/simple/test-stream-push-strings.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var util = require('util'); + + util.inherits(MyStream, Readable); +diff --git a/test/simple/test-stream-readable-event.js b/test/simple/test-stream-readable-event.js +index ba6a577..a8e6f7b 100644 +--- a/test/simple/test-stream-readable-event.js ++++ b/test/simple/test-stream-readable-event.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + (function first() { + // First test, not reading when the readable is added. +diff --git a/test/simple/test-stream-readable-flow-recursion.js b/test/simple/test-stream-readable-flow-recursion.js +index 2891ad6..11689ba 100644 +--- a/test/simple/test-stream-readable-flow-recursion.js ++++ b/test/simple/test-stream-readable-flow-recursion.js +@@ -27,7 +27,7 @@ var assert = require('assert'); + // more data continuously, but without triggering a nextTick + // warning or RangeError. + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + // throw an error if we trigger a nextTick warning. + process.throwDeprecation = true; +diff --git a/test/simple/test-stream-unshift-empty-chunk.js b/test/simple/test-stream-unshift-empty-chunk.js +index 0c96476..7827538 100644 +--- a/test/simple/test-stream-unshift-empty-chunk.js ++++ b/test/simple/test-stream-unshift-empty-chunk.js +@@ -24,7 +24,7 @@ var assert = require('assert'); + + // This test verifies that stream.unshift(Buffer(0)) or + // stream.unshift('') does not set state.reading=false. +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + var r = new Readable(); + var nChunks = 10; +diff --git a/test/simple/test-stream-unshift-read-race.js b/test/simple/test-stream-unshift-read-race.js +index 83fd9fa..17c18aa 100644 +--- a/test/simple/test-stream-unshift-read-race.js ++++ b/test/simple/test-stream-unshift-read-race.js +@@ -29,7 +29,7 @@ var assert = require('assert'); + // 3. push() after the EOF signaling null is an error. + // 4. _read() is not called after pushing the EOF null chunk. + +-var stream = require('stream'); ++var stream = require('../../'); + var hwm = 10; + var r = stream.Readable({ highWaterMark: hwm }); + var chunks = 10; +@@ -51,7 +51,14 @@ r._read = function(n) { + + function push(fast) { + assert(!pushedNull, 'push() after null push'); +- var c = pos >= data.length ? null : data.slice(pos, pos + n); ++ var c; ++ if (pos >= data.length) ++ c = null; ++ else { ++ if (n + pos > data.length) ++ n = data.length - pos; ++ c = data.slice(pos, pos + n); ++ } + pushedNull = c === null; + if (fast) { + pos += n; +diff --git a/test/simple/test-stream-writev.js b/test/simple/test-stream-writev.js +index 5b49e6e..b5321f3 100644 +--- a/test/simple/test-stream-writev.js ++++ b/test/simple/test-stream-writev.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var stream = require('stream'); ++var stream = require('../../'); + + var queue = []; + for (var decode = 0; decode < 2; decode++) { +diff --git a/test/simple/test-stream2-basic.js b/test/simple/test-stream2-basic.js +index 3814bf0..248c1be 100644 +--- a/test/simple/test-stream2-basic.js ++++ b/test/simple/test-stream2-basic.js +@@ -21,7 +21,7 @@ + + + var common = require('../common.js'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-compatibility.js b/test/simple/test-stream2-compatibility.js +index 6cdd4e9..f0fa84b 100644 +--- a/test/simple/test-stream2-compatibility.js ++++ b/test/simple/test-stream2-compatibility.js +@@ -21,7 +21,7 @@ + + + var common = require('../common.js'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-finish-pipe.js b/test/simple/test-stream2-finish-pipe.js +index 39b274f..006a19b 100644 +--- a/test/simple/test-stream2-finish-pipe.js ++++ b/test/simple/test-stream2-finish-pipe.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var stream = require('stream'); ++var stream = require('../../'); + var Buffer = require('buffer').Buffer; + + var r = new stream.Readable(); +diff --git a/test/simple/test-stream2-fs.js b/test/simple/test-stream2-fs.js +deleted file mode 100644 +index e162406..0000000 +--- a/test/simple/test-stream2-fs.js ++++ /dev/null +@@ -1,72 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// 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. +- +- +-var common = require('../common.js'); +-var R = require('_stream_readable'); +-var assert = require('assert'); +- +-var fs = require('fs'); +-var FSReadable = fs.ReadStream; +- +-var path = require('path'); +-var file = path.resolve(common.fixturesDir, 'x1024.txt'); +- +-var size = fs.statSync(file).size; +- +-var expectLengths = [1024]; +- +-var util = require('util'); +-var Stream = require('stream'); +- +-util.inherits(TestWriter, Stream); +- +-function TestWriter() { +- Stream.apply(this); +- this.buffer = []; +- this.length = 0; +-} +- +-TestWriter.prototype.write = function(c) { +- this.buffer.push(c.toString()); +- this.length += c.length; +- return true; +-}; +- +-TestWriter.prototype.end = function(c) { +- if (c) this.buffer.push(c.toString()); +- this.emit('results', this.buffer); +-} +- +-var r = new FSReadable(file); +-var w = new TestWriter(); +- +-w.on('results', function(res) { +- console.error(res, w.length); +- assert.equal(w.length, size); +- var l = 0; +- assert.deepEqual(res.map(function (c) { +- return c.length; +- }), expectLengths); +- console.log('ok'); +-}); +- +-r.pipe(w); +diff --git a/test/simple/test-stream2-httpclient-response-end.js b/test/simple/test-stream2-httpclient-response-end.js +deleted file mode 100644 +index 15cffc2..0000000 +--- a/test/simple/test-stream2-httpclient-response-end.js ++++ /dev/null +@@ -1,52 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// 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. +- +-var common = require('../common.js'); +-var assert = require('assert'); +-var http = require('http'); +-var msg = 'Hello'; +-var readable_event = false; +-var end_event = false; +-var server = http.createServer(function(req, res) { +- res.writeHead(200, {'Content-Type': 'text/plain'}); +- res.end(msg); +-}).listen(common.PORT, function() { +- http.get({port: common.PORT}, function(res) { +- var data = ''; +- res.on('readable', function() { +- console.log('readable event'); +- readable_event = true; +- data += res.read(); +- }); +- res.on('end', function() { +- console.log('end event'); +- end_event = true; +- assert.strictEqual(msg, data); +- server.close(); +- }); +- }); +-}); +- +-process.on('exit', function() { +- assert(readable_event); +- assert(end_event); +-}); +- +diff --git a/test/simple/test-stream2-large-read-stall.js b/test/simple/test-stream2-large-read-stall.js +index 2fbfbca..667985b 100644 +--- a/test/simple/test-stream2-large-read-stall.js ++++ b/test/simple/test-stream2-large-read-stall.js +@@ -30,7 +30,7 @@ var PUSHSIZE = 20; + var PUSHCOUNT = 1000; + var HWM = 50; + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var r = new Readable({ + highWaterMark: HWM + }); +@@ -39,23 +39,23 @@ var rs = r._readableState; + r._read = push; + + r.on('readable', function() { +- console.error('>> readable'); ++ //console.error('>> readable'); + do { +- console.error(' > read(%d)', READSIZE); ++ //console.error(' > read(%d)', READSIZE); + var ret = r.read(READSIZE); +- console.error(' < %j (%d remain)', ret && ret.length, rs.length); ++ //console.error(' < %j (%d remain)', ret && ret.length, rs.length); + } while (ret && ret.length === READSIZE); + +- console.error('<< after read()', +- ret && ret.length, +- rs.needReadable, +- rs.length); ++ //console.error('<< after read()', ++ // ret && ret.length, ++ // rs.needReadable, ++ // rs.length); + }); + + var endEmitted = false; + r.on('end', function() { + endEmitted = true; +- console.error('end'); ++ //console.error('end'); + }); + + var pushes = 0; +@@ -64,11 +64,11 @@ function push() { + return; + + if (pushes++ === PUSHCOUNT) { +- console.error(' push(EOF)'); ++ //console.error(' push(EOF)'); + return r.push(null); + } + +- console.error(' push #%d', pushes); ++ //console.error(' push #%d', pushes); + if (r.push(new Buffer(PUSHSIZE))) + setTimeout(push); + } +diff --git a/test/simple/test-stream2-objects.js b/test/simple/test-stream2-objects.js +index 3e6931d..ff47d89 100644 +--- a/test/simple/test-stream2-objects.js ++++ b/test/simple/test-stream2-objects.js +@@ -21,8 +21,8 @@ + + + var common = require('../common.js'); +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var assert = require('assert'); + + // tiny node-tap lookalike. +diff --git a/test/simple/test-stream2-pipe-error-handling.js b/test/simple/test-stream2-pipe-error-handling.js +index cf7531c..e3f3e4e 100644 +--- a/test/simple/test-stream2-pipe-error-handling.js ++++ b/test/simple/test-stream2-pipe-error-handling.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + + (function testErrorListenerCatches() { + var count = 1000; +diff --git a/test/simple/test-stream2-pipe-error-once-listener.js b/test/simple/test-stream2-pipe-error-once-listener.js +index 5e8e3cb..53b2616 100755 +--- a/test/simple/test-stream2-pipe-error-once-listener.js ++++ b/test/simple/test-stream2-pipe-error-once-listener.js +@@ -24,7 +24,7 @@ var common = require('../common.js'); + var assert = require('assert'); + + var util = require('util'); +-var stream = require('stream'); ++var stream = require('../../'); + + + var Read = function() { +diff --git a/test/simple/test-stream2-push.js b/test/simple/test-stream2-push.js +index b63edc3..eb2b0e9 100644 +--- a/test/simple/test-stream2-push.js ++++ b/test/simple/test-stream2-push.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var stream = require('stream'); ++var stream = require('../../'); + var Readable = stream.Readable; + var Writable = stream.Writable; + var assert = require('assert'); +diff --git a/test/simple/test-stream2-read-sync-stack.js b/test/simple/test-stream2-read-sync-stack.js +index e8a7305..9740a47 100644 +--- a/test/simple/test-stream2-read-sync-stack.js ++++ b/test/simple/test-stream2-read-sync-stack.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var r = new Readable(); + var N = 256 * 1024; + +diff --git a/test/simple/test-stream2-readable-empty-buffer-no-eof.js b/test/simple/test-stream2-readable-empty-buffer-no-eof.js +index cd30178..4b1659d 100644 +--- a/test/simple/test-stream2-readable-empty-buffer-no-eof.js ++++ b/test/simple/test-stream2-readable-empty-buffer-no-eof.js +@@ -22,10 +22,9 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + test1(); +-test2(); + + function test1() { + var r = new Readable(); +@@ -88,31 +87,3 @@ function test1() { + console.log('ok'); + }); + } +- +-function test2() { +- var r = new Readable({ encoding: 'base64' }); +- var reads = 5; +- r._read = function(n) { +- if (!reads--) +- return r.push(null); // EOF +- else +- return r.push(new Buffer('x')); +- }; +- +- var results = []; +- function flow() { +- var chunk; +- while (null !== (chunk = r.read())) +- results.push(chunk + ''); +- } +- r.on('readable', flow); +- r.on('end', function() { +- results.push('EOF'); +- }); +- flow(); +- +- process.on('exit', function() { +- assert.deepEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]); +- console.log('ok'); +- }); +-} +diff --git a/test/simple/test-stream2-readable-from-list.js b/test/simple/test-stream2-readable-from-list.js +index 7c96ffe..04a96f5 100644 +--- a/test/simple/test-stream2-readable-from-list.js ++++ b/test/simple/test-stream2-readable-from-list.js +@@ -21,7 +21,7 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var fromList = require('_stream_readable')._fromList; ++var fromList = require('../../lib/_stream_readable')._fromList; + + // tiny node-tap lookalike. + var tests = []; +diff --git a/test/simple/test-stream2-readable-legacy-drain.js b/test/simple/test-stream2-readable-legacy-drain.js +index 675da8e..51fd3d5 100644 +--- a/test/simple/test-stream2-readable-legacy-drain.js ++++ b/test/simple/test-stream2-readable-legacy-drain.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Stream = require('stream'); ++var Stream = require('../../'); + var Readable = Stream.Readable; + + var r = new Readable(); +diff --git a/test/simple/test-stream2-readable-non-empty-end.js b/test/simple/test-stream2-readable-non-empty-end.js +index 7314ae7..c971898 100644 +--- a/test/simple/test-stream2-readable-non-empty-end.js ++++ b/test/simple/test-stream2-readable-non-empty-end.js +@@ -21,7 +21,7 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var Readable = require('_stream_readable'); ++var Readable = require('../../lib/_stream_readable'); + + var len = 0; + var chunks = new Array(10); +diff --git a/test/simple/test-stream2-readable-wrap-empty.js b/test/simple/test-stream2-readable-wrap-empty.js +index 2e5cf25..fd8a3dc 100644 +--- a/test/simple/test-stream2-readable-wrap-empty.js ++++ b/test/simple/test-stream2-readable-wrap-empty.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); ++var Readable = require('../../lib/_stream_readable'); + var EE = require('events').EventEmitter; + + var oldStream = new EE(); +diff --git a/test/simple/test-stream2-readable-wrap.js b/test/simple/test-stream2-readable-wrap.js +index 90eea01..6b177f7 100644 +--- a/test/simple/test-stream2-readable-wrap.js ++++ b/test/simple/test-stream2-readable-wrap.js +@@ -22,8 +22,8 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var EE = require('events').EventEmitter; + + var testRuns = 0, completedRuns = 0; +diff --git a/test/simple/test-stream2-set-encoding.js b/test/simple/test-stream2-set-encoding.js +index 5d2c32a..685531b 100644 +--- a/test/simple/test-stream2-set-encoding.js ++++ b/test/simple/test-stream2-set-encoding.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var util = require('util'); + + // tiny node-tap lookalike. +diff --git a/test/simple/test-stream2-transform.js b/test/simple/test-stream2-transform.js +index 9c9ddd8..a0cacc6 100644 +--- a/test/simple/test-stream2-transform.js ++++ b/test/simple/test-stream2-transform.js +@@ -21,8 +21,8 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var PassThrough = require('_stream_passthrough'); +-var Transform = require('_stream_transform'); ++var PassThrough = require('../../').PassThrough; ++var Transform = require('../../').Transform; + + // tiny node-tap lookalike. + var tests = []; +diff --git a/test/simple/test-stream2-unpipe-drain.js b/test/simple/test-stream2-unpipe-drain.js +index d66dc3c..365b327 100644 +--- a/test/simple/test-stream2-unpipe-drain.js ++++ b/test/simple/test-stream2-unpipe-drain.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + var crypto = require('crypto'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js +index 99f8746..17c92ae 100644 +--- a/test/simple/test-stream2-unpipe-leak.js ++++ b/test/simple/test-stream2-unpipe-leak.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + + var chunk = new Buffer('hallo'); + +diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js +index 704100c..209c3a6 100644 +--- a/test/simple/test-stream2-writable.js ++++ b/test/simple/test-stream2-writable.js +@@ -20,8 +20,8 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var W = require('_stream_writable'); +-var D = require('_stream_duplex'); ++var W = require('../../').Writable; ++var D = require('../../').Duplex; + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream3-pause-then-read.js b/test/simple/test-stream3-pause-then-read.js +index b91bde3..2f72c15 100644 +--- a/test/simple/test-stream3-pause-then-read.js ++++ b/test/simple/test-stream3-pause-then-read.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var stream = require('stream'); ++var stream = require('../../'); + var Readable = stream.Readable; + var Writable = stream.Writable; + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_duplex.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_duplex.js new file mode 100644 index 00000000000..97deb6d2234 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_duplex.js @@ -0,0 +1,75 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +module.exports = Duplex; +var util = require('util'); +if (!util.isUndefined) { + var utilIs = require('core-util-is'); + for (var f in utilIs) { + util[f] = utilIs[f]; + } +} +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +Object.keys(Writable.prototype).forEach(function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); + +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) + this.readable = false; + + if (options && options.writable === false) + this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; + + // no more data can be written. + // But allow more writes to happen in this tick. + process.nextTick(this.end.bind(this)); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_passthrough.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_passthrough.js new file mode 100644 index 00000000000..bb4cafe2e05 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_passthrough.js @@ -0,0 +1,47 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +module.exports = PassThrough; + +var Transform = require('./_stream_transform'); +var util = require('util'); +if (!util.isUndefined) { + var utilIs = require('core-util-is'); + for (var f in utilIs) { + util[f] = utilIs[f]; + } +} +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_readable.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_readable.js new file mode 100644 index 00000000000..0aa193fa669 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_readable.js @@ -0,0 +1,925 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +module.exports = Readable; +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; +}; + +if (!global.setImmediate) global.setImmediate = function setImmediate(fn) { + return setTimeout(fn, 0); +}; +if (!global.clearImmediate) global.clearImmediate = function clearImmediate(i) { + return clearTimeout(i); +}; + +var Stream = require('stream'); +var util = require('util'); +var Buffer = require('buffer').Buffer; +if (!util.isUndefined) { + var utilIs = require('core-util-is'); + for (var f in utilIs) { + util[f] = utilIs[f]; + } +} +var StringDecoder; +var debug; +if (util.debuglog) + debug = util.debuglog('stream'); +else try { + debug = require('debuglog')('stream'); +} catch (er) { + debug = function() {}; +} + +util.inherits(Readable, Stream); + +function ReadableState(options, stream) { + options = options || {}; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function(chunk, encoding) { + var state = this._readableState; + + if (util.isString(chunk) && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (util.isNullOrUndefined(chunk)) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); + + if (!addToFront) + state.reading = false; + + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) + state.buffer.unshift(chunk); + else + state.buffer.push(chunk); + + if (state.needReadable) + emitReadable(stream); + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + + + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || util.isNull(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } + + if (n <= 0) + return 0; + + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + debug('read', n); + var state = this._readableState; + var nOrig = n; + + if (!util.isNumber(n) || n > 0) + state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && + state.needReadable && + (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) + endReadable(this); + else + emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) + endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } + + if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) + state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + } + + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); + + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; + + if (util.isNull(ret)) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended && state.length === 0) + endReadable(this); + + if (!util.isNull(ret)) + this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode && + !er) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function(n) { + this.emit('error', new Error('not implemented')); +}; + +Readable.prototype.pipe = function(dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && + (!dest._writableState || dest._writableState.needDrain)) + ondrain(); + } + + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + if (false === ret) { + debug('false write response, pause', + src._readableState.awaitDrain); + src._readableState.awaitDrain++; + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (Array.isArray(dest._events.error)) + dest._events.error.unshift(onerror); + else + dest._events.error = [onerror, dest._events.error]; + + + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) + state.awaitDrain--; + if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) + return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) + return this; + + if (!dest) + dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = state.pipes.indexOf(dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function(ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + // If listening to data, and it has not explicitly been paused, + // then call resume to start the flow of data on the next tick. + if (ev === 'data' && false !== this._readableState.flowing) { + this.resume(); + } + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + var self = this; + process.nextTick(function() { + debug('readable nexttick read 0'); + self.read(0); + }); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + if (!state.reading) { + debug('resume read 0'); + this.read(0); + } + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(function() { + resume_(stream, state); + }); + } +} + +function resume_(stream, state) { + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) + stream.read(0); +} + +Readable.prototype.pause = function() { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); + } +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function(stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + debug('wrapped data'); + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + events.forEach(function(ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_transform.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_transform.js new file mode 100644 index 00000000000..b0caf57d83b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_transform.js @@ -0,0 +1,210 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); +var util = require('util'); +if (!util.isUndefined) { + var utilIs = require('core-util-is'); + for (var f in utilIs) { + util[f] = utilIs[f]; + } +} +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (!util.isNullOrUndefined(data)) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + this.once('prefinish', function() { + if (util.isFunction(this._flush)) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +Transform.prototype.push = function(chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function(chunk, encoding, cb) { + throw new Error('not implemented'); +}; + +Transform.prototype._write = function(chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || + rs.needReadable || + rs.length < rs.highWaterMark) + this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function(n) { + var ts = this._transformState; + + if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_writable.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_writable.js new file mode 100644 index 00000000000..12076c5d520 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/lib/_stream_writable.js @@ -0,0 +1,467 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; +Writable.WritableState = WritableState; + +var util = require('util'); +var Buffer = require('buffer').Buffer; +if (!util.isUndefined) { + var utilIs = require('core-util-is'); + for (var f in utilIs) { + util[f] = utilIs[f]; + } +} +var Stream = require('stream'); + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + options = options || {}; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.buffer = []; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // Internal, used in net.js and _tls_wrap.js + this._errorEmitted = false; +} + +function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof require('./_stream_duplex'))) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); + valid = false; + } + return valid; +} + +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (util.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (!util.isFunction(cb)) + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function() { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function() { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && + !state.corked && + !state.finished && + !state.bufferProcessing && + state.buffer.length) + clearBuffer(this, state); + } +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + util.isString(chunk)) { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + if (util.isBuffer(chunk)) + encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; + + if (state.writing || state.corked) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, false, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) + stream._writev(chunk, state.onwrite); + else + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + state.pendingcb--; + cb(er); + }); + else { + state.pendingcb--; + cb(er); + } + + stream.emit('error', er); + stream._errorEmitted = true; +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) + onwriteError(stream, state, sync, er, cb); + else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(stream, state); + + if (!finished && + !state.corked && + !state.bufferProcessing && + state.buffer.length) { + clearBuffer(stream, state); + } + + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + + if (stream._writev && state.buffer.length > 1) { + // Fast case, write everything using _writev() + var cbs = []; + for (var c = 0; c < state.buffer.length; c++) + cbs.push(state.buffer[c].callback); + + // count the one we are adding, as well. + // TODO(isaacs) clean this up + state.pendingcb++; + doWrite(stream, state, true, state.length, state.buffer, '', function(err) { + for (var i = 0; i < cbs.length; i++) { + state.pendingcb--; + cbs[i](err); + } + }); + + // Clear buffer + state.buffer = []; + } else { + // Slow case, write chunks one-by-one + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; + } + + state.bufferProcessing = false; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); + +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function(chunk, encoding, cb) { + var state = this._writableState; + + if (util.isFunction(chunk)) { + cb = chunk; + chunk = null; + encoding = null; + } else if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (!util.isNullOrUndefined(chunk)) + this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else + prefinish(stream, state); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/README.md new file mode 100644 index 00000000000..5a76b4149c5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/README.md @@ -0,0 +1,3 @@ +# core-util-is + +The `util.is*` functions introduced in Node v0.12. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/float.patch b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/float.patch new file mode 100644 index 00000000000..a06d5c05f75 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/float.patch @@ -0,0 +1,604 @@ +diff --git a/lib/util.js b/lib/util.js +index a03e874..9074e8e 100644 +--- a/lib/util.js ++++ b/lib/util.js +@@ -19,430 +19,6 @@ + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + +-var formatRegExp = /%[sdj%]/g; +-exports.format = function(f) { +- if (!isString(f)) { +- var objects = []; +- for (var i = 0; i < arguments.length; i++) { +- objects.push(inspect(arguments[i])); +- } +- return objects.join(' '); +- } +- +- var i = 1; +- var args = arguments; +- var len = args.length; +- var str = String(f).replace(formatRegExp, function(x) { +- if (x === '%%') return '%'; +- if (i >= len) return x; +- switch (x) { +- case '%s': return String(args[i++]); +- case '%d': return Number(args[i++]); +- case '%j': +- try { +- return JSON.stringify(args[i++]); +- } catch (_) { +- return '[Circular]'; +- } +- default: +- return x; +- } +- }); +- for (var x = args[i]; i < len; x = args[++i]) { +- if (isNull(x) || !isObject(x)) { +- str += ' ' + x; +- } else { +- str += ' ' + inspect(x); +- } +- } +- return str; +-}; +- +- +-// Mark that a method should not be used. +-// Returns a modified function which warns once by default. +-// If --no-deprecation is set, then it is a no-op. +-exports.deprecate = function(fn, msg) { +- // Allow for deprecating things in the process of starting up. +- if (isUndefined(global.process)) { +- return function() { +- return exports.deprecate(fn, msg).apply(this, arguments); +- }; +- } +- +- if (process.noDeprecation === true) { +- return fn; +- } +- +- var warned = false; +- function deprecated() { +- if (!warned) { +- if (process.throwDeprecation) { +- throw new Error(msg); +- } else if (process.traceDeprecation) { +- console.trace(msg); +- } else { +- console.error(msg); +- } +- warned = true; +- } +- return fn.apply(this, arguments); +- } +- +- return deprecated; +-}; +- +- +-var debugs = {}; +-var debugEnviron; +-exports.debuglog = function(set) { +- if (isUndefined(debugEnviron)) +- debugEnviron = process.env.NODE_DEBUG || ''; +- set = set.toUpperCase(); +- if (!debugs[set]) { +- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { +- var pid = process.pid; +- debugs[set] = function() { +- var msg = exports.format.apply(exports, arguments); +- console.error('%s %d: %s', set, pid, msg); +- }; +- } else { +- debugs[set] = function() {}; +- } +- } +- return debugs[set]; +-}; +- +- +-/** +- * Echos the value of a value. Trys to print the value out +- * in the best way possible given the different types. +- * +- * @param {Object} obj The object to print out. +- * @param {Object} opts Optional options object that alters the output. +- */ +-/* legacy: obj, showHidden, depth, colors*/ +-function inspect(obj, opts) { +- // default options +- var ctx = { +- seen: [], +- stylize: stylizeNoColor +- }; +- // legacy... +- if (arguments.length >= 3) ctx.depth = arguments[2]; +- if (arguments.length >= 4) ctx.colors = arguments[3]; +- if (isBoolean(opts)) { +- // legacy... +- ctx.showHidden = opts; +- } else if (opts) { +- // got an "options" object +- exports._extend(ctx, opts); +- } +- // set default options +- if (isUndefined(ctx.showHidden)) ctx.showHidden = false; +- if (isUndefined(ctx.depth)) ctx.depth = 2; +- if (isUndefined(ctx.colors)) ctx.colors = false; +- if (isUndefined(ctx.customInspect)) ctx.customInspect = true; +- if (ctx.colors) ctx.stylize = stylizeWithColor; +- return formatValue(ctx, obj, ctx.depth); +-} +-exports.inspect = inspect; +- +- +-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +-inspect.colors = { +- 'bold' : [1, 22], +- 'italic' : [3, 23], +- 'underline' : [4, 24], +- 'inverse' : [7, 27], +- 'white' : [37, 39], +- 'grey' : [90, 39], +- 'black' : [30, 39], +- 'blue' : [34, 39], +- 'cyan' : [36, 39], +- 'green' : [32, 39], +- 'magenta' : [35, 39], +- 'red' : [31, 39], +- 'yellow' : [33, 39] +-}; +- +-// Don't use 'blue' not visible on cmd.exe +-inspect.styles = { +- 'special': 'cyan', +- 'number': 'yellow', +- 'boolean': 'yellow', +- 'undefined': 'grey', +- 'null': 'bold', +- 'string': 'green', +- 'date': 'magenta', +- // "name": intentionally not styling +- 'regexp': 'red' +-}; +- +- +-function stylizeWithColor(str, styleType) { +- var style = inspect.styles[styleType]; +- +- if (style) { +- return '\u001b[' + inspect.colors[style][0] + 'm' + str + +- '\u001b[' + inspect.colors[style][1] + 'm'; +- } else { +- return str; +- } +-} +- +- +-function stylizeNoColor(str, styleType) { +- return str; +-} +- +- +-function arrayToHash(array) { +- var hash = {}; +- +- array.forEach(function(val, idx) { +- hash[val] = true; +- }); +- +- return hash; +-} +- +- +-function formatValue(ctx, value, recurseTimes) { +- // Provide a hook for user-specified inspect functions. +- // Check that value is an object with an inspect function on it +- if (ctx.customInspect && +- value && +- isFunction(value.inspect) && +- // Filter out the util module, it's inspect function is special +- value.inspect !== exports.inspect && +- // Also filter out any prototype objects using the circular check. +- !(value.constructor && value.constructor.prototype === value)) { +- var ret = value.inspect(recurseTimes, ctx); +- if (!isString(ret)) { +- ret = formatValue(ctx, ret, recurseTimes); +- } +- return ret; +- } +- +- // Primitive types cannot have properties +- var primitive = formatPrimitive(ctx, value); +- if (primitive) { +- return primitive; +- } +- +- // Look up the keys of the object. +- var keys = Object.keys(value); +- var visibleKeys = arrayToHash(keys); +- +- if (ctx.showHidden) { +- keys = Object.getOwnPropertyNames(value); +- } +- +- // Some type of object without properties can be shortcutted. +- if (keys.length === 0) { +- if (isFunction(value)) { +- var name = value.name ? ': ' + value.name : ''; +- return ctx.stylize('[Function' + name + ']', 'special'); +- } +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } +- if (isDate(value)) { +- return ctx.stylize(Date.prototype.toString.call(value), 'date'); +- } +- if (isError(value)) { +- return formatError(value); +- } +- } +- +- var base = '', array = false, braces = ['{', '}']; +- +- // Make Array say that they are Array +- if (isArray(value)) { +- array = true; +- braces = ['[', ']']; +- } +- +- // Make functions say that they are functions +- if (isFunction(value)) { +- var n = value.name ? ': ' + value.name : ''; +- base = ' [Function' + n + ']'; +- } +- +- // Make RegExps say that they are RegExps +- if (isRegExp(value)) { +- base = ' ' + RegExp.prototype.toString.call(value); +- } +- +- // Make dates with properties first say the date +- if (isDate(value)) { +- base = ' ' + Date.prototype.toUTCString.call(value); +- } +- +- // Make error with message first say the error +- if (isError(value)) { +- base = ' ' + formatError(value); +- } +- +- if (keys.length === 0 && (!array || value.length == 0)) { +- return braces[0] + base + braces[1]; +- } +- +- if (recurseTimes < 0) { +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } else { +- return ctx.stylize('[Object]', 'special'); +- } +- } +- +- ctx.seen.push(value); +- +- var output; +- if (array) { +- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); +- } else { +- output = keys.map(function(key) { +- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); +- }); +- } +- +- ctx.seen.pop(); +- +- return reduceToSingleString(output, base, braces); +-} +- +- +-function formatPrimitive(ctx, value) { +- if (isUndefined(value)) +- return ctx.stylize('undefined', 'undefined'); +- if (isString(value)) { +- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') +- .replace(/'/g, "\\'") +- .replace(/\\"/g, '"') + '\''; +- return ctx.stylize(simple, 'string'); +- } +- if (isNumber(value)) { +- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0, +- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 . +- if (value === 0 && 1 / value < 0) +- return ctx.stylize('-0', 'number'); +- return ctx.stylize('' + value, 'number'); +- } +- if (isBoolean(value)) +- return ctx.stylize('' + value, 'boolean'); +- // For some reason typeof null is "object", so special case here. +- if (isNull(value)) +- return ctx.stylize('null', 'null'); +-} +- +- +-function formatError(value) { +- return '[' + Error.prototype.toString.call(value) + ']'; +-} +- +- +-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { +- var output = []; +- for (var i = 0, l = value.length; i < l; ++i) { +- if (hasOwnProperty(value, String(i))) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- String(i), true)); +- } else { +- output.push(''); +- } +- } +- keys.forEach(function(key) { +- if (!key.match(/^\d+$/)) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- key, true)); +- } +- }); +- return output; +-} +- +- +-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { +- var name, str, desc; +- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; +- if (desc.get) { +- if (desc.set) { +- str = ctx.stylize('[Getter/Setter]', 'special'); +- } else { +- str = ctx.stylize('[Getter]', 'special'); +- } +- } else { +- if (desc.set) { +- str = ctx.stylize('[Setter]', 'special'); +- } +- } +- if (!hasOwnProperty(visibleKeys, key)) { +- name = '[' + key + ']'; +- } +- if (!str) { +- if (ctx.seen.indexOf(desc.value) < 0) { +- if (isNull(recurseTimes)) { +- str = formatValue(ctx, desc.value, null); +- } else { +- str = formatValue(ctx, desc.value, recurseTimes - 1); +- } +- if (str.indexOf('\n') > -1) { +- if (array) { +- str = str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n').substr(2); +- } else { +- str = '\n' + str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n'); +- } +- } +- } else { +- str = ctx.stylize('[Circular]', 'special'); +- } +- } +- if (isUndefined(name)) { +- if (array && key.match(/^\d+$/)) { +- return str; +- } +- name = JSON.stringify('' + key); +- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { +- name = name.substr(1, name.length - 2); +- name = ctx.stylize(name, 'name'); +- } else { +- name = name.replace(/'/g, "\\'") +- .replace(/\\"/g, '"') +- .replace(/(^"|"$)/g, "'"); +- name = ctx.stylize(name, 'string'); +- } +- } +- +- return name + ': ' + str; +-} +- +- +-function reduceToSingleString(output, base, braces) { +- var numLinesEst = 0; +- var length = output.reduce(function(prev, cur) { +- numLinesEst++; +- if (cur.indexOf('\n') >= 0) numLinesEst++; +- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; +- }, 0); +- +- if (length > 60) { +- return braces[0] + +- (base === '' ? '' : base + '\n ') + +- ' ' + +- output.join(',\n ') + +- ' ' + +- braces[1]; +- } +- +- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +-} +- +- + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { +@@ -522,166 +98,10 @@ function isPrimitive(arg) { + exports.isPrimitive = isPrimitive; + + function isBuffer(arg) { +- return arg instanceof Buffer; ++ return Buffer.isBuffer(arg); + } + exports.isBuffer = isBuffer; + + function objectToString(o) { + return Object.prototype.toString.call(o); +-} +- +- +-function pad(n) { +- return n < 10 ? '0' + n.toString(10) : n.toString(10); +-} +- +- +-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', +- 'Oct', 'Nov', 'Dec']; +- +-// 26 Feb 16:19:34 +-function timestamp() { +- var d = new Date(); +- var time = [pad(d.getHours()), +- pad(d.getMinutes()), +- pad(d.getSeconds())].join(':'); +- return [d.getDate(), months[d.getMonth()], time].join(' '); +-} +- +- +-// log is just a thin wrapper to console.log that prepends a timestamp +-exports.log = function() { +- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +-}; +- +- +-/** +- * Inherit the prototype methods from one constructor into another. +- * +- * The Function.prototype.inherits from lang.js rewritten as a standalone +- * function (not on Function.prototype). NOTE: If this file is to be loaded +- * during bootstrapping this function needs to be rewritten using some native +- * functions as prototype setup using normal JavaScript does not work as +- * expected during bootstrapping (see mirror.js in r114903). +- * +- * @param {function} ctor Constructor function which needs to inherit the +- * prototype. +- * @param {function} superCtor Constructor function to inherit prototype from. +- */ +-exports.inherits = function(ctor, superCtor) { +- ctor.super_ = superCtor; +- ctor.prototype = Object.create(superCtor.prototype, { +- constructor: { +- value: ctor, +- enumerable: false, +- writable: true, +- configurable: true +- } +- }); +-}; +- +-exports._extend = function(origin, add) { +- // Don't do anything if add isn't an object +- if (!add || !isObject(add)) return origin; +- +- var keys = Object.keys(add); +- var i = keys.length; +- while (i--) { +- origin[keys[i]] = add[keys[i]]; +- } +- return origin; +-}; +- +-function hasOwnProperty(obj, prop) { +- return Object.prototype.hasOwnProperty.call(obj, prop); +-} +- +- +-// Deprecated old stuff. +- +-exports.p = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- console.error(exports.inspect(arguments[i])); +- } +-}, 'util.p: Use console.error() instead'); +- +- +-exports.exec = exports.deprecate(function() { +- return require('child_process').exec.apply(this, arguments); +-}, 'util.exec is now called `child_process.exec`.'); +- +- +-exports.print = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(String(arguments[i])); +- } +-}, 'util.print: Use console.log instead'); +- +- +-exports.puts = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(arguments[i] + '\n'); +- } +-}, 'util.puts: Use console.log instead'); +- +- +-exports.debug = exports.deprecate(function(x) { +- process.stderr.write('DEBUG: ' + x + '\n'); +-}, 'util.debug: Use console.error instead'); +- +- +-exports.error = exports.deprecate(function(x) { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stderr.write(arguments[i] + '\n'); +- } +-}, 'util.error: Use console.error instead'); +- +- +-exports.pump = exports.deprecate(function(readStream, writeStream, callback) { +- var callbackCalled = false; +- +- function call(a, b, c) { +- if (callback && !callbackCalled) { +- callback(a, b, c); +- callbackCalled = true; +- } +- } +- +- readStream.addListener('data', function(chunk) { +- if (writeStream.write(chunk) === false) readStream.pause(); +- }); +- +- writeStream.addListener('drain', function() { +- readStream.resume(); +- }); +- +- readStream.addListener('end', function() { +- writeStream.end(); +- }); +- +- readStream.addListener('close', function() { +- call(); +- }); +- +- readStream.addListener('error', function(err) { +- writeStream.end(); +- call(err); +- }); +- +- writeStream.addListener('error', function(err) { +- readStream.destroy(); +- call(err); +- }); +-}, 'util.pump(): Use readableStream.pipe() instead'); +- +- +-var uv; +-exports._errnoException = function(err, syscall) { +- if (isUndefined(uv)) uv = process.binding('uv'); +- var errname = uv.errname(err); +- var e = new Error(syscall + ' ' + errname); +- e.code = errname; +- e.errno = errname; +- e.syscall = syscall; +- return e; +-}; ++} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/lib/util.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/lib/util.js new file mode 100644 index 00000000000..9074e8ebcb6 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/lib/util.js @@ -0,0 +1,107 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +function isBuffer(arg) { + return Buffer.isBuffer(arg); +} +exports.isBuffer = isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/package.json new file mode 100644 index 00000000000..0cc66b9503c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/package.json @@ -0,0 +1,34 @@ +{ + "name": "core-util-is", + "version": "1.0.1", + "description": "The `util.is*` functions introduced in Node v0.12.", + "main": "lib/util.js", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/core-util-is" + }, + "keywords": [ + "util", + "isBuffer", + "isArray", + "isNumber", + "isString", + "isRegExp", + "isThis", + "isThat", + "polyfill" + ], + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/isaacs/core-util-is/issues" + }, + "readme": "# core-util-is\n\nThe `util.is*` functions introduced in Node v0.12.\n", + "readmeFilename": "README.md", + "_id": "core-util-is@1.0.1", + "_from": "core-util-is@~1.0.0" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/util.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/util.js new file mode 100644 index 00000000000..007fa105756 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/core-util-is/util.js @@ -0,0 +1,106 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && objectToString(e) === '[object Error]'; +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +function isBuffer(arg) { + return arg instanceof Buffer; +} +exports.isBuffer = isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/LICENSE new file mode 100644 index 00000000000..a3187cc1002 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/LICENSE @@ -0,0 +1,19 @@ +Copyright Joyent, Inc. and other Node contributors. 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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/README.md new file mode 100644 index 00000000000..dc6fccecc32 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/README.md @@ -0,0 +1,40 @@ +# debuglog - backport of util.debuglog() from node v0.11 + +To facilitate using the `util.debuglog()` function that will be available when +node v0.12 is released now, this is a copy extracted from the source. + +## require('debuglog') + +Return `util.debuglog`, if it exists, otherwise it will return an internal copy +of the implementation from node v0.11. + +## debuglog(section) + +* `section` {String} The section of the program to be debugged +* Returns: {Function} The logging function + +This is used to create a function which conditionally writes to stderr +based on the existence of a `NODE_DEBUG` environment variable. If the +`section` name appears in that environment variable, then the returned +function will be similar to `console.error()`. If not, then the +returned function is a no-op. + +For example: + +```javascript +var debuglog = util.debuglog('foo'); + +var bar = 123; +debuglog('hello from foo [%d]', bar); +``` + +If this program is run with `NODE_DEBUG=foo` in the environment, then +it will output something like: + + FOO 3245: hello from foo [123] + +where `3245` is the process id. If it is not run with that +environment variable set, then it will not print anything. + +You may separate multiple `NODE_DEBUG` environment variables with a +comma. For example, `NODE_DEBUG=fs,net,tls`. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/debuglog.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/debuglog.js new file mode 100644 index 00000000000..da465c29424 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/debuglog.js @@ -0,0 +1,22 @@ +var util = require('util'); + +module.exports = util.debuglog || debuglog; + +var debugs = {}; +var debugEnviron = process.env.NODE_DEBUG || ''; + +function debuglog(set) { + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = util.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/package.json new file mode 100644 index 00000000000..87f069a0244 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/package.json @@ -0,0 +1,29 @@ +{ + "name": "debuglog", + "version": "0.0.2", + "description": "backport of util.debuglog from node v0.11", + "license": "MIT", + "main": "debuglog.js", + "repository": { + "type": "git", + "url": "https://github.com/sam-github/node-debuglog.git" + }, + "author": { + "name": "Sam Roberts", + "email": "sam@strongloop.com" + }, + "engines": { + "node": "*" + }, + "readme": "# debuglog - backport of util.debuglog() from node v0.11\n\nTo facilitate using the `util.debuglog()` function that will be available when\nnode v0.12 is released now, this is a copy extracted from the source.\n\n## require('debuglog')\n\nReturn `util.debuglog`, if it exists, otherwise it will return an internal copy\nof the implementation from node v0.11.\n\n## debuglog(section)\n\n* `section` {String} The section of the program to be debugged\n* Returns: {Function} The logging function\n\nThis is used to create a function which conditionally writes to stderr\nbased on the existence of a `NODE_DEBUG` environment variable. If the\n`section` name appears in that environment variable, then the returned\nfunction will be similar to `console.error()`. If not, then the\nreturned function is a no-op.\n\nFor example:\n\n```javascript\nvar debuglog = util.debuglog('foo');\n\nvar bar = 123;\ndebuglog('hello from foo [%d]', bar);\n```\n\nIf this program is run with `NODE_DEBUG=foo` in the environment, then\nit will output something like:\n\n FOO 3245: hello from foo [123]\n\nwhere `3245` is the process id. If it is not run with that\nenvironment variable set, then it will not print anything.\n\nYou may separate multiple `NODE_DEBUG` environment variables with a\ncomma. For example, `NODE_DEBUG=fs,net,tls`.\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/sam-github/node-debuglog/issues" + }, + "_id": "debuglog@0.0.2", + "dist": { + "shasum": "a0e439ca87738aff3813659190fd30842ffea6f4" + }, + "_from": "debuglog@0.0.2", + "_resolved": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/.npmignore new file mode 100644 index 00000000000..206320cc1d2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/.npmignore @@ -0,0 +1,2 @@ +build +test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/LICENSE new file mode 100644 index 00000000000..6de584a48f5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/LICENSE @@ -0,0 +1,20 @@ +Copyright Joyent, Inc. and other Node contributors. + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/README.md new file mode 100644 index 00000000000..4d2aa001501 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/README.md @@ -0,0 +1,7 @@ +**string_decoder.js** (`require('string_decoder')`) from Node.js core + +Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details. + +Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.** + +The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/index.js new file mode 100644 index 00000000000..2e44a03e15d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/index.js @@ -0,0 +1,200 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var Buffer = require('buffer').Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + this.charBuffer = new Buffer(6); + this.charReceived = 0; + this.charLength = 0; +}; + + +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + var offset = 0; + + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var i = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, offset, i); + this.charReceived += (i - offset); + offset = i; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (i == buffer.length) return charStr; + + // otherwise cut off the characters end from the beginning of this buffer + buffer = buffer.slice(i, buffer.length); + break; + } + + var lenIncomplete = this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end); + this.charReceived = lenIncomplete; + end -= lenIncomplete; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + + return i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 2; + this.charLength = incomplete ? 2 : 0; + return incomplete; +} + +function base64DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 3; + this.charLength = incomplete ? 3 : 0; + return incomplete; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/package.json new file mode 100644 index 00000000000..7f5d0011eb4 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/string_decoder/package.json @@ -0,0 +1,32 @@ +{ + "name": "string_decoder", + "version": "0.10.25-1", + "description": "The string_decoder module from Node core", + "main": "index.js", + "dependencies": {}, + "devDependencies": { + "tap": "~0.4.8" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/rvagg/string_decoder.git" + }, + "homepage": "https://github.com/rvagg/string_decoder", + "keywords": [ + "string", + "decoder", + "browser", + "browserify" + ], + "license": "MIT", + "readme": "**string_decoder.js** (`require('string_decoder')`) from Node.js core\n\nCopyright Joyent, Inc. and other Node contributors. See LICENCE file for details.\n\nVersion numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.**\n\nThe *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version.", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/rvagg/string_decoder/issues" + }, + "_id": "string_decoder@0.10.25-1", + "_from": "string_decoder@~0.10.x" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/package.json new file mode 100644 index 00000000000..abbf1db4f6f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/package.json @@ -0,0 +1,42 @@ +{ + "name": "readable-stream", + "version": "1.1.11", + "description": "An exploration of a new kind of readable streams for Node.js", + "main": "readable.js", + "dependencies": { + "core-util-is": "~1.0.0", + "string_decoder": "~0.10.x", + "debuglog": "0.0.2" + }, + "devDependencies": { + "tap": "~0.2.6" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/isaacs/readable-stream" + }, + "keywords": [ + "readable", + "stream", + "pipe" + ], + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "license": "MIT", + "optionalDependencies": { + "debuglog": "0.0.2" + }, + "readme": "# readable-stream\n\n***Node-core streams for userland***\n\n[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true)](https://nodei.co/npm/readable-stream/)\n[![NPM](https://nodei.co/npm-dl/readable-stream.png)](https://nodei.co/npm/readable-stream/)\n\nThis package is a mirror of the Streams2 and Streams3 implementations in Node-core.\n\nIf you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *\"stream\"* module in Node-core.\n\n**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12.\n\n**readable-stream** uses proper patch-level versioning so if you pin to `\"~1.0.0\"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `\"~1.1.0\"`\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/isaacs/readable-stream/issues" + }, + "_id": "readable-stream@1.1.11", + "_from": "readable-stream@~1.1.9" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/passthrough.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/passthrough.js new file mode 100644 index 00000000000..27e8d8a5516 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/passthrough.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_passthrough.js") diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/readable.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/readable.js new file mode 100644 index 00000000000..09b8bf5091a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/readable.js @@ -0,0 +1,7 @@ +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = require('stream'); +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/transform.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/transform.js new file mode 100644 index 00000000000..5d482f0780e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/transform.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_transform.js") diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/writable.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/writable.js new file mode 100644 index 00000000000..e1e9efdf3c1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/writable.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_writable.js") diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/.npmignore new file mode 100644 index 00000000000..07e6e472cc7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/.npmignore @@ -0,0 +1 @@ +/node_modules diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/README.md new file mode 100644 index 00000000000..8d6a1928f65 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/README.md @@ -0,0 +1,14 @@ +# stream-counter + +Keep track of how many bytes have been written to a stream. + +## Usage + +```js +var StreamCounter = require('stream-counter'); +var counter = new StreamCounter(); +counter.on('progress', function() { + console.log("progress", counter.bytes); +}); +fs.createReadStream('foo.txt').pipe(counter); +``` diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/index.js new file mode 100644 index 00000000000..c490c2dbe86 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/index.js @@ -0,0 +1,16 @@ +module.exports = ByteCounter; + +var Writable = require('readable-stream').Writable; +var util = require('util'); + +util.inherits(ByteCounter, Writable); +function ByteCounter(options) { + Writable.call(this, options); + this.bytes = 0; +} + +ByteCounter.prototype._write = function(chunk, encoding, cb) { + this.bytes += chunk.length; + this.emit('progress'); + cb(); +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/package.json new file mode 100644 index 00000000000..4b9a4abdf5d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/package.json @@ -0,0 +1,31 @@ +{ + "name": "stream-counter", + "version": "0.2.0", + "description": "keeps track of how many bytes have been written to a stream", + "main": "index.js", + "scripts": { + "test": "node test/test.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/superjoe30/node-stream-counter.git" + }, + "author": { + "name": "Andrew Kelley", + "email": "superjoe30@gmail.com" + }, + "license": "BSD", + "engines": { + "node": ">=0.8.0" + }, + "dependencies": { + "readable-stream": "~1.1.8" + }, + "readme": "# stream-counter\n\nKeep track of how many bytes have been written to a stream.\n\n## Usage\n\n```js\nvar StreamCounter = require('stream-counter');\nvar counter = new StreamCounter();\ncounter.on('progress', function() {\n console.log(\"progress\", counter.bytes);\n});\nfs.createReadStream('foo.txt').pipe(counter);\n```\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/superjoe30/node-stream-counter/issues" + }, + "_id": "stream-counter@0.2.0", + "_from": "stream-counter@~0.2.0" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/test/test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/test/test.js new file mode 100644 index 00000000000..0da95660ae1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/test/test.js @@ -0,0 +1,20 @@ +var ByteCounter = require('../'); +var fs = require('fs'); +var path = require('path'); +var assert = require('assert'); + +var counter = new ByteCounter(); +var remainingTests = 2; +counter.once('progress', function() { + assert.strictEqual(counter.bytes, 5); + remainingTests -= 1; +}); +var is = fs.createReadStream(path.join(__dirname, 'test.txt')); +is.pipe(counter); +is.on('end', function() { + remainingTests -= 1; + assert.strictEqual(counter.bytes, 5); +}); +process.on('exit', function() { + assert.strictEqual(remainingTests, 0); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/test/test.txt b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/test/test.txt new file mode 100644 index 00000000000..81c545efebe --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/node_modules/stream-counter/test/test.txt @@ -0,0 +1 @@ +1234 diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/package.json new file mode 100644 index 00000000000..d458a860c5e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/package.json @@ -0,0 +1,42 @@ +{ + "name": "multiparty", + "version": "2.2.0", + "description": "multipart/form-data parser which supports streaming", + "repository": { + "type": "git", + "url": "git@github.com:superjoe30/node-multiparty.git" + }, + "keywords": [ + "file", + "upload", + "formidable", + "stream", + "s3" + ], + "devDependencies": { + "findit": "0.1.1", + "hashish": "0.0.4", + "mocha": "~1.8.2", + "request": "~2.16.6", + "mkdirp": "~0.3.5", + "superagent": "~0.14.1" + }, + "scripts": { + "test": "ulimit -n 500 && mocha --timeout 4000 --reporter spec --recursive test/test.js" + }, + "engines": { + "node": ">=0.8.0" + }, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.1.9", + "stream-counter": "~0.2.0" + }, + "readme": "[![Build Status](https://travis-ci.org/superjoe30/node-multiparty.png?branch=master)](https://travis-ci.org/superjoe30/node-multiparty)\n# multiparty\n\nParse http requests with content-type `multipart/form-data`, also known as file uploads.\n\nSee also [busboy](https://github.com/mscdex/busboy) - a\n[faster](https://github.com/mscdex/dicer/wiki/Benchmarks) alternative\nwhich may be worth looking into.\n\n### Why the fork?\n\n * This module uses the Node.js v0.10 streams properly, *even in Node.js v0.8*\n * It will not create a temp file for you unless you want it to.\n * Counts bytes and does math to help you figure out the `Content-Length` of\n each part.\n * You can easily stream uploads to s3 with\n [knox](https://github.com/LearnBoost/knox), for [example](examples/s3.js).\n * Less bugs. This code is simpler, has all deprecated functionality removed,\n has cleaner tests, and does not try to do anything beyond multipart stream\n parsing.\n\n## Installation\n\n```\nnpm install multiparty\n```\n\n## Usage\n\n * See [examples](examples).\n\nParse an incoming `multipart/form-data` request.\n\n```js\nvar multiparty = require('multiparty')\n , http = require('http')\n , util = require('util')\n\nhttp.createServer(function(req, res) {\n if (req.url === '/upload' && req.method === 'POST') {\n // parse a file upload\n var form = new multiparty.Form();\n\n form.parse(req, function(err, fields, files) {\n res.writeHead(200, {'content-type': 'text/plain'});\n res.write('received upload:\\n\\n');\n res.end(util.inspect({fields: fields, files: files}));\n });\n\n return;\n }\n\n // show a file upload form\n res.writeHead(200, {'content-type': 'text/html'});\n res.end(\n '
    '+\n '
    '+\n '
    '+\n ''+\n '
    '\n );\n}).listen(8080);\n```\n\n## API\n\n### multiparty.Form\n```js\nvar form = new multiparty.Form(options)\n```\nCreates a new form. Options:\n\n * `encoding` - sets encoding for the incoming form fields. Defaults to `utf8`.\n * `maxFieldSize` - Limits the amount of memory a field (not a file) can\n allocate in bytes. If this value is exceeded, an `error` event is emitted.\n The default size is 2MB.\n * `maxFields` - Limits the number of fields that will be parsed before\n emitting an `error` event. A file counts as a field in this case.\n Defaults to 1000.\n * `autoFields` - Enables `field` events. This is automatically set to `true`\n if you add a `field` listener.\n * `autoFiles` - Enables `file` events. This is automatically set to `true`\n if you add a `file` listener.\n * `uploadDir` - Only relevant when `autoFiles` is `true`. The directory for\n placing file uploads in. You can move them later using `fs.rename()`.\n Defaults to `os.tmpDir()`.\n * `hash` - Only relevant when `autoFiles` is `true`. If you want checksums\n calculated for incoming files, set this to either `sha1` or `md5`.\n Defaults to off.\n\n#### form.parse(request, [cb])\n\nParses an incoming node.js `request` containing form data. If `cb` is\nprovided, `autoFields` and `autoFiles` are set to `true` and all fields and\nfiles are collected and passed to the callback:\n\n```js\nform.parse(req, function(err, fieldsObject, filesObject, fieldsList, filesList) {\n // ...\n});\n```\n\nIt is often convenient to access a field or file by name. In this situation,\nuse `fieldsObject` or `filesObject`. However sometimes, as in the case of a\n`` the multipart stream will contain\nmultiple files of the same input name, and you are interested in all of them.\nIn this case, use `filesList`.\n\nAnother example is when you do not care what the field name of a file is; you\nare merely interested in a single upload. In this case, set `maxFields` to 1\n(assuming no other fields expected besides the file) and use `filesList[0]`.\n\n#### form.bytesReceived\n\nThe amount of bytes received for this form so far.\n\n#### form.bytesExpected\n\nThe expected number of bytes in this form.\n\n### Events\n\n#### 'error' (err)\n\nYou definitely want to handle this event. If not your server *will* crash when\nusers submit bogus multipart requests!\n\n#### 'part' (part)\n\nEmitted when a part is encountered in the request. `part` is a\n`ReadableStream`. It also has the following properties:\n\n * `headers` - the headers for this part. For example, you may be interested\n in `content-type`.\n * `name` - the field name for this part\n * `filename` - only if the part is an incoming file\n * `byteOffset` - the byte offset of this part in the request body\n * `byteCount` - assuming that this is the last part in the request,\n this is the size of this part in bytes. You could use this, for\n example, to set the `Content-Length` header if uploading to S3.\n If the part had a `Content-Length` header then that value is used\n here instead.\n\n#### 'aborted'\n\nEmitted when the request is aborted. This event will be followed shortly\nby an `error` event. In practice you do not need to handle this event.\n\n#### 'progress' (bytesReceived, bytesExpected)\n\n#### 'close'\n\nEmitted after all parts have been parsed and emitted. Not emitted if an `error`\nevent is emitted. This is typically when you would send your response.\n\n#### 'file' (name, file)\n\n**By default multiparty will not touch your hard drive.** But if you add this\nlistener, multiparty automatically sets `form.autoFiles` to `true` and will\nstream uploads to disk for you. \n\n * `name` - the field name for this file\n * `file` - an object with these properties:\n - `fieldName` - same as `name` - the field name for this file\n - `originalFilename` - the filename that the user reports for the file\n - `path` - the absolute path of the uploaded file on disk\n - `headers` - the HTTP headers that were sent along with this file\n - `size` - size of the file in bytes\n\nIf you set the `form.hash` option, then `file` will also contain a `hash`\nproperty which is the checksum of the file.\n\n#### 'field' (name, value)\n\n * `name` - field name\n * `value` - string field value\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/superjoe30/node-multiparty/issues" + }, + "_id": "multiparty@2.2.0", + "_from": "multiparty@2.2.0" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/bench-multipart-parser.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/bench-multipart-parser.js new file mode 100644 index 00000000000..ee5dbad4d29 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/bench-multipart-parser.js @@ -0,0 +1,76 @@ +var assert = require('assert') + , Form = require('../').Form + , boundary = '-----------------------------168072824752491622650073' + , mb = 100 + , buffer = createMultipartBuffer(boundary, mb * 1024 * 1024) + +var callbacks = { + partBegin: -1, + partEnd: -1, + headerField: -1, + headerValue: -1, + partData: -1, + end: -1, +}; + +var form = new Form({ boundary: boundary }); + +hijack('onParseHeaderField', function() { + callbacks.headerField++; +}); + +hijack('onParseHeaderValue', function() { + callbacks.headerValue++; +}); + +hijack('onParsePartBegin', function() { + callbacks.partBegin++; +}); + +hijack('onParsePartData', function() { + callbacks.partData++; +}); + +hijack('onParsePartEnd', function() { + callbacks.partEnd++; +}); + +form.on('finish', function() { + callbacks.end++; +}); + +var start = new Date(); +form.write(buffer, function(err) { + var duration = new Date() - start; + assert.ifError(err); + var mbPerSec = (mb / (duration / 1000)).toFixed(2); + console.log(mbPerSec+' mb/sec'); +}); + +process.on('exit', function() { + for (var k in callbacks) { + assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]); + } +}); + +function createMultipartBuffer(boundary, size) { + var head = + '--'+boundary+'\r\n' + + 'content-disposition: form-data; name="field1"\r\n' + + '\r\n' + , tail = '\r\n--'+boundary+'--\r\n' + , buffer = new Buffer(size); + + buffer.write(head, 'ascii', 0); + buffer.write(tail, 'ascii', buffer.length - tail.length); + return buffer; +} + +function hijack(name, fn) { + var oldFn = form[name]; + form[name] = function() { + fn(); + return oldFn.apply(this, arguments); + }; +} + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/beta-sticker-1.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/beta-sticker-1.png new file mode 100644 index 00000000000..20b1a7f1779 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/beta-sticker-1.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/binaryfile.tar.gz b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/binaryfile.tar.gz new file mode 100644 index 00000000000..4a85af7a1c8 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/binaryfile.tar.gz differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/blank.gif b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/blank.gif new file mode 100644 index 00000000000..75b945d2553 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/blank.gif differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/funkyfilename.txt b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/funkyfilename.txt new file mode 100644 index 00000000000..e7a4785e00c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/funkyfilename.txt @@ -0,0 +1 @@ +I am a text file with a funky name! diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/menu_separator.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/menu_separator.png new file mode 100644 index 00000000000..1c16a71ed41 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/menu_separator.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/pf1y5.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/pf1y5.png new file mode 100644 index 00000000000..44d60175960 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/pf1y5.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/plain.txt b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/plain.txt new file mode 100644 index 00000000000..9b6903e26fc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/file/plain.txt @@ -0,0 +1 @@ +I am a plain text file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/beta-sticker-1.png.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/beta-sticker-1.png.http new file mode 100644 index 00000000000..7bfc6dcca84 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/beta-sticker-1.png.http @@ -0,0 +1,12 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Length: 2483 + +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Disposition: form-data; name="sticker"; filename="beta-sticker-1.png" +Content-Type: image/png +Content-Transfer-Encoding: base64 + +iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABh5JREFUeNrMmHtIHEcYwGfv5SNwaovxEanEiJKqlYCCTRo1f0SvDeof1legEcE/YttQaNOiaQjYFFtpKaJILZU8SCRUWqlJGpoWepGLTXqUEnzFxCrnK9DEelbvvPOe/WacuY7r7HmGFjrwsbNzt7u//V7zfYvQ/2xI/9K1/NyvMP9PgCTuGmmL6/0ckD9UOGmbIExUsqMkAPHJjv5QwKRtgKioqDlh5+w/7IFeCuLlxCeA2zQ0IcCwh2qoaLH09fUdTElJ2e/1elU+n0/y+9fvPz4+fvfYsWN3YOoBcXPiocLghD4mBYHhQTCErqWlZU9FRcXJqKiowyqVSk/uSEH4o8fjWVlYWDB2d3e3d3R0WGB5jYqLg/NyGgsKxMNgkDB4451NTU3vxcXF1SlBKB0tFsuVxsbGjlu3bj2GJQeIk8K5RVBqBTMxrYRfuHAh9/jx4+ejo6MPS9I6f6hHPOC6rOLi4vyVlZXf7t27Z5c5/iZfkgMxxyUwFy9ezC0tLe3V6XRJ/MOCAYjWwsLCni0oKCh98uSJaWhoyMZFn0/uT2qBqYi/1NbWxjc0NJwPFUYExc/B53R5eXk5ZrN5YH5+3slFn5+D2uBDzG90IJETExOtzGdC9RelNf78wYMH3xQWFn4Ep0sgyyCr1NmJP6kEIa5tbW3dEx8fXxeKRoJpT76OR3p6enllZWUKTCOwNalFAglWDkTCvLq6+uR2YYKZSw4GQVKNfZQCafjkqhKYTBsTE3NY/uYi2Q4MP5KTkw9QGB3VEMv6G/YioqFLly5lazQavfytxobnUW+PWTGisIyNPEL3QYLB4PPIyMi4EydO7JUBbTIZ0RDYOFPkE8t/OdHczCK6Y/qdzP8BfUTW8Tj/uQndvT1F5vOzVvTLz1PwX4cQbt++fekURsNpSNLIw16v1z/HLsRRgecsSnovm8nxs5bvUe+NN1Bz47fkfBaAXj2aA2BWEsM/3hhFX1/5Fe3NTEAfvn8NXTO+tSH68IiNjU2Qw/AmCzg2XCQp+YyhJAu9c+pl9GJ+KmhiEt38bhjpoyJQRtYudA60k3dwD6o4mouKjmSiolcy0ArRqnXz3rT+knwFEShhNKLNlmmFP7Kf8XxuehHpj0QQmLdPGch/ioYyCSAe57pMaHnJgcprctDdwUkRjKi8CUTWhipvbm7uvlJo3zFNoHJDOznPeGEXqn+9EBUf+AQZXvqU+BEG/KCpHz2flYh+ALO9++ZX5L/Mj3gfevjw4ZRoP+PzD/b4HadPn844c+aMkb0F1DqIz9byzBvquXytvr6+7vr16+Ow9CfN2njjdfFAWpo9o2FnNmm12kQMw24gcvSnhbHb7Y+huHsNlhapLNHSxK3idlq287qhhrkKlSByOBzIZrPhGyCn04ncbjfRGAMV5ZlQxvDw8E+yYi1Q3qpleYjUQlNTU5aysrJqgNBhIAwGVSDCkFj48BVFULA1eCl7XV3dx1CKYK3YqKnY7u9Ti2royclJ76FDh1YhxefgsoFpCIOtra0RuGBQwYbRaLzc1dVlpjA2ZiqmKbWsDAmEYU9Pz8Tg4OCNoqKixNTU1BQostDq6iqBcrlcRBiYfEff1KBR+OnpabPBYOikWlnhtOOWm0zUffpnZ2ednZ2dJtCYMTs7+xkA2x0eHk6gsMYwFPYr/EC1Wo2LMEWzWa1WC1QRZ8FUVgpj42ohD3umWqHjRFxf5RkZGVkCNQ9CcTWQn5+flpSUtBOiMKAt7Fek/FSAmpmZMVdVVZ0dGxv7g4PhteMVlbBIofv0sh4Lbmhtb2+/Cbv1eFpaWmJCQsJODMO0hGGgUghAAay9v7//i5KSki9lmmG+4+Jg/MHaIH6f0dCkqaNFFc5VkViam5v319TUNEDdvRubEGsNYHGqsAwMDFxta2u7DdpdpA+3c+LgWiHfVkCiFnpDw0iLqwgqO6BVKoPo00K6WIDsOzE6OrpE395FzeLgxMn5jVe0dYTa26s5jfFg4VR0nAuwNtrFda1rgmToD6VzVWq3eTPyYAxOwwH5gvT2PiWY7X4fUgJTywp1fivyyL6E+Lb6XvQ0X9AkBeeXZED+p/k+9LcAAwAXm3hBLzoZPAAAAABJRU5ErkJggg== +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/binaryfile.tar.gz.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/binaryfile.tar.gz.http new file mode 100644 index 00000000000..28b1d0e69a2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/binaryfile.tar.gz.http @@ -0,0 +1,12 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Length: 676 + +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Disposition: form-data; name="file"; filename="binaryfile.tar.gz" +Content-Type: application/x-gzip +Content-Transfer-Encoding: base64 + +H4sIAGiNIU8AA+3R0W6CMBQGYK59iobLZantRDG73osUOGqnFNJWM2N897UghG1ZdmWWLf93U/jP4bRAq8q92hJ/dY1J7kQEqyyLq8yXYrp2ltkqkTKXYiEykYc++ZTLVcLEvQ40dXReWcYSV1pdnL/v+6n+R11mjKVG1ZQ+s3TT2FpXqjhQ+hjzE1mnGxNLkgu+7tOKWjIVmVKTC6XL9ZaeXj4VQhwKWzL+cI4zwgQuuhkh3mhTad/Hkssh3im3027X54JnQ360R/M19OT8kC7SEN7Ooi2VvrEfznHQRWzl83gxttZKmzGehzPRW/+W8X+3fvL8sFet9sS6m3EIma02071MU3Uf9KHrmV1/+y8DAAAAAAAAAAAAAAAAAAAAAMB/9A6txIuJACgAAA== +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/blank.gif.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/blank.gif.http new file mode 100644 index 00000000000..cf54956dc2b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/blank.gif.http @@ -0,0 +1,12 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Length: 323 + +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Disposition: form-data; name="file"; filename="blank.gif" +Content-Type: image/gif +Content-Transfer-Encoding: base64 + +R0lGODlhAQABAJH/AP///wAAAMDAwAAAACH5BAEAAAIALAAAAAABAAEAAAICVAEAOw== +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/menu_seperator.png.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/menu_seperator.png.http new file mode 100644 index 00000000000..3fd5085e769 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/menu_seperator.png.http @@ -0,0 +1,12 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Length: 1509 + +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +Content-Disposition: form-data; name="image"; filename="menu_separator.png" +Content-Type: image/png +Content-Transfer-Encoding: base64 + +iVBORw0KGgoAAAANSUhEUgAAAAIAAAAYCAIAAABfmbuOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDcxODNBNzJERDcyMTFFMUFBOEVFNDQzOTA0MDJDMjQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDcxODNBNzNERDcyMTFFMUFBOEVFNDQzOTA0MDJDMjQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNzE4M0E3MERENzIxMUUxQUE4RUU0NDM5MDQwMkMyNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowNzE4M0E3MURENzIxMUUxQUE4RUU0NDM5MDQwMkMyNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pmvhbb8AAAAXSURBVHjaYnHk9PON8WJiAIPBSwEEGAAPrgG+VozFWgAAAABJRU5ErkJggg== +--\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/pf1y5.png.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/pf1y5.png.http new file mode 100644 index 00000000000..20c2c2dfcb8 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/pf1y5.png.http differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/plain.txt.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/plain.txt.http new file mode 100644 index 00000000000..230b2054e3f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/encoding/plain.txt.http @@ -0,0 +1,13 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=----TLV0SrKD4z1TRxRhAPUvZ +Content-Length: 221 + +------TLV0SrKD4z1TRxRhAPUvZ +Content-Disposition: form-data; name="file"; filename="plain.txt" +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +I am a plain text file + +------TLV0SrKD4z1TRxRhAPUvZ-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/no-filename/filename-name.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/no-filename/filename-name.http new file mode 100644 index 00000000000..e449156bd9a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/no-filename/filename-name.http @@ -0,0 +1,13 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytyE4wkKlZ5CQJVTG +Content-Length: 1000 + +------WebKitFormBoundarytyE4wkKlZ5CQJVTG +Content-Disposition: form-data; filename="plain.txt"; name="upload" +Content-Type: text/plain + +I am a plain text file + +------WebKitFormBoundarytyE4wkKlZ5CQJVTG-- + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/no-filename/generic.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/no-filename/generic.http new file mode 100644 index 00000000000..c051d852cb2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/no-filename/generic.http @@ -0,0 +1,13 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytyE4wkKlZ5CQJVTG +Content-Length: 1000 + +------WebKitFormBoundarytyE4wkKlZ5CQJVTG +Content-Disposition: form-data; name="upload"; filename="" +Content-Type: text/plain + +I am a plain text file + +------WebKitFormBoundarytyE4wkKlZ5CQJVTG-- + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/preamble/crlf.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/preamble/crlf.http new file mode 100644 index 00000000000..1357950a8e3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/preamble/crlf.http @@ -0,0 +1,13 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=----TLV0SrKD4z1TRxRhAPUvZ +Content-Length: 184 + + +------TLV0SrKD4z1TRxRhAPUvZ +Content-Disposition: form-data; name="upload"; filename="plain.txt" +Content-Type: text/plain + +I am a plain text file + +------TLV0SrKD4z1TRxRhAPUvZ-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/preamble/preamble.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/preamble/preamble.http new file mode 100644 index 00000000000..ab490a36003 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/preamble/preamble.http @@ -0,0 +1,13 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=----TLV0SrKD4z1TRxRhAPUvZ +Content-Length: 226 + +This is a preamble which should be ignored +------TLV0SrKD4z1TRxRhAPUvZ +Content-Disposition: form-data; name="upload"; filename="plain.txt" +Content-Type: text/plain + +I am a plain text file + +------TLV0SrKD4z1TRxRhAPUvZ-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/info.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/info.md new file mode 100644 index 00000000000..3c9dbe3dd07 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/info.md @@ -0,0 +1,3 @@ +* Opera does not allow submitting this file, it shows a warning to the + user that the file could not be found instead. Tested in 9.8, 11.51 on OSX. + Reported to Opera on 08.09.2011 (tracking email DSK-346009@bugs.opera.com). diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-chrome-13.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-chrome-13.http new file mode 100644 index 00000000000..6dec0d38cf5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-chrome-13.http @@ -0,0 +1,26 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Connection: keep-alive +Referer: http://localhost:8080/ +Content-Length: 383 +Cache-Control: max-age=0 +Origin: http://localhost:8080 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytyE4wkKlZ5CQJVTG +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Encoding: gzip,deflate,sdch +Accept-Language: en-US,en;q=0.8 +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 +Cookie: jqCookieJar_tablesorter=%7B%22showListTable%22%3A%5B%5B5%2C1%5D%2C%5B1%2C0%5D%5D%7D + +------WebKitFormBoundarytyE4wkKlZ5CQJVTG +Content-Disposition: form-data; name="title" + +Weird filename +------WebKitFormBoundarytyE4wkKlZ5CQJVTG +Content-Disposition: form-data; name="upload"; filename=": \ ? % * | %22 < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt" +Content-Type: text/plain + +I am a text file with a funky name! + +------WebKitFormBoundarytyE4wkKlZ5CQJVTG-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http new file mode 100644 index 00000000000..76ff2b34abc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http @@ -0,0 +1,24 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.22) Gecko/20110902 Firefox/3.6.22 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-us,en;q=0.5 +Accept-Encoding: gzip,deflate +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 +Keep-Alive: 115 +Connection: keep-alive +Referer: http://localhost:8080/ +Content-Type: multipart/form-data; boundary=---------------------------9849436581144108930470211272 +Content-Length: 438 + +-----------------------------9849436581144108930470211272 +Content-Disposition: form-data; name="title" + +Weird filename +-----------------------------9849436581144108930470211272 +Content-Disposition: form-data; name="upload"; filename=": \ ? % * | " < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt" +Content-Type: text/plain + +I am a text file with a funky name! + +-----------------------------9849436581144108930470211272-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-safari-5.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-safari-5.http new file mode 100644 index 00000000000..b3652d90e64 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/osx-safari-5.http @@ -0,0 +1,23 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Origin: http://localhost:8080 +Content-Length: 383 +User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQJZ1gvhvdgfisJPJ +Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 +Referer: http://localhost:8080/ +Accept-Language: en-us +Accept-Encoding: gzip, deflate +Connection: keep-alive + +------WebKitFormBoundaryQJZ1gvhvdgfisJPJ +Content-Disposition: form-data; name="title" + +Weird filename +------WebKitFormBoundaryQJZ1gvhvdgfisJPJ +Content-Disposition: form-data; name="upload"; filename=": \ ? % * | %22 < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt" +Content-Type: text/plain + +I am a text file with a funky name! + +------WebKitFormBoundaryQJZ1gvhvdgfisJPJ-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-chrome-12.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-chrome-12.http new file mode 100644 index 00000000000..ef8d1d6028c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-chrome-12.http @@ -0,0 +1,24 @@ +POST /upload HTTP/1.1 +Host: 192.168.56.1:8080 +Connection: keep-alive +Referer: http://192.168.56.1:8080/ +Content-Length: 344 +Cache-Control: max-age=0 +Origin: http://192.168.56.1:8080 +User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryEvqBNplR3ByrwQPa +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Encoding: gzip,deflate,sdch +Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4 +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 + +------WebKitFormBoundaryEvqBNplR3ByrwQPa +Content-Disposition: form-data; name="title" + +Weird filename +------WebKitFormBoundaryEvqBNplR3ByrwQPa +Content-Disposition: form-data; name="upload"; filename=" ? % * | %22 < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt" +Content-Type: text/plain + + +------WebKitFormBoundaryEvqBNplR3ByrwQPa-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-ie-7.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-ie-7.http new file mode 100644 index 00000000000..4befdc71199 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-ie-7.http @@ -0,0 +1,22 @@ +POST /upload HTTP/1.1 +Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */* +Referer: http://192.168.56.1:8080/ +Accept-Language: de +User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1) +Content-Type: multipart/form-data; boundary=---------------------------7db1fe232017c +Accept-Encoding: gzip, deflate +Host: 192.168.56.1:8080 +Content-Length: 368 +Connection: Keep-Alive +Cache-Control: no-cache + +-----------------------------7db1fe232017c +Content-Disposition: form-data; name="title" + +Weird filename +-----------------------------7db1fe232017c +Content-Disposition: form-data; name="upload"; filename=" ? % * | " < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt" +Content-Type: application/octet-stream + + +-----------------------------7db1fe232017c-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-ie-8.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-ie-8.http new file mode 100644 index 00000000000..9c1c53305de --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-ie-8.http @@ -0,0 +1,22 @@ +POST /upload HTTP/1.1 +Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */* +Referer: http://192.168.56.1:8080/ +Accept-Language: de +User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0) +Content-Type: multipart/form-data; boundary=---------------------------7db3a8372017c +Accept-Encoding: gzip, deflate +Host: 192.168.56.1:8080 +Content-Length: 368 +Connection: Keep-Alive +Cache-Control: no-cache + +-----------------------------7db3a8372017c +Content-Disposition: form-data; name="title" + +Weird filename +-----------------------------7db3a8372017c +Content-Disposition: form-data; name="upload"; filename=" ? % * | " < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt" +Content-Type: application/octet-stream + + +-----------------------------7db3a8372017c-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-safari-5.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-safari-5.http new file mode 100644 index 00000000000..2b7bacb52ff --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/special-chars-in-filename/xp-safari-5.http @@ -0,0 +1,22 @@ +POST /upload HTTP/1.1 +Host: 192.168.56.1:8080 +Referer: http://192.168.56.1:8080/ +Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 +Accept-Language: en-US +Origin: http://192.168.56.1:8080 +User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4 +Accept-Encoding: gzip, deflate +Content-Type: multipart/form-data; boundary=----WebKitFormBoundarykmaWSUbu697WN9TM +Content-Length: 344 +Connection: keep-alive + +------WebKitFormBoundarykmaWSUbu697WN9TM +Content-Disposition: form-data; name="title" + +Weird filename +------WebKitFormBoundarykmaWSUbu697WN9TM +Content-Disposition: form-data; name="upload"; filename=" ? % * | %22 < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt" +Content-Type: text/plain + + +------WebKitFormBoundarykmaWSUbu697WN9TM-- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/workarounds/missing-hyphens1.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/workarounds/missing-hyphens1.http new file mode 100644 index 00000000000..31ea39594fa --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/workarounds/missing-hyphens1.http @@ -0,0 +1,12 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=----TLV0SrKD4z1TRxRhAPUvZ +Content-Length: 178 + +------TLV0SrKD4z1TRxRhAPUvZ +Content-Disposition: form-data; name="upload"; filename="plain.txt" +Content-Type: text/plain + +I am a plain text file + +------TLV0SrKD4z1TRxRhAPUvZ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/workarounds/missing-hyphens2.http b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/workarounds/missing-hyphens2.http new file mode 100644 index 00000000000..515f519c213 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/http/workarounds/missing-hyphens2.http @@ -0,0 +1,12 @@ +POST /upload HTTP/1.1 +Host: localhost:8080 +Content-Type: multipart/form-data; boundary=----TLV0SrKD4z1TRxRhAPUvZ +Content-Length: 180 + +------TLV0SrKD4z1TRxRhAPUvZ +Content-Disposition: form-data; name="upload"; filename="plain.txt" +Content-Type: text/plain + +I am a plain text file + +------TLV0SrKD4z1TRxRhAPUvZ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/encoding.js new file mode 100644 index 00000000000..1ade96568a7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/encoding.js @@ -0,0 +1,69 @@ +module.exports['menu_seperator.png.http'] = [ + { + type: 'file', + name: 'image', + filename: 'menu_separator.png', + fixture: 'menu_separator.png', + sha1: 'c845ca3ea794be298f2a1b79769b71939eaf4e54', + size: 931, + } +]; + +module.exports['beta-sticker-1.png.http'] = [ + { + type: 'file', + name: 'sticker', + filename: 'beta-sticker-1.png', + fixture: 'beta-sticker-1.png', + sha1: '6abbcffd12b4ada5a6a084fe9e4584f846331bc4', + size: 1660, + } +]; + +module.exports['blank.gif.http'] = [ + { + type: 'file', + name: 'file', + filename: 'blank.gif', + fixture: 'blank.gif', + sha1: 'a1fdee122b95748d81cee426d717c05b5174fe96', + size: 49, + } +]; + +module.exports['binaryfile.tar.gz.http'] = [ + { + type: 'file', + name: 'file', + filename: 'binaryfile.tar.gz', + fixture: 'binaryfile.tar.gz', + sha1: 'cfabe13b348e5e69287d677860880c52a69d2155', + size: 301, + } +]; + +module.exports['plain.txt.http'] = [ + { + type: 'file', + name: 'file', + filename: 'plain.txt', + fixture: 'plain.txt', + sha1: 'b31d07bac24ac32734de88b3687dddb10e976872', + size: 23, + } +]; + +module.exports['pf1y5.png.http'] = [ + { + type: 'field', + name: 'path', + }, + { + type: 'file', + name: 'upload', + filename: 'pf1y5.png', + fixture: 'pf1y5.png', + sha1: '805cc640c5b182e86f2b5c8ebf34ecf063cd34fd', + size: 768323, + } +]; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/no-filename.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/no-filename.js new file mode 100644 index 00000000000..f03b4f01d80 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/no-filename.js @@ -0,0 +1,9 @@ +module.exports['generic.http'] = [ + {type: 'file', name: 'upload', filename: '', fixture: 'plain.txt', + sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, +]; + +module.exports['filename-name.http'] = [ + {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', + sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, +]; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/preamble.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/preamble.js new file mode 100644 index 00000000000..d2e4cfdb24d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/preamble.js @@ -0,0 +1,9 @@ +module.exports['crlf.http'] = [ + {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', + sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, +]; + +module.exports['preamble.http'] = [ + {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', + sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, +]; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/special-chars-in-filename.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/special-chars-in-filename.js new file mode 100644 index 00000000000..aa0b79f3401 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/special-chars-in-filename.js @@ -0,0 +1,30 @@ +var properFilename = 'funkyfilename.txt'; + +function expect(filename) { + return [ + { + type: 'field', + name: 'title', + value: 'Weird filename', + }, + { + type: 'file', + name: 'upload', + filename: filename, + fixture: properFilename, + }, + ]; +} + +var webkit = " ? % * | \" < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; +var ffOrIe = " ? % * | \" < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; + +module.exports = { + 'osx-chrome-13.http' : expect(webkit), + 'osx-firefox-3.6.http' : expect(ffOrIe), + 'osx-safari-5.http' : expect(webkit), + 'xp-chrome-12.http' : expect(webkit), + 'xp-ie-7.http' : expect(ffOrIe), + 'xp-ie-8.http' : expect(ffOrIe), + 'xp-safari-5.http' : expect(webkit), +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/workarounds.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/workarounds.js new file mode 100644 index 00000000000..e59c5b265d7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/js/workarounds.js @@ -0,0 +1,8 @@ +module.exports['missing-hyphens1.http'] = [ + {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', + sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, +]; +module.exports['missing-hyphens2.http'] = [ + {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', + sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, +]; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/multi_video.upload b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/multi_video.upload new file mode 100644 index 00000000000..9c82ba3661f Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/multi_video.upload differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/multipart.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/multipart.js new file mode 100644 index 00000000000..a4761699e9c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/fixture/multipart.js @@ -0,0 +1,72 @@ +exports['rfc1867'] = + { boundary: 'AaB03x', + raw: + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="field1"\r\n'+ + '\r\n'+ + 'Joe Blow\r\nalmost tricked you!\r\n'+ + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ + 'Content-Type: text/plain\r\n'+ + '\r\n'+ + '... contents of file1.txt ...\r\r\n'+ + '--AaB03x--\r\n', + parts: + [ { headers: { + 'content-disposition': 'form-data; name="field1"', + }, + data: 'Joe Blow\r\nalmost tricked you!', + }, + { headers: { + 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', + 'Content-Type': 'text/plain', + }, + data: '... contents of file1.txt ...\r', + } + ] + }; + +exports['noTrailing\r\n'] = + { boundary: 'AaB03x', + raw: + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="field1"\r\n'+ + '\r\n'+ + 'Joe Blow\r\nalmost tricked you!\r\n'+ + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ + 'Content-Type: text/plain\r\n'+ + '\r\n'+ + '... contents of file1.txt ...\r\r\n'+ + '--AaB03x--', + parts: + [ { headers: { + 'content-disposition': 'form-data; name="field1"', + }, + data: 'Joe Blow\r\nalmost tricked you!', + }, + { headers: { + 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', + 'Content-Type': 'text/plain', + }, + data: '... contents of file1.txt ...\r', + } + ] + }; + +exports['emptyHeader'] = + { boundary: 'AaB03x', + raw: + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="field1"\r\n'+ + ': foo\r\n'+ + '\r\n'+ + 'Joe Blow\r\nalmost tricked you!\r\n'+ + '--AaB03x\r\n'+ + 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ + 'Content-Type: text/plain\r\n'+ + '\r\n'+ + '... contents of file1.txt ...\r\r\n'+ + '--AaB03x--\r\n', + expectError: true, + }; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/record.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/record.js new file mode 100644 index 00000000000..9f1cef86fad --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/record.js @@ -0,0 +1,47 @@ +var http = require('http'); +var fs = require('fs'); +var connections = 0; + +var server = http.createServer(function(req, res) { + var socket = req.socket; + console.log('Request: %s %s -> %s', req.method, req.url, socket.filename); + + req.on('end', function() { + if (req.url !== '/') { + res.end(JSON.stringify({ + method: req.method, + url: req.url, + filename: socket.filename, + })); + return; + } + + res.writeHead(200, {'content-type': 'text/html'}); + res.end( + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    ' + ); + }); +}); + +server.on('connection', function(socket) { + connections++; + + socket.id = connections; + socket.filename = 'connection-' + socket.id + '.http'; + socket.file = fs.createWriteStream(socket.filename); + socket.pipe(socket.file); + + console.log('--> %s', socket.filename); + socket.on('close', function() { + console.log('<-- %s', socket.filename); + }); +}); + +var port = process.env.PORT || 8080; +server.listen(port, function() { + console.log('Recording connections on port %s', port); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-connection-aborted.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-connection-aborted.js new file mode 100644 index 00000000000..bd83e1d6bdc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-connection-aborted.js @@ -0,0 +1,27 @@ +var assert = require('assert'); +var http = require('http'); +var net = require('net'); +var multiparty = require('../../'); + +var server = http.createServer(function (req, res) { + var form = new multiparty.Form(); + var aborted_received = false; + form.on('aborted', function () { + aborted_received = true; + }); + form.on('error', function () { + assert(aborted_received, 'Error event should follow aborted'); + server.close(); + }); + form.on('end', function () { + throw new Error('Unexpected "end" event'); + }); + form.parse(req); +}).listen(0, 'localhost', function () { + var client = net.connect(server.address().port); + client.write( + "POST / HTTP/1.1\r\n" + + "Content-Length: 70\r\n" + + "Content-Type: multipart/form-data; boundary=foo\r\n\r\n"); + client.end(); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-content-transfer-encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-content-transfer-encoding.js new file mode 100644 index 00000000000..35e5a1f848c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-content-transfer-encoding.js @@ -0,0 +1,52 @@ +var assert = require('assert') + , multiparty = require('../../') + , http = require('http') + , path = require('path') + , TMP_PATH = path.join(__dirname, '..', 'tmp') + +var server = http.createServer(function(req, res) { + var form = new multiparty.Form(); + form.uploadDir = TMP_PATH; + form.on('close', function () { + throw new Error('Unexpected "close" event'); + }); + form.on('end', function () { + throw new Error('Unexpected "end" event'); + }); + form.on('error', function (e) { + res.writeHead(500); + res.end(e.message); + }); + form.parse(req); +}); + +server.listen(0, function() { + var body = + '--foo\r\n' + + 'Content-Disposition: form-data; name="file1"; filename="file1"\r\n' + + 'Content-Type: application/octet-stream\r\n' + + '\r\nThis is the first file\r\n' + + '--foo\r\n' + + 'Content-Type: application/octet-stream\r\n' + + 'Content-Disposition: form-data; name="file2"; filename="file2"\r\n' + + 'Content-Transfer-Encoding: unknown\r\n' + + '\r\nThis is the second file\r\n' + + '--foo--\r\n'; + + var req = http.request({ + method: 'POST', + port: server.address().port, + headers: { + 'Content-Length': body.length, + 'Content-Type': 'multipart/form-data; boundary=foo' + } + }); + req.on('response', function (res) { + assert.equal(res.statusCode, 500); + res.on('data', function () {}); + res.on('end', function () { + server.close(); + }); + }); + req.end(body); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-invalid.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-invalid.js new file mode 100644 index 00000000000..ede541da517 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-invalid.js @@ -0,0 +1,35 @@ +var superagent = require('superagent') + , multiparty = require('../../') + , http = require('http') + +var server = http.createServer(function(req, resp) { + var form = new multiparty.Form(); + + var errCount = 0; + form.on('error', function(err) { + errCount += 1; + resp.end(); + }); + form.on('file', function(name, file) { + }); + form.on('field', function(name, file) { + }); + + form.parse(req); +}); +server.listen(function() { + var url = 'http://localhost:' + server.address().port + '/' + var req = superagent.post(url) + req.set('Content-Type', 'multipart/form-data; boundary=foo') + req.write('--foo\r\n') + req.write('Content-filename="foo.txt"\r\n') + req.write('\r\n') + req.write('some text here') + req.write('Content-Disposition: form-data; name="text"; filename="bar.txt"\r\n') + req.write('\r\n') + req.write('some more text stuff') + req.write('\r\n--foo--') + req.end(function(err, resp) { + server.close(); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-15.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-15.js new file mode 100644 index 00000000000..43982fa7abc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-15.js @@ -0,0 +1,88 @@ +var http = require('http') + , multiparty = require('../../') + , assert = require('assert') + , superagent = require('superagent') + , path = require('path') + +var server = http.createServer(function(req, res) { + assert.strictEqual(req.url, '/upload'); + assert.strictEqual(req.method, 'POST'); + + var form = new multiparty.Form({autoFields:true,autoFiles:true}); + + form.on('error', function(err) { + console.log(err); + }); + + form.on('close', function() { + }); + + var fileCount = 0; + form.on('file', function(name, file) { + fileCount += 1; + }); + + form.parse(req, function(err, fields, files) { + var objFileCount = 0; + for (var file in files) { + objFileCount += 1; + } + // multiparty does NOT try to do intelligent things based on + // the part name. + assert.strictEqual(fileCount, 2); + assert.strictEqual(objFileCount, 1); + res.end(); + }); +}); +server.listen(function() { + var url = 'http://localhost:' + server.address().port + '/upload'; + var req = superagent.post(url); + req.attach('files[]', fixture('pf1y5.png'), 'SOG2.JPG'); + req.attach('files[]', fixture('binaryfile.tar.gz'), 'BenF364_LIB353.zip'); + + // Get the existing boundary. + var contentType = req.get('content-type'); + var split = contentType.split(' '); + + // Set the content-type. + req.set('content-type', split.join('')); + + req.end(function(err, resp) { + assert.ifError(err); + resp.on('end', function() { + server.close(); + }); + }); + + // No space. + createRequest(''); + + // Single space. + createRequest(' '); + + // Multiple spaces. + createRequest(' '); +}); + +function createRequest(separator) { + var url = 'http://localhost:' + server.address().port + '/upload'; + var req = superagent.post(url); + req.attach('files[]', fixture('pf1y5.png'), 'SOG2.JPG'); + req.attach('files[]', fixture('binaryfile.tar.gz'), 'BenF364_LIB353.zip'); + + // Get the existing boundary. + var contentType = req.get('content-type'); + var split = contentType.split(' '); + + // Set the content-type. + req.set('content-type', split.join(separator)); + + req.end(function(err, resp) { + assert.ifError(err); + // We don't close the server, to allow other requests to pass. + }); +} + +function fixture(name) { + return path.join(__dirname, '..', 'fixture', 'file', name) +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-19.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-19.js new file mode 100644 index 00000000000..d7da0cfb4da --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-19.js @@ -0,0 +1,44 @@ +var assert = require('assert'); +var http = require('http'); +var net = require('net'); +var multiparty = require('../../'); + +var client; +var server = http.createServer(function (req, res) { + var form = new multiparty.Form({maxFields: 1}); + form.on('aborted', function () { + throw new Error("did not expect aborted"); + }); + var first = true; + form.on('error', function (err) { + assert.ok(first); + first = false; + client.end(); + assert.ok(/maxFields/.test(err.message)); + server.close(); + }); + form.on('end', function () { + throw new Error('Unexpected "end" event'); + }); + form.parse(req); +}); +server.listen(function() { + client = net.connect(server.address().port); + + client.write("POST /upload HTTP/1.1\r\n" + + "Content-Length: 728\r\n" + + "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "Content-Disposition: form-data; name=\"title\"\r\n" + + "\r\n" + + "foofoo" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "Content-Disposition: form-data; name=\"upload\"; filename=\"blah1.txt\"\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "hi1\r\n" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n"); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-21.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-21.js new file mode 100644 index 00000000000..155fba05045 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-21.js @@ -0,0 +1,66 @@ +var assert = require('assert'); +var http = require('http'); +var net = require('net'); +var multiparty = require('../../'); + +var client; +var server = http.createServer(function(req, res) { + var form = new multiparty.Form(); + + form.parse(req, function(err, fieldsTable, filesTable, fieldsList, filesList) { + if (err) { + console.error(err.stack); + return; + } + assert.strictEqual(fieldsList.length, 1); + assert.strictEqual(fieldsList[0].name, "title"); + assert.strictEqual(fieldsList[0].value, "foofoo"); + assert.strictEqual(filesList.length, 4); + assert.strictEqual(filesList[0].fieldName, "upload"); + assert.strictEqual(filesList[1].fieldName, "upload"); + assert.strictEqual(filesList[2].fieldName, "upload"); + assert.strictEqual(filesList[3].fieldName, "upload"); + res.end(); + client.end(); + server.close(); + }); +}); +server.listen(function() { + client = net.connect(server.address().port); + + client.write("POST /upload HTTP/1.1\r\n" + + "Content-Length: 728\r\n" + + "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "Content-Disposition: form-data; name=\"title\"\r\n" + + "\r\n" + + "foofoo" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "Content-Disposition: form-data; name=\"upload\"; filename=\"blah1.txt\"\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "hi1\r\n" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "Content-Disposition: form-data; name=\"upload\"; filename=\"blah2.txt\"\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "hi2\r\n" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "Content-Disposition: form-data; name=\"upload\"; filename=\"blah3.txt\"\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "hi3\r\n" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "Content-Disposition: form-data; name=\"upload\"; filename=\"blah4.txt\"\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "hi4\r\n" + + "\r\n" + + "------WebKitFormBoundaryvfUZhxgsZDO7FXLF--\r\n" + ); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-4.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-4.js new file mode 100644 index 00000000000..66b2a69002e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-4.js @@ -0,0 +1,51 @@ +var http = require('http') + , multiparty = require('../../') + , assert = require('assert') + , superagent = require('superagent') + , path = require('path') + +var server = http.createServer(function(req, res) { + assert.strictEqual(req.url, '/upload'); + assert.strictEqual(req.method, 'POST'); + + var form = new multiparty.Form({autoFields:true,autoFiles:true}); + + form.on('error', function(err) { + console.log(err); + }); + + form.on('close', function() { + }); + + var fileCount = 0; + form.on('file', function(name, file) { + fileCount += 1; + }); + + form.parse(req, function(err, fields, files) { + var objFileCount = 0; + for (var file in files) { + objFileCount += 1; + } + // multiparty does NOT try to do intelligent things based on + // the part name. + assert.strictEqual(fileCount, 2); + assert.strictEqual(objFileCount, 1); + res.end(); + }); +}); +server.listen(function() { + var url = 'http://localhost:' + server.address().port + '/upload'; + var req = superagent.post(url); + req.attach('files[]', fixture('pf1y5.png'), 'SOG2.JPG'); + req.attach('files[]', fixture('binaryfile.tar.gz'), 'BenF364_LIB353.zip'); + req.end(function(err, resp) { + assert.ifError(err); + resp.on('end', function() { + server.close(); + }); + }); +}); +function fixture(name) { + return path.join(__dirname, '..', 'fixture', 'file', name) +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-46.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-46.js new file mode 100644 index 00000000000..676b87094a3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-46.js @@ -0,0 +1,49 @@ +var http = require('http'), + multiparty = require('../../'), + request = require('request'), + assert = require('assert'); + +var host = 'localhost'; + +var index = [ + '
    ', + ' ', + ' ', + '
    ' +].join("\n"); + +var server = http.createServer(function(req, res) { + + // Show a form for testing purposes. + if (req.method === 'GET') { + res.writeHead(200, {'content-type': 'text/html'}); + res.end(index); + return; + } + + // Parse form and write results to response. + var form = new multiparty.Form(); + form.parse(req, function(err, fields, files) { + res.writeHead(200, {'content-type': 'text/plain'}); + res.write(JSON.stringify({err: err, fields: fields, files: files})); + res.end(); + }); + +}).listen(0, host, function() { + + //console.log("Server up and running..."); + + var server = this, + url = 'http://' + host + ':' + server.address().port; + + var parts = [ + {'Content-Disposition': 'form-data; name="foo"', 'body': 'bar'} + ] + + var req = request({method: 'POST', url: url, multipart: parts}, function(e, res, body) { + var obj = JSON.parse(body); + assert.equal("bar", obj.fields.foo); + server.close(); + }); + +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-5.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-5.js new file mode 100644 index 00000000000..80eadf20dce --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/standalone/test-issue-5.js @@ -0,0 +1,39 @@ +var assert = require('assert'); +var http = require('http'); +var net = require('net'); +var multiparty = require('../../'); + +var client; +var attachmentCount = 510; +var server = http.createServer(function(req, res) { + var form = new multiparty.Form({maxFields: 10000}); + + form.parse(req, function(err, fieldsTable, filesTable, fieldsList, filesList) { + assert.strictEqual(err.code, "EMFILE"); + res.end(); + client.end(); + server.close(); + }); +}); +server.listen(function() { + client = net.connect(server.address().port); + + var boundary = "------WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n"; + var oneAttachment = boundary + + "Content-Disposition: form-data; name=\"upload\"; filename=\"blah1.txt\"\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "hi1\r\n" + + "\r\n"; + var payloadSize = oneAttachment.length * attachmentCount + boundary.length; + + client.write("POST /upload HTTP/1.1\r\n" + + "Content-Length: " + payloadSize + "\r\n" + + "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvfUZhxgsZDO7FXLF\r\n" + + "\r\n"); + + for (var i = 0; i < attachmentCount; i += 1) { + client.write(oneAttachment); + } + client.write(boundary); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/test.js new file mode 100644 index 00000000000..199d5cddc4a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/multiparty/test/test.js @@ -0,0 +1,117 @@ +var spawn = require('child_process').spawn + , findit = require('findit') + , path = require('path') + , hashish = require('hashish') + , fs = require('fs') + , http = require('http') + , net = require('net') + , assert = require('assert') + , multiparty = require('../') + , mkdirp = require('mkdirp') + , STANDALONE_PATH = path.join(__dirname, 'standalone') + , server = http.createServer() + , PORT = 13532 + , FIXTURE_PATH = path.join(__dirname, 'fixture') + , TMP_PATH = path.join(__dirname, 'tmp') + +mkdirp.sync(TMP_PATH); + +describe("fixtures", function() { + before(function(done) { + server.listen(PORT, done); + }); + var fixtures = []; + findit + .sync(path.join(FIXTURE_PATH, 'js')) + .forEach(function(jsPath) { + if (!/\.js$/.test(jsPath)) return; + var group = path.basename(jsPath, '.js'); + hashish.forEach(require(jsPath), function(fixture, name) { + it(group + '/' + name, createTest({ + name : group + '/' + name, + fixture : fixture, + })); + }); + }); +}); + +describe("standalone", function() { + findit + .sync(STANDALONE_PATH) + .forEach(function(jsPath) { + if (!/\.js$/.test(jsPath)) return; + it(path.basename(jsPath, '.js'), function(done) { + var child = spawn(process.execPath, [jsPath], { stdio: 'inherit' }); + child.on('error', function(err) { + done(err); + }); + child.on('exit', function(code) { + if (code) return done(new Error("exited with code " + code)); + done(); + }); + }); + }); +}); + +function createTest(fixture) { + var name = fixture.name; + fixture = fixture.fixture; + return function(done) { + uploadFixture(name, function(err, parts) { + if (err) return done(err); + fixture.forEach(function(expectedPart, i) { + var parsedPart = parts[i]; + assert.equal(parsedPart.type, expectedPart.type); + assert.equal(parsedPart.name, expectedPart.name); + + if (parsedPart.type === 'file') { + var file = parsedPart.value; + assert.equal(file.originalFilename, expectedPart.filename); + if(expectedPart.sha1) assert.strictEqual(file.hash, expectedPart.sha1); + if(expectedPart.size) assert.strictEqual(file.size, expectedPart.size); + } + }); + done(); + }); + }; + +} + +function uploadFixture(name, cb) { + server.once('request', function(req, res) { + var parts = []; + var form = new multiparty.Form({ + autoFields: true, + autoFiles: true, + }); + form.uploadDir = TMP_PATH; + form.hash = "sha1"; + + form.on('error', callback); + form.on('file', function(name, value) { + parts.push({type: 'file', name: name, value: value}); + }); + form.on('field', function(name, value) { + parts.push({type: 'field', name: name, value: value}); + }); + form.on('close', function() { + res.end('OK'); + callback(null, parts); + }); + form.parse(req); + + function callback() { + var realCallback = cb; + cb = function() {}; + realCallback.apply(null, arguments); + } + }); + + var socket = net.createConnection(PORT); + var file = fs.createReadStream(FIXTURE_PATH + '/http/' + name); + + file.pipe(socket, {end: false}); + socket.on('data', function () { + socket.end(); + }); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/.npmignore new file mode 100644 index 00000000000..f1250e584c9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/History.md new file mode 100644 index 00000000000..c8aa68fa881 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/History.md @@ -0,0 +1,5 @@ + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/Makefile new file mode 100644 index 00000000000..4e9c8d36ebc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/Makefile @@ -0,0 +1,7 @@ + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter spec + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/Readme.md new file mode 100644 index 00000000000..1cdd68a2a83 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/Readme.md @@ -0,0 +1,29 @@ + +# pause + + Pause streams... + +## License + +(The MIT License) + +Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/index.js new file mode 100644 index 00000000000..1b7b37948c1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/index.js @@ -0,0 +1,29 @@ + +module.exports = function(obj){ + var onData + , onEnd + , events = []; + + // buffer data + obj.on('data', onData = function(data, encoding){ + events.push(['data', data, encoding]); + }); + + // buffer end + obj.on('end', onEnd = function(data, encoding){ + events.push(['end', data, encoding]); + }); + + return { + end: function(){ + obj.removeListener('data', onData); + obj.removeListener('end', onEnd); + }, + resume: function(){ + this.end(); + for (var i = 0, len = events.length; i < len; ++i) { + obj.emit.apply(obj, events[i]); + } + } + }; +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/package.json new file mode 100644 index 00000000000..9296b245af2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/pause/package.json @@ -0,0 +1,24 @@ +{ + "name": "pause", + "version": "0.0.1", + "description": "Pause streams...", + "keywords": [], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "main": "index", + "readme": "\n# pause\n\n Pause streams...\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + "readmeFilename": "Readme.md", + "_id": "pause@0.0.1", + "dist": { + "shasum": "1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + }, + "_from": "pause@0.0.1", + "_resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/.gitmodules b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/.gitmodules new file mode 100644 index 00000000000..49e31dac7d7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/.gitmodules @@ -0,0 +1,6 @@ +[submodule "support/expresso"] + path = support/expresso + url = git://github.com/visionmedia/expresso.git +[submodule "support/should"] + path = support/should + url = git://github.com/visionmedia/should.js.git diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/.npmignore new file mode 100644 index 00000000000..e85ce2afa21 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/.npmignore @@ -0,0 +1,7 @@ +test +.travis.yml +benchmark.js +component.json +examples.js +History.md +Makefile diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/Readme.md new file mode 100644 index 00000000000..27e54a4af18 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/Readme.md @@ -0,0 +1,58 @@ +# node-querystring + + query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. + +## Installation + + $ npm install qs + +## Examples + +```js +var qs = require('qs'); + +qs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com'); +// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } } + +qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}) +// => user[name]=Tobi&user[email]=tobi%40learnboost.com +``` + +## Testing + +Install dev dependencies: + + $ npm install -d + +and execute: + + $ make test + +browser: + + $ open test/browser/index.html + +## License + +(The MIT License) + +Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/index.js new file mode 100644 index 00000000000..b05938acc42 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/index.js @@ -0,0 +1,366 @@ +/** + * Object#toString() ref for stringify(). + */ + +var toString = Object.prototype.toString; + +/** + * Object#hasOwnProperty ref + */ + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Array#indexOf shim. + */ + +var indexOf = typeof Array.prototype.indexOf === 'function' + ? function(arr, el) { return arr.indexOf(el); } + : function(arr, el) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === el) return i; + } + return -1; + }; + +/** + * Array.isArray shim. + */ + +var isArray = Array.isArray || function(arr) { + return toString.call(arr) == '[object Array]'; +}; + +/** + * Object.keys shim. + */ + +var objectKeys = Object.keys || function(obj) { + var ret = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + ret.push(key); + } + } + return ret; +}; + +/** + * Array#forEach shim. + */ + +var forEach = typeof Array.prototype.forEach === 'function' + ? function(arr, fn) { return arr.forEach(fn); } + : function(arr, fn) { + for (var i = 0; i < arr.length; i++) fn(arr[i]); + }; + +/** + * Array#reduce shim. + */ + +var reduce = function(arr, fn, initial) { + if (typeof arr.reduce === 'function') return arr.reduce(fn, initial); + var res = initial; + for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]); + return res; +}; + +/** + * Cache non-integer test regexp. + */ + +var isint = /^[0-9]+$/; + +function promote(parent, key) { + if (parent[key].length == 0) return parent[key] = {} + var t = {}; + for (var i in parent[key]) { + if (hasOwnProperty.call(parent[key], i)) { + t[i] = parent[key][i]; + } + } + parent[key] = t; + return t; +} + +function parse(parts, parent, key, val) { + var part = parts.shift(); + + // illegal + if (Object.getOwnPropertyDescriptor(Object.prototype, key)) return; + + // end + if (!part) { + if (isArray(parent[key])) { + parent[key].push(val); + } else if ('object' == typeof parent[key]) { + parent[key] = val; + } else if ('undefined' == typeof parent[key]) { + parent[key] = val; + } else { + parent[key] = [parent[key], val]; + } + // array + } else { + var obj = parent[key] = parent[key] || []; + if (']' == part) { + if (isArray(obj)) { + if ('' != val) obj.push(val); + } else if ('object' == typeof obj) { + obj[objectKeys(obj).length] = val; + } else { + obj = parent[key] = [parent[key], val]; + } + // prop + } else if (~indexOf(part, ']')) { + part = part.substr(0, part.length - 1); + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + // key + } else { + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + } + } +} + +/** + * Merge parent key/val pair. + */ + +function merge(parent, key, val){ + if (~indexOf(key, ']')) { + var parts = key.split('[') + , len = parts.length + , last = len - 1; + parse(parts, parent, 'base', val); + // optimize + } else { + if (!isint.test(key) && isArray(parent.base)) { + var t = {}; + for (var k in parent.base) t[k] = parent.base[k]; + parent.base = t; + } + set(parent.base, key, val); + } + + return parent; +} + +/** + * Compact sparse arrays. + */ + +function compact(obj) { + if ('object' != typeof obj) return obj; + + if (isArray(obj)) { + var ret = []; + + for (var i in obj) { + if (hasOwnProperty.call(obj, i)) { + ret.push(obj[i]); + } + } + + return ret; + } + + for (var key in obj) { + obj[key] = compact(obj[key]); + } + + return obj; +} + +/** + * Parse the given obj. + */ + +function parseObject(obj){ + var ret = { base: {} }; + + forEach(objectKeys(obj), function(name){ + merge(ret, name, obj[name]); + }); + + return compact(ret.base); +} + +/** + * Parse the given str. + */ + +function parseString(str){ + var ret = reduce(String(str).split('&'), function(ret, pair){ + var eql = indexOf(pair, '=') + , brace = lastBraceInKey(pair) + , key = pair.substr(0, brace || eql) + , val = pair.substr(brace || eql, pair.length) + , val = val.substr(indexOf(val, '=') + 1, val.length); + + // ?foo + if ('' == key) key = pair, val = ''; + if ('' == key) return ret; + + return merge(ret, decode(key), decode(val)); + }, { base: {} }).base; + + return compact(ret); +} + +/** + * Parse the given query `str` or `obj`, returning an object. + * + * @param {String} str | {Object} obj + * @return {Object} + * @api public + */ + +exports.parse = function(str){ + if (null == str || '' == str) return {}; + return 'object' == typeof str + ? parseObject(str) + : parseString(str); +}; + +/** + * Turn the given `obj` into a query string + * + * @param {Object} obj + * @return {String} + * @api public + */ + +var stringify = exports.stringify = function(obj, prefix) { + if (isArray(obj)) { + return stringifyArray(obj, prefix); + } else if ('[object Object]' == toString.call(obj)) { + return stringifyObject(obj, prefix); + } else if ('string' == typeof obj) { + return stringifyString(obj, prefix); + } else { + return prefix + '=' + encodeURIComponent(String(obj)); + } +}; + +/** + * Stringify the given `str`. + * + * @param {String} str + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyString(str, prefix) { + if (!prefix) throw new TypeError('stringify expects an object'); + return prefix + '=' + encodeURIComponent(str); +} + +/** + * Stringify the given `arr`. + * + * @param {Array} arr + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyArray(arr, prefix) { + var ret = []; + if (!prefix) throw new TypeError('stringify expects an object'); + for (var i = 0; i < arr.length; i++) { + ret.push(stringify(arr[i], prefix + '[' + i + ']')); + } + return ret.join('&'); +} + +/** + * Stringify the given `obj`. + * + * @param {Object} obj + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyObject(obj, prefix) { + var ret = [] + , keys = objectKeys(obj) + , key; + + for (var i = 0, len = keys.length; i < len; ++i) { + key = keys[i]; + if ('' == key) continue; + if (null == obj[key]) { + ret.push(encodeURIComponent(key) + '='); + } else { + ret.push(stringify(obj[key], prefix + ? prefix + '[' + encodeURIComponent(key) + ']' + : encodeURIComponent(key))); + } + } + + return ret.join('&'); +} + +/** + * Set `obj`'s `key` to `val` respecting + * the weird and wonderful syntax of a qs, + * where "foo=bar&foo=baz" becomes an array. + * + * @param {Object} obj + * @param {String} key + * @param {String} val + * @api private + */ + +function set(obj, key, val) { + var v = obj[key]; + if (Object.getOwnPropertyDescriptor(Object.prototype, key)) return; + if (undefined === v) { + obj[key] = val; + } else if (isArray(v)) { + v.push(val); + } else { + obj[key] = [v, val]; + } +} + +/** + * Locate last brace in `str` within the key. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function lastBraceInKey(str) { + var len = str.length + , brace + , c; + for (var i = 0; i < len; ++i) { + c = str[i]; + if (']' == c) brace = false; + if ('[' == c) brace = true; + if ('=' == c && !brace) return i; + } +} + +/** + * Decode `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function decode(str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (err) { + return str; + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/package.json new file mode 100644 index 00000000000..26198312186 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/qs/package.json @@ -0,0 +1,41 @@ +{ + "name": "qs", + "description": "querystring parser", + "version": "0.6.6", + "keywords": [ + "query string", + "parser", + "component" + ], + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/node-querystring.git" + }, + "devDependencies": { + "mocha": "*", + "expect.js": "*" + }, + "scripts": { + "test": "make test" + }, + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "main": "index", + "engines": { + "node": "*" + }, + "readme": "# node-querystring\n\n query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others.\n\n## Installation\n\n $ npm install qs\n\n## Examples\n\n```js\nvar qs = require('qs');\n\nqs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com');\n// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } }\n\nqs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }})\n// => user[name]=Tobi&user[email]=tobi%40learnboost.com\n```\n\n## Testing\n\nInstall dev dependencies:\n\n $ npm install -d\n\nand execute:\n\n $ make test\n\nbrowser:\n\n $ open test/browser/index.html\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/node-querystring/issues" + }, + "_id": "qs@0.6.6", + "dist": { + "shasum": "6e015098ff51968b8a3c819001d5f2c89bc4b107" + }, + "_from": "qs@0.6.6", + "_resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/.npmignore new file mode 100644 index 00000000000..b59f7e3a95a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/.npmignore @@ -0,0 +1 @@ +test/ \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/.travis.yml new file mode 100644 index 00000000000..d84ef855222 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/.travis.yml @@ -0,0 +1,5 @@ +node_js: +- "0.8" +- "0.10" +- "0.11" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/Makefile new file mode 100644 index 00000000000..7e4e77d098c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/Makefile @@ -0,0 +1,14 @@ +NODE ?= node +BIN = ./node_modules/.bin/ + +test: + @${NODE} ${BIN}mocha \ + --harmony-generators \ + --reporter spec \ + --bail \ + ./test/index.js + +clean: + @rm -rf node_modules + +.PHONY: test clean diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/README.md new file mode 100644 index 00000000000..049ef6410a9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/README.md @@ -0,0 +1,96 @@ +# Raw Body [![Build Status](https://travis-ci.org/stream-utils/raw-body.png)](https://travis-ci.org/stream-utils/raw-body) + +Gets the entire buffer of a stream either as a `Buffer` or a string. +Validates the stream's length against an expected length and maximum limit. +Ideal for parsing request bodies. + +## API + +```js +var getRawBody = require('raw-body') + +app.use(function (req, res, next) { + getRawBody(req, { + length: req.headers['content-length'], + limit: '1mb', + encoding: 'utf8' + }, function (err, string) { + if (err) + return next(err) + + req.text = string + next() + }) +}) +``` + +or in a Koa generator: + +```js +app.use(function* (next) { + var string = yield getRawBody(this.req, { + length: this.length, + limit: '1mb', + encoding: 'utf8' + }) +}) +``` + +### getRawBody(stream, [options], [callback]) + +Returns a thunk for yielding with generators. + +Options: + +- `length` - The length length of the stream. + If the contents of the stream do not add up to this length, + an `400` error code is returned. +- `limit` - The byte limit of the body. + If the body ends up being larger than this limit, + a `413` error code is returned. +- `encoding` - The requested encoding. + By default, a `Buffer` instance will be returned. + Most likely, you want `utf8`. + You can use any type of encoding supported by [StringDecoder](http://nodejs.org/api/string_decoder.html). + You can also pass `true` which sets it to the default `utf8` + +`callback(err, res)`: + +- `err` - the following attributes will be defined if applicable: + + - `limit` - the limit in bytes + - `length` and `expected` - the expected length of the stream + - `received` - the received bytes + - `status` and `statusCode` - the corresponding status code for the error + - `type` - either `entity.too.large`, `request.size.invalid`, or `stream.encoding.set` + +- `res` - the result, either as a `String` if an encoding was set or a `Buffer` otherwise. + +If an error occurs, the stream will be paused, +and you are responsible for correctly disposing the stream. +For HTTP requests, no handling is required if you send a response. +For streams that use file descriptors, you should `stream.destroy()` or `stream.close()` to prevent leaks. + +## License + +The MIT License (MIT) + +Copyright (c) 2013 Jonathan Ong me@jongleberry.com + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/index.js new file mode 100644 index 00000000000..687f614c07d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/index.js @@ -0,0 +1,160 @@ +var StringDecoder = require('string_decoder').StringDecoder +var bytes = require('bytes') + +module.exports = function (stream, options, done) { + if (typeof options === 'function') { + done = options + options = {} + } else if (!options) { + options = {} + } + + // convert the limit to an integer + var limit = null + if (typeof options.limit === 'number') + limit = options.limit + if (typeof options.limit === 'string') + limit = bytes(options.limit) + + // convert the expected length to an integer + var length = null + if (options.length != null && !isNaN(options.length)) + length = parseInt(options.length, 10) + + // check the length and limit options. + // note: we intentionally leave the stream paused, + // so users should handle the stream themselves. + if (limit !== null && length !== null && length > limit) { + if (typeof stream.pause === 'function') + stream.pause() + + process.nextTick(function () { + var err = makeError('request entity too large', 'entity.too.large') + err.status = err.statusCode = 413 + err.length = err.expected = length + err.limit = limit + done(err) + }) + return defer + } + + var state = stream._readableState + // streams2+: assert the stream encoding is buffer. + if (state && state.encoding != null) { + if (typeof stream.pause === 'function') + stream.pause() + + process.nextTick(function () { + var err = makeError('stream encoding should not be set', + 'stream.encoding.set') + // developer error + err.status = err.statusCode = 500 + done(err) + }) + return defer + } + + var received = 0 + // note: we delegate any invalid encodings to the constructor + var decoder = options.encoding + ? new StringDecoder(options.encoding === true ? 'utf8' : options.encoding) + : null + var buffer = decoder + ? '' + : [] + + stream.on('data', onData) + stream.once('end', onEnd) + stream.once('error', onEnd) + stream.once('close', cleanup) + + return defer + + // yieldable support + function defer(fn) { + done = fn + } + + function onData(chunk) { + received += chunk.length + decoder + ? buffer += decoder.write(chunk) + : buffer.push(chunk) + + if (limit !== null && received > limit) { + if (typeof stream.pause === 'function') + stream.pause() + var err = makeError('request entity too large', 'entity.too.large') + err.status = err.statusCode = 413 + err.received = received + err.limit = limit + done(err) + cleanup() + } + } + + function onEnd(err) { + if (err) { + if (typeof stream.pause === 'function') + stream.pause() + done(err) + } else if (length !== null && received !== length) { + err = makeError('request size did not match content length', + 'request.size.invalid') + err.status = err.statusCode = 400 + err.received = received + err.length = err.expected = length + done(err) + } else { + done(null, decoder + ? buffer + endStringDecoder(decoder) + : Buffer.concat(buffer) + ) + } + + cleanup() + } + + function cleanup() { + received = buffer = null + + stream.removeListener('data', onData) + stream.removeListener('end', onEnd) + stream.removeListener('error', onEnd) + stream.removeListener('close', cleanup) + } +} + +// to create serializable errors you must re-set message so +// that it is enumerable and you must re configure the type +// property so that is writable and enumerable +function makeError(message, type) { + var error = new Error() + error.message = message + Object.defineProperty(error, 'type', { + value: type, + enumerable: true, + writable: true, + configurable: true + }) + return error +} + +// https://github.com/Raynos/body/blob/2512ced39e31776e5a2f7492b907330badac3a40/index.js#L72 +// bug fix for missing `StringDecoder.end` in v0.8.x +function endStringDecoder(decoder) { + if (decoder.end) { + return decoder.end() + } + + var res = "" + + if (decoder.charReceived) { + var cr = decoder.charReceived + var buf = decoder.charBuffer + var enc = decoder.encoding + res += buf.slice(0, cr).toString(enc) + } + + return res +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/package.json new file mode 100644 index 00000000000..eea915ca048 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/raw-body/package.json @@ -0,0 +1,44 @@ +{ + "name": "raw-body", + "description": "Get and validate the raw body of a readable stream.", + "version": "1.1.3", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/stream-utils/raw-body.git" + }, + "bugs": { + "url": "https://github.com/stream-utils/raw-body/issues" + }, + "dependencies": { + "bytes": "~0.2.1" + }, + "devDependencies": { + "readable-stream": "~1.0.17", + "co": "3", + "gnode": "~0.0.4", + "mocha": "^1.14.0", + "through2": "~0.4.1", + "request": "^2.27.0", + "assert-tap": "~0.1.4" + }, + "scripts": { + "test": "NODE=gnode make test && node ./test/acceptance.js" + }, + "engines": { + "node": ">= 0.8.0" + }, + "readme": "# Raw Body [![Build Status](https://travis-ci.org/stream-utils/raw-body.png)](https://travis-ci.org/stream-utils/raw-body)\n\nGets the entire buffer of a stream either as a `Buffer` or a string.\nValidates the stream's length against an expected length and maximum limit.\nIdeal for parsing request bodies.\n\n## API\n\n```js\nvar getRawBody = require('raw-body')\n\napp.use(function (req, res, next) {\n getRawBody(req, {\n length: req.headers['content-length'],\n limit: '1mb',\n encoding: 'utf8'\n }, function (err, string) {\n if (err)\n return next(err)\n\n req.text = string\n next()\n })\n})\n```\n\nor in a Koa generator:\n\n```js\napp.use(function* (next) {\n var string = yield getRawBody(this.req, {\n length: this.length,\n limit: '1mb',\n encoding: 'utf8'\n })\n})\n```\n\n### getRawBody(stream, [options], [callback])\n\nReturns a thunk for yielding with generators.\n\nOptions:\n\n- `length` - The length length of the stream.\n If the contents of the stream do not add up to this length,\n an `400` error code is returned.\n- `limit` - The byte limit of the body.\n If the body ends up being larger than this limit,\n a `413` error code is returned.\n- `encoding` - The requested encoding.\n By default, a `Buffer` instance will be returned.\n Most likely, you want `utf8`.\n You can use any type of encoding supported by [StringDecoder](http://nodejs.org/api/string_decoder.html).\n You can also pass `true` which sets it to the default `utf8`\n\n`callback(err, res)`:\n\n- `err` - the following attributes will be defined if applicable:\n\n - `limit` - the limit in bytes\n - `length` and `expected` - the expected length of the stream\n - `received` - the received bytes\n - `status` and `statusCode` - the corresponding status code for the error\n - `type` - either `entity.too.large`, `request.size.invalid`, or `stream.encoding.set`\n\n- `res` - the result, either as a `String` if an encoding was set or a `Buffer` otherwise.\n\nIf an error occurs, the stream will be paused,\nand you are responsible for correctly disposing the stream.\nFor HTTP requests, no handling is required if you send a response.\nFor streams that use file descriptors, you should `stream.destroy()` or `stream.close()` to prevent leaks.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", + "readmeFilename": "README.md", + "_id": "raw-body@1.1.3", + "dist": { + "shasum": "3d2f91e2449259cc67b8c3ce9f061db5b987935b" + }, + "_from": "raw-body@1.1.3", + "_resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.3.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/.npmignore new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/Makefile new file mode 100644 index 00000000000..bd17c559a73 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/Makefile @@ -0,0 +1,9 @@ +BIN = ./node_modules/.bin/ + +test: + @$(BIN)mocha \ + --require should \ + --reporter spec \ + --bail + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/README.md new file mode 100644 index 00000000000..77606ef014b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/README.md @@ -0,0 +1,23 @@ +# Response Time + +Response time middleware extracted from connect. + +Usage: + +```js +var responseTime = require('response-time'); + +app.use(responseTime()); +``` + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/index.js new file mode 100644 index 00000000000..cacaba467a8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/index.js @@ -0,0 +1,34 @@ + +/*! + * Connect - responseTime + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Reponse time: + * + * Adds the `X-Response-Time` header displaying the response + * duration in milliseconds. + * + * @return {Function} + * @api public + */ + +module.exports = function responseTime(){ + return function(req, res, next){ + next = next || noop; + if (res._responseTime) return next(); + var writeHead = res.writeHead; + var start = Date.now(); + res._responseTime = true; + res.writeHead = function(){ + var duration = Date.now() - start; + res.setHeader('X-Response-Time', duration + 'ms'); + writeHead.apply(res, arguments); + }; + next(); + }; +}; + +function noop() {}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/package.json new file mode 100644 index 00000000000..8906755b03c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/response-time/package.json @@ -0,0 +1,34 @@ +{ + "name": "response-time", + "description": "X-Response-Time header for node.js", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/response-time.git" + }, + "bugs": { + "url": "https://github.com/expressjs/response-time/issues" + }, + "devDependencies": { + "mocha": "*", + "should": "*", + "supertest": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# Response Time\n\nResponse time middleware extracted from connect.\n\nUsage:\n\n```js\nvar responseTime = require('response-time');\n\napp.use(responseTime());\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.", + "readmeFilename": "README.md", + "_id": "response-time@1.0.0", + "dist": { + "shasum": "c2bc8d08f3c359f97eae1d6da86eead175fabdc9" + }, + "_from": "response-time@1.0.0", + "_resolved": "https://registry.npmjs.org/response-time/-/response-time-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/.npmignore new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/.npmignore @@ -0,0 +1 @@ +test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/.travis.yml new file mode 100644 index 00000000000..cc4dba29d95 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/LICENSE new file mode 100644 index 00000000000..b7bc0852e3f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/LICENSE @@ -0,0 +1,25 @@ +(The MIT License) + +Copyright (c) 2010 Sencha Inc. +Copyright (c) 2011 LearnBoost +Copyright (c) 2011 TJ Holowaychuk +Copyright (c) 2014 Douglas Christopher Wilson + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/Readme.md new file mode 100644 index 00000000000..f45f283e94e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/Readme.md @@ -0,0 +1,42 @@ +# Serve Index + +Previously `connect.directory()`. + +Usage: + +```js +var connect = require('connect'); +var serveIndex = require('serve-index'); + +var app = connect(); + +app.use(serveIndex('public/ftp', {'icons': true})); +app.listen(); +``` + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Douglas Christopher Wilson + +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. + +The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons are created +by/copyright of [FAMFAMFAM](http://www.famfamfam.com/). diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/index.js new file mode 100644 index 00000000000..1c058a5f775 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/index.js @@ -0,0 +1,498 @@ + +/*! + * Connect - directory + * Copyright(c) 2011 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + +// TODO: arrow key navigation +// TODO: make icons extensible + +/** + * Module dependencies. + */ + +var http = require('http') + , fs = require('fs') + , parse = require('url').parse + , path = require('path') + , normalize = path.normalize + , sep = path.sep + , extname = path.extname + , join = path.join; +var Batch = require('batch'); +var Negotiator = require('negotiator'); + +/*! + * Icon cache. + */ + +var cache = {}; + +/*! + * Default template. + */ + +var defaultTemplate = join(__dirname, 'public', 'directory.html'); + +/*! + * Stylesheet. + */ + +var stylesheet = join(__dirname, 'public', 'style.css'); + +/** + * Media types and the map for content negotiation. + */ + +var mediaTypes = [ + 'text/html', + 'text/plain', + 'application/json' +]; + +var mediaType = { + 'text/html': 'html', + 'text/plain': 'plain', + 'application/json': 'json' +}; + +/** + * Directory: + * + * Serve directory listings with the given `root` path. + * + * Options: + * + * - `hidden` display hidden (dot) files. Defaults to false. + * - `icons` display icons. Defaults to false. + * - `filter` Apply this filter function to files. Defaults to false. + * - `template` Optional path to html template. Defaults to a built-in template. + * The following tokens are replaced: + * - `{directory}` with the name of the directory. + * - `{files}` with the HTML of an unordered list of file links. + * - `{linked-path}` with the HTML of a link to the directory. + * - `{style}` with the built-in CSS and embedded images. + * + * @param {String} root + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function directory(root, options){ + options = options || {}; + + // root required + if (!root) throw new Error('directory() root path required'); + var hidden = options.hidden + , icons = options.icons + , view = options.view || 'tiles' + , filter = options.filter + , root = normalize(root + sep) + , template = options.template || defaultTemplate; + + return function directory(req, res, next) { + if ('GET' != req.method && 'HEAD' != req.method) return next(); + + var url = parse(req.url) + , dir = decodeURIComponent(url.pathname) + , path = normalize(join(root, dir)) + , originalUrl = parse(req.originalUrl) + , originalDir = decodeURIComponent(originalUrl.pathname) + , showUp = path != root; + + // null byte(s), bad request + if (~path.indexOf('\0')) return next(createError(400)); + + // malicious path, forbidden + if (0 != path.indexOf(root)) return next(createError(403)); + + // check if we have a directory + fs.stat(path, function(err, stat){ + if (err) return 'ENOENT' == err.code + ? next() + : next(err); + + if (!stat.isDirectory()) return next(); + + // fetch files + fs.readdir(path, function(err, files){ + if (err) return next(err); + if (!hidden) files = removeHidden(files); + if (filter) files = files.filter(filter); + files.sort(); + + // content-negotiation + var type = new Negotiator(req).preferredMediaType(mediaTypes); + + // not acceptable + if (!type) return next(createError(406)); + exports[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, view, template); + }); + }); + }; +}; + +/** + * Respond with text/html. + */ + +exports.html = function(req, res, files, next, dir, showUp, icons, path, view, template){ + fs.readFile(template, 'utf8', function(err, str){ + if (err) return next(err); + fs.readFile(stylesheet, 'utf8', function(err, style){ + if (err) return next(err); + stat(path, files, function(err, stats){ + if (err) return next(err); + files = files.map(function(file, i){ return { name: file, stat: stats[i] }; }); + files.sort(fileSort); + if (showUp) files.unshift({ name: '..' }); + str = str + .replace('{style}', style.concat(iconStyle(files, icons))) + .replace('{files}', html(files, dir, icons, view)) + .replace('{directory}', dir) + .replace('{linked-path}', htmlPath(dir)); + res.setHeader('Content-Type', 'text/html'); + res.setHeader('Content-Length', str.length); + res.end(str); + }); + }); + }); +}; + +/** + * Respond with application/json. + */ + +exports.json = function(req, res, files){ + files = JSON.stringify(files); + res.setHeader('Content-Type', 'application/json'); + res.setHeader('Content-Length', files.length); + res.end(files); +}; + +/** + * Respond with text/plain. + */ + +exports.plain = function(req, res, files){ + files = files.join('\n') + '\n'; + res.setHeader('Content-Type', 'text/plain'); + res.setHeader('Content-Length', files.length); + res.end(files); +}; + +/** + * Generate an `Error` from the given status `code` + * and optional `msg`. + * + * @param {Number} code + * @param {String} msg + * @return {Error} + * @api private + */ + +function createError(code, msg) { + var err = new Error(msg || http.STATUS_CODES[code]); + err.status = code; + return err; +}; + +/** + * Sort function for with directories first. + */ + +function fileSort(a, b) { + return Number(b.stat && b.stat.isDirectory()) - Number(a.stat && a.stat.isDirectory()) || + String(a.name).toLocaleLowerCase().localeCompare(String(b.name).toLocaleLowerCase()); +} + +/** + * Map html `dir`, returning a linked path. + */ + +function htmlPath(dir) { + var curr = []; + return dir.split('/').map(function(part){ + curr.push(encodeURIComponent(part)); + return part ? '' + part + '' : ''; + }).join(' / '); +} + +/** + * Load icon images, return css string. + */ + +function iconStyle (files, useIcons) { + if (!useIcons) return ''; + var className; + var i; + var icon; + var list = []; + var rules = {}; + var selector; + var selectors = {}; + var style = ''; + + for (i = 0; i < files.length; i++) { + var file = files[i]; + + var isDir = '..' == file.name || (file.stat && file.stat.isDirectory()); + icon = isDir ? icons.folder : icons[extname(file.name)] || icons.default; + + var ext = extname(file.name); + className = 'icon-' + (isDir ? 'directory' : (icons[ext] ? ext.substring(1) : 'default')); + selector = '#files .' + className + ' .name'; + + if (!rules[icon]) { + rules[icon] = 'background-image: url(data:image/png;base64,' + load(icon) + ');' + selectors[icon] = []; + list.push(icon); + } + + if (!~selectors[icon].indexOf(selector)) { + selectors[icon].push(selector); + } + } + + for (i = 0; i < list.length; i++) { + icon = list[i]; + style += selectors[icon].join(',\n') + ' {\n ' + rules[icon] + '\n}\n'; + } + + return style; +} + +/** + * Map html `files`, returning an html unordered list. + */ + +function html(files, dir, useIcons, view) { + return '
      ' + + (view == 'details' ? ( + '
    • ' + + 'Name' + + 'Size' + + 'Modified' + + '
    • ') : '') + + files.map(function(file){ + var isDir = '..' == file.name || (file.stat && file.stat.isDirectory()) + , classes = [] + , path = dir.split('/').map(function (c) { return encodeURIComponent(c); }); + + if (useIcons) { + var ext = extname(file.name); + ext = isDir ? '.directory' : (icons[ext] ? ext : '.default'); + classes.push('icon'); + classes.push('icon-' + ext.substring(1)); + } + + path.push(encodeURIComponent(file.name)); + + var date = file.name == '..' ? '' + : file.stat.mtime.toDateString()+' '+file.stat.mtime.toLocaleTimeString(); + var size = isDir ? '' : file.stat.size; + + return '
    • ' + + ''+file.name+'' + + ''+size+'' + + ''+date+'' + + '
    • '; + + }).join('\n') + '
    '; +} + +/** + * Load and cache the given `icon`. + * + * @param {String} icon + * @return {String} + * @api private + */ + +function load(icon) { + if (cache[icon]) return cache[icon]; + return cache[icon] = fs.readFileSync(__dirname + '/public/icons/' + icon, 'base64'); +} + +/** + * Normalizes the path separator from system separator + * to URL separator, aka `/`. + * + * @param {String} path + * @return {String} + * @api private + */ + +function normalizeSlashes(path) { + return path.split(sep).join('/'); +}; + +/** + * Filter "hidden" `files`, aka files + * beginning with a `.`. + * + * @param {Array} files + * @return {Array} + * @api private + */ + +function removeHidden(files) { + return files.filter(function(file){ + return '.' != file[0]; + }); +} + +/** + * Stat all files and return array of stat + * in same order. + */ + +function stat(dir, files, cb) { + var batch = new Batch(); + + batch.concurrency(10); + + files.forEach(function(file){ + batch.push(function(done){ + fs.stat(join(dir, file), done); + }); + }); + + batch.end(cb); +} + +/** + * Icon map. + */ + +var icons = { + '.js': 'page_white_code_red.png' + , '.json': 'page_white_code.png' + , '.c': 'page_white_c.png' + , '.h': 'page_white_h.png' + , '.cc': 'page_white_cplusplus.png' + , '.php': 'page_white_php.png' + , '.rb': 'page_white_ruby.png' + , '.erb': 'page_white_ruby.png' + , '.cpp': 'page_white_cplusplus.png' + , '.as': 'page_white_actionscript.png' + , '.cfm': 'page_white_coldfusion.png' + , '.cs': 'page_white_csharp.png' + , '.java': 'page_white_cup.png' + , '.jsp': 'page_white_cup.png' + , '.dll': 'page_white_gear.png' + , '.ini': 'page_white_gear.png' + , '.asp': 'page_white_code.png' + , '.aspx': 'page_white_code.png' + , '.clj': 'page_white_code.png' + , '.css': 'page_white_code.png' + , '.sass': 'page_white_code.png' + , '.scss': 'page_white_code.png' + , '.less': 'page_white_code.png' + , '.htm': 'page_white_code.png' + , '.html': 'page_white_code.png' + , '.xhtml': 'page_white_code.png' + , '.lua': 'page_white_code.png' + , '.m': 'page_white_code.png' + , '.pl': 'page_white_code.png' + , '.py': 'page_white_code.png' + , '.vb': 'page_white_code.png' + , '.vbs': 'page_white_code.png' + , '.xml': 'page_white_code.png' + , '.yaws': 'page_white_code.png' + , '.map': 'map.png' + + , '.app': 'application_xp.png' + , '.exe': 'application_xp.png' + , '.bat': 'application_xp_terminal.png' + , '.cgi': 'application_xp_terminal.png' + , '.sh': 'application_xp_terminal.png' + + , '.avi': 'film.png' + , '.flv': 'film.png' + , '.mv4': 'film.png' + , '.mov': 'film.png' + , '.mp4': 'film.png' + , '.mpeg': 'film.png' + , '.mpg': 'film.png' + , '.ogv': 'film.png' + , '.rm': 'film.png' + , '.webm': 'film.png' + , '.wmv': 'film.png' + , '.fnt': 'font.png' + , '.otf': 'font.png' + , '.ttf': 'font.png' + , '.woff': 'font.png' + , '.bmp': 'image.png' + , '.gif': 'image.png' + , '.ico': 'image.png' + , '.jpeg': 'image.png' + , '.jpg': 'image.png' + , '.png': 'image.png' + , '.psd': 'page_white_picture.png' + , '.xcf': 'page_white_picture.png' + , '.pdf': 'page_white_acrobat.png' + , '.swf': 'page_white_flash.png' + , '.ai': 'page_white_vector.png' + , '.eps': 'page_white_vector.png' + , '.ps': 'page_white_vector.png' + , '.svg': 'page_white_vector.png' + + , '.ods': 'page_white_excel.png' + , '.xls': 'page_white_excel.png' + , '.xlsx': 'page_white_excel.png' + , '.odp': 'page_white_powerpoint.png' + , '.ppt': 'page_white_powerpoint.png' + , '.pptx': 'page_white_powerpoint.png' + , '.md': 'page_white_text.png' + , '.srt': 'page_white_text.png' + , '.txt': 'page_white_text.png' + , '.doc': 'page_white_word.png' + , '.docx': 'page_white_word.png' + , '.odt': 'page_white_word.png' + , '.rtf': 'page_white_word.png' + + , '.dmg': 'drive.png' + , '.iso': 'cd.png' + , '.7z': 'box.png' + , '.apk': 'box.png' + , '.bz2': 'box.png' + , '.cab': 'box.png' + , '.deb': 'box.png' + , '.gz': 'box.png' + , '.jar': 'box.png' + , '.lz': 'box.png' + , '.lzma': 'box.png' + , '.msi': 'box.png' + , '.pkg': 'box.png' + , '.rar': 'box.png' + , '.rpm': 'box.png' + , '.tar': 'box.png' + , '.tbz2': 'box.png' + , '.tgz': 'box.png' + , '.tlz': 'box.png' + , '.xz': 'box.png' + , '.zip': 'box.png' + + , '.accdb': 'page_white_database.png' + , '.db': 'page_white_database.png' + , '.dbf': 'page_white_database.png' + , '.mdb': 'page_white_database.png' + , '.pdb': 'page_white_database.png' + , '.sql': 'page_white_database.png' + + , '.gam': 'controller.png' + , '.rom': 'controller.png' + , '.sav': 'controller.png' + + , 'folder': 'folder.png' + , 'default': 'page_white.png' +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/.npmignore new file mode 100644 index 00000000000..f1250e584c9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/History.md new file mode 100644 index 00000000000..b1b77526a2b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/History.md @@ -0,0 +1,66 @@ + +0.5.0 / 2013-07-29 +================== + + * add `.throws(true)` to opt-in to responding with an array of error objects + * make `new` optional + +0.4.0 / 2013-06-05 +================== + + * add catching of immediate callback errors + +0.3.2 / 2013-03-15 +================== + + * remove Emitter call in constructor + +0.3.1 / 2013-03-13 +================== + + * add Emitter() mixin for client. Closes #8 + +0.3.0 / 2013-03-13 +================== + + * add component.json + * add result example + * add .concurrency support + * add concurrency example + * add parallel example + +0.2.1 / 2012-11-08 +================== + + * add .start, .end, and .duration properties + * change dependencies to devDependencies + +0.2.0 / 2012-10-04 +================== + + * add progress events. Closes #5 (__BREAKING CHANGE__) + +0.1.1 / 2012-07-03 +================== + + * change "complete" event to "progress" + +0.1.0 / 2012-07-03 +================== + + * add Emitter inheritance and emit "complete" [burcu] + +0.0.3 / 2012-06-02 +================== + + * Callback results should be in the order of the queued functions. + +0.0.2 / 2012-02-12 +================== + + * any node + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/Makefile new file mode 100644 index 00000000000..634e3721928 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/Makefile @@ -0,0 +1,6 @@ + +test: + @./node_modules/.bin/mocha \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/Readme.md new file mode 100644 index 00000000000..f2345c67bdf --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/Readme.md @@ -0,0 +1,74 @@ + +# batch + + Simple async batch with concurrency control and progress reporting. + +## Installation + +``` +$ npm install batch +``` + +## API + +```js +var Batch = require('batch') + , batch = new Batch; + +batch.concurrency(4); + +ids.forEach(function(id){ + batch.push(function(done){ + User.get(id, done); + }); +}); + +batch.on('progress', function(e){ + +}); + +batch.end(function(err, users){ + +}); +``` + +### Progress events + + Contain the "job" index, response value, duration information, and completion data. + +```js +{ index: 1, + value: 'bar', + pending: 2, + total: 3, + complete: 2, + percent: 66, + start: Thu Oct 04 2012 12:25:53 GMT-0700 (PDT), + end: Thu Oct 04 2012 12:25:53 GMT-0700 (PDT), + duration: 0 } +``` + +## License + +(The MIT License) + +Copyright (c) 2013 TJ Holowaychuk <tj@vision-media.ca> + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/component.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/component.json new file mode 100644 index 00000000000..0ea7e58247c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/component.json @@ -0,0 +1,14 @@ +{ + "name": "batch", + "repo": "visionmedia/batch", + "description": "Async task batching", + "version": "0.5.0", + "keywords": ["batch", "async", "utility", "concurrency", "concurrent"], + "dependencies": { + "component/emitter": "*" + }, + "development": {}, + "scripts": [ + "index.js" + ] +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/index.js new file mode 100644 index 00000000000..932d40455d8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/index.js @@ -0,0 +1,158 @@ +/** + * Module dependencies. + */ + +try { + var EventEmitter = require('events').EventEmitter; +} catch (err) { + var Emitter = require('emitter'); +} + +/** + * Noop. + */ + +function noop(){} + +/** + * Expose `Batch`. + */ + +module.exports = Batch; + +/** + * Create a new Batch. + */ + +function Batch() { + if (!(this instanceof Batch)) return new Batch; + this.fns = []; + this.concurrency(Infinity); + this.throws(true); + for (var i = 0, len = arguments.length; i < len; ++i) { + this.push(arguments[i]); + } +} + +/** + * Inherit from `EventEmitter.prototype`. + */ + +if (EventEmitter) { + Batch.prototype.__proto__ = EventEmitter.prototype; +} else { + Emitter(Batch.prototype); +} + +/** + * Set concurrency to `n`. + * + * @param {Number} n + * @return {Batch} + * @api public + */ + +Batch.prototype.concurrency = function(n){ + this.n = n; + return this; +}; + +/** + * Queue a function. + * + * @param {Function} fn + * @return {Batch} + * @api public + */ + +Batch.prototype.push = function(fn){ + this.fns.push(fn); + return this; +}; + +/** + * Set wether Batch will or will not throw up. + * + * @param {Boolean} throws + * @return {Batch} + * @api public + */ +Batch.prototype.throws = function(throws) { + this.e = !!throws; + return this; +}; + +/** + * Execute all queued functions in parallel, + * executing `cb(err, results)`. + * + * @param {Function} cb + * @return {Batch} + * @api public + */ + +Batch.prototype.end = function(cb){ + var self = this + , total = this.fns.length + , pending = total + , results = [] + , errors = [] + , cb = cb || noop + , fns = this.fns + , max = this.n + , throws = this.e + , index = 0 + , done; + + // empty + if (!fns.length) return cb(null, results); + + // process + function next() { + var i = index++; + var fn = fns[i]; + if (!fn) return; + var start = new Date; + + try { + fn(callback); + } catch (err) { + callback(err); + } + + function callback(err, res){ + if (done) return; + if (err && throws) return done = true, cb(err); + var complete = total - pending + 1; + var end = new Date; + + results[i] = res; + errors[i] = err; + + self.emit('progress', { + index: i, + value: res, + error: err, + pending: pending, + total: total, + complete: complete, + percent: complete / total * 100 | 0, + start: start, + end: end, + duration: end - start + }); + + if (--pending) next() + else if(!throws) cb(errors, results); + else cb(null, results); + } + } + + // concurrency + for (var i = 0; i < fns.length; i++) { + if (i == max) break; + next(); + } + + return this; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/package.json new file mode 100644 index 00000000000..4c2c1758531 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/batch/package.json @@ -0,0 +1,22 @@ +{ + "name": "batch", + "version": "0.5.0", + "description": "Simple async batch", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "main": "index", + "readme": "\n# batch\n\n Simple async batch with concurrency control and progress reporting.\n\n## Installation\n\n```\n$ npm install batch\n```\n\n## API\n\n```js\nvar Batch = require('batch')\n , batch = new Batch;\n\nbatch.concurrency(4);\n\nids.forEach(function(id){\n batch.push(function(done){\n User.get(id, done);\n });\n});\n\nbatch.on('progress', function(e){\n\n});\n\nbatch.end(function(err, users){\n\n});\n```\n\n### Progress events\n\n Contain the \"job\" index, response value, duration information, and completion data.\n\n```js\n{ index: 1,\n value: 'bar',\n pending: 2,\n total: 3,\n complete: 2,\n percent: 66,\n start: Thu Oct 04 2012 12:25:53 GMT-0700 (PDT),\n end: Thu Oct 04 2012 12:25:53 GMT-0700 (PDT),\n duration: 0 }\n```\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2013 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "Readme.md", + "_id": "batch@0.5.0", + "dist": { + "shasum": "4f41ac9cbe3be6cd5aaa900854ac3ce7b627fa21" + }, + "_from": "batch@0.5.0", + "_resolved": "https://registry.npmjs.org/batch/-/batch-0.5.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/.travis.yml new file mode 100644 index 00000000000..1932865cc8b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.11" diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/LICENSE new file mode 100644 index 00000000000..42ca2e7d7bb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/LICENSE @@ -0,0 +1,27 @@ +Original "Negotiator" program Copyright Federico Romero +Port to JavaScript Copyright Isaac Z. Schlueter + +All rights reserved. + +MIT License + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/accept.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/accept.js new file mode 100644 index 00000000000..994d06be33f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/accept.js @@ -0,0 +1,47 @@ +(function() { + var Negotiator, availableMediaTypes, http, key, representations, server, val; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + representations = { + 'text/html': '

    Hello world!

    ', + 'text/plain': 'Hello World!', + 'application/json': JSON.stringify({ + hello: 'world!' + }) + }; + + availableMediaTypes = (function() { + var _results; + _results = []; + for (key in representations) { + val = representations[key]; + _results.push(key); + } + return _results; + })(); + + server = http.createServer(function(req, res) { + var mediaType, negotiator; + negotiator = new Negotiator(req); + console.log("Accept: " + req.headers['accept']); + console.log("Preferred: " + (negotiator.mediaTypes())); + console.log("Possible: " + (negotiator.mediaTypes(availableMediaTypes))); + mediaType = negotiator.mediaType(availableMediaTypes); + console.log("Selected: " + mediaType); + if (mediaType) { + res.writeHead(200, { + 'Content-Type': mediaType + }); + return res.end(representations[mediaType]); + } else { + res.writeHead(406); + return res.end(); + } + }); + + server.listen(8080); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/charset.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/charset.js new file mode 100644 index 00000000000..39ef9f5102b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/charset.js @@ -0,0 +1,52 @@ +(function() { + var Buffer, Iconv, Negotiator, availableCharsets, http, iconv, key, message, messages, server, val; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + Buffer = require('buffer').Buffer; + + Iconv = require('iconv').Iconv; + + iconv = new Iconv('UTF-8', 'ISO-8859-1'); + + message = "ë"; + + messages = { + 'utf-8': message, + 'iso-8859-1': iconv.convert(new Buffer(message)) + }; + + availableCharsets = (function() { + var _results; + _results = []; + for (key in messages) { + val = messages[key]; + _results.push(key); + } + return _results; + })(); + + server = http.createServer(function(req, res) { + var charset, negotiator; + negotiator = new Negotiator(req); + console.log("Accept-Charset: " + req.headers['accept-charset']); + console.log("Preferred: " + (negotiator.charsets())); + console.log("Possible: " + (negotiator.charsets(availableCharsets))); + charset = negotiator.charset(availableCharsets); + console.log("Selected: " + charset); + if (charset) { + res.writeHead(200, { + 'Content-Type': "text/html; charset=" + charset + }); + return res.end(messages[charset]); + } else { + res.writeHead(406); + return res.end(); + } + }); + + server.listen(8080); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/encoding.js new file mode 100644 index 00000000000..06c3917d03f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/encoding.js @@ -0,0 +1,48 @@ +(function() { + var Negotiator, gbuf, http, messages; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + gbuf = require('gzip-buffer'); + + messages = { + identity: 'Hello World' + }; + + gbuf.gzip(messages.identity, function(zipped) { + var availableEncodings, key, server, val; + messages.gzip = zipped; + availableEncodings = (function() { + var _results; + _results = []; + for (key in messages) { + val = messages[key]; + _results.push(key); + } + return _results; + })(); + console.log(availableEncodings); + server = http.createServer(function(req, res) { + var encoding, negotiator; + negotiator = new Negotiator(req); + console.log("Accept-Encoding: " + req.headers['accept-encoding']); + console.log("Preferred: " + (negotiator.encodings())); + console.log("Possible: " + (negotiator.encodings(availableEncodings))); + encoding = negotiator.encoding(availableEncodings); + console.log("Selected: " + encoding); + if (encoding) { + res.writeHead(200, { + 'Content-Encoding': encoding + }); + return res.end(messages[encoding]); + } else { + res.writeHead(406); + return res.end(); + } + }); + return server.listen(8080); + }); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/language.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/language.js new file mode 100644 index 00000000000..e42ae19ce71 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/examples/language.js @@ -0,0 +1,44 @@ +(function() { + var Negotiator, availableLanguages, http, key, messages, server, val; + + Negotiator = require('../lib/negotiator').Negotiator; + + http = require('http'); + + messages = { + es: "¡Hola Mundo!", + en: "Hello World!" + }; + + availableLanguages = (function() { + var _results; + _results = []; + for (key in messages) { + val = messages[key]; + _results.push(key); + } + return _results; + })(); + + server = http.createServer(function(req, res) { + var language, negotiator; + negotiator = new Negotiator(req); + console.log("Accept-Language: " + req.headers['accept-language']); + console.log("Preferred: " + (negotiator.languages())); + console.log("Possible: " + (negotiator.languages(availableLanguages))); + language = negotiator.language(availableLanguages); + console.log("Selected: " + language); + if (language) { + res.writeHead(200, { + 'Content-Language': language + }); + return res.end(messages[language]); + } else { + res.writeHead(406); + return res.end(); + } + }); + + server.listen(8080); + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/charset.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/charset.js new file mode 100644 index 00000000000..1af10a5f1f1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/charset.js @@ -0,0 +1,81 @@ +module.exports = preferredCharsets; +preferredCharsets.preferredCharsets = preferredCharsets; + +function parseAcceptCharset(accept) { + return accept.split(',').map(function(e) { + return parseCharset(e.trim()); + }).filter(function(e) { + return e; + }); +} + +function parseCharset(s) { + var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/); + if (!match) return null; + + var charset = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(';') + for (var i = 0; i < params.length; i ++) { + var p = params[i].trim().split('='); + if (p[0] === 'q') { + q = parseFloat(p[1]); + break; + } + } + } + + return { + charset: charset, + q: q + }; +} + +function getCharsetPriority(charset, accepted) { + return (accepted.filter(function(a) { + return specify(charset, a); + }).sort(function (a, b) { + // revsort + return a.s > b.s ? -1 : 1; + })[0] || {q:0}).q; +} + +function specify(charset, spec) { + var s = 0; + if(spec.charset === charset){ + s |= 1; + } else if (spec.charset !== '*' ) { + return null + } + + return { + s: s, + q: spec.q, + } +} + +function preferredCharsets(accept, provided) { + accept = parseAcceptCharset(accept || ''); + if (provided) { + return provided.map(function(type) { + return [type, getCharsetPriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).filter(function(type) { + return type.q > 0; + }).map(function(type) { + return type.charset; + }); + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/encoding.js new file mode 100644 index 00000000000..8950413a1be --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/encoding.js @@ -0,0 +1,114 @@ +module.exports = preferredEncodings; +preferredEncodings.preferredEncodings = preferredEncodings; + +function parseAcceptEncoding(accept) { + var acceptableEncodings; + + if (accept) { + acceptableEncodings = accept.split(',').map(function(e) { + return parseEncoding(e.trim()); + }); + } else { + acceptableEncodings = []; + } + + if (!acceptableEncodings.some(function(e) { + return e && specify('identity', e); + })) { + /* + * If identity doesn't explicitly appear in the accept-encoding header, + * it's added to the list of acceptable encoding with the lowest q + * + */ + var lowestQ = 1; + + for(var i = 0; i < acceptableEncodings.length; i++){ + var e = acceptableEncodings[i]; + if(e && e.q < lowestQ){ + lowestQ = e.q; + } + } + acceptableEncodings.push({ + encoding: 'identity', + q: lowestQ / 2, + }); + } + + return acceptableEncodings.filter(function(e) { + return e; + }); +} + +function parseEncoding(s) { + var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/); + + if (!match) return null; + + var encoding = match[1]; + var q = 1; + if (match[2]) { + var params = match[2].split(';'); + for (var i = 0; i < params.length; i ++) { + var p = params[i].trim().split('='); + if (p[0] === 'q') { + q = parseFloat(p[1]); + break; + } + } + } + + return { + encoding: encoding, + q: q + }; +} + +function getEncodingPriority(encoding, accepted) { + return (accepted.map(function(a) { + return specify(encoding, a); + }).filter(function(a){ + return a; + }).sort(function (a, b) { + // revsort + return a.s > b.s ? -1 : 1; + })[0] || {q:0}).q; +} + +function specify(encoding, spec) { + var s = 0; + if(spec.encoding === encoding){ + s |= 1; + } else if (spec.encoding !== '*' ) { + return null + } + + return { + s: s, + q: spec.q, + } +}; + +function preferredEncodings(accept, provided) { + accept = parseAcceptEncoding(accept || ''); + if (provided) { + return provided.map(function(type) { + return [type, getEncodingPriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).filter(function(type){ + return type.q > 0; + }).map(function(type) { + return type.encoding; + }); + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/language.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/language.js new file mode 100644 index 00000000000..cd1cf9cdd32 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/language.js @@ -0,0 +1,95 @@ +module.exports = preferredLanguages; +preferredLanguages.preferredLanguages = preferredLanguages; + +function parseAcceptLanguage(accept) { + return accept.split(',').map(function(e) { + return parseLanguage(e.trim()); + }).filter(function(e) { + return e; + }); +} + +function parseLanguage(s) { + var match = s.match(/^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/); + if (!match) return null; + + var prefix = match[1], + suffix = match[2], + full = prefix; + + if (suffix) full += "-" + suffix; + + var q = 1; + if (match[3]) { + var params = match[3].split(';') + for (var i = 0; i < params.length; i ++) { + var p = params[i].split('='); + if (p[0] === 'q') q = parseFloat(p[1]); + } + } + + return { + prefix: prefix, + suffix: suffix, + q: q, + full: full + }; +} + +function getLanguagePriority(language, accepted) { + return (accepted.map(function(a){ + return specify(language, a); + }).filter(function(a){ + return a; + }).sort(function(a, b){ + // revsort + return a.s > b.s ? -1 : 1; + })[0] || {q:0}).q; +} + +function specify(language, spec) { + var p = parseLanguage(language) + var s = 0; + if(spec.full === p.full){ + s |= 4; + } else if (spec.prefix === p.full) { + s |= 2; + } else if (spec.full === p.prefix) { + s |= 1; + } else if (spec.full !== '*' ) { + return null + } + + return { + s: s, + q: spec.q, + } +}; + +function preferredLanguages(accept, provided) { + accept = parseAcceptLanguage(accept || ''); + if (provided) { + + var ret = provided.map(function(type) { + return [type, getLanguagePriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + return ret; + + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).filter(function(type) { + return type.q > 0; + }).map(function(type) { + return type.full; + }); + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/mediaType.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/mediaType.js new file mode 100644 index 00000000000..bf2c19bf64e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/mediaType.js @@ -0,0 +1,113 @@ +module.exports = preferredMediaTypes; +preferredMediaTypes.preferredMediaTypes = preferredMediaTypes; + +function parseAccept(accept) { + return accept.split(',').map(function(e) { + return parseMediaType(e.trim()); + }).filter(function(e) { + return e; + }); +}; + +function parseMediaType(s) { + var match = s.match(/\s*(\S+)\/([^;\s]+)\s*(?:;(.*))?/); + if (!match) return null; + + var type = match[1], + subtype = match[2], + full = "" + type + "/" + subtype, + params = {}, + q = 1; + + if (match[3]) { + params = match[3].split(';').map(function(s) { + return s.trim().split('='); + }).reduce(function (set, p) { + set[p[0]] = p[1]; + return set + }, params); + + if (params.q != null) { + q = parseFloat(params.q); + delete params.q; + } + } + + return { + type: type, + subtype: subtype, + params: params, + q: q, + full: full + }; +} + +function getMediaTypePriority(type, accepted) { + return (accepted.map(function(a) { + return specify(type, a); + }).filter(Boolean).sort(function (a, b) { + // revsort + return a.s > b.s ? -1 : 1; + })[0] || {q:0}).q; +} + +function specify(type, spec) { + var p = parseMediaType(type); + var s = 0; + if(spec.type == p.type) { + s |= 4 + } else if(spec.type != '*') { + return null; + } + + if(spec.subtype == p.subtype) { + s |= 2 + } else if(spec.subtype != '*') { + return null; + } + + var keys = Object.keys(spec.params); + if (keys.length > 0) { + if (keys.every(function (k) { + return spec.params[k] == '*' || spec.params[k] == p.params[k]; + })) { + s |= 1 + } else { + return null + } + } + + return { + q: spec.q, + s: s, + } + +} + +function preferredMediaTypes(accept, provided) { + accept = parseAccept(accept || ''); + if (provided) { + return provided.map(function(type) { + return [type, getMediaTypePriority(type, accept)]; + }).filter(function(pair) { + return pair[1] > 0; + }).sort(function(a, b) { + // revsort + return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1; + }).map(function(pair) { + return pair[0]; + }); + + } else { + return accept.sort(function (a, b) { + // revsort + return a.q < b.q ? 1 : -1; + }).filter(function(type) { + return type.q > 0; + }).map(function(type) { + return type.full; + }); + } +} + + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/negotiator.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/negotiator.js new file mode 100644 index 00000000000..ba0c48b9d7a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/lib/negotiator.js @@ -0,0 +1,37 @@ +module.exports = Negotiator; +Negotiator.Negotiator = Negotiator; + +function Negotiator(request) { + if (!(this instanceof Negotiator)) return new Negotiator(request); + this.request = request; +} + +var set = { charset: 'accept-charset', + encoding: 'accept-encoding', + language: 'accept-language', + mediaType: 'accept' }; + + +function capitalize(string){ + return string.charAt(0).toUpperCase() + string.slice(1); +} + +Object.keys(set).forEach(function (k) { + var header = set[k], + method = require('./'+k+'.js'), + singular = k, + plural = k + 's'; + + Negotiator.prototype[plural] = function (available) { + return method(this.request.headers[header], available); + }; + + Negotiator.prototype[singular] = function(available) { + var set = this[plural](available); + if (set) return set[0]; + }; + + // Keep preferred* methods for legacy compatibility + Negotiator.prototype['preferred'+capitalize(plural)] = Negotiator.prototype[plural]; + Negotiator.prototype['preferred'+capitalize(singular)] = Negotiator.prototype[singular]; +}) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/package.json new file mode 100644 index 00000000000..9b9ea7d473d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/package.json @@ -0,0 +1,53 @@ +{ + "name": "negotiator", + "description": "HTTP content negotiation", + "version": "0.4.2", + "author": { + "name": "Federico Romero", + "email": "federico.romero@outboxlabs.com" + }, + "contributors": [ + { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/federomero/negotiator.git" + }, + "keywords": [ + "http", + "content negotiation", + "accept", + "accept-language", + "accept-encoding", + "accept-charset" + ], + "engine": "node >= 0.6", + "license": "MIT", + "devDependencies": { + "nodeunit": "0.8.x" + }, + "scripts": { + "test": "nodeunit test" + }, + "optionalDependencies": {}, + "engines": { + "node": "*" + }, + "main": "lib/negotiator.js", + "readme": "# Negotiator [![Build Status](https://travis-ci.org/federomero/negotiator.png)](https://travis-ci.org/federomero/negotiator)\n\nAn HTTP content negotiator for node.js written in javascript.\n\n# Accept Negotiation\n\n Negotiator = require('negotiator')\n\n availableMediaTypes = ['text/html', 'text/plain', 'application/json']\n\n // The negotiator constructor receives a request object\n negotiator = new Negotiator(request)\n\n // Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'\n\n negotiator.mediaTypes()\n // -> ['text/html', 'image/jpeg', 'application/*']\n\n negotiator.mediaTypes(availableMediaTypes)\n // -> ['text/html', 'application/json']\n\n negotiator.mediaType(availableMediaTypes)\n // -> 'text/html'\n\nYou can check a working example at `examples/accept.js`.\n\n## Methods\n\n`mediaTypes(availableMediaTypes)`:\n\nReturns an array of preferred media types ordered by priority from a list of available media types.\n\n`mediaType(availableMediaType)`:\n\nReturns the top preferred media type from a list of available media types.\n\n# Accept-Language Negotiation\n\n Negotiator = require('negotiator')\n\n negotiator = new Negotiator(request)\n\n availableLanguages = 'en', 'es', 'fr'\n\n // Let's say Accept-Language header is 'en;q=0.8, es, pt'\n\n negotiator.languages()\n // -> ['es', 'pt', 'en']\n\n negotiator.languages(availableLanguages)\n // -> ['es', 'en']\n\n language = negotiator.language(availableLanguages)\n // -> 'es'\n\nYou can check a working example at `examples/language.js`.\n\n## Methods\n\n`languages(availableLanguages)`:\n\nReturns an array of preferred languages ordered by priority from a list of available languages.\n\n`language(availableLanguages)`:\n\nReturns the top preferred language from a list of available languages.\n\n# Accept-Charset Negotiation\n\n Negotiator = require('negotiator')\n\n availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']\n\n negotiator = new Negotiator(request)\n\n // Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'\n\n negotiator.charsets()\n // -> ['utf-8', 'iso-8859-1', 'utf-7']\n\n negotiator.charsets(availableCharsets)\n // -> ['utf-8', 'iso-8859-1']\n\n negotiator.charset(availableCharsets)\n // -> 'utf-8'\n\nYou can check a working example at `examples/charset.js`.\n\n## Methods\n\n`charsets(availableCharsets)`:\n\nReturns an array of preferred charsets ordered by priority from a list of available charsets.\n\n`charset(availableCharsets)`:\n\nReturns the top preferred charset from a list of available charsets.\n\n# Accept-Encoding Negotiation\n\n Negotiator = require('negotiator').Negotiator\n\n availableEncodings = ['identity', 'gzip']\n\n negotiator = new Negotiator(request)\n\n // Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'\n\n negotiator.encodings()\n // -> ['gzip', 'identity', 'compress']\n\n negotiator.encodings(availableEncodings)\n // -> ['gzip', 'identity']\n\n negotiator.encoding(availableEncodings)\n // -> 'gzip'\n\nYou can check a working example at `examples/encoding.js`.\n\n## Methods\n\n`encodings(availableEncodings)`:\n\nReturns an array of preferred encodings ordered by priority from a list of available encodings.\n\n`encoding(availableEncodings)`:\n\nReturns the top preferred encoding from a list of available encodings.\n\n# License\n\nMIT\n", + "readmeFilename": "readme.md", + "bugs": { + "url": "https://github.com/federomero/negotiator/issues" + }, + "dependencies": {}, + "_id": "negotiator@0.4.2", + "dist": { + "shasum": "8c43ea7e4c40ddfe40c3c0234c4ef77500b8fd37" + }, + "_from": "negotiator@0.4.2", + "_resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.2.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/readme.md new file mode 100644 index 00000000000..d982a9c1f37 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/readme.md @@ -0,0 +1,132 @@ +# Negotiator [![Build Status](https://travis-ci.org/federomero/negotiator.png)](https://travis-ci.org/federomero/negotiator) + +An HTTP content negotiator for node.js written in javascript. + +# Accept Negotiation + + Negotiator = require('negotiator') + + availableMediaTypes = ['text/html', 'text/plain', 'application/json'] + + // The negotiator constructor receives a request object + negotiator = new Negotiator(request) + + // Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8' + + negotiator.mediaTypes() + // -> ['text/html', 'image/jpeg', 'application/*'] + + negotiator.mediaTypes(availableMediaTypes) + // -> ['text/html', 'application/json'] + + negotiator.mediaType(availableMediaTypes) + // -> 'text/html' + +You can check a working example at `examples/accept.js`. + +## Methods + +`mediaTypes(availableMediaTypes)`: + +Returns an array of preferred media types ordered by priority from a list of available media types. + +`mediaType(availableMediaType)`: + +Returns the top preferred media type from a list of available media types. + +# Accept-Language Negotiation + + Negotiator = require('negotiator') + + negotiator = new Negotiator(request) + + availableLanguages = 'en', 'es', 'fr' + + // Let's say Accept-Language header is 'en;q=0.8, es, pt' + + negotiator.languages() + // -> ['es', 'pt', 'en'] + + negotiator.languages(availableLanguages) + // -> ['es', 'en'] + + language = negotiator.language(availableLanguages) + // -> 'es' + +You can check a working example at `examples/language.js`. + +## Methods + +`languages(availableLanguages)`: + +Returns an array of preferred languages ordered by priority from a list of available languages. + +`language(availableLanguages)`: + +Returns the top preferred language from a list of available languages. + +# Accept-Charset Negotiation + + Negotiator = require('negotiator') + + availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5'] + + negotiator = new Negotiator(request) + + // Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2' + + negotiator.charsets() + // -> ['utf-8', 'iso-8859-1', 'utf-7'] + + negotiator.charsets(availableCharsets) + // -> ['utf-8', 'iso-8859-1'] + + negotiator.charset(availableCharsets) + // -> 'utf-8' + +You can check a working example at `examples/charset.js`. + +## Methods + +`charsets(availableCharsets)`: + +Returns an array of preferred charsets ordered by priority from a list of available charsets. + +`charset(availableCharsets)`: + +Returns the top preferred charset from a list of available charsets. + +# Accept-Encoding Negotiation + + Negotiator = require('negotiator').Negotiator + + availableEncodings = ['identity', 'gzip'] + + negotiator = new Negotiator(request) + + // Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5' + + negotiator.encodings() + // -> ['gzip', 'identity', 'compress'] + + negotiator.encodings(availableEncodings) + // -> ['gzip', 'identity'] + + negotiator.encoding(availableEncodings) + // -> 'gzip' + +You can check a working example at `examples/encoding.js`. + +## Methods + +`encodings(availableEncodings)`: + +Returns an array of preferred encodings ordered by priority from a list of available encodings. + +`encoding(availableEncodings)`: + +Returns the top preferred encoding from a list of available encodings. + +# License + +MIT diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/charset.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/charset.js new file mode 100644 index 00000000000..34fe2619790 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/charset.js @@ -0,0 +1,66 @@ +(function() { + var configuration, preferredCharsets, testConfigurations, testCorrectCharset, _i, _len, + _this = this; + + preferredCharsets = require('../lib/charset').preferredCharsets; + + this["Should not return a charset when no charset is provided"] = function(test) { + test.deepEqual(preferredCharsets('*', []), []); + return test.done(); + }; + + this["Should not return a charset when no charset is acceptable"] = function(test) { + test.deepEqual(preferredCharsets('ISO-8859-1', ['utf-8']), []); + return test.done(); + }; + + this["Should not return a charset with q = 0"] = function(test) { + test.deepEqual(preferredCharsets('utf-8;q=0', ['utf-8']), []); + return test.done(); + }; + + testCorrectCharset = function(c) { + return _this["Should return " + c.selected + " for accept-charset header " + c.accept + " with provided charset " + c.provided] = function(test) { + test.deepEqual(preferredCharsets(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'utf-8', + provided: ['utf-8'], + selected: ['utf-8'] + }, { + accept: '*', + provided: ['utf-8'], + selected: ['utf-8'] + }, { + accept: 'utf-8', + provided: ['utf-8', 'ISO-8859-1'], + selected: ['utf-8'] + }, { + accept: 'utf-8, ISO-8859-1', + provided: ['utf-8'], + selected: ['utf-8'] + }, { + accept: 'utf-8;q=0.8, ISO-8859-1', + provided: ['utf-8', 'ISO-8859-1'], + selected: ['ISO-8859-1', 'utf-8'] + }, { + accept: 'utf-8;q=0.8, ISO-8859-1', + provided: null, + selected: ['ISO-8859-1', 'utf-8'] + }, { + accept: '*, utf-8;q=0', + provided: ['utf-8', 'ISO-8859-1'], + selected: ['ISO-8859-1'] + } + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectCharset(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/encoding.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/encoding.js new file mode 100644 index 00000000000..b28c5b585d4 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/encoding.js @@ -0,0 +1,84 @@ +(function() { + var configuration, preferredEncodings, testConfigurations, testCorrectEncoding, _i, _len, + _this = this; + + preferredEncodings = require('../lib/encoding').preferredEncodings; + + this["Should return identity encoding when no encoding is provided"] = function(test) { + test.deepEqual(preferredEncodings(null), ['identity']); + return test.done(); + }; + + this["Should include the identity encoding even if not explicity listed"] = function(test) { + test.ok(preferredEncodings('gzip').indexOf('identity') !== -1); + return test.done(); + }; + + this["Should not return identity encoding if q = 0"] = function(test) { + test.ok(preferredEncodings('identity;q=0').indexOf('identity') === -1); + return test.done(); + }; + + this["Should not return identity encoding if * has q = 0"] = function(test) { + test.ok(preferredEncodings('*;q=0').indexOf('identity') === -1); + return test.done(); + }; + + this["Should not return identity encoding if * has q = 0 but identity explicitly has q > 0"] = function(test) { + test.ok(preferredEncodings('*;q=0, identity;q=0.5').indexOf('identity') !== -1); + return test.done(); + }; + + testCorrectEncoding = function(c) { + return _this["Should return " + c.selected + " for accept-encoding header " + c.accept + " with provided encoding " + c.provided] = function(test) { + test.deepEqual(preferredEncodings(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'gzip', + provided: ['identity', 'gzip'], + selected: ['gzip', 'identity'] + }, { + accept: 'gzip, compress', + provided: ['compress'], + selected: ['compress'] + }, { + accept: 'deflate', + provided: ['gzip', 'identity'], + selected: ['identity'] + }, { + accept: '*', + provided: ['identity', 'gzip'], + selected: ['identity', 'gzip'] + }, { + accept: 'gzip, compress', + provided: ['compress', 'identity'], + selected: ['compress', 'identity'] + }, { + accept: 'gzip;q=0.8, identity;q=0.5, *;q=0.3', + provided: ['identity', 'gzip', 'compress'], + selected: ['gzip', 'identity', 'compress'] + }, { + accept: 'gzip;q=0.8, compress', + provided: ['gzip', 'compress'], + selected: ['compress', 'gzip'] + }, { + accept: '*, compress;q=0', + provided: ['gzip', 'compress'], + selected: ['gzip'] + }, { + accept: 'gzip;q=0.8, compress', + provided: null, + selected: ['compress', 'gzip', 'identity'] + } + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectEncoding(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/language.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/language.js new file mode 100644 index 00000000000..fbd45a4bb1d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/language.js @@ -0,0 +1,74 @@ +(function() { + var configuration, preferredLanguages, testConfigurations, testCorrectType, _i, _len, + _this = this; + + preferredLanguages = require('../lib/language').preferredLanguages; + + this["Should not return a language when no is provided"] = function(test) { + test.deepEqual(preferredLanguages('*', []), []); + return test.done(); + }; + + this["Should not return a language when no language is acceptable"] = function(test) { + test.deepEqual(preferredLanguages('en', ['es']), []); + return test.done(); + }; + + this["Should not return a language with q = 0"] = function(test) { + test.deepEqual(preferredLanguages('en;q=0', ['en']), []); + return test.done(); + }; + + testCorrectType = function(c) { + return _this["Should return " + c.selected + " for accept-language header " + c.accept + " with provided language " + c.provided] = function(test) { + test.deepEqual(preferredLanguages(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'en', + provided: ['en'], + selected: ['en'] + }, { + accept: '*', + provided: ['en'], + selected: ['en'] + }, { + accept: 'en-US, en;q=0.8', + provided: ['en-US', 'en-GB'], + selected: ['en-US', 'en-GB'] + }, { + accept: 'en-US, en-GB', + provided: ['en-US'], + selected: ['en-US'] + }, { + accept: 'en', + provided: ['en-US'], + selected: ['en-US'] + }, { + accept: 'en;q=0.8, es', + provided: ['en', 'es'], + selected: ['es', 'en'] + }, { + accept: 'en-US;q=0.8, es', + provided: ['en', 'es'], + selected: ['es', 'en'] + }, { + accept: '*, en;q=0', + provided: ['en', 'es'], + selected: ['es'] + }, { + accept: 'en-US;q=0.8, es', + provided: null, + selected: ['es', 'en-US'] + } + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectType(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/mediaType.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/mediaType.js new file mode 100644 index 00000000000..622afdbed30 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/node_modules/negotiator/test/mediaType.js @@ -0,0 +1,111 @@ +(function() { + var configuration, preferredMediaTypes, testConfigurations, testCorrectType, _i, _len, + _this = this; + + preferredMediaTypes = require('../lib/mediaType').preferredMediaTypes; + + this["Should not return a media type when no media type provided"] = function(test) { + test.deepEqual(preferredMediaTypes('*/*', []), []); + return test.done(); + }; + + this["Should not return a media type when no media type is acceptable"] = function(test) { + test.deepEqual(preferredMediaTypes('application/json', ['text/html']), []); + return test.done(); + }; + + this["Should not return a media type with q = 0"] = function(test) { + test.deepEqual(preferredMediaTypes('text/html;q=0', ['text/html']), []); + return test.done(); + }; + + testCorrectType = function(c) { + return _this["Should return " + c.selected + " for access header " + c.accept + " with provided types " + c.provided] = function(test) { + test.deepEqual(preferredMediaTypes(c.accept, c.provided), c.selected); + return test.done(); + }; + }; + + testConfigurations = [ + { + accept: 'text/html', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: '*/*', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'text/*', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'application/json, text/html', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'text/html;q=0.1', + provided: ['text/html'], + selected: ['text/html'] + }, { + accept: 'application/json, text/html', + provided: ['application/json', 'text/html'], + selected: ['application/json', 'text/html'] + }, { + accept: 'application/json;q=0.2, text/html', + provided: ['application/json', 'text/html'], + selected: ['text/html', 'application/json'] + }, { + accept: 'application/json;q=0.2, text/html', + provided: null, + selected: ['text/html', 'application/json'] + }, { + accept: 'text/*, text/html;q=0', + provided: ['text/html', 'text/plain'], + selected: ['text/plain'] + }, { + accept: 'text/*, text/html;q=0.5', + provided: ['text/html', 'text/plain'], + selected: ['text/plain', 'text/html'] + }, { + accept: 'application/json, */*; q=0.01', + provided: ['text/html', 'application/json'], + selected: ['application/json', 'text/html'] + }, { + accept: 'application/vnd.example;attribute=value', + provided: ['application/vnd.example;attribute=other', 'application/vnd.example;attribute=value'], + selected: ['application/vnd.example;attribute=value'] + }, { + accept: 'application/vnd.example;attribute=other', + provided: ['application/vnd.example', 'application/vnd.example;attribute=other'], + selected: ['application/vnd.example;attribute=other'] + }, { + accept: 'text/html;level=1', + provided: ['text/html;level=1;foo=bar'], + selected: ['text/html;level=1;foo=bar'] + }, { + accept: 'text/html;level=1;foo=bar', + provided: ['text/html;level=1'], + selected: [] + }, { + accept: 'text/html;level=2', + provided: ['text/html;level=1'], + selected: [] + }, { + accept : 'text/html, text/html;level=1;q=0.1', + provided : ['text/html', 'text/html;level=1'], + selected : ['text/html', 'text/html;level=1'] + }, { + accept : 'text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5', + provided : ['text/html;level=1', 'text/html', 'text/html;level=3', 'image/jpeg', 'text/html;level=2', 'text/plain'], + selected : ['text/html;level=1', 'text/html', 'text/html;level=3', 'image/jpeg', 'text/html;level=2', 'text/plain'] + } + + ]; + + for (_i = 0, _len = testConfigurations.length; _i < _len; _i++) { + configuration = testConfigurations[_i]; + testCorrectType(configuration); + } + +}).call(this); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/package.json new file mode 100644 index 00000000000..5a36e0dd6f7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/package.json @@ -0,0 +1,41 @@ +{ + "name": "serve-index", + "description": "Serve directory listings", + "version": "1.0.1", + "author": { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/serve-index.git" + }, + "bugs": { + "url": "https://github.com/expressjs/serve-index/issues" + }, + "dependencies": { + "batch": "0.5.0", + "negotiator": "0.4.2" + }, + "devDependencies": { + "connect": "^2.13.0", + "mocha": "^1.17.0", + "should": "^3.0.0", + "supertest": "~0.9.0" + }, + "engines": { + "node": ">= 0.8.0" + }, + "scripts": { + "test": "mocha --reporter spec --require should" + }, + "readme": "# Serve Index\n\nPreviously `connect.directory()`.\n\nUsage:\n\n```js\nvar connect = require('connect');\nvar serveIndex = require('serve-index');\n\nvar app = connect();\n\napp.use(serveIndex('public/ftp', {'icons': true}));\napp.listen();\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Douglas Christopher Wilson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\nThe [Silk](http://www.famfamfam.com/lab/icons/silk/) icons are created\nby/copyright of [FAMFAMFAM](http://www.famfamfam.com/).\n", + "readmeFilename": "Readme.md", + "_id": "serve-index@1.0.1", + "dist": { + "shasum": "f23770c8a37731a1c972633b922a8e289a0e169f" + }, + "_from": "serve-index@1.0.1", + "_resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.0.1.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/directory.html b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/directory.html new file mode 100644 index 00000000000..8ed8b4ae7d3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/directory.html @@ -0,0 +1,82 @@ + + + + + + listing directory {directory} + + + + + +
    +

    {linked-path}

    + {files} +
    + + \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/application_xp.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/application_xp.png new file mode 100644 index 00000000000..d22860a3166 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/application_xp.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/application_xp_terminal.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/application_xp_terminal.png new file mode 100644 index 00000000000..c28dd63812d Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/application_xp_terminal.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/box.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/box.png new file mode 100644 index 00000000000..8443c23eb94 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/box.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/cd.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/cd.png new file mode 100644 index 00000000000..ef4322357cb Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/cd.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/controller.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/controller.png new file mode 100644 index 00000000000..5cf76ed029a Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/controller.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/drive.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/drive.png new file mode 100644 index 00000000000..37b7c9b27d3 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/drive.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/film.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/film.png new file mode 100644 index 00000000000..b0ce7bb198a Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/film.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/folder.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/folder.png new file mode 100644 index 00000000000..698f3d30368 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/folder.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/font.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/font.png new file mode 100644 index 00000000000..b7960db9dae Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/font.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/image.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/image.png new file mode 100644 index 00000000000..fc3c393caa3 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/image.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/map.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/map.png new file mode 100644 index 00000000000..f90ef25ec7f Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/map.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page.png new file mode 100644 index 00000000000..03ddd799fa0 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_add.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_add.png new file mode 100644 index 00000000000..d5bfa0719bc Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_add.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_attach.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_attach.png new file mode 100644 index 00000000000..89ee2da0753 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_attach.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_code.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_code.png new file mode 100644 index 00000000000..f7ea90419d9 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_code.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_copy.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_copy.png new file mode 100644 index 00000000000..195dc6d6c36 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_copy.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_delete.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_delete.png new file mode 100644 index 00000000000..3141467c678 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_delete.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_edit.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_edit.png new file mode 100644 index 00000000000..046811ed7a6 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_edit.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_error.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_error.png new file mode 100644 index 00000000000..f07f449a44f Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_error.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_excel.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_excel.png new file mode 100644 index 00000000000..eb6158eb5ca Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_excel.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_find.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_find.png new file mode 100644 index 00000000000..2f193889f7e Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_find.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_gear.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_gear.png new file mode 100644 index 00000000000..8e83281c5f8 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_gear.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_go.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_go.png new file mode 100644 index 00000000000..80fe1ed0cc7 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_go.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_green.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_green.png new file mode 100644 index 00000000000..de8e003f9fb Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_green.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_key.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_key.png new file mode 100644 index 00000000000..d6626cb09eb Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_key.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_lightning.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_lightning.png new file mode 100644 index 00000000000..7e568703d64 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_lightning.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_link.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_link.png new file mode 100644 index 00000000000..312eab0914a Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_link.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_paintbrush.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_paintbrush.png new file mode 100644 index 00000000000..246a2f0b426 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_paintbrush.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_paste.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_paste.png new file mode 100644 index 00000000000..968f073fddd Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_paste.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_red.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_red.png new file mode 100644 index 00000000000..0b18247da58 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_red.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_refresh.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_refresh.png new file mode 100644 index 00000000000..cf347c7d468 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_refresh.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_save.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_save.png new file mode 100644 index 00000000000..caea546af54 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_save.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white.png new file mode 100644 index 00000000000..8b8b1ca0000 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_acrobat.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_acrobat.png new file mode 100644 index 00000000000..8f8095e46fa Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_acrobat.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_actionscript.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_actionscript.png new file mode 100644 index 00000000000..159b2407519 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_actionscript.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_add.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_add.png new file mode 100644 index 00000000000..aa23dde3746 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_add.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_c.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_c.png new file mode 100644 index 00000000000..34a05cccf06 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_c.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_camera.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_camera.png new file mode 100644 index 00000000000..f501a593a4e Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_camera.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cd.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cd.png new file mode 100644 index 00000000000..848bdaf3f15 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cd.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_code.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_code.png new file mode 100644 index 00000000000..0c76bd12977 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_code.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_code_red.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_code_red.png new file mode 100644 index 00000000000..87a69145075 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_code_red.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_coldfusion.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_coldfusion.png new file mode 100644 index 00000000000..c66011fb0fb Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_coldfusion.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_compressed.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_compressed.png new file mode 100644 index 00000000000..2b6b1007f33 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_compressed.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_copy.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_copy.png new file mode 100644 index 00000000000..a9f31a278e1 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_copy.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cplusplus.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cplusplus.png new file mode 100644 index 00000000000..a87cf847cb7 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cplusplus.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_csharp.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_csharp.png new file mode 100644 index 00000000000..ffb8fc932f3 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_csharp.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cup.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cup.png new file mode 100644 index 00000000000..0a7d6f4a6f6 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_cup.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_database.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_database.png new file mode 100644 index 00000000000..bddba1f98ca Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_database.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_delete.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_delete.png new file mode 100644 index 00000000000..af1ecaf2981 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_delete.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_dvd.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_dvd.png new file mode 100644 index 00000000000..4cc537af0b3 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_dvd.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_edit.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_edit.png new file mode 100644 index 00000000000..b93e77600de Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_edit.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_error.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_error.png new file mode 100644 index 00000000000..9fc5a0a103d Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_error.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_excel.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_excel.png new file mode 100644 index 00000000000..b977d7e52e2 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_excel.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_find.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_find.png new file mode 100644 index 00000000000..58184363707 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_find.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_flash.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_flash.png new file mode 100644 index 00000000000..5769120b1b6 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_flash.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_freehand.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_freehand.png new file mode 100644 index 00000000000..8d719df5205 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_freehand.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_gear.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_gear.png new file mode 100644 index 00000000000..106f5aa3611 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_gear.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_get.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_get.png new file mode 100644 index 00000000000..e4a1ecba1b6 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_get.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_go.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_go.png new file mode 100644 index 00000000000..7e62a924bc5 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_go.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_h.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_h.png new file mode 100644 index 00000000000..e902abb0767 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_h.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_horizontal.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_horizontal.png new file mode 100644 index 00000000000..1d2d0a49870 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_horizontal.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_key.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_key.png new file mode 100644 index 00000000000..d6164845228 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_key.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_lightning.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_lightning.png new file mode 100644 index 00000000000..7215d1e8b06 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_lightning.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_link.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_link.png new file mode 100644 index 00000000000..bf7bd1c9bfd Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_link.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_magnify.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_magnify.png new file mode 100644 index 00000000000..f6b74cc40f8 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_magnify.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_medal.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_medal.png new file mode 100644 index 00000000000..d3fffb6d989 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_medal.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_office.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_office.png new file mode 100644 index 00000000000..a65bcb3e1e9 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_office.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paint.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paint.png new file mode 100644 index 00000000000..23a37b891c2 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paint.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paintbrush.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paintbrush.png new file mode 100644 index 00000000000..f907e44b333 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paintbrush.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paste.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paste.png new file mode 100644 index 00000000000..5b2cbb3fd02 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_paste.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_php.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_php.png new file mode 100644 index 00000000000..7868a25945c Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_php.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_picture.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_picture.png new file mode 100644 index 00000000000..134b6693687 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_picture.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_powerpoint.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_powerpoint.png new file mode 100644 index 00000000000..c4eff0387d5 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_powerpoint.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_put.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_put.png new file mode 100644 index 00000000000..884ffd6f0aa Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_put.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_ruby.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_ruby.png new file mode 100644 index 00000000000..f59b7c4365f Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_ruby.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_stack.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_stack.png new file mode 100644 index 00000000000..44084add79b Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_stack.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_star.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_star.png new file mode 100644 index 00000000000..3a1441c9a12 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_star.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_swoosh.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_swoosh.png new file mode 100644 index 00000000000..e7708292ada Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_swoosh.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_text.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_text.png new file mode 100644 index 00000000000..813f712f726 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_text.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_text_width.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_text_width.png new file mode 100644 index 00000000000..d9cf13256f4 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_text_width.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_tux.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_tux.png new file mode 100644 index 00000000000..52699bfee0c Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_tux.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_vector.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_vector.png new file mode 100644 index 00000000000..4a05955b337 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_vector.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_visualstudio.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_visualstudio.png new file mode 100644 index 00000000000..a0a433dfbb6 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_visualstudio.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_width.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_width.png new file mode 100644 index 00000000000..1eb880947dd Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_width.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_word.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_word.png new file mode 100644 index 00000000000..ae8ecbf4767 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_word.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_world.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_world.png new file mode 100644 index 00000000000..6ed2490ed14 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_world.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_wrench.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_wrench.png new file mode 100644 index 00000000000..fecadd08afe Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_wrench.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_zip.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_zip.png new file mode 100644 index 00000000000..fd4bbccdf16 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_white_zip.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_word.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_word.png new file mode 100644 index 00000000000..834cdfaf48a Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_word.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_world.png b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_world.png new file mode 100644 index 00000000000..b8895ddecf5 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/icons/page_world.png differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/style.css b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/style.css new file mode 100644 index 00000000000..0709908a666 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-index/public/style.css @@ -0,0 +1,257 @@ +* { + margin: 0; + padding: 0; + outline: 0; +} + +body { + padding: 80px 100px; + font: 13px "Helvetica Neue", "Lucida Grande", "Arial"; + background: #ECE9E9 -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ECE9E9)); + background: #ECE9E9 -moz-linear-gradient(top, #fff, #ECE9E9); + background-repeat: no-repeat; + color: #555; + -webkit-font-smoothing: antialiased; +} +h1, h2, h3 { + font-size: 22px; + color: #343434; +} +h1 em, h2 em { + padding: 0 5px; + font-weight: normal; +} +h1 { + font-size: 60px; +} +h2 { + margin-top: 10px; +} +h3 { + margin: 5px 0 10px 0; + padding-bottom: 5px; + border-bottom: 1px solid #eee; + font-size: 18px; +} +ul li { + list-style: none; +} +ul li:hover { + cursor: pointer; + color: #2e2e2e; +} +ul li .path { + padding-left: 5px; + font-weight: bold; +} +ul li .line { + padding-right: 5px; + font-style: italic; +} +ul li:first-child .path { + padding-left: 0; +} +p { + line-height: 1.5; +} +a { + color: #555; + text-decoration: none; +} +a:hover { + color: #303030; +} +#stacktrace { + margin-top: 15px; +} +.directory h1 { + margin-bottom: 15px; + font-size: 18px; +} +ul#files { + width: 100%; + height: 100%; + overflow: hidden; +} +ul#files li { + float: left; + width: 30%; + line-height: 25px; + margin: 1px; +} +ul#files li a { + display: block; + height: 25px; + border: 1px solid transparent; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + overflow: hidden; + white-space: nowrap; +} +ul#files li a:focus, +ul#files li a:hover { + background: rgba(255,255,255,0.65); + border: 1px solid #ececec; +} +ul#files li a.highlight { + -webkit-transition: background .4s ease-in-out; + background: #ffff4f; + border-color: #E9DC51; +} +#search { + display: block; + position: fixed; + top: 20px; + right: 20px; + width: 90px; + -webkit-transition: width ease 0.2s, opacity ease 0.4s; + -moz-transition: width ease 0.2s, opacity ease 0.4s; + -webkit-border-radius: 32px; + -moz-border-radius: 32px; + -webkit-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); + -moz-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); + -webkit-font-smoothing: antialiased; + text-align: left; + font: 13px "Helvetica Neue", Arial, sans-serif; + padding: 4px 10px; + border: none; + background: transparent; + margin-bottom: 0; + outline: none; + opacity: 0.7; + color: #888; +} +#search:focus { + width: 120px; + opacity: 1.0; +} + +/*views*/ +#files span { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + text-indent: 10px; +} +#files .name { + background-repeat: no-repeat; +} +#files .icon .name { + text-indent: 28px; +} + +/*tiles*/ +.view-tiles .name { + width: 100%; + background-position: 8px 5px; +} +.view-tiles .size, +.view-tiles .date { + display: none; +} + +/*details*/ +ul#files.view-details li { + float: none; + display: block; + width: 90%; +} +ul#files.view-details li.header { + height: 25px; + background: #000; + color: #fff; + font-weight: bold; +} +.view-details .header { + border-radius: 5px; +} +.view-details .name { + width: 60%; + background-position: 8px 5px; +} +.view-details .size { + width: 10%; +} +.view-details .date { + width: 30%; +} +.view-details .size, +.view-details .date { + text-align: right; + direction: rtl; +} + +/*mobile*/ +@media (max-width: 768px) { + body { + font-size: 13px; + line-height: 16px; + padding: 0; + } + #search { + position: static; + width: 100%; + font-size: 2em; + line-height: 1.8em; + text-indent: 10px; + border: 0; + border-radius: 0; + padding: 10px 0; + margin: 0; + } + #search:focus { + width: 100%; + border: 0; + opacity: 1; + } + .directory h1 { + font-size: 2em; + line-height: 1.5em; + color: #fff; + background: #000; + padding: 15px 10px; + margin: 0; + } + ul#files { + border-top: 1px solid #cacaca; + } + ul#files li { + float: none; + width: auto !important; + display: block; + border-bottom: 1px solid #cacaca; + font-size: 2em; + line-height: 1.2em; + text-indent: 0; + margin: 0; + } + ul#files li:nth-child(odd) { + background: #e0e0e0; + } + ul#files li a { + height: auto; + border: 0; + border-radius: 0; + padding: 15px 10px; + } + ul#files li a:focus, + ul#files li a:hover { + border: 0; + } + #files .header, + #files .size, + #files .date { + display: none !important; + } + #files .name { + float: none; + display: inline-block; + width: 100%; + text-indent: 0; + background-position: 0 0; + } + #files .icon .name { + text-indent: 41px; + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/.npmignore new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/.npmignore @@ -0,0 +1 @@ +test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/.travis.yml new file mode 100644 index 00000000000..cc4dba29d95 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/LICENSE new file mode 100644 index 00000000000..b7bc0852e3f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/LICENSE @@ -0,0 +1,25 @@ +(The MIT License) + +Copyright (c) 2010 Sencha Inc. +Copyright (c) 2011 LearnBoost +Copyright (c) 2011 TJ Holowaychuk +Copyright (c) 2014 Douglas Christopher Wilson + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/Readme.md new file mode 100644 index 00000000000..4daf806f22a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/Readme.md @@ -0,0 +1,39 @@ +# Serve Static + +Previously `connect.static()`. + +Usage: + +```js +var connect = require('connect'); +var serveStatic = require('serve-static'); + +var app = connect(); + +app.use(serveStatic('public/ftp', {'index': 'default.html'})); +app.listen(); +``` + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Douglas Christopher Wilson + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/index.js new file mode 100644 index 00000000000..310051f4618 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/index.js @@ -0,0 +1,131 @@ +/*! + * Connect - static + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var send = require('send'); +var url = require('url'); + +/** + * Static: + * + * Static file server with the given `root` path. + * + * Examples: + * + * var oneDay = 86400000; + * var serveStatic = require('serve-static'); + * + * connect() + * .use(serveStatic(__dirname + '/public')) + * + * connect() + * .use(serveStatic(__dirname + '/public', { maxAge: oneDay })) + * + * Options: + * + * - `maxAge` Browser cache maxAge in milliseconds. defaults to 0 + * - `hidden` Allow transfer of hidden files. defaults to false + * - `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to true + * - `index` Default file name, defaults to 'index.html' + * + * @param {String} root + * @param {Object} options + * @return {Function} + * @api public + */ + +exports = module.exports = function(root, options){ + options = options || {}; + + // root required + if (!root) throw new TypeError('root path required'); + + // default redirect + var redirect = false !== options.redirect; + + return function staticMiddleware(req, res, next) { + if ('GET' != req.method && 'HEAD' != req.method) return next(); + var originalUrl = url.parse(req.originalUrl); + var path = parse(req).pathname; + + if (path == '/' && originalUrl.pathname[originalUrl.pathname.length - 1] != '/') { + return directory(); + } + + function directory() { + if (!redirect) return next(); + var target; + originalUrl.pathname += '/'; + target = url.format(originalUrl); + res.statusCode = 303; + res.setHeader('Location', target); + res.end('Redirecting to ' + escape(target)); + } + + function error(err) { + if (404 == err.status) return next(); + next(err); + } + + send(req, path) + .maxage(options.maxAge || 0) + .root(root) + .index(options.index || 'index.html') + .hidden(options.hidden) + .on('error', error) + .on('directory', directory) + .pipe(res); + }; +}; + +/** + * Expose mime module. + * + * If you wish to extend the mime table use this + * reference to the "mime" module in the npm registry. + */ + +exports.mime = send.mime; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +function escape(html) { + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Parse the `req` url. + * + * @param {ServerRequest} req + * @return {Object} + * @api private + */ + +function parse(req) { + var parsed = url.parse(req.url); + + if (parsed.auth && !parsed.protocol && ~parsed.href.indexOf('//')) { + // This parses pathnames, and a strange pathname like //r@e should work + parsed = url.parse(req.url.replace(/@/g, '%40')); + } + + return parsed; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/.npmignore new file mode 100644 index 00000000000..f1250e584c9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/History.md new file mode 100644 index 00000000000..50b76215b85 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/History.md @@ -0,0 +1,45 @@ + +0.2.0 / 2014-01-29 +================== + + * update range-parser and fresh + +0.1.4 / 2013-08-11 +================== + + * update fresh + +0.1.3 / 2013-07-08 +================== + + * Revert "Fix fd leak" + +0.1.2 / 2013-07-03 +================== + + * Fix fd leak + +0.1.0 / 2012-08-25 +================== + + * add options parameter to send() that is passed to fs.createReadStream() [kanongil] + +0.0.4 / 2012-08-16 +================== + + * allow custom "Accept-Ranges" definition + +0.0.3 / 2012-07-16 +================== + + * fix normalization of the root directory. Closes #3 + +0.0.2 / 2012-07-09 +================== + + * add passing of req explicitly for now (YUCK) + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/Makefile new file mode 100644 index 00000000000..a9dcfd50dbd --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/Makefile @@ -0,0 +1,8 @@ + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter spec \ + --bail + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/Readme.md new file mode 100644 index 00000000000..ea7b234109f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/Readme.md @@ -0,0 +1,128 @@ +# send + + Send is Connect's `static()` extracted for generalized use, a streaming static file + server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework. + +## Installation + + $ npm install send + +## Examples + + Small: + +```js +var http = require('http'); +var send = require('send'); + +var app = http.createServer(function(req, res){ + send(req, req.url).pipe(res); +}).listen(3000); +``` + + Serving from a root directory with custom error-handling: + +```js +var http = require('http'); +var send = require('send'); +var url = require('url'); + +var app = http.createServer(function(req, res){ + // your custom error-handling logic: + function error(err) { + res.statusCode = err.status || 500; + res.end(err.message); + } + + // your custom directory handling logic: + function redirect() { + res.statusCode = 301; + res.setHeader('Location', req.url + '/'); + res.end('Redirecting to ' + req.url + '/'); + } + + // transfer arbitrary files from within + // /www/example.com/public/* + send(req, url.parse(req.url).pathname) + .root('/www/example.com/public') + .on('error', error) + .on('directory', redirect) + .pipe(res); +}).listen(3000); +``` + +## API + +### Events + + - `error` an error occurred `(err)` + - `directory` a directory was requested + - `file` a file was requested `(path, stat)` + - `stream` file streaming has started `(stream)` + - `end` streaming has completed + +### .root(dir) + + Serve files relative to `path`. Aliased as `.from(dir)`. + +### .index(path) + + By default send supports "index.html" files, to disable this + invoke `.index(false)` or to supply a new index pass a string. + +### .maxage(ms) + + Provide a max-age in milliseconds for http caching, defaults to 0. + +### .hidden(bool) + + Enable or disable transfer of hidden files, defaults to false. + +## Error-handling + + By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc. + +## Caching + + It does _not_ perform internal caching, you should use a reverse proxy cache such + as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;). + +## Debugging + + To enable `debug()` instrumentation output export __DEBUG__: + +``` +$ DEBUG=send node app +``` + +## Running tests + +``` +$ npm install +$ make test +``` + +## License + +(The MIT License) + +Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/index.js new file mode 100644 index 00000000000..f17158d853e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/send'); \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/lib/send.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/lib/send.js new file mode 100644 index 00000000000..a3d94a69d45 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/lib/send.js @@ -0,0 +1,474 @@ + +/** + * Module dependencies. + */ + +var debug = require('debug')('send') + , parseRange = require('range-parser') + , Stream = require('stream') + , mime = require('mime') + , fresh = require('fresh') + , path = require('path') + , http = require('http') + , fs = require('fs') + , basename = path.basename + , normalize = path.normalize + , join = path.join + , utils = require('./utils'); + +/** + * Expose `send`. + */ + +exports = module.exports = send; + +/** + * Expose mime module. + */ + +exports.mime = mime; + +/** + * Return a `SendStream` for `req` and `path`. + * + * @param {Request} req + * @param {String} path + * @param {Object} options + * @return {SendStream} + * @api public + */ + +function send(req, path, options) { + return new SendStream(req, path, options); +} + +/** + * Initialize a `SendStream` with the given `path`. + * + * Events: + * + * - `error` an error occurred + * - `stream` file streaming has started + * - `end` streaming has completed + * - `directory` a directory was requested + * + * @param {Request} req + * @param {String} path + * @param {Object} options + * @api private + */ + +function SendStream(req, path, options) { + var self = this; + this.req = req; + this.path = path; + this.options = options || {}; + this.maxage(0); + this.hidden(false); + this.index('index.html'); +} + +/** + * Inherits from `Stream.prototype`. + */ + +SendStream.prototype.__proto__ = Stream.prototype; + +/** + * Enable or disable "hidden" (dot) files. + * + * @param {Boolean} path + * @return {SendStream} + * @api public + */ + +SendStream.prototype.hidden = function(val){ + debug('hidden %s', val); + this._hidden = val; + return this; +}; + +/** + * Set index `path`, set to a falsy + * value to disable index support. + * + * @param {String|Boolean} path + * @return {SendStream} + * @api public + */ + +SendStream.prototype.index = function(path){ + debug('index %s', path); + this._index = path; + return this; +}; + +/** + * Set root `path`. + * + * @param {String} path + * @return {SendStream} + * @api public + */ + +SendStream.prototype.root = +SendStream.prototype.from = function(path){ + this._root = normalize(path); + return this; +}; + +/** + * Set max-age to `ms`. + * + * @param {Number} ms + * @return {SendStream} + * @api public + */ + +SendStream.prototype.maxage = function(ms){ + if (Infinity == ms) ms = 60 * 60 * 24 * 365 * 1000; + debug('max-age %d', ms); + this._maxage = ms; + return this; +}; + +/** + * Emit error with `status`. + * + * @param {Number} status + * @api private + */ + +SendStream.prototype.error = function(status, err){ + var res = this.res; + var msg = http.STATUS_CODES[status]; + err = err || new Error(msg); + err.status = status; + if (this.listeners('error').length) return this.emit('error', err); + res.statusCode = err.status; + res.end(msg); +}; + +/** + * Check if the pathname is potentially malicious. + * + * @return {Boolean} + * @api private + */ + +SendStream.prototype.isMalicious = function(){ + return !this._root && ~this.path.indexOf('..'); +}; + +/** + * Check if the pathname ends with "/". + * + * @return {Boolean} + * @api private + */ + +SendStream.prototype.hasTrailingSlash = function(){ + return '/' == this.path[this.path.length - 1]; +}; + +/** + * Check if the basename leads with ".". + * + * @return {Boolean} + * @api private + */ + +SendStream.prototype.hasLeadingDot = function(){ + return '.' == basename(this.path)[0]; +}; + +/** + * Check if this is a conditional GET request. + * + * @return {Boolean} + * @api private + */ + +SendStream.prototype.isConditionalGET = function(){ + return this.req.headers['if-none-match'] + || this.req.headers['if-modified-since']; +}; + +/** + * Strip content-* header fields. + * + * @api private + */ + +SendStream.prototype.removeContentHeaderFields = function(){ + var res = this.res; + Object.keys(res._headers).forEach(function(field){ + if (0 == field.indexOf('content')) { + res.removeHeader(field); + } + }); +}; + +/** + * Respond with 304 not modified. + * + * @api private + */ + +SendStream.prototype.notModified = function(){ + var res = this.res; + debug('not modified'); + this.removeContentHeaderFields(); + res.statusCode = 304; + res.end(); +}; + +/** + * Check if the request is cacheable, aka + * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}). + * + * @return {Boolean} + * @api private + */ + +SendStream.prototype.isCachable = function(){ + var res = this.res; + return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode; +}; + +/** + * Handle stat() error. + * + * @param {Error} err + * @api private + */ + +SendStream.prototype.onStatError = function(err){ + var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR']; + if (~notfound.indexOf(err.code)) return this.error(404, err); + this.error(500, err); +}; + +/** + * Check if the cache is fresh. + * + * @return {Boolean} + * @api private + */ + +SendStream.prototype.isFresh = function(){ + return fresh(this.req.headers, this.res._headers); +}; + +/** + * Redirect to `path`. + * + * @param {String} path + * @api private + */ + +SendStream.prototype.redirect = function(path){ + if (this.listeners('directory').length) return this.emit('directory'); + var res = this.res; + path += '/'; + res.statusCode = 301; + res.setHeader('Location', path); + res.end('Redirecting to ' + utils.escape(path)); +}; + +/** + * Pipe to `res. + * + * @param {Stream} res + * @return {Stream} res + * @api public + */ + +SendStream.prototype.pipe = function(res){ + var self = this + , args = arguments + , path = this.path + , root = this._root; + + // references + this.res = res; + + // invalid request uri + path = utils.decode(path); + if (-1 == path) return this.error(400); + + // null byte(s) + if (~path.indexOf('\0')) return this.error(400); + + // join / normalize from optional root dir + if (root) path = normalize(join(this._root, path)); + + // ".." is malicious without "root" + if (this.isMalicious()) return this.error(403); + + // malicious path + if (root && 0 != path.indexOf(root)) return this.error(403); + + // hidden file support + if (!this._hidden && this.hasLeadingDot()) return this.error(404); + + // index file support + if (this._index && this.hasTrailingSlash()) path += this._index; + + debug('stat "%s"', path); + fs.stat(path, function(err, stat){ + if (err) return self.onStatError(err); + if (stat.isDirectory()) return self.redirect(self.path); + self.emit('file', path, stat); + self.send(path, stat); + }); + + return res; +}; + +/** + * Transfer `path`. + * + * @param {String} path + * @api public + */ + +SendStream.prototype.send = function(path, stat){ + var options = this.options; + var len = stat.size; + var res = this.res; + var req = this.req; + var ranges = req.headers.range; + var offset = options.start || 0; + + // set header fields + this.setHeader(stat); + + // set content-type + this.type(path); + + // conditional GET support + if (this.isConditionalGET() + && this.isCachable() + && this.isFresh()) { + return this.notModified(); + } + + // adjust len to start/end options + len = Math.max(0, len - offset); + if (options.end !== undefined) { + var bytes = options.end - offset + 1; + if (len > bytes) len = bytes; + } + + // Range support + if (ranges) { + ranges = parseRange(len, ranges); + + // unsatisfiable + if (-1 == ranges) { + res.setHeader('Content-Range', 'bytes */' + stat.size); + return this.error(416); + } + + // valid (syntactically invalid ranges are treated as a regular response) + if (-2 != ranges) { + options.start = offset + ranges[0].start; + options.end = offset + ranges[0].end; + + // Content-Range + res.statusCode = 206; + res.setHeader('Content-Range', 'bytes ' + + ranges[0].start + + '-' + + ranges[0].end + + '/' + + len); + len = options.end - options.start + 1; + } + } + + // content-length + res.setHeader('Content-Length', len); + + // HEAD support + if ('HEAD' == req.method) return res.end(); + + this.stream(path, options); +}; + +/** + * Stream `path` to the response. + * + * @param {String} path + * @param {Object} options + * @api private + */ + +SendStream.prototype.stream = function(path, options){ + // TODO: this is all lame, refactor meeee + var self = this; + var res = this.res; + var req = this.req; + + // pipe + var stream = fs.createReadStream(path, options); + this.emit('stream', stream); + stream.pipe(res); + + // socket closed, done with the fd + req.on('close', stream.destroy.bind(stream)); + + // error handling code-smell + stream.on('error', function(err){ + // no hope in responding + if (res._header) { + console.error(err.stack); + req.destroy(); + return; + } + + // 500 + err.status = 500; + self.emit('error', err); + }); + + // end + stream.on('end', function(){ + self.emit('end'); + }); +}; + +/** + * Set content-type based on `path` + * if it hasn't been explicitly set. + * + * @param {String} path + * @api private + */ + +SendStream.prototype.type = function(path){ + var res = this.res; + if (res.getHeader('Content-Type')) return; + var type = mime.lookup(path); + var charset = mime.charsets.lookup(type); + debug('content-type %s', type); + res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')); +}; + +/** + * Set reaponse header fields, most + * fields may be pre-defined. + * + * @param {Object} stat + * @api private + */ + +SendStream.prototype.setHeader = function(stat){ + var res = this.res; + if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes'); + if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat)); + if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString()); + if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (this._maxage / 1000)); + if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString()); +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/lib/utils.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/lib/utils.js new file mode 100644 index 00000000000..950e5a2c13d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/lib/utils.js @@ -0,0 +1,47 @@ + +/** + * Return an ETag in the form of `"-"` + * from the given `stat`. + * + * @param {Object} stat + * @return {String} + * @api private + */ + +exports.etag = function(stat) { + return '"' + stat.size + '-' + Number(stat.mtime) + '"'; +}; + +/** + * decodeURIComponent. + * + * Allows V8 to only deoptimize this fn instead of all + * of send(). + * + * @param {String} path + * @api private + */ + +exports.decode = function(path){ + try { + return decodeURIComponent(path); + } catch (err) { + return -1; + } +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/LICENSE new file mode 100644 index 00000000000..451fc4550c2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Benjamin Thomas, Robert Kieffer + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/README.md new file mode 100644 index 00000000000..6ca19bd1e85 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/README.md @@ -0,0 +1,66 @@ +# mime + +Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community. + +## Install + +Install with [npm](http://github.com/isaacs/npm): + + npm install mime + +## API - Queries + +### mime.lookup(path) +Get the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g. + + var mime = require('mime'); + + mime.lookup('/path/to/file.txt'); // => 'text/plain' + mime.lookup('file.txt'); // => 'text/plain' + mime.lookup('.TXT'); // => 'text/plain' + mime.lookup('htm'); // => 'text/html' + +### mime.default_type +Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.) + +### mime.extension(type) +Get the default extension for `type` + + mime.extension('text/html'); // => 'html' + mime.extension('application/octet-stream'); // => 'bin' + +### mime.charsets.lookup() + +Map mime-type to charset + + mime.charsets.lookup('text/plain'); // => 'UTF-8' + +(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) + +## API - Defining Custom Types + +The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types). + +### mime.define() + +Add custom mime/extension mappings + + mime.define({ + 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], + 'application/x-my-type': ['x-mt', 'x-mtt'], + // etc ... + }); + + mime.lookup('x-sft'); // => 'text/x-some-format' + +The first entry in the extensions array is returned by `mime.extension()`. E.g. + + mime.extension('text/x-some-format'); // => 'x-sf' + +### mime.load(filepath) + +Load mappings from an Apache ".types" format file + + mime.load('./my_project.types'); + +The .types file format is simple - See the `types` dir for examples. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/mime.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/mime.js new file mode 100644 index 00000000000..48be0c5e42b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/mime.js @@ -0,0 +1,114 @@ +var path = require('path'); +var fs = require('fs'); + +function Mime() { + // Map of extension -> mime type + this.types = Object.create(null); + + // Map of mime type -> extension + this.extensions = Object.create(null); +} + +/** + * Define mimetype -> extension mappings. Each key is a mime-type that maps + * to an array of extensions associated with the type. The first extension is + * used as the default extension for the type. + * + * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); + * + * @param map (Object) type definitions + */ +Mime.prototype.define = function (map) { + for (var type in map) { + var exts = map[type]; + + for (var i = 0; i < exts.length; i++) { + if (process.env.DEBUG_MIME && this.types[exts]) { + console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' + + this.types[exts] + ' to ' + type); + } + + this.types[exts[i]] = type; + } + + // Default extension is the first one we encounter + if (!this.extensions[type]) { + this.extensions[type] = exts[0]; + } + } +}; + +/** + * Load an Apache2-style ".types" file + * + * This may be called multiple times (it's expected). Where files declare + * overlapping types/extensions, the last file wins. + * + * @param file (String) path of file to load. + */ +Mime.prototype.load = function(file) { + + this._loading = file; + // Read file and split into lines + var map = {}, + content = fs.readFileSync(file, 'ascii'), + lines = content.split(/[\r\n]+/); + + lines.forEach(function(line) { + // Clean up whitespace/comments, and split into fields + var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); + map[fields.shift()] = fields; + }); + + this.define(map); + + this._loading = null; +}; + +/** + * Lookup a mime type based on extension + */ +Mime.prototype.lookup = function(path, fallback) { + var ext = path.replace(/.*[\.\/\\]/, '').toLowerCase(); + + return this.types[ext] || fallback || this.default_type; +}; + +/** + * Return file extension associated with a mime type + */ +Mime.prototype.extension = function(mimeType) { + var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase(); + return this.extensions[type]; +}; + +// Default instance +var mime = new Mime(); + +// Load local copy of +// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types +mime.load(path.join(__dirname, 'types/mime.types')); + +// Load additional types from node.js community +mime.load(path.join(__dirname, 'types/node.types')); + +// Default type +mime.default_type = mime.lookup('bin'); + +// +// Additional API specific to the default instance +// + +mime.Mime = Mime; + +/** + * Lookup a charset based on mime type. + */ +mime.charsets = { + lookup: function(mimeType, fallback) { + // Assume text types are utf8 + return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; + } +}; + +module.exports = mime; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/package.json new file mode 100644 index 00000000000..4e7b0fdb26e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/package.json @@ -0,0 +1,35 @@ +{ + "author": { + "name": "Robert Kieffer", + "email": "robert@broofa.com", + "url": "http://github.com/broofa" + }, + "contributors": [ + { + "name": "Benjamin Thomas", + "email": "benjamin@benjaminthomas.org", + "url": "http://github.com/bentomas" + } + ], + "dependencies": {}, + "description": "A comprehensive library for mime-type mapping", + "devDependencies": {}, + "keywords": [ + "util", + "mime" + ], + "main": "mime.js", + "name": "mime", + "repository": { + "url": "https://github.com/broofa/node-mime", + "type": "git" + }, + "version": "1.2.11", + "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.default_type\nSets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/broofa/node-mime/issues" + }, + "_id": "mime@1.2.11", + "_from": "mime@~1.2.9" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/test.js new file mode 100644 index 00000000000..2cda1c7ad19 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/test.js @@ -0,0 +1,84 @@ +/** + * Usage: node test.js + */ + +var mime = require('./mime'); +var assert = require('assert'); +var path = require('path'); + +function eq(a, b) { + console.log('Test: ' + a + ' === ' + b); + assert.strictEqual.apply(null, arguments); +} + +console.log(Object.keys(mime.extensions).length + ' types'); +console.log(Object.keys(mime.types).length + ' extensions\n'); + +// +// Test mime lookups +// + +eq('text/plain', mime.lookup('text.txt')); // normal file +eq('text/plain', mime.lookup('TEXT.TXT')); // uppercase +eq('text/plain', mime.lookup('dir/text.txt')); // dir + file +eq('text/plain', mime.lookup('.text.txt')); // hidden file +eq('text/plain', mime.lookup('.txt')); // nameless +eq('text/plain', mime.lookup('txt')); // extension-only +eq('text/plain', mime.lookup('/txt')); // extension-less () +eq('text/plain', mime.lookup('\\txt')); // Windows, extension-less +eq('application/octet-stream', mime.lookup('text.nope')); // unrecognized +eq('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default + +// +// Test extensions +// + +eq('txt', mime.extension(mime.types.text)); +eq('html', mime.extension(mime.types.htm)); +eq('bin', mime.extension('application/octet-stream')); +eq('bin', mime.extension('application/octet-stream ')); +eq('html', mime.extension(' text/html; charset=UTF-8')); +eq('html', mime.extension('text/html; charset=UTF-8 ')); +eq('html', mime.extension('text/html; charset=UTF-8')); +eq('html', mime.extension('text/html ; charset=UTF-8')); +eq('html', mime.extension('text/html;charset=UTF-8')); +eq('html', mime.extension('text/Html;charset=UTF-8')); +eq(undefined, mime.extension('unrecognized')); + +// +// Test node.types lookups +// + +eq('application/font-woff', mime.lookup('file.woff')); +eq('application/octet-stream', mime.lookup('file.buffer')); +eq('audio/mp4', mime.lookup('file.m4a')); +eq('font/opentype', mime.lookup('file.otf')); + +// +// Test charsets +// + +eq('UTF-8', mime.charsets.lookup('text/plain')); +eq(undefined, mime.charsets.lookup(mime.types.js)); +eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); + +// +// Test for overlaps between mime.types and node.types +// + +var apacheTypes = new mime.Mime(), nodeTypes = new mime.Mime(); +apacheTypes.load(path.join(__dirname, 'types/mime.types')); +nodeTypes.load(path.join(__dirname, 'types/node.types')); + +var keys = [].concat(Object.keys(apacheTypes.types)) + .concat(Object.keys(nodeTypes.types)); +keys.sort(); +for (var i = 1; i < keys.length; i++) { + if (keys[i] == keys[i-1]) { + console.warn('Warning: ' + + 'node.types defines ' + keys[i] + '->' + nodeTypes.types[keys[i]] + + ', mime.types defines ' + keys[i] + '->' + apacheTypes.types[keys[i]]); + } +} + +console.log('\nOK'); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/types/mime.types b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/types/mime.types new file mode 100644 index 00000000000..da8cd691879 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/types/mime.types @@ -0,0 +1,1588 @@ +# This file maps Internet media types to unique file extension(s). +# Although created for httpd, this file is used by many software systems +# and has been placed in the public domain for unlimited redisribution. +# +# The table below contains both registered and (common) unregistered types. +# A type that has no unique extension can be ignored -- they are listed +# here to guide configurations toward known types and to make it easier to +# identify "new" types. File extensions are also commonly used to indicate +# content languages and encodings, so choose them carefully. +# +# Internet media types should be registered as described in RFC 4288. +# The registry is at . +# +# MIME type (lowercased) Extensions +# ============================================ ========== +# application/1d-interleaved-parityfec +# application/3gpp-ims+xml +# application/activemessage +application/andrew-inset ez +# application/applefile +application/applixware aw +application/atom+xml atom +application/atomcat+xml atomcat +# application/atomicmail +application/atomsvc+xml atomsvc +# application/auth-policy+xml +# application/batch-smtp +# application/beep+xml +# application/calendar+xml +# application/cals-1840 +# application/ccmp+xml +application/ccxml+xml ccxml +application/cdmi-capability cdmia +application/cdmi-container cdmic +application/cdmi-domain cdmid +application/cdmi-object cdmio +application/cdmi-queue cdmiq +# application/cea-2018+xml +# application/cellml+xml +# application/cfw +# application/cnrp+xml +# application/commonground +# application/conference-info+xml +# application/cpl+xml +# application/csta+xml +# application/cstadata+xml +application/cu-seeme cu +# application/cybercash +application/davmount+xml davmount +# application/dca-rft +# application/dec-dx +# application/dialog-info+xml +# application/dicom +# application/dns +application/docbook+xml dbk +# application/dskpp+xml +application/dssc+der dssc +application/dssc+xml xdssc +# application/dvcs +application/ecmascript ecma +# application/edi-consent +# application/edi-x12 +# application/edifact +application/emma+xml emma +# application/epp+xml +application/epub+zip epub +# application/eshop +# application/example +application/exi exi +# application/fastinfoset +# application/fastsoap +# application/fits +application/font-tdpfr pfr +# application/framework-attributes+xml +application/gml+xml gml +application/gpx+xml gpx +application/gxf gxf +# application/h224 +# application/held+xml +# application/http +application/hyperstudio stk +# application/ibe-key-request+xml +# application/ibe-pkg-reply+xml +# application/ibe-pp-data +# application/iges +# application/im-iscomposing+xml +# application/index +# application/index.cmd +# application/index.obj +# application/index.response +# application/index.vnd +application/inkml+xml ink inkml +# application/iotp +application/ipfix ipfix +# application/ipp +# application/isup +application/java-archive jar +application/java-serialized-object ser +application/java-vm class +application/javascript js +application/json json +application/jsonml+json jsonml +# application/kpml-request+xml +# application/kpml-response+xml +application/lost+xml lostxml +application/mac-binhex40 hqx +application/mac-compactpro cpt +# application/macwriteii +application/mads+xml mads +application/marc mrc +application/marcxml+xml mrcx +application/mathematica ma nb mb +# application/mathml-content+xml +# application/mathml-presentation+xml +application/mathml+xml mathml +# application/mbms-associated-procedure-description+xml +# application/mbms-deregister+xml +# application/mbms-envelope+xml +# application/mbms-msk+xml +# application/mbms-msk-response+xml +# application/mbms-protection-description+xml +# application/mbms-reception-report+xml +# application/mbms-register+xml +# application/mbms-register-response+xml +# application/mbms-user-service-description+xml +application/mbox mbox +# application/media_control+xml +application/mediaservercontrol+xml mscml +application/metalink+xml metalink +application/metalink4+xml meta4 +application/mets+xml mets +# application/mikey +application/mods+xml mods +# application/moss-keys +# application/moss-signature +# application/mosskey-data +# application/mosskey-request +application/mp21 m21 mp21 +application/mp4 mp4s +# application/mpeg4-generic +# application/mpeg4-iod +# application/mpeg4-iod-xmt +# application/msc-ivr+xml +# application/msc-mixer+xml +application/msword doc dot +application/mxf mxf +# application/nasdata +# application/news-checkgroups +# application/news-groupinfo +# application/news-transmission +# application/nss +# application/ocsp-request +# application/ocsp-response +application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy +application/oda oda +application/oebps-package+xml opf +application/ogg ogx +application/omdoc+xml omdoc +application/onenote onetoc onetoc2 onetmp onepkg +application/oxps oxps +# application/parityfec +application/patch-ops-error+xml xer +application/pdf pdf +application/pgp-encrypted pgp +# application/pgp-keys +application/pgp-signature asc sig +application/pics-rules prf +# application/pidf+xml +# application/pidf-diff+xml +application/pkcs10 p10 +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkcs8 p8 +application/pkix-attr-cert ac +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +# application/poc-settings+xml +application/postscript ai eps ps +# application/prs.alvestrand.titrax-sheet +application/prs.cww cww +# application/prs.nprend +# application/prs.plucker +# application/prs.rdf-xml-crypt +# application/prs.xsf+xml +application/pskc+xml pskcxml +# application/qsig +application/rdf+xml rdf +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +# application/remote-printing +application/resource-lists+xml rl +application/resource-lists-diff+xml rld +# application/riscos +# application/rlmi+xml +application/rls-services+xml rs +application/rpki-ghostbusters gbr +application/rpki-manifest mft +application/rpki-roa roa +# application/rpki-updown +application/rsd+xml rsd +application/rss+xml rss +application/rtf rtf +# application/rtx +# application/samlassertion+xml +# application/samlmetadata+xml +application/sbml+xml sbml +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +# application/set-payment +application/set-payment-initiation setpay +# application/set-registration +application/set-registration-initiation setreg +# application/sgml +# application/sgml-open-catalog +application/shf+xml shf +# application/sieve +# application/simple-filter+xml +# application/simple-message-summary +# application/simplesymbolcontainer +# application/slate +# application/smil +application/smil+xml smi smil +# application/soap+fastinfoset +# application/soap+xml +application/sparql-query rq +application/sparql-results+xml srx +# application/spirits-event+xml +application/srgs gram +application/srgs+xml grxml +application/sru+xml sru +application/ssdl+xml ssdl +application/ssml+xml ssml +# application/tamp-apex-update +# application/tamp-apex-update-confirm +# application/tamp-community-update +# application/tamp-community-update-confirm +# application/tamp-error +# application/tamp-sequence-adjust +# application/tamp-sequence-adjust-confirm +# application/tamp-status-query +# application/tamp-status-response +# application/tamp-update +# application/tamp-update-confirm +application/tei+xml tei teicorpus +application/thraud+xml tfi +# application/timestamp-query +# application/timestamp-reply +application/timestamped-data tsd +# application/tve-trigger +# application/ulpfec +# application/vcard+xml +# application/vemmi +# application/vividence.scriptfile +# application/vnd.3gpp.bsf+xml +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +# application/vnd.3gpp.sms +# application/vnd.3gpp2.bcmcsinfo+xml +# application/vnd.3gpp2.sms +application/vnd.3gpp2.tcap tcap +application/vnd.3m.post-it-notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.air-application-installer-package+zip air +application/vnd.adobe.formscentral.fcdt fcdt +application/vnd.adobe.fxp fxp fxpl +# application/vnd.adobe.partial-upload +application/vnd.adobe.xdp+xml xdp +application/vnd.adobe.xfdf xfdf +# application/vnd.aether.imp +# application/vnd.ah-barcode +application/vnd.ahead.space ahead +application/vnd.airzip.filesecure.azf azf +application/vnd.airzip.filesecure.azs azs +application/vnd.amazon.ebook azw +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +# application/vnd.amundsen.maze+xml +application/vnd.android.package-archive apk +application/vnd.anser-web-certificate-issue-initiation cii +application/vnd.anser-web-funds-transfer-initiation fti +application/vnd.antix.game-component atx +application/vnd.apple.installer+xml mpkg +application/vnd.apple.mpegurl m3u8 +# application/vnd.arastra.swi +application/vnd.aristanetworks.swi swi +application/vnd.astraea-software.iota iota +application/vnd.audiograph aep +# application/vnd.autopackage +# application/vnd.avistar+xml +application/vnd.blueice.multipass mpm +# application/vnd.bluetooth.ep.oob +application/vnd.bmi bmi +application/vnd.businessobjects rep +# application/vnd.cab-jscript +# application/vnd.canon-cpdl +# application/vnd.canon-lips +# application/vnd.cendio.thinlinc.clientconf +application/vnd.chemdraw+xml cdxml +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.cinderella cdy +# application/vnd.cirpack.isdn-ext +application/vnd.claymore cla +application/vnd.cloanto.rp9 rp9 +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.cluetrust.cartomobile-config c11amc +application/vnd.cluetrust.cartomobile-config-pkg c11amz +# application/vnd.collection+json +# application/vnd.commerce-battelle +application/vnd.commonspace csp +application/vnd.contact.cmsg cdbcmsg +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.ctc-posml pml +# application/vnd.ctct.ws+xml +# application/vnd.cups-pdf +# application/vnd.cups-postscript +application/vnd.cups-ppd ppd +# application/vnd.cups-raster +# application/vnd.cups-raw +# application/vnd.curl +application/vnd.curl.car car +application/vnd.curl.pcurl pcurl +# application/vnd.cybank +application/vnd.dart dart +application/vnd.data-vision.rdz rdz +application/vnd.dece.data uvf uvvf uvd uvvd +application/vnd.dece.ttml+xml uvt uvvt +application/vnd.dece.unspecified uvx uvvx +application/vnd.dece.zip uvz uvvz +application/vnd.denovo.fcselayout-link fe_launch +# application/vnd.dir-bi.plate-dl-nosuffix +application/vnd.dna dna +application/vnd.dolby.mlp mlp +# application/vnd.dolby.mobile.1 +# application/vnd.dolby.mobile.2 +application/vnd.dpgraph dpg +application/vnd.dreamfactory dfac +application/vnd.ds-keypoint kpxx +application/vnd.dvb.ait ait +# application/vnd.dvb.dvbj +# application/vnd.dvb.esgcontainer +# application/vnd.dvb.ipdcdftnotifaccess +# application/vnd.dvb.ipdcesgaccess +# application/vnd.dvb.ipdcesgaccess2 +# application/vnd.dvb.ipdcesgpdd +# application/vnd.dvb.ipdcroaming +# application/vnd.dvb.iptv.alfec-base +# application/vnd.dvb.iptv.alfec-enhancement +# application/vnd.dvb.notif-aggregate-root+xml +# application/vnd.dvb.notif-container+xml +# application/vnd.dvb.notif-generic+xml +# application/vnd.dvb.notif-ia-msglist+xml +# application/vnd.dvb.notif-ia-registration-request+xml +# application/vnd.dvb.notif-ia-registration-response+xml +# application/vnd.dvb.notif-init+xml +# application/vnd.dvb.pfr +application/vnd.dvb.service svc +# application/vnd.dxr +application/vnd.dynageo geo +# application/vnd.easykaraoke.cdgdownload +# application/vnd.ecdis-update +application/vnd.ecowin.chart mag +# application/vnd.ecowin.filerequest +# application/vnd.ecowin.fileupdate +# application/vnd.ecowin.series +# application/vnd.ecowin.seriesrequest +# application/vnd.ecowin.seriesupdate +# application/vnd.emclient.accessrequest+xml +application/vnd.enliven nml +# application/vnd.eprints.data+xml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +# application/vnd.ericsson.quickcall +application/vnd.eszigno3+xml es3 et3 +# application/vnd.etsi.aoc+xml +# application/vnd.etsi.cug+xml +# application/vnd.etsi.iptvcommand+xml +# application/vnd.etsi.iptvdiscovery+xml +# application/vnd.etsi.iptvprofile+xml +# application/vnd.etsi.iptvsad-bc+xml +# application/vnd.etsi.iptvsad-cod+xml +# application/vnd.etsi.iptvsad-npvr+xml +# application/vnd.etsi.iptvservice+xml +# application/vnd.etsi.iptvsync+xml +# application/vnd.etsi.iptvueprofile+xml +# application/vnd.etsi.mcid+xml +# application/vnd.etsi.overload-control-policy-dataset+xml +# application/vnd.etsi.sci+xml +# application/vnd.etsi.simservs+xml +# application/vnd.etsi.tsl+xml +# application/vnd.etsi.tsl.der +# application/vnd.eudora.data +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +# application/vnd.f-secure.mobile +application/vnd.fdf fdf +application/vnd.fdsn.mseed mseed +application/vnd.fdsn.seed seed dataless +# application/vnd.ffsns +# application/vnd.fints +application/vnd.flographit gph +application/vnd.fluxtime.clip ftc +# application/vnd.font-fontforge-sfd +application/vnd.framemaker fm frame maker book +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +# application/vnd.fujixerox.art-ex +# application/vnd.fujixerox.art4 +# application/vnd.fujixerox.hbpl +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +# application/vnd.fut-misnet +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +# application/vnd.geocube+xml +application/vnd.geogebra.file ggb +application/vnd.geogebra.tool ggt +application/vnd.geometry-explorer gex gre +application/vnd.geonext gxt +application/vnd.geoplan g2w +application/vnd.geospace g3w +# application/vnd.globalplatform.card-content-mgt +# application/vnd.globalplatform.card-content-mgt-response +application/vnd.gmx gmx +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +application/vnd.grafeq gqf gqs +# application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +# application/vnd.hal+json +application/vnd.hal+xml hal +application/vnd.handheld-entertainment+xml zmm +application/vnd.hbci hbci +# application/vnd.hcl-bireports +application/vnd.hhe.lesson-player les +application/vnd.hp-hpgl hpgl +application/vnd.hp-hpid hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-pcl pcl +application/vnd.hp-pclxl pclxl +# application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +# application/vnd.hzn-3d-crossword +# application/vnd.ibm.afplinedata +# application/vnd.ibm.electronic-media +application/vnd.ibm.minipay mpy +application/vnd.ibm.modcap afp listafp list3820 +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +application/vnd.igloader igl +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +# application/vnd.informedcontrol.rms+xml +# application/vnd.informix-visionary +# application/vnd.infotech.project +# application/vnd.infotech.project+xml +# application/vnd.innopath.wamp.notification +application/vnd.insors.igm igm +application/vnd.intercon.formnet xpw xpx +application/vnd.intergeo i2g +# application/vnd.intertrust.digibox +# application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +# application/vnd.iptc.g2.conceptitem+xml +# application/vnd.iptc.g2.knowledgeitem+xml +# application/vnd.iptc.g2.newsitem+xml +# application/vnd.iptc.g2.newsmessage+xml +# application/vnd.iptc.g2.packageitem+xml +# application/vnd.iptc.g2.planningitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.isac.fcs fcs +application/vnd.jam jam +# application/vnd.japannet-directory-service +# application/vnd.japannet-jpnstore-wakeup +# application/vnd.japannet-payment-wakeup +# application/vnd.japannet-registration +# application/vnd.japannet-registration-wakeup +# application/vnd.japannet-setstore-wakeup +# application/vnd.japannet-verification +# application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.kinar kne knp +application/vnd.koan skp skd skt skm +application/vnd.kodak-descriptor sse +application/vnd.las.las+xml lasxml +# application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.lotus-1-2-3 123 +application/vnd.lotus-approach apr +application/vnd.lotus-freelance pre +application/vnd.lotus-notes nsf +application/vnd.lotus-organizer org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp +application/vnd.macports.portpkg portpkg +# application/vnd.marlin.drm.actiontoken+xml +# application/vnd.marlin.drm.conftoken+xml +# application/vnd.marlin.drm.license+xml +# application/vnd.marlin.drm.mdcf +application/vnd.mcd mcd +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +# application/vnd.meridian-slingshot +application/vnd.mfer mwf +application/vnd.mfmp mfm +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +application/vnd.mif mif +# application/vnd.minisoft-hp3000-save +# application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf daf +application/vnd.mobius.dis dis +application/vnd.mobius.mbk mbk +application/vnd.mobius.mqy mqy +application/vnd.mobius.msl msl +application/vnd.mobius.plc plc +application/vnd.mobius.txf txf +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +# application/vnd.motorola.flexsuite +# application/vnd.motorola.flexsuite.adsi +# application/vnd.motorola.flexsuite.fis +# application/vnd.motorola.flexsuite.gotap +# application/vnd.motorola.flexsuite.kmr +# application/vnd.motorola.flexsuite.ttc +# application/vnd.motorola.flexsuite.wem +# application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry cil +# application/vnd.ms-asf +application/vnd.ms-cab-compressed cab +# application/vnd.ms-color.iccprofile +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-excel.addin.macroenabled.12 xlam +application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb +application/vnd.ms-excel.sheet.macroenabled.12 xlsm +application/vnd.ms-excel.template.macroenabled.12 xltm +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +# application/vnd.ms-office.activex+xml +application/vnd.ms-officetheme thmx +# application/vnd.ms-opentype +# application/vnd.ms-package.obfuscated-opentype +application/vnd.ms-pki.seccat cat +application/vnd.ms-pki.stl stl +# application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-powerpoint.addin.macroenabled.12 ppam +application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm +application/vnd.ms-powerpoint.slide.macroenabled.12 sldm +application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm +application/vnd.ms-powerpoint.template.macroenabled.12 potm +# application/vnd.ms-printing.printticket+xml +application/vnd.ms-project mpp mpt +# application/vnd.ms-tnef +# application/vnd.ms-wmdrm.lic-chlg-req +# application/vnd.ms-wmdrm.lic-resp +# application/vnd.ms-wmdrm.meter-chlg-req +# application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-word.document.macroenabled.12 docm +application/vnd.ms-word.template.macroenabled.12 dotm +application/vnd.ms-works wps wks wcm wdb +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +application/vnd.mseq mseq +# application/vnd.msign +# application/vnd.multiad.creator +# application/vnd.multiad.creator.cif +# application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +application/vnd.mynfc taglet +# application/vnd.ncd.control +# application/vnd.ncd.reference +# application/vnd.nervana +# application/vnd.netfpx +application/vnd.neurolanguage.nlu nlu +application/vnd.nitf ntf nitf +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +# application/vnd.nokia.catalogs +# application/vnd.nokia.conml+wbxml +# application/vnd.nokia.conml+xml +# application/vnd.nokia.isds-radio-presets +# application/vnd.nokia.iptv.config+xml +# application/vnd.nokia.landmark+wbxml +# application/vnd.nokia.landmark+xml +# application/vnd.nokia.landmarkcollection+xml +# application/vnd.nokia.n-gage.ac+xml +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +# application/vnd.nokia.ncd +# application/vnd.nokia.pcd+wbxml +# application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.edm edm +application/vnd.novadigm.edx edx +application/vnd.novadigm.ext ext +# application/vnd.ntt-local.file-transfer +# application/vnd.ntt-local.sip-ta_remote +# application/vnd.ntt-local.sip-ta_tcp_stream +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +application/vnd.oasis.opendocument.database odb +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.formula-template odft +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +# application/vnd.obn +# application/vnd.oftn.l10n+json +# application/vnd.oipf.contentaccessdownload+xml +# application/vnd.oipf.contentaccessstreaming+xml +# application/vnd.oipf.cspg-hexbinary +# application/vnd.oipf.dae.svg+xml +# application/vnd.oipf.dae.xhtml+xml +# application/vnd.oipf.mippvcontrolmessage+xml +# application/vnd.oipf.pae.gem +# application/vnd.oipf.spdiscovery+xml +# application/vnd.oipf.spdlist+xml +# application/vnd.oipf.ueprofile+xml +# application/vnd.oipf.userprofile+xml +application/vnd.olpc-sugar xo +# application/vnd.oma-scws-config +# application/vnd.oma-scws-http-request +# application/vnd.oma-scws-http-response +# application/vnd.oma.bcast.associated-procedure-parameter+xml +# application/vnd.oma.bcast.drm-trigger+xml +# application/vnd.oma.bcast.imd+xml +# application/vnd.oma.bcast.ltkm +# application/vnd.oma.bcast.notification+xml +# application/vnd.oma.bcast.provisioningtrigger +# application/vnd.oma.bcast.sgboot +# application/vnd.oma.bcast.sgdd+xml +# application/vnd.oma.bcast.sgdu +# application/vnd.oma.bcast.simple-symbol-container +# application/vnd.oma.bcast.smartcard-trigger+xml +# application/vnd.oma.bcast.sprov+xml +# application/vnd.oma.bcast.stkm +# application/vnd.oma.cab-address-book+xml +# application/vnd.oma.cab-feature-handler+xml +# application/vnd.oma.cab-pcc+xml +# application/vnd.oma.cab-user-prefs+xml +# application/vnd.oma.dcd +# application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +# application/vnd.oma.drm.risd+xml +# application/vnd.oma.group-usage-list+xml +# application/vnd.oma.pal+xml +# application/vnd.oma.poc.detailed-progress-report+xml +# application/vnd.oma.poc.final-report+xml +# application/vnd.oma.poc.groups+xml +# application/vnd.oma.poc.invocation-descriptor+xml +# application/vnd.oma.poc.optimized-progress-report+xml +# application/vnd.oma.push +# application/vnd.oma.scidm.messages+xml +# application/vnd.oma.xcap-directory+xml +# application/vnd.omads-email+xml +# application/vnd.omads-file+xml +# application/vnd.omads-folder+xml +# application/vnd.omaloc-supl-init +application/vnd.openofficeorg.extension oxt +# application/vnd.openxmlformats-officedocument.custom-properties+xml +# application/vnd.openxmlformats-officedocument.customxmlproperties+xml +# application/vnd.openxmlformats-officedocument.drawing+xml +# application/vnd.openxmlformats-officedocument.drawingml.chart+xml +# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml +# application/vnd.openxmlformats-officedocument.extended-properties+xml +# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml +# application/vnd.openxmlformats-officedocument.presentationml.comments+xml +# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml +application/vnd.openxmlformats-officedocument.presentationml.presentation pptx +# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml +application/vnd.openxmlformats-officedocument.presentationml.slide sldx +# application/vnd.openxmlformats-officedocument.presentationml.slide+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml +application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx +# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml +# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml +# application/vnd.openxmlformats-officedocument.presentationml.tags+xml +application/vnd.openxmlformats-officedocument.presentationml.template potx +# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx +# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml +# application/vnd.openxmlformats-officedocument.theme+xml +# application/vnd.openxmlformats-officedocument.themeoverride+xml +# application/vnd.openxmlformats-officedocument.vmldrawing +# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document docx +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx +# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml +# application/vnd.openxmlformats-package.core-properties+xml +# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml +# application/vnd.openxmlformats-package.relationships+xml +# application/vnd.quobject-quoxdocument +# application/vnd.osa.netdeploy +application/vnd.osgeo.mapguide.package mgp +# application/vnd.osgi.bundle +application/vnd.osgi.dp dp +application/vnd.osgi.subsystem esa +# application/vnd.otps.ct-kip+xml +application/vnd.palm pdb pqa oprc +# application/vnd.paos.xml +application/vnd.pawaafile paw +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +# application/vnd.piaccess.application-licence +application/vnd.picsel efif +application/vnd.pmi.widget wg +# application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +# application/vnd.powerbuilder6-s +# application/vnd.powerbuilder7 +# application/vnd.powerbuilder7-s +# application/vnd.powerbuilder75 +# application/vnd.powerbuilder75-s +# application/vnd.preminet +application/vnd.previewsystems.box box +application/vnd.proteus.magazine mgz +application/vnd.publishare-delta-tree qps +application/vnd.pvi.ptid1 ptid +# application/vnd.pwg-multiplexed +# application/vnd.pwg-xhtml-print+xml +# application/vnd.qualcomm.brew-app-res +application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb +# application/vnd.radisys.moml+xml +# application/vnd.radisys.msml+xml +# application/vnd.radisys.msml-audit+xml +# application/vnd.radisys.msml-audit-conf+xml +# application/vnd.radisys.msml-audit-conn+xml +# application/vnd.radisys.msml-audit-dialog+xml +# application/vnd.radisys.msml-audit-stream+xml +# application/vnd.radisys.msml-conf+xml +# application/vnd.radisys.msml-dialog+xml +# application/vnd.radisys.msml-dialog-base+xml +# application/vnd.radisys.msml-dialog-fax-detect+xml +# application/vnd.radisys.msml-dialog-fax-sendrecv+xml +# application/vnd.radisys.msml-dialog-group+xml +# application/vnd.radisys.msml-dialog-speech+xml +# application/vnd.radisys.msml-dialog-transform+xml +# application/vnd.rainstor.data +# application/vnd.rapid +application/vnd.realvnc.bed bed +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml musicxml +# application/vnd.renlearn.rlprint +application/vnd.rig.cryptonote cryptonote +application/vnd.rim.cod cod +application/vnd.rn-realmedia rm +application/vnd.rn-realmedia-vbr rmvb +application/vnd.route66.link66+xml link66 +# application/vnd.rs-274x +# application/vnd.ruckus.download +# application/vnd.s3sms +application/vnd.sailingtracker.track st +# application/vnd.sbm.cid +# application/vnd.sbm.mid2 +# application/vnd.scribus +# application/vnd.sealed.3df +# application/vnd.sealed.csf +# application/vnd.sealed.doc +# application/vnd.sealed.eml +# application/vnd.sealed.mht +# application/vnd.sealed.net +# application/vnd.sealed.ppt +# application/vnd.sealed.tiff +# application/vnd.sealed.xls +# application/vnd.sealedmedia.softseal.html +# application/vnd.sealedmedia.softseal.pdf +application/vnd.seemail see +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.simtech-mindmapper twd twds +application/vnd.smaf mmf +# application/vnd.smart.notebook +application/vnd.smart.teacher teacher +# application/vnd.software602.filler.form+xml +# application/vnd.software602.filler.form-xml-zip +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +# application/vnd.sss-cod +# application/vnd.sss-dtf +# application/vnd.sss-ntf +application/vnd.stardivision.calc sdc +application/vnd.stardivision.draw sda +application/vnd.stardivision.impress sdd +application/vnd.stardivision.math smf +application/vnd.stardivision.writer sdw vor +application/vnd.stardivision.writer-global sgl +application/vnd.stepmania.package smzip +application/vnd.stepmania.stepchart sm +# application/vnd.street-stream +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +# application/vnd.sun.wadl+xml +application/vnd.sus-calendar sus susp +application/vnd.svd svd +# application/vnd.swiftview-ics +application/vnd.symbian.install sis sisx +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +# application/vnd.syncml.dm.notification +# application/vnd.syncml.ds.notification +application/vnd.tao.intent-module-archive tao +application/vnd.tcpdump.pcap pcap cap dmp +application/vnd.tmobile-livetv tmo +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +# application/vnd.truedoc +# application/vnd.ubisoft.webplayer +application/vnd.ufdl ufd ufdl +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml +# application/vnd.uplanet.alert +# application/vnd.uplanet.alert-wbxml +# application/vnd.uplanet.bearer-choice +# application/vnd.uplanet.bearer-choice-wbxml +# application/vnd.uplanet.cacheop +# application/vnd.uplanet.cacheop-wbxml +# application/vnd.uplanet.channel +# application/vnd.uplanet.channel-wbxml +# application/vnd.uplanet.list +# application/vnd.uplanet.list-wbxml +# application/vnd.uplanet.listcmd +# application/vnd.uplanet.listcmd-wbxml +# application/vnd.uplanet.signal +application/vnd.vcx vcx +# application/vnd.vd-study +# application/vnd.vectorworks +# application/vnd.verimatrix.vcas +# application/vnd.vidsoft.vidconference +application/vnd.visio vsd vst vss vsw +application/vnd.visionary vis +# application/vnd.vividence.scriptfile +application/vnd.vsf vsf +# application/vnd.wap.sic +# application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo wtb +# application/vnd.wfa.wsc +# application/vnd.wmc +# application/vnd.wmf.bootstrap +# application/vnd.wolfram.mathematica +# application/vnd.wolfram.mathematica.package +application/vnd.wolfram.player nbp +application/vnd.wordperfect wpd +application/vnd.wqd wqd +# application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +# application/vnd.wv.csp+wbxml +# application/vnd.wv.csp+xml +# application/vnd.wv.ssp+xml +application/vnd.xara xar +application/vnd.xfdl xfdl +# application/vnd.xfdl.webform +# application/vnd.xmi+xml +# application/vnd.xmpie.cpkg +# application/vnd.xmpie.dpkg +# application/vnd.xmpie.plan +# application/vnd.xmpie.ppkg +# application/vnd.xmpie.xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.openscoreformat osf +application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg +# application/vnd.yamaha.remote-setup +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +# application/vnd.yamaha.through-ngn +# application/vnd.yamaha.tunnel-udpencap +application/vnd.yellowriver-custom-menu cmp +application/vnd.zul zir zirz +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +# application/vq-rtcpxr +# application/watcherinfo+xml +# application/whoispp-query +# application/whoispp-response +application/widget wgt +application/winhlp hlp +# application/wita +# application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +application/x-7z-compressed 7z +application/x-abiword abw +application/x-ace-compressed ace +# application/x-amf +application/x-apple-diskimage dmg +application/x-authorware-bin aab x32 u32 vox +application/x-authorware-map aam +application/x-authorware-seg aas +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-blorb blb blorb +application/x-bzip bz +application/x-bzip2 bz2 boz +application/x-cbr cbr cba cbt cbz cb7 +application/x-cdlink vcd +application/x-cfs-compressed cfs +application/x-chat chat +application/x-chess-pgn pgn +application/x-conference nsc +# application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-debian-package deb udeb +application/x-dgc-compressed dgc +application/x-director dir dcr dxr cst cct cxt w3d fgd swa +application/x-doom wad +application/x-dtbncx+xml ncx +application/x-dtbook+xml dtb +application/x-dtbresource+xml res +application/x-dvi dvi +application/x-envoy evy +application/x-eva eva +application/x-font-bdf bdf +# application/x-font-dos +# application/x-font-framemaker +application/x-font-ghostscript gsf +# application/x-font-libgrx +application/x-font-linux-psf psf +application/x-font-otf otf +application/x-font-pcf pcf +application/x-font-snf snf +# application/x-font-speedo +# application/x-font-sunos-news +application/x-font-ttf ttf ttc +application/x-font-type1 pfa pfb pfm afm +application/font-woff woff +# application/x-font-vfont +application/x-freearc arc +application/x-futuresplash spl +application/x-gca-compressed gca +application/x-glulx ulx +application/x-gnumeric gnumeric +application/x-gramps-xml gramps +application/x-gtar gtar +# application/x-gzip +application/x-hdf hdf +application/x-install-instructions install +application/x-iso9660-image iso +application/x-java-jnlp-file jnlp +application/x-latex latex +application/x-lzh-compressed lzh lha +application/x-mie mie +application/x-mobipocket-ebook prc mobi +application/x-ms-application application +application/x-ms-shortcut lnk +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-ms-xbap xbap +application/x-msaccess mdb +application/x-msbinder obd +application/x-mscardfile crd +application/x-msclip clp +application/x-msdownload exe dll com bat msi +application/x-msmediaview mvb m13 m14 +application/x-msmetafile wmf wmz emf emz +application/x-msmoney mny +application/x-mspublisher pub +application/x-msschedule scd +application/x-msterminal trm +application/x-mswrite wri +application/x-netcdf nc cdf +application/x-nzb nzb +application/x-pkcs12 p12 pfx +application/x-pkcs7-certificates p7b spc +application/x-pkcs7-certreqresp p7r +application/x-rar-compressed rar +application/x-research-info-systems ris +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-silverlight-app xap +application/x-sql sql +application/x-stuffit sit +application/x-stuffitx sitx +application/x-subrip srt +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-t3vm-image t3 +application/x-tads gam +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-tex-tfm tfm +application/x-texinfo texinfo texi +application/x-tgif obj +application/x-ustar ustar +application/x-wais-source src +application/x-x509-ca-cert der crt +application/x-xfig fig +application/x-xliff+xml xlf +application/x-xpinstall xpi +application/x-xz xz +application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8 +# application/x400-bp +application/xaml+xml xaml +# application/xcap-att+xml +# application/xcap-caps+xml +application/xcap-diff+xml xdf +# application/xcap-el+xml +# application/xcap-error+xml +# application/xcap-ns+xml +# application/xcon-conference-info-diff+xml +# application/xcon-conference-info+xml +application/xenc+xml xenc +application/xhtml+xml xhtml xht +# application/xhtml-voice+xml +application/xml xml xsl +application/xml-dtd dtd +# application/xml-external-parsed-entity +# application/xmpp+xml +application/xop+xml xop +application/xproc+xml xpl +application/xslt+xml xslt +application/xspf+xml xspf +application/xv+xml mxml xhvml xvml xvm +application/yang yang +application/yin+xml yin +application/zip zip +# audio/1d-interleaved-parityfec +# audio/32kadpcm +# audio/3gpp +# audio/3gpp2 +# audio/ac3 +audio/adpcm adp +# audio/amr +# audio/amr-wb +# audio/amr-wb+ +# audio/asc +# audio/atrac-advanced-lossless +# audio/atrac-x +# audio/atrac3 +audio/basic au snd +# audio/bv16 +# audio/bv32 +# audio/clearmode +# audio/cn +# audio/dat12 +# audio/dls +# audio/dsr-es201108 +# audio/dsr-es202050 +# audio/dsr-es202211 +# audio/dsr-es202212 +# audio/dv +# audio/dvi4 +# audio/eac3 +# audio/evrc +# audio/evrc-qcp +# audio/evrc0 +# audio/evrc1 +# audio/evrcb +# audio/evrcb0 +# audio/evrcb1 +# audio/evrcwb +# audio/evrcwb0 +# audio/evrcwb1 +# audio/example +# audio/fwdred +# audio/g719 +# audio/g722 +# audio/g7221 +# audio/g723 +# audio/g726-16 +# audio/g726-24 +# audio/g726-32 +# audio/g726-40 +# audio/g728 +# audio/g729 +# audio/g7291 +# audio/g729d +# audio/g729e +# audio/gsm +# audio/gsm-efr +# audio/gsm-hr-08 +# audio/ilbc +# audio/ip-mr_v2.5 +# audio/isac +# audio/l16 +# audio/l20 +# audio/l24 +# audio/l8 +# audio/lpc +audio/midi mid midi kar rmi +# audio/mobile-xmf +audio/mp4 mp4a +# audio/mp4a-latm +# audio/mpa +# audio/mpa-robust +audio/mpeg mpga mp2 mp2a mp3 m2a m3a +# audio/mpeg4-generic +# audio/musepack +audio/ogg oga ogg spx +# audio/opus +# audio/parityfec +# audio/pcma +# audio/pcma-wb +# audio/pcmu-wb +# audio/pcmu +# audio/prs.sid +# audio/qcelp +# audio/red +# audio/rtp-enc-aescm128 +# audio/rtp-midi +# audio/rtx +audio/s3m s3m +audio/silk sil +# audio/smv +# audio/smv0 +# audio/smv-qcp +# audio/sp-midi +# audio/speex +# audio/t140c +# audio/t38 +# audio/telephone-event +# audio/tone +# audio/uemclip +# audio/ulpfec +# audio/vdvi +# audio/vmr-wb +# audio/vnd.3gpp.iufp +# audio/vnd.4sb +# audio/vnd.audiokoz +# audio/vnd.celp +# audio/vnd.cisco.nse +# audio/vnd.cmles.radio-events +# audio/vnd.cns.anp1 +# audio/vnd.cns.inf1 +audio/vnd.dece.audio uva uvva +audio/vnd.digital-winds eol +# audio/vnd.dlna.adts +# audio/vnd.dolby.heaac.1 +# audio/vnd.dolby.heaac.2 +# audio/vnd.dolby.mlp +# audio/vnd.dolby.mps +# audio/vnd.dolby.pl2 +# audio/vnd.dolby.pl2x +# audio/vnd.dolby.pl2z +# audio/vnd.dolby.pulse.1 +audio/vnd.dra dra +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +# audio/vnd.dvb.file +# audio/vnd.everad.plj +# audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +# audio/vnd.nokia.mobile-xmf +# audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +# audio/vnd.octel.sbc +# audio/vnd.qcelp +# audio/vnd.rhetorex.32kadpcm +audio/vnd.rip rip +# audio/vnd.sealedmedia.softseal.mpeg +# audio/vnd.vmx.cvsd +# audio/vorbis +# audio/vorbis-config +audio/webm weba +audio/x-aac aac +audio/x-aiff aif aiff aifc +audio/x-caf caf +audio/x-flac flac +audio/x-matroska mka +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin rmp +# audio/x-tta +audio/x-wav wav +audio/xm xm +chemical/x-cdx cdx +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-csml csml +# chemical/x-pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +# image/example +# image/fits +image/g3fax g3 +image/gif gif +image/ief ief +# image/jp2 +image/jpeg jpeg jpg jpe +# image/jpm +# image/jpx +image/ktx ktx +# image/naplps +image/png png +image/prs.btif btif +# image/prs.pti +image/sgi sgi +image/svg+xml svg svgz +# image/t38 +image/tiff tiff tif +# image/tiff-fx +image/vnd.adobe.photoshop psd +# image/vnd.cns.inf2 +image/vnd.dece.graphic uvi uvvi uvg uvvg +image/vnd.dvb.subtitle sub +image/vnd.djvu djvu djv +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +# image/vnd.globalgraphics.pgb +# image/vnd.microsoft.icon +# image/vnd.mix +image/vnd.ms-modi mdi +image/vnd.ms-photo wdp +image/vnd.net-fpx npx +# image/vnd.radiance +# image/vnd.sealed.png +# image/vnd.sealedmedia.softseal.gif +# image/vnd.sealedmedia.softseal.jpg +# image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +image/webp webp +image/x-3ds 3ds +image/x-cmu-raster ras +image/x-cmx cmx +image/x-freehand fh fhc fh4 fh5 fh7 +image/x-icon ico +image/x-mrsid-image sid +image/x-pcx pcx +image/x-pict pic pct +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-tga tga +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +# message/cpim +# message/delivery-status +# message/disposition-notification +# message/example +# message/external-body +# message/feedback-report +# message/global +# message/global-delivery-status +# message/global-disposition-notification +# message/global-headers +# message/http +# message/imdn+xml +# message/news +# message/partial +message/rfc822 eml mime +# message/s-http +# message/sip +# message/sipfrag +# message/tracking-status +# message/vnd.si.simp +# model/example +model/iges igs iges +model/mesh msh mesh silo +model/vnd.collada+xml dae +model/vnd.dwf dwf +# model/vnd.flatland.3dml +model/vnd.gdl gdl +# model/vnd.gs-gdl +# model/vnd.gs.gdl +model/vnd.gtw gtw +# model/vnd.moml+xml +model/vnd.mts mts +# model/vnd.parasolid.transmit.binary +# model/vnd.parasolid.transmit.text +model/vnd.vtu vtu +model/vrml wrl vrml +model/x3d+binary x3db x3dbz +model/x3d+vrml x3dv x3dvz +model/x3d+xml x3d x3dz +# multipart/alternative +# multipart/appledouble +# multipart/byteranges +# multipart/digest +# multipart/encrypted +# multipart/example +# multipart/form-data +# multipart/header-set +# multipart/mixed +# multipart/parallel +# multipart/related +# multipart/report +# multipart/signed +# multipart/voice-message +# text/1d-interleaved-parityfec +text/cache-manifest appcache +text/calendar ics ifb +text/css css +text/csv csv +# text/directory +# text/dns +# text/ecmascript +# text/enriched +# text/example +# text/fwdred +text/html html htm +# text/javascript +text/n3 n3 +# text/parityfec +text/plain txt text conf def list log in +# text/prs.fallenstein.rst +text/prs.lines.tag dsc +# text/vnd.radisys.msml-basic-layout +# text/red +# text/rfc822-headers +text/richtext rtx +# text/rtf +# text/rtp-enc-aescm128 +# text/rtx +text/sgml sgml sgm +# text/t140 +text/tab-separated-values tsv +text/troff t tr roff man me ms +text/turtle ttl +# text/ulpfec +text/uri-list uri uris urls +text/vcard vcard +# text/vnd.abc +text/vnd.curl curl +text/vnd.curl.dcurl dcurl +text/vnd.curl.scurl scurl +text/vnd.curl.mcurl mcurl +# text/vnd.dmclientscript +text/vnd.dvb.subtitle sub +# text/vnd.esmertec.theme-descriptor +text/vnd.fly fly +text/vnd.fmi.flexstor flx +text/vnd.graphviz gv +text/vnd.in3d.3dml 3dml +text/vnd.in3d.spot spot +# text/vnd.iptc.newsml +# text/vnd.iptc.nitf +# text/vnd.latex-z +# text/vnd.motorola.reflex +# text/vnd.ms-mediapackage +# text/vnd.net2phone.commcenter.command +# text/vnd.si.uricatalogue +text/vnd.sun.j2me.app-descriptor jad +# text/vnd.trolltech.linguist +# text/vnd.wap.si +# text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-asm s asm +text/x-c c cc cxx cpp h hh dic +text/x-fortran f for f77 f90 +text/x-java-source java +text/x-opml opml +text/x-pascal p pas +text/x-nfo nfo +text/x-setext etx +text/x-sfv sfv +text/x-uuencode uu +text/x-vcalendar vcs +text/x-vcard vcf +# text/xml +# text/xml-external-parsed-entity +# video/1d-interleaved-parityfec +video/3gpp 3gp +# video/3gpp-tt +video/3gpp2 3g2 +# video/bmpeg +# video/bt656 +# video/celb +# video/dv +# video/example +video/h261 h261 +video/h263 h263 +# video/h263-1998 +# video/h263-2000 +video/h264 h264 +# video/h264-rcdo +# video/h264-svc +video/jpeg jpgv +# video/jpeg2000 +video/jpm jpm jpgm +video/mj2 mj2 mjp2 +# video/mp1s +# video/mp2p +# video/mp2t +video/mp4 mp4 mp4v mpg4 +# video/mp4v-es +video/mpeg mpeg mpg mpe m1v m2v +# video/mpeg4-generic +# video/mpv +# video/nv +video/ogg ogv +# video/parityfec +# video/pointer +video/quicktime qt mov +# video/raw +# video/rtp-enc-aescm128 +# video/rtx +# video/smpte292m +# video/ulpfec +# video/vc1 +# video/vnd.cctv +video/vnd.dece.hd uvh uvvh +video/vnd.dece.mobile uvm uvvm +# video/vnd.dece.mp4 +video/vnd.dece.pd uvp uvvp +video/vnd.dece.sd uvs uvvs +video/vnd.dece.video uvv uvvv +# video/vnd.directv.mpeg +# video/vnd.directv.mpeg-tts +# video/vnd.dlna.mpeg-tts +video/vnd.dvb.file dvb +video/vnd.fvt fvt +# video/vnd.hns.video +# video/vnd.iptvforum.1dparityfec-1010 +# video/vnd.iptvforum.1dparityfec-2005 +# video/vnd.iptvforum.2dparityfec-1010 +# video/vnd.iptvforum.2dparityfec-2005 +# video/vnd.iptvforum.ttsavc +# video/vnd.iptvforum.ttsmpeg2 +# video/vnd.motorola.video +# video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +# video/vnd.nokia.interleaved-multimedia +# video/vnd.nokia.videovoip +# video/vnd.objectvideo +# video/vnd.sealed.mpeg1 +# video/vnd.sealed.mpeg4 +# video/vnd.sealed.swf +# video/vnd.sealedmedia.softseal.mov +video/vnd.uvvu.mp4 uvu uvvu +video/vnd.vivo viv +video/webm webm +video/x-f4v f4v +video/x-fli fli +video/x-flv flv +video/x-m4v m4v +video/x-matroska mkv mk3d mks +video/x-mng mng +video/x-ms-asf asf asx +video/x-ms-vob vob +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +video/x-smv smv +x-conference/x-cooltalk ice diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/types/node.types b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/types/node.types new file mode 100644 index 00000000000..55b2cf794ee --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/mime/types/node.types @@ -0,0 +1,77 @@ +# What: WebVTT +# Why: To allow formats intended for marking up external text track resources. +# http://dev.w3.org/html5/webvtt/ +# Added by: niftylettuce +text/vtt vtt + +# What: Google Chrome Extension +# Why: To allow apps to (work) be served with the right content type header. +# http://codereview.chromium.org/2830017 +# Added by: niftylettuce +application/x-chrome-extension crx + +# What: HTC support +# Why: To properly render .htc files such as CSS3PIE +# Added by: niftylettuce +text/x-component htc + +# What: HTML5 application cache manifes ('.manifest' extension) +# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps +# per https://developer.mozilla.org/en/offline_resources_in_firefox +# Added by: louisremi +text/cache-manifest manifest + +# What: node binary buffer format +# Why: semi-standard extension w/in the node community +# Added by: tootallnate +application/octet-stream buffer + +# What: The "protected" MP-4 formats used by iTunes. +# Why: Required for streaming music to browsers (?) +# Added by: broofa +application/mp4 m4p +audio/mp4 m4a + +# What: Video format, Part of RFC1890 +# Why: See https://github.com/bentomas/node-mime/pull/6 +# Added by: mjrusso +video/MP2T ts + +# What: EventSource mime type +# Why: mime type of Server-Sent Events stream +# http://www.w3.org/TR/eventsource/#text-event-stream +# Added by: francois2metz +text/event-stream event-stream + +# What: Mozilla App manifest mime type +# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests +# Added by: ednapiranha +application/x-web-app-manifest+json webapp + +# What: Lua file types +# Why: Googling around shows de-facto consensus on these +# Added by: creationix (Issue #45) +text/x-lua lua +application/x-lua-bytecode luac + +# What: Markdown files, as per http://daringfireball.net/projects/markdown/syntax +# Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown +# Added by: avoidwork +text/x-markdown markdown md mkd + +# What: ini files +# Why: because they're just text files +# Added by: Matthew Kastor +text/plain ini + +# What: DASH Adaptive Streaming manifest +# Why: https://developer.mozilla.org/en-US/docs/DASH_Adaptive_Streaming_for_HTML_5_Video +# Added by: eelcocramer +application/dash+xml mdp + +# What: OpenType font files - http://www.microsoft.com/typography/otspec/ +# Why: Browsers usually ignore the font MIME types and sniff the content, +# but Chrome, shows a warning if OpenType fonts aren't served with +# the `font/opentype` MIME type: http://i.imgur.com/8c5RN8M.png. +# Added by: alrra +font/opentype otf diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/.npmignore new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/.npmignore @@ -0,0 +1 @@ +test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/History.md new file mode 100644 index 00000000000..b35ba515ced --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/History.md @@ -0,0 +1,21 @@ + +1.0.0 / 2013-12-11 +================== + + * add repository to package.json + * add MIT license + +0.0.4 / 2012-06-17 +================== + + * changed: ret -1 for unsatisfiable and -2 when invalid + +0.0.3 / 2012-06-17 +================== + + * fix last-byte-pos default to len - 1 + +0.0.2 / 2012-06-14 +================== + + * add `.type` diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/Makefile new file mode 100644 index 00000000000..8e8640f2e6d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/Makefile @@ -0,0 +1,7 @@ + +test: + @./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/Readme.md new file mode 100644 index 00000000000..cb30a5ac014 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/Readme.md @@ -0,0 +1,53 @@ + +# node-range-parser + + Range header field parser. + +## Example: + +```js +assert(-1 == parse(200, 'bytes=500-20')); +assert(-2 == parse(200, 'bytes=malformed')); +parse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }])); +parse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }])); +parse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }])); +parse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }])); +parse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }])); +parse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }])); +parse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }])); +parse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }])); +parse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }])); +parse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }])); +parse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }])); +``` + +## Installation + +``` +$ npm install range-parser +``` + +## License + +(The MIT License) + +Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/index.js new file mode 100644 index 00000000000..9b0f7a8ec11 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/index.js @@ -0,0 +1,49 @@ + +/** + * Parse "Range" header `str` relative to the given file `size`. + * + * @param {Number} size + * @param {String} str + * @return {Array} + * @api public + */ + +module.exports = function(size, str){ + var valid = true; + var i = str.indexOf('='); + + if (-1 == i) return -2; + + var arr = str.slice(i + 1).split(',').map(function(range){ + var range = range.split('-') + , start = parseInt(range[0], 10) + , end = parseInt(range[1], 10); + + // -nnn + if (isNaN(start)) { + start = size - end; + end = size - 1; + // nnn- + } else if (isNaN(end)) { + end = size - 1; + } + + // limit last-byte-pos to current length + if (end > size - 1) end = size - 1; + + // invalid + if (isNaN(start) + || isNaN(end) + || start > end + || start < 0) valid = false; + + return { + start: start, + end: end + }; + }); + + arr.type = str.slice(0, i); + + return valid ? arr : -1; +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/package.json new file mode 100644 index 00000000000..afbdd7dd52b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/node_modules/range-parser/package.json @@ -0,0 +1,37 @@ +{ + "name": "range-parser", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "description": "Range header field string parser", + "version": "1.0.0", + "repository": { + "type": "git", + "url": "https://github.com/visionmedia/node-range-parser.git" + }, + "main": "index.js", + "dependencies": {}, + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/visionmedia/node-range-parser#license" + } + ], + "readme": "\n# node-range-parser\n\n Range header field parser.\n\n## Example:\n\n```js\nassert(-1 == parse(200, 'bytes=500-20'));\nassert(-2 == parse(200, 'bytes=malformed'));\nparse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }]));\nparse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }]));\nparse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }]));\nparse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }]));\nparse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }]));\nparse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }]));\nparse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }]));\nparse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }]));\nparse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }]));\n```\n\n## Installation\n\n```\n$ npm install range-parser\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/node-range-parser/issues" + }, + "_id": "range-parser@1.0.0", + "dist": { + "shasum": "a4b264cfe0be5ce36abe3765ac9c2a248746dbc0" + }, + "_from": "range-parser@~1.0.0", + "_resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/package.json new file mode 100644 index 00000000000..dfeb6602e99 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/node_modules/send/package.json @@ -0,0 +1,45 @@ +{ + "name": "send", + "version": "0.2.0", + "description": "Better streaming static file server with Range and conditional-GET support", + "keywords": [ + "static", + "file", + "server" + ], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "dependencies": { + "debug": "*", + "mime": "~1.2.9", + "fresh": "~0.2.1", + "range-parser": "~1.0.0" + }, + "devDependencies": { + "mocha": "*", + "should": "*", + "supertest": "0.0.1", + "connect": "2.x" + }, + "scripts": { + "test": "make test" + }, + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/send.git" + }, + "main": "index", + "readme": "# send\n\n Send is Connect's `static()` extracted for generalized use, a streaming static file\n server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.\n\n## Installation\n\n $ npm install send\n\n## Examples\n\n Small:\n\n```js\nvar http = require('http');\nvar send = require('send');\n\nvar app = http.createServer(function(req, res){\n send(req, req.url).pipe(res);\n}).listen(3000);\n```\n\n Serving from a root directory with custom error-handling:\n\n```js\nvar http = require('http');\nvar send = require('send');\nvar url = require('url');\n\nvar app = http.createServer(function(req, res){\n // your custom error-handling logic:\n function error(err) {\n res.statusCode = err.status || 500;\n res.end(err.message);\n }\n\n // your custom directory handling logic:\n function redirect() {\n res.statusCode = 301;\n res.setHeader('Location', req.url + '/');\n res.end('Redirecting to ' + req.url + '/');\n }\n\n // transfer arbitrary files from within\n // /www/example.com/public/*\n send(req, url.parse(req.url).pathname)\n .root('/www/example.com/public')\n .on('error', error)\n .on('directory', redirect)\n .pipe(res);\n}).listen(3000);\n```\n\n## API\n\n### Events\n\n - `error` an error occurred `(err)`\n - `directory` a directory was requested\n - `file` a file was requested `(path, stat)`\n - `stream` file streaming has started `(stream)`\n - `end` streaming has completed\n\n### .root(dir)\n\n Serve files relative to `path`. Aliased as `.from(dir)`.\n\n### .index(path)\n\n By default send supports \"index.html\" files, to disable this\n invoke `.index(false)` or to supply a new index pass a string.\n\n### .maxage(ms)\n\n Provide a max-age in milliseconds for http caching, defaults to 0.\n\n### .hidden(bool)\n\n Enable or disable transfer of hidden files, defaults to false.\n\n## Error-handling\n\n By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.\n\n## Caching\n\n It does _not_ perform internal caching, you should use a reverse proxy cache such\n as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).\n\n## Debugging\n\n To enable `debug()` instrumentation output export __DEBUG__:\n\n```\n$ DEBUG=send node app\n```\n\n## Running tests\n\n```\n$ npm install\n$ make test\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/send/issues" + }, + "_id": "send@0.2.0", + "dist": { + "shasum": "067abf45cff8bffb29cbdb7439725b32388a2c58" + }, + "_from": "send@0.2.0", + "_resolved": "https://registry.npmjs.org/send/-/send-0.2.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/package.json new file mode 100644 index 00000000000..d870a9b3a1a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/serve-static/package.json @@ -0,0 +1,40 @@ +{ + "name": "serve-static", + "description": "Serve static files", + "version": "1.0.2", + "author": { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/serve-static.git" + }, + "bugs": { + "url": "https://github.com/expressjs/serve-static/issues" + }, + "dependencies": { + "send": "0.2.0" + }, + "devDependencies": { + "connect": "^2.13.0", + "mocha": "^1.17.0", + "should": "^3.0.0", + "supertest": "~0.9.0" + }, + "engines": { + "node": ">= 0.8.0" + }, + "scripts": { + "test": "mocha --reporter spec --require should" + }, + "readme": "# Serve Static\n\nPreviously `connect.static()`.\n\nUsage:\n\n```js\nvar connect = require('connect');\nvar serveStatic = require('serve-static');\n\nvar app = connect();\n\napp.use(serveStatic('public/ftp', {'index': 'default.html'}));\napp.listen();\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Douglas Christopher Wilson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", + "readmeFilename": "Readme.md", + "_id": "serve-static@1.0.2", + "dist": { + "shasum": "53795d020bddab2894689052a455c09589c9ff6c" + }, + "_from": "serve-static@1.0.2", + "_resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.0.2.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/.npmignore new file mode 100644 index 00000000000..3c3629e647f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/.travis.yml new file mode 100644 index 00000000000..20082f9ee9b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - "0.10" + - "0.11" +matrix: + allow_failures: + - node_js: "0.11" + fast_finish: true diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/LICENSE new file mode 100644 index 00000000000..0c5d22d96df --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2010 Sencha Inc. +Copyright (c) 2011 LearnBoost +Copyright (c) 2011 TJ Holowaychuk + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/README.md new file mode 100644 index 00000000000..e373314b308 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/README.md @@ -0,0 +1,19 @@ +# static-favicon + +express/connect middleware to serves a favicon. + +```js +app.use(favicon(__dirname + '/public/favicon.ico')); +``` + +Typically this middleware will come very early in your stack (maybe even first) to avoid processing any other middleware if we already know the request is for favicon.ico + +## api + +### favicon(path, options) + +Create new middleware to serve a favicon from the given `path` to a favicon file. + +**options** + + - `maxAge` cache-control max-age directive, defaulting to 1 day diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/favicon.ico b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/favicon.ico new file mode 100644 index 00000000000..895fc96a76b Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/favicon.ico differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/index.js new file mode 100644 index 00000000000..084c63adba8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/index.js @@ -0,0 +1,87 @@ +/*! + * Connect - favicon + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var fs = require('fs'); +var crypto = require('crypto'); + +/** + * Favicon: + * + * By default serves the connect favicon, or the favicon + * located by the given `path`. + * + * Options: + * + * - `maxAge` cache-control max-age directive, defaulting to 1 day + * + * Examples: + * + * Serve default favicon: + * + * connect() + * .use(connect.favicon()) + * + * Serve favicon before logging for brevity: + * + * connect() + * .use(connect.favicon()) + * .use(connect.logger('dev')) + * + * Serve custom favicon: + * + * connect() + * .use(connect.favicon('public/favicon.ico')) + * + * @param {String} path + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function favicon(path, options){ + var options = options || {} + , path = path || __dirname + '/favicon.ico' + , maxAge = options.maxAge || 86400000 + , icon; // favicon cache + + return function favicon(req, res, next){ + if ('/favicon.ico' == req.url) { + if (icon) { + res.writeHead(200, icon.headers); + res.end(icon.body); + } else { + fs.readFile(path, function(err, buf){ + if (err) return next(err); + icon = { + headers: { + 'Content-Type': 'image/x-icon' + , 'Content-Length': buf.length + , 'ETag': '"' + md5(buf) + '"' + , 'Cache-Control': 'public, max-age=' + (maxAge / 1000) + }, + body: buf + }; + res.writeHead(200, icon.headers); + res.end(icon.body); + }); + } + } else { + next(); + } + }; +}; + +function md5(str, encoding){ + return crypto + .createHash('md5') + .update(str, 'utf8') + .digest(encoding || 'hex'); +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/package.json new file mode 100644 index 00000000000..c19b8ebd7c2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/static-favicon/package.json @@ -0,0 +1,41 @@ +{ + "name": "static-favicon", + "version": "1.0.2", + "description": "favicon serving middleware with caching", + "keywords": [ + "favicon", + "middleware" + ], + "repository": { + "type": "git", + "url": "git://github.com/expressjs/favicon.git" + }, + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "dependencies": {}, + "devDependencies": { + "mocha": ">= 1.17.0" + }, + "licenses": "MIT", + "main": "./index.js", + "engines": { + "node": ">= 0.10.0" + }, + "scripts": { + "test": "true" + }, + "readme": "# static-favicon\n\nexpress/connect middleware to serves a favicon.\n\n```js\napp.use(favicon(__dirname + '/public/favicon.ico'));\n```\n\nTypically this middleware will come very early in your stack (maybe even first) to avoid processing any other middleware if we already know the request is for favicon.ico\n\n## api\n\n### favicon(path, options)\n\nCreate new middleware to serve a favicon from the given `path` to a favicon file.\n\n**options**\n\n - `maxAge` cache-control max-age directive, defaulting to 1 day\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/expressjs/favicon/issues" + }, + "_id": "static-favicon@1.0.2", + "dist": { + "shasum": "7c15920dda2bf33f414b0e60aebbd65cdd2a1d2f" + }, + "_from": "static-favicon@1.0.2", + "_resolved": "https://registry.npmjs.org/static-favicon/-/static-favicon-1.0.2.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/.npmignore new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/.travis.yml new file mode 100644 index 00000000000..3e3646a12ca --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/.travis.yml @@ -0,0 +1,4 @@ +node_js: +- "0.10" +- "0.11" +language: node_js \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/Makefile new file mode 100644 index 00000000000..083aa531ac9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/Makefile @@ -0,0 +1,6 @@ +test: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter spec \ + --require should + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/README.md new file mode 100644 index 00000000000..ccc8e3d5930 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/README.md @@ -0,0 +1,40 @@ +# Virtual Host + +Previously `connect.vhost()`. + +Usage: + +```js +var connect = require('connect'); +var vhost = require('vhost'); + +var app = connect(); + +app.use(vhost('mail.example.com', function(req, res){})); +app.use(vhost('*.example.com', connect())); +app.use(connect()); +``` + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/index.js new file mode 100644 index 00000000000..abbb0500a7f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/index.js @@ -0,0 +1,40 @@ + +/*! + * Connect - vhost + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Vhost: + * + * Setup vhost for the given `hostname` and `server`. + * + * connect() + * .use(connect.vhost('foo.com', fooApp)) + * .use(connect.vhost('bar.com', barApp)) + * .use(connect.vhost('*.com', mainApp)) + * + * The `server` may be a Connect server or + * a regular Node `http.Server`. + * + * @param {String} hostname + * @param {Server} server + * @return {Function} + * @api public + */ + +module.exports = function vhost(hostname, server){ + if (!hostname) throw new Error('vhost hostname required'); + if (!server) throw new Error('vhost server required'); + var regexp = new RegExp('^' + hostname.replace(/[^*\w]/g, '\\$&').replace(/[*]/g, '(?:.*?)') + '$', 'i'); + if (server.onvhost) server.onvhost(hostname); + return function vhost(req, res, next){ + if (!req.headers.host) return next(); + var host = req.headers.host.split(':')[0]; + if (!regexp.test(host)) return next(); + if ('function' == typeof server) return server(req, res, next); + server.emit('request', req, res); + }; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/package.json new file mode 100644 index 00000000000..e3374ab3053 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/node_modules/vhost/package.json @@ -0,0 +1,35 @@ +{ + "name": "vhost", + "description": "virtual domain hosting", + "version": "1.0.0", + "author": { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/expressjs/vhost.git" + }, + "bugs": { + "url": "https://github.com/expressjs/vhost/issues" + }, + "devDependencies": { + "mocha": "^1.17.0", + "should": "^3.0.0", + "supertest": "*", + "connect": "*" + }, + "scripts": { + "test": "make test" + }, + "readme": "# Virtual Host\n\nPreviously `connect.vhost()`.\n\nUsage:\n\n```js\nvar connect = require('connect');\nvar vhost = require('vhost');\n\nvar app = connect();\n\napp.use(vhost('mail.example.com', function(req, res){}));\napp.use(vhost('*.example.com', connect()));\napp.use(connect());\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", + "readmeFilename": "README.md", + "_id": "vhost@1.0.0", + "dist": { + "shasum": "654513f289a4f898aab745bbd633e40180c9c4c0" + }, + "_from": "vhost@1.0.0", + "_resolved": "https://registry.npmjs.org/vhost/-/vhost-1.0.0.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/package.json new file mode 100644 index 00000000000..6ed19aa9ad1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/connect/package.json @@ -0,0 +1,75 @@ +{ + "name": "connect", + "version": "2.14.3", + "description": "High performance middleware framework", + "keywords": [ + "framework", + "web", + "middleware", + "connect", + "rack" + ], + "repository": { + "type": "git", + "url": "git://github.com/senchalabs/connect.git" + }, + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "http://tjholowaychuk.com" + }, + "dependencies": { + "basic-auth-connect": "1.0.0", + "cookie-parser": "1.0.1", + "cookie-signature": "1.0.3", + "compression": "1.0.0", + "connect-timeout": "1.0.0", + "csurf": "1.0.0", + "errorhandler": "1.0.0", + "express-session": "1.0.2", + "fresh": "0.2.2", + "method-override": "1.0.0", + "morgan": "1.0.0", + "qs": "0.6.6", + "response-time": "1.0.0", + "serve-index": "1.0.1", + "serve-static": "1.0.2", + "static-favicon": "1.0.2", + "vhost": "1.0.0", + "bytes": "0.2.1", + "pause": "0.0.1", + "debug": ">= 0.7.3 < 1", + "raw-body": "1.1.3", + "multiparty": "2.2.0" + }, + "devDependencies": { + "should": "~3.1.3", + "mocha": ">= 1.13.0 < 2", + "jade": ">= 0.35.0 < 1", + "dox": ">= 0.4.4 < 1" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/senchalabs/connect/master/LICENSE" + } + ], + "main": "index", + "engines": { + "node": ">= 0.8.0" + }, + "scripts": { + "test": "make" + }, + "readme": "# Connect [![build status](https://secure.travis-ci.org/senchalabs/connect.png)](http://travis-ci.org/senchalabs/connect)\n\n Connect is an extensible HTTP server framework for [node](http://nodejs.org), providing high performance \"plugins\" known as _middleware_.\n\n Connect is bundled with over _20_ commonly used middleware, including\n a logger, session support, cookie parser, and [more](http://senchalabs.github.com/connect). Be sure to view the 2.x [documentation](http://www.senchalabs.org/connect/).\n\n```js\nvar connect = require('connect')\n , http = require('http');\n\nvar app = connect()\n .use(connect.favicon())\n .use(connect.logger('dev'))\n .use(connect.static('public'))\n .use(connect.directory('public'))\n .use(connect.cookieParser())\n .use(connect.session({ secret: 'my secret here' }))\n .use(function(req, res){\n res.end('Hello from Connect!\\n');\n });\n\nhttp.createServer(app).listen(3000);\n```\n\n## Middleware\n\n - [basicAuth](http://www.senchalabs.org/connect/basicAuth.html)\n - [bodyParser](http://www.senchalabs.org/connect/bodyParser.html)\n - [compress](http://www.senchalabs.org/connect/compress.html)\n - [cookieParser](http://www.senchalabs.org/connect/cookieParser.html)\n - [cookieSession](http://www.senchalabs.org/connect/cookieSession.html)\n - [csrf](http://www.senchalabs.org/connect/csrf.html)\n - [directory](http://www.senchalabs.org/connect/directory.html)\n - [errorHandler](http://www.senchalabs.org/connect/errorHandler.html)\n - [favicon](http://www.senchalabs.org/connect/favicon.html)\n - [json](http://www.senchalabs.org/connect/json.html)\n - [limit](http://www.senchalabs.org/connect/limit.html)\n - [logger](http://www.senchalabs.org/connect/logger.html)\n - [methodOverride](http://www.senchalabs.org/connect/methodOverride.html)\n - [multipart](http://www.senchalabs.org/connect/multipart.html)\n - [urlencoded](http://www.senchalabs.org/connect/urlencoded.html)\n - [query](http://www.senchalabs.org/connect/query.html)\n - [responseTime](http://www.senchalabs.org/connect/responseTime.html)\n - [session](http://www.senchalabs.org/connect/session.html)\n - [static](http://www.senchalabs.org/connect/static.html)\n - [staticCache](http://www.senchalabs.org/connect/staticCache.html)\n - [subdomains](http://www.senchalabs.org/connect/subdomains.html)\n - [vhost](http://www.senchalabs.org/connect/vhost.html)\n\n## Running Tests\n\nfirst:\n\n $ npm install -d\n\nthen:\n\n $ make test\n\n## Contributors\n\n https://github.com/senchalabs/connect/graphs/contributors\n\n## Node Compatibility\n\n Connect `< 1.x` is compatible with node 0.2.x\n\n\n Connect `1.x` is compatible with node 0.4.x\n\n\n Connect `2.x` is compatible with node 0.6.x\n\n\n Connect (_master_) is compatible with node 0.8.x\n\n## CLA\n\n [http://sencha.com/cla](http://sencha.com/cla)\n\n## License\n\nView the [LICENSE](https://github.com/senchalabs/connect/blob/master/LICENSE) file. The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons used by the `directory` middleware created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).\n", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/senchalabs/connect/issues" + }, + "_id": "connect@2.14.3", + "dist": { + "shasum": "892e3c60d3a0cbfae2d2a390ea8a049cec0ad8b8" + }, + "_from": "connect@", + "_resolved": "https://registry.npmjs.org/connect/-/connect-2.14.3.tgz" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/LICENSE.txt b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/LICENSE.txt new file mode 100644 index 00000000000..49869bbab37 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2013 The Dojo Foundation +Based on Underscore.js 1.5.2, copyright 2009-2013 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/README.md new file mode 100644 index 00000000000..6f9598e8a9d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/README.md @@ -0,0 +1,163 @@ +# Lo-Dash v2.4.1 +A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features). + +## Download + +Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds. + +* Modern builds perfect for newer browsers/environments:
    +[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) & +[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js) + +* Compatibility builds for older environment support too:
    +[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) & +[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js) + +* Underscore builds to use as a drop-in replacement:
    +[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) & +[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js) + +CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed. + +Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method. + +## Dive in + +There’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).
    +Check out DevDocs as a fast, organized, & searchable interface for our documentation. + +The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).
    +A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap). + +## Features *not* in Underscore + + * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) + * [_(…)](http://lodash.com/docs#_) supports intuitive chaining + * [_.at](http://lodash.com/docs#at) for cherry-picking collection values + * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions + * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` + * [_.create](http://lodash.com/docs#create) for easier object inheritance + * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins + * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions + * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control + * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys + * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early + * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties + * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties + * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object` + * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object + * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions + * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend) + * [_.noop](http://lodash.com/docs#noop) for function placeholders + * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative + * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior + * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays + * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers + * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking + * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties + * [_.support](http://lodash.com/docs#support) for flagging environment features + * [_.template](http://lodash.com/docs#template) supports [*“imports”*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) + * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects + * [_.where](http://lodash.com/docs#where) supports deep object comparisons + * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union) + * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values + * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), & + [more](http://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks + * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), & + [more](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings + * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), & + [more](http://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands + * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), & + [more](http://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods + +## Resources + + * Podcasts + - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) + + * Posts + - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) + - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) + + * Videos + - [Introduction](https://vimeo.com/44154599) + - [Origins](https://vimeo.com/44154600) + - [Optimizations & builds](https://vimeo.com/44154601) + - [Native method use](https://vimeo.com/48576012) + - [Testing](https://vimeo.com/45865290) + - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) + + A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). + +## Support + +Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.
    +Automated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash). + +Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
    +[![Sauce Labs](http://lodash.com/_img/sauce.png)](https://saucelabs.com/ "Sauce Labs: Selenium Testing & More") + +## Installation & usage + +In browsers: + +```html + +``` + +Using [`npm`](http://npmjs.org/): + +```bash +npm i --save lodash + +{sudo} npm i -g lodash +npm ln lodash +``` + +In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): + +```js +var _ = require('lodash'); +// or as Underscore +var _ = require('lodash/dist/lodash.underscore'); +``` + +**Notes:** + * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL + * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader: + +```js +require({ + 'packages': [ + { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } + ] +}, +['lodash'], function(_) { + console.log(_.VERSION); +}); +``` + +## Author + +| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") | +|---| +| [John-David Dalton](http://allyoucanleet.com/) | + +## Contributors + +| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | +|---|---|---| +| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) | + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/dist/lodash.compat.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/dist/lodash.compat.js new file mode 100644 index 00000000000..23798ba8538 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/lodash/dist/lodash.compat.js @@ -0,0 +1,7157 @@ +/** + * @license + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowedProps = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used as the data object for `iteratorTemplate` */ + var iteratorData = { + 'args': '', + 'array': null, + 'bottom': '', + 'firstArg': '', + 'init': '', + 'keys': null, + 'loop': '', + 'shadowedProps': null, + 'support': null, + 'top': '', + 'useHas': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var errorProto = Error.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to avoid iterating non-enumerable properties in IE < 9 */ + var nonEnumProps = {}; + nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; + nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; + nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; + nonEnumProps[objectClass] = { 'constructor': true }; + + (function() { + var length = shadowedProps.length; + while (length--) { + var key = shadowedProps[length]; + for (var className in nonEnumProps) { + if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { + nonEnumProps[className][key] = false; + } + } + } + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function() { + var ctor = function() { this.x = 1; }, + object = { '0': 1, 'length': 1 }, + props = []; + + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var key in new ctor) { props.push(key); } + for (key in arguments) { } + + /** + * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.argsClass = toString.call(arguments) == argsClass; + + /** + * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). + * + * @memberOf _.support + * @type boolean + */ + support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); + + /** + * Detect if `name` or `message` properties of `Error.prototype` are + * enumerable by default. (IE < 9, Safari < 5.1) + * + * @memberOf _.support + * @type boolean + */ + support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); + + /** + * Detect if `prototype` properties are enumerable by default. + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + * + * @memberOf _.support + * @type boolean + */ + support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if `arguments` object indexes are non-enumerable + * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumArgs = key != 0; + + /** + * Detect if properties shadowing those on `Object.prototype` are non-enumerable. + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumShadows = !/valueOf/.test(props); + + /** + * Detect if own properties are iterated after inherited properties (all but IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.ownLast = props[0] != 'x'; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + + /** + * Detect lack of support for accessing string characters by index. + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + * + * @memberOf _.support + * @type boolean + */ + support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to + * a string without a `toString` function. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); + } catch(e) { + support.nodeClass = true; + } + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Object} data The data object used to populate the text. + * @returns {string} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg) + + ', result = ' + + (obj.init) + + ';\nif (!iterable) return result;\n' + + (obj.top) + + ';'; + if (obj.array) { + __p += '\nvar length = iterable.length; index = -1;\nif (' + + (obj.array) + + ') { '; + if (support.unindexedChars) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } + __p += '\n while (++index < length) {\n ' + + (obj.loop) + + ';\n }\n}\nelse { '; + } else if (support.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop) + + ';\n }\n } else { '; + } + + if (support.enumPrototypes) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } + + if (support.enumErrorProps) { + __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; + } + + var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } + + if (obj.useHas && obj.keys) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; + if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + } else { + __p += '\n for (index in iterable) {\n'; + if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + if (support.nonEnumShadows) { + __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; + for (k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowedProps[k]) + + '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; + if (!obj.useHas) { + __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; + } + __p += ') {\n ' + + (obj.loop) + + ';\n } '; + } + __p += '\n } '; + } + + } + + if (obj.array || support.nonEnumArgs) { + __p += '\n}'; + } + __p += + (obj.bottom) + + ';\nreturn result'; + + return __p + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? baseEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, + ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {...Object} [options] The compile options object(s). + * @param {string} [options.array] Code to determine if the iterable is an array or array-like. + * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. + * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. + * @param {string} [options.args] A comma separated string of iteration function arguments. + * @param {string} [options.top] Code to execute before the iteration branches. + * @param {string} [options.loop] Code to execute in the object loop. + * @param {string} [options.bottom] Code to execute after the iteration branches. + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + // data properties + iteratorData.shadowedProps = shadowedProps; + + // iterator options + iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; + iteratorData.init = 'iterable'; + iteratorData.useHas = true; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + iteratorData[key] = object[key]; + } + } + var args = iteratorData.args; + iteratorData.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', + 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' + ); + + // return the compiled function + return factory( + baseCreateCallback, errorClass, errorProto, hasOwnProperty, + indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, + objectTypes, nonEnumProps, stringClass, stringProto, toString + ); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || + (!support.argsClass && isArguments(value)) || + (!support.nodeClass && isNode(value))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (support.ownLast) { + forIn(value, function(value, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!support.argsClass) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = createIterator({ + 'args': 'object', + 'init': '[]', + 'top': 'if (!(objectTypes[typeof object])) return result', + 'loop': 'result.push(index)' + }); + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((support.enumPrototypes && typeof object == 'function') || + (support.nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", + 'array': "typeof length == 'number'", + 'keys': keys, + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'keys': keys, + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'array': false + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the callback for each + * element in the collection. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createIterator(eachIteratorOptions); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + (support.argsClass ? className == argsClass : isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? baseEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + baseEach(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + baseEach(collection, callback, thisArg); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (support.unindexedChars && isString(collection)) { + iterable = collection.split(''); + } + baseEach(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(iterable[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = lodash.createCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + baseEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + baseEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } else if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (support.unindexedChars && isString(collection)) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

    ' + func(text) + '

    '; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '

    Fred, Wilma, & Pebbles

    ' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * http://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': '\n```\n\nUsing [`npm`](http://npmjs.org/):\n\n```bash\nnpm i --save lodash\n\n{sudo} npm i -g lodash\nnpm ln lodash\n```\n\nIn [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/):\n\n```js\nvar _ = require('lodash');\n// or as Underscore\nvar _ = require('lodash/dist/lodash.underscore');\n```\n\n**Notes:**\n * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL\n * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it\n\nIn [Rhino](http://www.mozilla.org/rhino/):\n\n```js\nload('lodash.js');\n```\n\nIn an AMD loader:\n\n```js\nrequire({\n 'packages': [\n { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' }\n ]\n},\n['lodash'], function(_) {\n console.log(_.VERSION);\n});\n```\n\n## Author\n\n| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton \"Follow @jdalton on Twitter\") |\n|---|\n| [John-David Dalton](http://allyoucanleet.com/) |\n\n## Contributors\n\n| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz \"Follow @BlaineBublitz on Twitter\") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge \"Follow @kitcambridge on Twitter\") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias \"Follow @mathias on Twitter\") |\n|---|---|---|\n| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) |\n\n[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free \"Bitdeli Badge\")\n", + "readmeFilename": "README.md", + "_id": "lodash@2.4.1", + "_from": "lodash@" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.jshintignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.jshintignore new file mode 100644 index 00000000000..651665bbd97 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.jshintignore @@ -0,0 +1,2 @@ +node_modules +.git diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.jshintrc b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.jshintrc new file mode 100644 index 00000000000..765fb34a1ec --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.jshintrc @@ -0,0 +1,27 @@ +{ + "bitwise": true, + "curly": true, + "eqeqeq": true, + "forin": true, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": true, + "plusplus": false, + "regexp": false, + "undef": true, + "strict": false, + "trailing": true, + + "eqnull": true, + "laxcomma": true, + + "node": true, + + "onevar": true, + "white": true, + + "indent": 2 +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.npmignore new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/.npmignore @@ -0,0 +1 @@ +test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/LICENSE new file mode 100644 index 00000000000..58b5cd2414f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 Jay Jordan + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/README.md new file mode 100644 index 00000000000..4fc0d54ecea --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/README.md @@ -0,0 +1,33 @@ +# open + +Open a file or url in the user's preferred application. + +# Usage + +```javascript +var open = require("open"); +open("http://www.google.com"); +``` + +`open` taks an optional argument specifying the program to be used to open the +file or URL. + +```javascript +open("http://www.google.com", "firefox"); +``` + +# Installation + + npm install open + +# How it works + +- on `win32` uses `start` +- on `darwin` uses `open` +- otherwise uses the `xdg-open` script from [freedesktop.org](http://portland.freedesktop.org/xdg-utils-1.0/xdg-open.html) + +# Warning + +The same care should be taken when calling open as if you were calling +[child_process.exec](http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) +directly. If it is an executable it will run in a new shell. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/lib/open.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/lib/open.js new file mode 100644 index 00000000000..3b77c3f3bb9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/lib/open.js @@ -0,0 +1,60 @@ +var exec = require('child_process').exec + , path = require('path') + ; + + +/** + * open a file or uri using the default application for the file type. + * + * @return {ChildProcess} - the child process object. + * @param {string} target - the file/uri to open. + * @param {string} appName - (optional) the application to be used to open the + * file (for example, "chrome", "firefox") + * @param {function(Error)} callback - called with null on success, or + * an error object that contains a property 'code' with the exit + * code of the process. + */ + +module.exports = open; + +function open(target, appName, callback) { + var opener; + + if (typeof(appName) === 'function') { + callback = appName; + appName = null; + } + + switch (process.platform) { + case 'darwin': + if (appName) { + opener = 'open -a "' + escape(appName) + '"'; + } else { + opener = 'open'; + } + break; + case 'win32': + // if the first parameter to start is quoted, it uses that as the title + // so we pass a blank title so we can quote the file we are opening + if (appName) { + opener = 'start "" "' + escape(appName) + '"'; + } else { + opener = 'start ""'; + } + break; + default: + if (appName) { + opener = escape(appName); + } else { + // use Portlands xdg-open everywhere else + opener = path.join(__dirname, '../vendor/xdg-open'); + } + break; + } + + return exec(opener + ' "' + escape(target) + '"', callback); +} + +function escape(s) { + return s.replace(/"/g, '\\\"'); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/package.json new file mode 100644 index 00000000000..38af4f025f0 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/package.json @@ -0,0 +1,48 @@ +{ + "name": "open", + "version": "0.0.4", + "description": "open a file or url in the user's preferred application", + "keywords": [ + "start", + "open", + "browser", + "editor", + "default" + ], + "homepage": "https://github.com/jjrdn/node-open", + "author": { + "name": "J Jordan", + "email": "jjrdn@styosis.com" + }, + "license": "MIT", + "contributors": [ + { + "name": "Victor Costan", + "email": "victor@costan.us", + "url": "http://www.costan.us" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/pwnall/node-open.git" + }, + "bugs": { + "url": "https://github.com/pwnall/node-open/issues" + }, + "engines": { + "node": ">= 0.6.0" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "*" + }, + "optionalDependencies": {}, + "main": "lib/open.js", + "scripts": { + "test": "node_modules/mocha/bin/mocha" + }, + "readme": "# open\n\nOpen a file or url in the user's preferred application.\n\n# Usage\n\n```javascript\nvar open = require(\"open\");\nopen(\"http://www.google.com\");\n```\n\n`open` taks an optional argument specifying the program to be used to open the\nfile or URL.\n\n```javascript\nopen(\"http://www.google.com\", \"firefox\");\n```\n\n# Installation\n\n npm install open\n\n# How it works\n\n- on `win32` uses `start`\n- on `darwin` uses `open`\n- otherwise uses the `xdg-open` script from [freedesktop.org](http://portland.freedesktop.org/xdg-utils-1.0/xdg-open.html)\n\n# Warning\n\nThe same care should be taken when calling open as if you were calling\n[child_process.exec](http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)\ndirectly. If it is an executable it will run in a new shell.\n", + "readmeFilename": "README.md", + "_id": "open@0.0.4", + "_from": "open@" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/vendor/xdg-open b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/vendor/xdg-open new file mode 100644 index 00000000000..13caac1a43f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/open/vendor/xdg-open @@ -0,0 +1,767 @@ +#!/bin/sh +#--------------------------------------------- +# xdg-open +# +# Utility script to open a URL in the registered default application. +# +# Refer to the usage() function below for usage. +# +# Copyright 2009-2010, Fathi Boudra +# Copyright 2009-2010, Rex Dieter +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# LICENSE: +# +# 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. +# +#--------------------------------------------- + +manualpage() +{ +cat << _MANUALPAGE +Name + + xdg-open -- opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +Description + + xdg-open opens a file or URL in the user's preferred + application. If a URL is provided the URL will be opened in the + user's preferred web browser. If a file is provided the file + will be opened in the preferred application for files of that + type. xdg-open supports file, ftp, http and https URLs. + + xdg-open is for use inside a desktop session only. It is not + recommended to use xdg-open as root. + +Options + + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. + +Exit Codes + + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 2 + One of the files passed on the command line did not + exist. + + 3 + A required tool could not be found. + + 4 + The action failed. + +Examples + +xdg-open 'http://www.freedesktop.org/' + + Opens the freedesktop.org website in the user's default + browser. + +xdg-open /tmp/foobar.png + + Opens the PNG image file /tmp/foobar.png in the user's default + image viewing application. +_MANUALPAGE +} + +usage() +{ +cat << _USAGE + xdg-open -- opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + echo "Try 'xdg-open --help' for more information." >&2 + else + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to write a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [a-zA-Z]*-*) + return + ;; + esac + + echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-open 1.1.0 rc1" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + GNOME) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + XFCE) + DE=xfce + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` + major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +last_word() +{ + read first rest + echo "$rest" +} + +open_darwin() +{ + open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_kde() +{ + if kde-open -v 2>/dev/null 1>&2; then + kde-open "$1" + else + if [ x"$KDE_SESSION_VERSION" = x"4" ]; then + kfmclient openURL "$1" + else + kfmclient exec "$1" + kfmclient_fix_exit_code $? + fi + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome() +{ + if gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + gnome-open "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_mate() +{ + if gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + mate-open "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_xfce() +{ + exo-open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +#----------------------------------------- +# Recursively search .desktop file + +search_desktop_file() +{ + local default="$1" + local dir="$2" + local arg="$3" + + local file="" + # look for both vendor-app.desktop, vendor/app.desktop + if [ -r "$dir/$default" ]; then + file="$dir/$default" + elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then + file="$dir/`echo $default | sed -e 's|-|/|'`" + fi + + if [ -r "$file" ] ; then + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command_exec=`which $command 2>/dev/null` + arguments="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | last_word`" + arg_one="`echo $arg | sed 's/&/\\\\&/g'`" + arguments_exec="`echo $arguments | sed -e 's*%[fFuU]*"'"$arg_one"'"*g'`" + + if [ -x "$command_exec" ] ; then + if echo $arguments | grep -iq '%[fFuU]' ; then + echo START $command_exec $arguments_exec + eval $command_exec $arguments_exec + else + echo START $command_exec $arguments_exec "$arg" + eval $command_exec $arguments_exec "$arg" + fi + + if [ $? -eq 0 ]; then + exit_success + fi + fi + fi + + for d in $dir/*/; do + [ -d "$d" ] && search_desktop_file "$default" "$d" "$arg" + done +} + + +open_generic_xdg_mime() +{ + filetype="$2" + default=`xdg-mime query default "$filetype"` + if [ -n "$default" ] ; then + xdg_user_dir="$XDG_DATA_HOME" + [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" + + xdg_system_dirs="$XDG_DATA_DIRS" + [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ + +DEBUG 3 "$xdg_user_dir:$xdg_system_dirs" + for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do + search_desktop_file "$default" "$x/applications/" "$1" + done + fi +} + +open_generic_xdg_file_mime() +{ + filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"` + open_generic_xdg_mime "$1" "$filetype" +} + +open_generic_xdg_x_scheme_handler() +{ + scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`" + if [ -n $scheme ]; then + filetype="x-scheme-handler/$scheme" + open_generic_xdg_mime "$1" "$filetype" + fi +} + +open_generic() +{ + # Paths or file:// URLs + if (echo "$1" | grep -q '^file://' || + ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:'); then + + local file="$1" + + # Decode URLs + if echo "$file" | grep -q '^file:///'; then + file=${file#file://} + file="$(printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")" + fi + check_input_file "$file" + + open_generic_xdg_file_mime "$file" + + if [ -f /etc/debian_version ] && + which run-mailcap 2>/dev/null 1>&2; then + run-mailcap --action=view "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + + if mimeopen -v 2>/dev/null 1>&2; then + mimeopen -L -n "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + fi + + open_generic_xdg_x_scheme_handler "$1" + + IFS=":" + for browser in $BROWSER; do + if [ x"$browser" != x"" ]; then + + browser_with_arg=`printf "$browser" "$1" 2>/dev/null` + if [ $? -ne 0 ]; then + browser_with_arg=$browser; + fi + + if [ x"$browser_with_arg" = x"$browser" ]; then + eval '$browser $1'$xdg_redirect_output; + else eval '$browser_with_arg'$xdg_redirect_output; + fi + + if [ $? -eq 0 ]; then + exit_success; + fi + fi + done + + exit_failure_operation_impossible "no method available for opening '$1'" +} + +open_lxde() +{ + # pcmanfm only knows how to handle file:// urls and filepaths, it seems. + if (echo "$1" | grep -q '^file://' || + ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:') + then + local file="$(echo "$1" | sed 's%^file://%%')" + + # handle relative paths + if ! echo "$file" | grep -q '^/'; then + file="$(pwd)/$file" + fi + + pcmanfm "$file" + + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +[ x"$1" != x"" ] || exit_failure_syntax + +url= +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + *) + if [ -n "$url" ] ; then + exit_failure_syntax "unexpected argument '$parm'" + fi + url="$parm" + ;; + esac +done + +if [ -z "${url}" ] ; then + exit_failure_syntax "file or URL argument missing" +fi + +detectDE + +if [ x"$DE" = x"" ]; then + DE=generic +fi + +DEBUG 2 "Selected DE $DE" + +# if BROWSER variable is not set, check some well known browsers instead +if [ x"$BROWSER" = x"" ]; then + BROWSER=links2:elinks:links:lynx:w3m + if [ -n "$DISPLAY" ]; then + BROWSER=x-www-browser:firefox:seamonkey:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER + fi +fi + +case "$DE" in + kde) + open_kde "$url" + ;; + + gnome*) + open_gnome "$url" + ;; + + mate) + open_mate "$url" + ;; + + xfce) + open_xfce "$url" + ;; + + lxde) + open_lxde "$url" + ;; + + generic) + open_generic "$url" + ;; + + *) + exit_failure_operation_impossible "no method available for opening '$url'" + ;; +esac diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/.npmignore new file mode 100644 index 00000000000..8233793969d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/.npmignore @@ -0,0 +1,6 @@ +npm-debug.log +node_modules +.*.swp +.lock-* +build + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/.travis.yml new file mode 100644 index 00000000000..08e4dad6fab --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +npm_args: --ws:native +node_js: + - "0.6" + - "0.8" + - "0.10" diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/History.md new file mode 100644 index 00000000000..63cf0ea6a95 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/History.md @@ -0,0 +1,312 @@ +v0.4.31 - September 23th, 2013 +===================== + +* Component support + +v0.4.30 - August 30th, 2013 +===================== + +* BufferedAmount could be undefined, default to 0 [TooTallNate] +* Support protocols as second argument and options as third [TooTallNate] +* Proper browserify shim [mcollina] +* Broadcasting example in README [stefanocudini] + +v0.4.29 - August 23th, 2013 +===================== +* Small clean up of the Node 0.11 support by using NAN from the NPM registry [kkoopa] +* Support for custom `Agent`'s through the options. [gramakri] & [TooTallNate] +* Support for custom headers through the options [3rd-Eden] +* Added a `gypfile` flag to the package.json for compiled module discovery [wolfeidau] + +v0.4.28 - August 16th, 2013 +===================== +* Node 0.11 support. [kkoopa] +* Authorization headers are sent when basic auth is used in the url [jcrugzz] +* Origin header will now include the port number [Jason Plum] +* Race condition fixed where data was received before the readyState was updated. [saschagehlich] + +v0.4.27 - June 27th, 2013 +===================== +* Frames are no longer masked in `wscat`. [slaskis] +* Don't retrain reference to large slab buffers. [jmatthewsr-msi] +* Don't use Buffer.byteLength for ArrayBuffer's. [Anthony Pesch] +* Fix browser field in package.json. [shtylman] +* Client-side certificate support & documentation improvements. [Lukas Berns] +* WebSocket readyState's is added to the prototype for spec compatiblity. [BallBearing] +* Use Object.defineProperty. [arlolra] +* Autodetect ArrayBuffers as binary when sending. [BallBearing] +* Check instanceof Buffer for binary data. [arlolra] +* Emit the close event before destroying the internal socket. [3rd-Eden] +* Don't setup multiply timeouts for one connection. [AndreasMadsen] +* Allow support for binding to ethereal port. [wpreul] +* Fix broken terminate reference. [3rd-Eden] +* Misc node 0.10 test fixes and documentation improvements. [3rd-Eden] +* Ensure ssl options are propagated to request. [einaros] +* Add 'Host' and 'Origin' to request header. [Lars-Magnus Skog] +* Subprotocol support. [kanaka] +* Honor ArrayBufferView's byteOffset when sending. [Anthony Pesch] +* Added target attribute for events. [arlolra] + +v0.4.26 - Skipped +===================== + +v0.4.25 - December 17th, 2012 +===================== +* Removed install.js. [shtylman] +* Added browser field to package.json. [shtylman] +* Support overwriting host header. [Raynos] +* Emit 'listening' also with custom http server. [sebiq] + +v0.4.24 - December 6th, 2012 +===================== +* Yet another intermediate release, to not delay minor features any longer. +* Native support installation issues further circumvented. [einaros] + +v0.4.23 - November 19th, 2012 +===================== +* Service release - last before major upgrade. +* Changes default host from 127.0.0.1 to 0.0.0.0. [einaros] + +v0.4.22 - October 3rd, 2012 +===================== +* clear failsafe cleanup timeout once cleanup is called [AndreasMadsen] +* added w3c compatible CloseEvent for onclose / addEventListener("close", ...). [einaros] +* fix the sub protocol header handler [sonnyp] +* fix unhandled exception if socket closes and 'error' is emitted [jmatthewsr-ms] + +v0.4.21 - July 14th, 2012 +===================== +* Emit error if server reponds with anything other than status code 101. [einaros] +* Added 'headers' event to server. [rauchg] +* path.exists moved to fs.exists. [blakmatrix] + +v0.4.20 - June 26th, 2012 +===================== +* node v0.8.0 compatibility release. + +v0.4.19 - June 19th, 2012 +===================== +* Change sender to merge buffers for relatively small payloads, may improve perf in some cases [einaros] +* Avoid EventEmitter for Receiver classes. As above this may improve perf. [einaros] +* Renamed fallback files from the somewhat misleading '*Windows'. [einaros] + +v0.4.18 - June 14th 2012 +===================== +* Fixed incorrect md5 digest encoding in Hixie handshake [nicokaiser] +* Added example of use with Express 3 [einaros] +* Change installation procedure to not require --ws:native to build native extensions. They will now build if a compiler is available. [einaros] + +v0.4.17 - June 13th 2012 +===================== +* Improve error handling during connection handshaking [einaros] +* Ensure that errors are caught also after connection teardown [nicokaiser] +* Update 'mocha' version to 1.1.0. [einaros] +* Stop showing 'undefined' for some error logs. [tricknotes] +* Update 'should' version to 0.6.3 [tricknotes] + +v0.4.16 - June 1st 2012 +===================== +* Build fix for Windows. [einaros] + +v0.4.15 - May 20th 2012 +===================== +* Enable fauxe streaming for hixie tansport. [einaros] +* Allow hixie sender to deal with buffers. [einaros/pigne] +* Allow error code 1011. [einaros] +* Fix framing for empty packets (empty pings and pongs might break). [einaros] +* Improve error and close handling, to avoid connections lingering in CLOSING state. [einaros] + +v0.4.14 - Apr 30th 2012 +===================== +* use node-gyp instead of node-waf [TooTallNate] +* remove old windows compatibility makefile, and silently fall back to native modules [einaros] +* ensure connection status [nicokaiser] +* websocket client updated to use port 443 by default for wss:// connections [einaros] +* support unix sockets [kschzt] + +v0.4.13 - Apr 12th 2012 +===================== + +* circumvent node 0.6+ related memory leak caused by Object.defineProperty [nicokaiser] +* improved error handling, improving stability in massive load use cases [nicokaiser] + +v0.4.12 - Mar 30th 2012 +===================== + +* various memory leak / possible memory leak cleanups [einaros] +* api documentation [nicokaiser] +* add option to disable client tracking [nicokaiser] + +v0.4.11 - Mar 24th 2012 +===================== + +* node v0.7 compatibillity release +* gyp support [TooTallNate] +* commander dependency update [jwueller] +* loadbalancer support [nicokaiser] + +v0.4.10 - Mar 22th 2012 +===================== + +* Final hixie close frame fixes. [nicokaiser] + +v0.4.9 - Mar 21st 2012 +===================== + +* Various hixie bugfixes (such as proper close frame handling). [einaros] + +v0.4.8 - Feb 29th 2012 +===================== + +* Allow verifyClient to run asynchronously [karlsequin] +* Various bugfixes and cleanups. [einaros] + +v0.4.7 - Feb 21st 2012 +===================== + +* Exposed bytesReceived from websocket client object, which makes it possible to implement bandwidth sampling. [einaros] +* Updated browser based file upload example to include and output per websocket channel bandwidth sampling. [einaros] +* Changed build scripts to check which architecture is currently in use. Required after the node.js changes to have prebuilt packages target ia32 by default. [einaros] + +v0.4.6 - Feb 9th 2012 +===================== + +* Added browser based file upload example. [einaros] +* Added server-to-browser status push example. [einaros] +* Exposed pause() and resume() on WebSocket object, to enable client stream shaping. [einaros] + +v0.4.5 - Feb 7th 2012 +===================== + +* Corrected regression bug in handling of connections with the initial frame delivered across both http upgrade head and a standalone packet. This would lead to a race condition, which in some cases could cause message corruption. [einaros] + +v0.4.4 - Feb 6th 2012 +===================== + +* Pass original request object to verifyClient, for cookie or authentication verifications. [einaros] +* Implemented addEventListener and slightly improved the emulation API by adding a MessageEvent with a readonly data attribute. [aslakhellesoy] +* Rewrite parts of hybi receiver to avoid stack overflows for large amounts of packets bundled in the same buffer / packet. [einaros] + +v0.4.3 - Feb 4th 2012 +===================== + +* Prioritized update: Corrected issue which would cause sockets to stay open longer than necessary, and resource leakage because of this. [einaros] + +v0.4.2 - Feb 4th 2012 +===================== + +* Breaking change: WebSocketServer's verifyOrigin option has been renamed to verifyClient. [einaros] +* verifyClient now receives { origin: 'origin header', secure: true/false }, where 'secure' will be true for ssl connections. [einaros] +* Split benchmark, in preparation for more thorough case. [einaros] +* Introduced hixie-76 draft support for server, since Safari (iPhone / iPad / OS X) and Opera still aren't updated to use Hybi. [einaros] +* Expose 'supports' object from WebSocket, to indicate e.g. the underlying transport's support for binary data. [einaros] +* Test and code cleanups. [einaros] + +v0.4.1 - Jan 25th 2012 +===================== + +* Use readline in wscat [tricknotes] +* Refactor _state away, in favor of the new _readyState [tricknotes] +* travis-ci integration [einaros] +* Fixed race condition in testsuite, causing a few tests to fail (without actually indicating errors) on travis [einaros] +* Expose pong event [paddybyers] +* Enabled running of WebSocketServer in noServer-mode, meaning that upgrades are passed in manually. [einaros] +* Reworked connection procedure for WebSocketServer, and cleaned up tests. [einaros] + +v0.4.0 - Jan 2nd 2012 +===================== + +* Windows compatibility [einaros] +* Windows compatible test script [einaros] + +v0.3.9 - Jan 1st 2012 +====================== + +* Improved protocol framing performance [einaros] +* WSS support [kazuyukitanimura] +* WSS tests [einaros] +* readyState exposed [justinlatimer, tricknotes] +* url property exposed [justinlatimer] +* Removed old 'state' property [einaros] +* Test cleanups [einaros] + +v0.3.8 - Dec 27th 2011 +====================== + +* Made it possible to listen on specific paths, which is especially good to have for precreated http servers [einaros] +* Extensive WebSocket / WebSocketServer cleanup, including changing all internal properties to unconfigurable, unenumerable properties [einaros] +* Receiver modifications to ensure even better performance with fragmented sends [einaros] +* Fixed issue in sender.js, which would cause SlowBuffer instances (such as returned from the crypto library's randomBytes) to be copied (and thus be dead slow) [einaros] +* Removed redundant buffer copy in sender.js, which should improve server performance [einaros] + +v0.3.7 - Dec 25nd 2011 +====================== + +* Added a browser based API which uses EventEmitters internally [3rd-Eden] +* Expose request information from upgrade event for websocket server clients [mmalecki] + +v0.3.6 - Dec 19th 2011 +====================== + +* Added option to let WebSocket.Server use an already existing http server [mmalecki] +* Migrating various option structures to use options.js module [einaros] +* Added a few more tests, options and handshake verifications to ensure that faulty connections are dealt with [einaros] +* Code cleanups in Sender and Receiver, to ensure even faster parsing [einaros] + +v0.3.5 - Dec 13th 2011 +====================== + +* Optimized Sender.js, Receiver.js and bufferutil.cc: + * Apply loop-unrolling-like small block copies rather than use node.js Buffer#copy() (which is slow). + * Mask blocks of data using combination of 32bit xor and loop-unrolling, instead of single bytes. + * Keep pre-made send buffer for small transfers. +* Leak fixes and code cleanups. + +v0.3.3 - Dec 12th 2011 +====================== + +* Compile fix for Linux. +* Rewrote parts of WebSocket.js, to avoid try/catch and thus avoid optimizer bailouts. + +v0.3.2 - Dec 11th 2011 +====================== + +* Further performance updates, including the additions of a native BufferUtil module, which deals with several of the cpu intensive WebSocket operations. + +v0.3.1 - Dec 8th 2011 +====================== + +* Service release, fixing broken tests. + +v0.3.0 - Dec 8th 2011 +====================== + +* Node.js v0.4.x compatibility. +* Code cleanups and efficiency improvements. +* WebSocket server added, although this will still mainly be a client library. +* WebSocket server certified to pass the Autobahn test suite. +* Protocol improvements and corrections - such as handling (redundant) masks for empty fragments. +* 'wscat' command line utility added, which can act as either client or server. + +v0.2.6 - Dec 3rd 2011 +====================== + +* Renamed to 'ws'. Big woop, right -- but easy-websocket really just doesn't cut it anymore! + +v0.2.5 - Dec 3rd 2011 +====================== + + * Rewrote much of the WebSocket parser, to ensure high speed for highly fragmented messages. + * Added a BufferPool, as a start to more efficiently deal with allocations for WebSocket connections. More work to come, in that area. + * Updated the Autobahn report, at http://einaros.github.com/easy-websocket, with comparisons against WebSocket-Node 1.0.2 and Chrome 16. + +v0.2.0 - Nov 25th 2011 +====================== + + * Major rework to make sure all the Autobahn test cases pass. Also updated the internal tests to cover more corner cases. + +v0.1.2 - Nov 14th 2011 +====================== + + * Back and forth, back and forth: now settled on keeping the api (event names, methods) closer to the websocket browser api. This will stick now. + * Started keeping this history record. Better late than never, right? diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/Makefile new file mode 100644 index 00000000000..151aa2ba535 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/Makefile @@ -0,0 +1,40 @@ +ALL_TESTS = $(shell find test/ -name '*.test.js') +ALL_INTEGRATION = $(shell find test/ -name '*.integration.js') + +all: + node-gyp configure build + +clean: + node-gyp clean + +run-tests: + @./node_modules/.bin/mocha \ + -t 2000 \ + -s 2400 \ + $(TESTFLAGS) \ + $(TESTS) + +run-integrationtests: + @./node_modules/.bin/mocha \ + -t 5000 \ + -s 6000 \ + $(TESTFLAGS) \ + $(TESTS) + +test: + @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests + +integrationtest: + @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_INTEGRATION)" run-integrationtests + +benchmark: + @node bench/sender.benchmark.js + @node bench/parser.benchmark.js + +autobahn: + @NODE_PATH=lib node test/autobahn.js + +autobahn-server: + @NODE_PATH=lib node test/autobahn-server.js + +.PHONY: test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/README.md new file mode 100644 index 00000000000..e6646e76065 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/README.md @@ -0,0 +1,171 @@ +[![Build Status](https://secure.travis-ci.org/einaros/ws.png)](http://travis-ci.org/einaros/ws) + +# ws: a node.js websocket library # + +`ws` is a simple to use websocket implementation, up-to-date against RFC-6455, and [probably the fastest WebSocket library for node.js](http://web.archive.org/web/20130314230536/http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs). + +Passes the quite extensive Autobahn test suite. See http://einaros.github.com/ws for the full reports. + +Comes with a command line utility, `wscat`, which can either act as a server (--listen), or client (--connect); Use it to debug simple websocket services. + +## Protocol support ## + +* **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera. Added to ws version 0.4.2, but server only. Can be disabled by setting the `disableHixie` option to true.) +* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`, or argument `-p 8` for wscat) +* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`, or argument `-p 13` for wscat) + +_See the echo.websocket.org example below for how to use the `protocolVersion` option._ + +## Usage ## + +### Installing ### + +`npm install ws` + +### Sending and receiving text data ### + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://www.host.com/path'); +ws.on('open', function() { + ws.send('something'); +}); +ws.on('message', function(data, flags) { + // flags.binary will be set if a binary data is received + // flags.masked will be set if the data was masked +}); +``` + +### Sending binary data ### + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://www.host.com/path'); +ws.on('open', function() { + var array = new Float32Array(5); + for (var i = 0; i < array.length; ++i) array[i] = i / 2; + ws.send(array, {binary: true, mask: true}); +}); +``` + +Setting `mask`, as done for the send options above, will cause the data to be masked according to the websocket protocol. The same option applies for text data. + +### Server example ### + +```js +var WebSocketServer = require('ws').Server + , wss = new WebSocketServer({port: 8080}); +wss.on('connection', function(ws) { + ws.on('message', function(message) { + console.log('received: %s', message); + }); + ws.send('something'); +}); +``` + +### Server sending broadcast data ### + +```js +var WebSocketServer = require('ws').Server + , wss = new WebSocketServer({port: 8080}); + +wss.broadcast = function(data) { + for(var i in this.clients) + this.clients[i].send(data); +}; +``` + +### Error handling best practices ### + +```js +// If the WebSocket is closed before the following send is attempted +ws.send('something'); + +// Errors (both immediate and async write errors) can be detected in an optional callback. +// The callback is also the only way of being notified that data has actually been sent. +ws.send('something', function(error) { + // if error is null, the send has been completed, + // otherwise the error object will indicate what failed. +}); + +// Immediate errors can also be handled with try/catch-blocks, but **note** +// that since sends are inherently asynchronous, socket write failures will *not* +// be captured when this technique is used. +try { + ws.send('something'); +} +catch (e) { + // handle error +} +``` + +### echo.websocket.org demo ### + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://echo.websocket.org/', {protocolVersion: 8, origin: 'http://websocket.org'}); +ws.on('open', function() { + console.log('connected'); + ws.send(Date.now().toString(), {mask: true}); +}); +ws.on('close', function() { + console.log('disconnected'); +}); +ws.on('message', function(data, flags) { + console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags); + setTimeout(function() { + ws.send(Date.now().toString(), {mask: true}); + }, 500); +}); +``` + +### wscat against echo.websocket.org ### + + $ npm install -g ws + $ wscat -c ws://echo.websocket.org -p 8 + connected (press CTRL+C to quit) + > hi there + < hi there + > are you a happy parrot? + < are you a happy parrot? + +### Other examples ### + +For a full example with a browser client communicating with a ws server, see the examples folder. + +Note that the usage together with Express 3.0 is quite different from Express 2.x. The difference is expressed in the two different serverstats-examples. + +Otherwise, see the test cases. + +### Running the tests ### + +`make test` + +## API Docs ## + +See the doc/ directory for Node.js-like docs for the ws classes. + +## License ## + +(The MIT License) + +Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com> + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/parser.benchmark.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/parser.benchmark.js new file mode 100644 index 00000000000..ff5f737c0fe --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/parser.benchmark.js @@ -0,0 +1,115 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +/** + * Benchmark dependencies. + */ + +var benchmark = require('benchmark') + , Receiver = require('../').Receiver + , suite = new benchmark.Suite('Receiver'); +require('tinycolor'); +require('./util'); + +/** + * Setup receiver. + */ + +suite.on('start', function () { + receiver = new Receiver(); +}); + +suite.on('cycle', function () { + receiver = new Receiver(); +}); + +/** + * Benchmarks. + */ + +var pingMessage = 'Hello' + , pingPacket1 = getBufferFromHexString('89 ' + (pack(2, 0x80 | pingMessage.length)) + + ' 34 83 a8 68 '+ getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68'))); +suite.add('ping message', function () { + receiver.add(pingPacket1); +}); + +var pingPacket2 = getBufferFromHexString('89 00') +suite.add('ping with no data', function () { + receiver.add(pingPacket2); +}); + +var closePacket = getBufferFromHexString('88 00'); +suite.add('close message', function () { + receiver.add(closePacket); + receiver.endPacket(); +}); + +var maskedTextPacket = getBufferFromHexString('81 93 34 83 a8 68 01 b9 92 52 4f a1 c6 09 59 e6 8a 52 16 e6 cb 00 5b a1 d5'); +suite.add('masked text message', function () { + receiver.add(maskedTextPacket); +}); + +binaryDataPacket = (function() { + var length = 125 + , message = new Buffer(length) + for (var i = 0; i < length; ++i) message[i] = i % 10; + return getBufferFromHexString('82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + + getHexStringFromBuffer(mask(message), '34 83 a8 68')); +})(); +suite.add('binary data (125 bytes)', function () { + try { + receiver.add(binaryDataPacket); + + } + catch(e) {console.log(e)} +}); + +binaryDataPacket2 = (function() { + var length = 65535 + , message = new Buffer(length) + for (var i = 0; i < length; ++i) message[i] = i % 10; + return getBufferFromHexString('82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + + getHexStringFromBuffer(mask(message), '34 83 a8 68')); +})(); +suite.add('binary data (65535 bytes)', function () { + receiver.add(binaryDataPacket2); +}); + +binaryDataPacket3 = (function() { + var length = 200*1024 + , message = new Buffer(length) + for (var i = 0; i < length; ++i) message[i] = i % 10; + return getBufferFromHexString('82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + + getHexStringFromBuffer(mask(message), '34 83 a8 68')); +})(); +suite.add('binary data (200 kB)', function () { + receiver.add(binaryDataPacket3); +}); + +/** + * Output progress. + */ + +suite.on('cycle', function (bench, details) { + console.log('\n ' + suite.name.grey, details.name.white.bold); + console.log(' ' + [ + details.hz.toFixed(2).cyan + ' ops/sec'.grey + , details.count.toString().white + ' times executed'.grey + , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey + , + ].join(', '.grey)); +}); + +/** + * Run/export benchmarks. + */ + +if (!module.parent) { + suite.run(); +} else { + module.exports = suite; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/sender.benchmark.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/sender.benchmark.js new file mode 100644 index 00000000000..20c171a509a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/sender.benchmark.js @@ -0,0 +1,66 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +/** + * Benchmark dependencies. + */ + +var benchmark = require('benchmark') + , Sender = require('../').Sender + , suite = new benchmark.Suite('Sender'); +require('tinycolor'); +require('./util'); + +/** + * Setup sender. + */ + +suite.on('start', function () { + sender = new Sender(); + sender._socket = { write: function() {} }; +}); + +suite.on('cycle', function () { + sender = new Sender(); + sender._socket = { write: function() {} }; +}); + +/** + * Benchmarks + */ + +framePacket = new Buffer(200*1024); +framePacket.fill(99); +suite.add('frameAndSend, unmasked (200 kB)', function () { + sender.frameAndSend(0x2, framePacket, true, false); +}); +suite.add('frameAndSend, masked (200 kB)', function () { + sender.frameAndSend(0x2, framePacket, true, true); +}); + +/** + * Output progress. + */ + +suite.on('cycle', function (bench, details) { + console.log('\n ' + suite.name.grey, details.name.white.bold); + console.log(' ' + [ + details.hz.toFixed(2).cyan + ' ops/sec'.grey + , details.count.toString().white + ' times executed'.grey + , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey + , + ].join(', '.grey)); +}); + +/** + * Run/export benchmarks. + */ + +if (!module.parent) { + suite.run(); +} else { + module.exports = suite; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/speed.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/speed.js new file mode 100644 index 00000000000..3ce6414610a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/speed.js @@ -0,0 +1,105 @@ +var cluster = require('cluster') + , WebSocket = require('../') + , WebSocketServer = WebSocket.Server + , crypto = require('crypto') + , util = require('util') + , ansi = require('ansi'); +require('tinycolor'); + +function roundPrec(num, prec) { + var mul = Math.pow(10, prec); + return Math.round(num * mul) / mul; +} + +function humanSize(bytes) { + if (bytes >= 1048576) return roundPrec(bytes / 1048576, 2) + ' MB'; + if (bytes >= 1024) return roundPrec(bytes / 1024, 2) + ' kB'; + return roundPrec(bytes, 2) + ' B'; +} + +function generateRandomData(size) { + var buffer = new Buffer(size); + for (var i = 0; i < size; ++i) { + buffer[i] = ~~(Math.random() * 127); + } + return buffer; +} + +if (cluster.isMaster) { + var wss = new WebSocketServer({port: 8181}, function() { + cluster.fork(); + }); + wss.on('connection', function(ws) { + ws.on('message', function(data, flags) { + ws.send(data, {binary: flags&&flags.binary}); + }); + ws.on('close', function() {}); + }); + cluster.on('death', function(worker) { + wss.close(); + }); +} +else { + var cursor = ansi(process.stdout); + + var configs = [ + [true, 10000, 64], + [true, 5000, 16*1024], + [true, 1000, 128*1024], + [true, 100, 1024*1024], + [true, 1, 500*1024*1024], + [false, 10000, 64], + [false, 5000, 16*1024], + [false, 1000, 128*1024], + [false, 100, 1024*1024], + ]; + + var largest = configs[0][1]; + for (var i = 0, l = configs.length; i < l; ++i) { + if (configs[i][2] > largest) largest = configs[i][2]; + } + + console.log('Generating %s of test data ...', humanSize(largest)); + var randomBytes = generateRandomData(largest); + + function roundtrip(useBinary, roundtrips, size, cb) { + var data = randomBytes.slice(0, size); + var prefix = util.format('Running %d roundtrips of %s %s data', roundtrips, humanSize(size), useBinary ? 'binary' : 'text'); + console.log(prefix); + var client = new WebSocket('ws://localhost:' + '8181'); + var dt; + var roundtrip = 0; + function send() { + client.send(data, {binary: useBinary}); + } + client.on('error', function(e) { + console.error(e); + process.exit(); + }); + client.on('open', function() { + dt = Date.now(); + send(); + }); + client.on('message', function(data, flags) { + if (++roundtrip == roundtrips) { + var elapsed = Date.now() - dt; + cursor.up(); + console.log('%s:\t%ss\t%s' + , useBinary ? prefix.green : prefix.cyan + , roundPrec(elapsed / 1000, 1).toString().green.bold + , (humanSize((size * roundtrips) / elapsed * 1000) + '/s').blue.bold); + client.close(); + cb(); + return; + } + process.nextTick(send); + }); + } + + (function run() { + if (configs.length == 0) process.exit(); + var config = configs.shift(); + config.push(run); + roundtrip.apply(null, config); + })(); +} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/util.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/util.js new file mode 100644 index 00000000000..5f012819084 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bench/util.js @@ -0,0 +1,105 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +/** + * Returns a Buffer from a "ff 00 ff"-type hex string. + */ + +getBufferFromHexString = function(byteStr) { + var bytes = byteStr.split(' '); + var buf = new Buffer(bytes.length); + for (var i = 0; i < bytes.length; ++i) { + buf[i] = parseInt(bytes[i], 16); + } + return buf; +} + +/** + * Returns a hex string from a Buffer. + */ + +getHexStringFromBuffer = function(data) { + var s = ''; + for (var i = 0; i < data.length; ++i) { + s += padl(data[i].toString(16), 2, '0') + ' '; + } + return s.trim(); +} + +/** + * Splits a buffer in two parts. + */ + +splitBuffer = function(buffer) { + var b1 = new Buffer(Math.ceil(buffer.length / 2)); + buffer.copy(b1, 0, 0, b1.length); + var b2 = new Buffer(Math.floor(buffer.length / 2)); + buffer.copy(b2, 0, b1.length, b1.length + b2.length); + return [b1, b2]; +} + +/** + * Performs hybi07+ type masking on a hex string or buffer. + */ + +mask = function(buf, maskString) { + if (typeof buf == 'string') buf = new Buffer(buf); + var mask = getBufferFromHexString(maskString || '34 83 a8 68'); + for (var i = 0; i < buf.length; ++i) { + buf[i] ^= mask[i % 4]; + } + return buf; +} + +/** + * Returns a hex string representing the length of a message + */ + +getHybiLengthAsHexString = function(len, masked) { + if (len < 126) { + var buf = new Buffer(1); + buf[0] = (masked ? 0x80 : 0) | len; + } + else if (len < 65536) { + var buf = new Buffer(3); + buf[0] = (masked ? 0x80 : 0) | 126; + getBufferFromHexString(pack(4, len)).copy(buf, 1); + } + else { + var buf = new Buffer(9); + buf[0] = (masked ? 0x80 : 0) | 127; + getBufferFromHexString(pack(16, len)).copy(buf, 1); + } + return getHexStringFromBuffer(buf); +} + +/** + * Unpacks a Buffer into a number. + */ + +unpack = function(buffer) { + var n = 0; + for (var i = 0; i < buffer.length; ++i) { + n = (i == 0) ? buffer[i] : (n * 256) + buffer[i]; + } + return n; +} + +/** + * Returns a hex string, representing a specific byte count 'length', from a number. + */ + +pack = function(length, number) { + return padl(number.toString(16), length, '0').replace(/([0-9a-f][0-9a-f])/gi, '$1 ').trim(); +} + +/** + * Left pads the string 's' to a total length of 'n' with char 'c'. + */ + +padl = function(s, n, c) { + return new Array(1 + n - s.length).join(c) + s; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bin/wscat b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bin/wscat new file mode 100644 index 00000000000..0ec894df751 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/bin/wscat @@ -0,0 +1,190 @@ +#!/usr/bin/env node + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var WebSocket = require('../') + , fs = require('fs') + , program = require('commander') + , util = require('util') + , events = require('events') + , readline = require('readline'); + +/** + * InputReader - processes console input + */ + +function Console() { + this.stdin = process.stdin; + this.stdout = process.stdout; + + this.readlineInterface = readline.createInterface(this.stdin, this.stdout); + + var self = this; + this.readlineInterface.on('line', function(data) { + self.emit('line', data); + }); + this.readlineInterface.on('close', function() { + self.emit('close'); + }); + + this._resetInput = function() { + self.clear(); + } +} +util.inherits(Console, events.EventEmitter); + +Console.Colors = { + Red: '\033[31m', + Green: '\033[32m', + Yellow: '\033[33m', + Blue: '\033[34m', + Default: '\033[39m' +}; + +Console.prototype.prompt = function() { + this.readlineInterface.prompt(); +} + +Console.prototype.print = function(msg, color) { + this.clear(); + color = color || Console.Colors.Default; + this.stdout.write(color + msg + Console.Colors.Default + '\n'); + this.prompt(); +} + +Console.prototype.clear = function() { + this.stdout.write('\033[2K\033[E'); +} + +Console.prototype.pause = function() { + this.stdin.on('keypress', this._resetInput); +} + +Console.prototype.resume = function() { + this.stdin.removeListener('keypress', this._resetInput); +} + +/** + * The actual application + */ + +var version = JSON.parse(fs.readFileSync(__dirname + '/../package.json', 'utf8')).version; +program + .version(version) + .usage('[options] ') + .option('-l, --listen ', 'listen on port') + .option('-c, --connect ', 'connect to a websocket server') + .option('-p, --protocol ', 'optional protocol version') + .option('-o, --origin ', 'optional origin') + .option('--host ', 'optional host') + .option('-s, --subprotocol ', 'optional subprotocol') + .parse(process.argv); + +if (program.listen && program.connect) { + console.error('\033[33merror: use either --listen or --connect\033[39m'); + process.exit(-1); +} +else if (program.listen) { + var wsConsole = new Console(); + wsConsole.pause(); + var options = {}; + if (program.protocol) options.protocolVersion = program.protocol; + if (program.origin) options.origin = program.origin; + if (program.subprotocol) options.protocol = program.subprotocol; + var ws = null; + var wss = new WebSocket.Server({port: program.listen}, function() { + wsConsole.print('listening on port ' + program.listen + ' (press CTRL+C to quit)', Console.Colors.Green); + wsConsole.clear(); + }); + wsConsole.on('close', function() { + if (ws) { + try { + ws.close(); + } + catch (e) {} + } + process.exit(0); + }); + wsConsole.on('line', function(data) { + if (ws) { + ws.send(data, {mask: false}); + wsConsole.prompt(); + } + }); + wss.on('connection', function(newClient) { + if (ws) { + // limit to one client + newClient.terminate(); + return; + }; + ws = newClient; + wsConsole.resume(); + wsConsole.prompt(); + wsConsole.print('client connected', Console.Colors.Green); + ws.on('close', function() { + wsConsole.print('disconnected', Console.Colors.Green); + wsConsole.clear(); + wsConsole.pause(); + ws = null; + }); + ws.on('error', function(code, description) { + wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow); + }); + ws.on('message', function(data, flags) { + wsConsole.print('< ' + data, Console.Colors.Blue); + }); + }); + wss.on('error', function(error) { + wsConsole.print('error: ' + error.toString(), Console.Colors.Yellow); + process.exit(-1); + }); +} +else if (program.connect) { + var wsConsole = new Console(); + var options = {}; + if (program.protocol) options.protocolVersion = program.protocol; + if (program.origin) options.origin = program.origin; + if (program.subprotocol) options.protocol = program.subprotocol; + if (program.host) options.host = program.host; + var ws = new WebSocket(program.connect, options); + ws.on('open', function() { + wsConsole.print('connected (press CTRL+C to quit)', Console.Colors.Green); + wsConsole.on('line', function(data) { + ws.send(data, {mask: true}); + wsConsole.prompt(); + }); + }); + ws.on('close', function() { + wsConsole.print('disconnected', Console.Colors.Green); + wsConsole.clear(); + process.exit(); + }); + ws.on('error', function(code, description) { + wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow); + process.exit(-1); + }); + ws.on('message', function(data, flags) { + wsConsole.print('< ' + data, Console.Colors.Blue); + }); + wsConsole.on('close', function() { + if (ws) { + try { + ws.close(); + } + catch(e) {} + process.exit(); + } + }); +} +else { + console.error('\033[33merror: use either --listen or --connect\033[39m'); + process.exit(-1); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/binding.gyp b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/binding.gyp new file mode 100644 index 00000000000..c9b4d1a4d2a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/binding.gyp @@ -0,0 +1,16 @@ +{ + 'targets': [ + { + 'target_name': 'validation', + 'include_dirs': ["> $(depfile) +# Add extra rules as in (2). +# We remove slashes and replace spaces with new lines; +# remove blank lines; +# delete the first line and append a colon to the remaining lines. +sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ + grep -v '^$$' |\ + sed -e 1d -e 's|$$|:|' \ + >> $(depfile) +rm $(depfile).raw +endef + +# Command definitions: +# - cmd_foo is the actual command to run; +# - quiet_cmd_foo is the brief-output summary of the command. + +quiet_cmd_cc = CC($(TOOLSET)) $@ +cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< + +quiet_cmd_cxx = CXX($(TOOLSET)) $@ +cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< + +quiet_cmd_objc = CXX($(TOOLSET)) $@ +cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< + +quiet_cmd_objcxx = CXX($(TOOLSET)) $@ +cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< + +# Commands for precompiled header files. +quiet_cmd_pch_c = CXX($(TOOLSET)) $@ +cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< +quiet_cmd_pch_cc = CXX($(TOOLSET)) $@ +cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< +quiet_cmd_pch_m = CXX($(TOOLSET)) $@ +cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< +quiet_cmd_pch_mm = CXX($(TOOLSET)) $@ +cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< + +# gyp-mac-tool is written next to the root Makefile by gyp. +# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd +# already. +quiet_cmd_mac_tool = MACTOOL $(4) $< +cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@" + +quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@ +cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4) + +quiet_cmd_infoplist = INFOPLIST $@ +cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@" + +quiet_cmd_touch = TOUCH $@ +cmd_touch = touch $@ + +quiet_cmd_copy = COPY $@ +# send stderr to /dev/null to ignore messages when linking directories. +cmd_copy = rm -rf "$@" && cp -af "$<" "$@" + +quiet_cmd_alink = LIBTOOL-STATIC $@ +cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^) + +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) + +# TODO(thakis): Find out and document the difference between shared_library and +# loadable_module on mac. +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) + +# TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass +# -bundle -single_module here (for osmesa.so). +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) + + +# Define an escape_quotes function to escape single quotes. +# This allows us to handle quotes properly as long as we always use +# use single quotes and escape_quotes. +escape_quotes = $(subst ','\'',$(1)) +# This comment is here just to include a ' to unconfuse syntax highlighting. +# Define an escape_vars function to escape '$' variable syntax. +# This allows us to read/write command lines with shell variables (e.g. +# $LD_LIBRARY_PATH), without triggering make substitution. +escape_vars = $(subst $$,$$$$,$(1)) +# Helper that expands to a shell command to echo a string exactly as it is in +# make. This uses printf instead of echo because printf's behaviour with respect +# to escape sequences is more portable than echo's across different shells +# (e.g., dash, bash). +exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' + +# Helper to compare the command we're about to run against the command +# we logged the last time we ran the command. Produces an empty +# string (false) when the commands match. +# Tricky point: Make has no string-equality test function. +# The kernel uses the following, but it seems like it would have false +# positives, where one string reordered its arguments. +# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ +# $(filter-out $(cmd_$@), $(cmd_$(1)))) +# We instead substitute each for the empty string into the other, and +# say they're equal if both substitutions produce the empty string. +# .d files contain ? instead of spaces, take that into account. +command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ + $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) + +# Helper that is non-empty when a prerequisite changes. +# Normally make does this implicitly, but we force rules to always run +# so we can check their command lines. +# $? -- new prerequisites +# $| -- order-only dependencies +prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) + +# Helper that executes all postbuilds until one fails. +define do_postbuilds + @E=0;\ + for p in $(POSTBUILDS); do\ + eval $$p;\ + E=$$?;\ + if [ $$E -ne 0 ]; then\ + break;\ + fi;\ + done;\ + if [ $$E -ne 0 ]; then\ + rm -rf "$@";\ + exit $$E;\ + fi +endef + +# do_cmd: run a command via the above cmd_foo names, if necessary. +# Should always run for a given target to handle command-line changes. +# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. +# Third argument, if non-zero, makes it do POSTBUILDS processing. +# Note: We intentionally do NOT call dirx for depfile, since it contains ? for +# spaces already and dirx strips the ? characters. +define do_cmd +$(if $(or $(command_changed),$(prereq_changed)), + @$(call exact_echo, $($(quiet)cmd_$(1))) + @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" + $(if $(findstring flock,$(word 2,$(cmd_$1))), + @$(cmd_$(1)) + @echo " $(quiet_cmd_$(1)): Finished", + @$(cmd_$(1)) + ) + @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) + @$(if $(2),$(fixup_dep)) + $(if $(and $(3), $(POSTBUILDS)), + $(call do_postbuilds) + ) +) +endef + +# Declare the "all" target first so it is the default, +# even though we don't have the deps yet. +.PHONY: all +all: + +# make looks for ways to re-generate included makefiles, but in our case, we +# don't have a direct way. Explicitly telling make that it has nothing to do +# for them makes it go faster. +%.d: ; + +# Use FORCE_DO_CMD to force a target to run. Should be coupled with +# do_cmd. +.PHONY: FORCE_DO_CMD +FORCE_DO_CMD: + +TOOLSET := target +# Suffix rules, putting all outputs into $(obj). +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.m FORCE_DO_CMD + @$(call do_cmd,objc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.mm FORCE_DO_CMD + @$(call do_cmd,objcxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + +# Try building from generated source, too. +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.m FORCE_DO_CMD + @$(call do_cmd,objc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.mm FORCE_DO_CMD + @$(call do_cmd,objcxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + +$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.m FORCE_DO_CMD + @$(call do_cmd,objc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.mm FORCE_DO_CMD + @$(call do_cmd,objcxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + + +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,bufferutil.target.mk)))),) + include bufferutil.target.mk +endif +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,validation.target.mk)))),) + include validation.target.mk +endif + +quiet_cmd_regen_makefile = ACTION Regenerating $@ +cmd_regen_makefile = /Users/nj/.nvm/v0.10.20/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/Users/nj/github/LiveDev2/node/node_modules/ws/build/config.gypi -I/Users/nj/.nvm/v0.10.20/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/Users/nj/.node-gyp/0.10.20/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dmac_sdk=10.7" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/nj/.node-gyp/0.10.20" "-Dmodule_root_dir=/Users/nj/github/LiveDev2/node/node_modules/ws" binding.gyp +Makefile: $(srcdir)/../../../../../.nvm/v0.10.20/lib/node_modules/npm/node_modules/node-gyp/addon.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../.node-gyp/0.10.20/common.gypi + $(call do_cmd,regen_makefile) + +# "all" is a concatenation of the "all" targets from all the included +# sub-makefiles. This is just here to clarify. +all: + +# Add in dependency-tracking rules. $(all_deps) is the list of every single +# target in our tree. Only consider the ones with .d (dependency) info: +d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) +ifneq ($(d_files),) + include $(d_files) +endif diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/bufferutil.node.d b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/bufferutil.node.d new file mode 100644 index 00000000000..8b191311c21 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/bufferutil.node.d @@ -0,0 +1 @@ +cmd_Release/bufferutil.node := ./gyp-mac-tool flock ./Release/linker.lock c++ -shared -Wl,-search_paths_first -mmacosx-version-min=10.5 -arch x86_64 -L./Release -install_name @rpath/bufferutil.node -o Release/bufferutil.node Release/obj.target/bufferutil/src/bufferutil.o -undefined dynamic_lookup diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d new file mode 100644 index 00000000000..1f3de98fafa --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d @@ -0,0 +1,23 @@ +cmd_Release/obj.target/bufferutil/src/bufferutil.o := c++ '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/nj/.node-gyp/0.10.20/src -I/Users/nj/.node-gyp/0.10.20/deps/uv/include -I/Users/nj/.node-gyp/0.10.20/deps/v8/include -I/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan -Os -gdwarf-2 -mmacosx-version-min=10.5 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d.raw -c -o Release/obj.target/bufferutil/src/bufferutil.o ../src/bufferutil.cc +Release/obj.target/bufferutil/src/bufferutil.o: ../src/bufferutil.cc \ + /Users/nj/.node-gyp/0.10.20/deps/v8/include/v8.h \ + /Users/nj/.node-gyp/0.10.20/deps/v8/include/v8stdint.h \ + /Users/nj/.node-gyp/0.10.20/src/node.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-unix.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/ngx-queue.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-darwin.h \ + /Users/nj/.node-gyp/0.10.20/src/node_object_wrap.h \ + /Users/nj/.node-gyp/0.10.20/src/node_buffer.h \ + /Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan/nan.h +../src/bufferutil.cc: +/Users/nj/.node-gyp/0.10.20/deps/v8/include/v8.h: +/Users/nj/.node-gyp/0.10.20/deps/v8/include/v8stdint.h: +/Users/nj/.node-gyp/0.10.20/src/node.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-unix.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/ngx-queue.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-darwin.h: +/Users/nj/.node-gyp/0.10.20/src/node_object_wrap.h: +/Users/nj/.node-gyp/0.10.20/src/node_buffer.h: +/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan/nan.h: diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/obj.target/validation/src/validation.o.d b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/obj.target/validation/src/validation.o.d new file mode 100644 index 00000000000..258a752bcf7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/obj.target/validation/src/validation.o.d @@ -0,0 +1,23 @@ +cmd_Release/obj.target/validation/src/validation.o := c++ '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/nj/.node-gyp/0.10.20/src -I/Users/nj/.node-gyp/0.10.20/deps/uv/include -I/Users/nj/.node-gyp/0.10.20/deps/v8/include -I/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan -Os -gdwarf-2 -mmacosx-version-min=10.5 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/validation/src/validation.o.d.raw -c -o Release/obj.target/validation/src/validation.o ../src/validation.cc +Release/obj.target/validation/src/validation.o: ../src/validation.cc \ + /Users/nj/.node-gyp/0.10.20/deps/v8/include/v8.h \ + /Users/nj/.node-gyp/0.10.20/deps/v8/include/v8stdint.h \ + /Users/nj/.node-gyp/0.10.20/src/node.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-unix.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/ngx-queue.h \ + /Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-darwin.h \ + /Users/nj/.node-gyp/0.10.20/src/node_object_wrap.h \ + /Users/nj/.node-gyp/0.10.20/src/node_buffer.h \ + /Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan/nan.h +../src/validation.cc: +/Users/nj/.node-gyp/0.10.20/deps/v8/include/v8.h: +/Users/nj/.node-gyp/0.10.20/deps/v8/include/v8stdint.h: +/Users/nj/.node-gyp/0.10.20/src/node.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-unix.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/ngx-queue.h: +/Users/nj/.node-gyp/0.10.20/deps/uv/include/uv-private/uv-darwin.h: +/Users/nj/.node-gyp/0.10.20/src/node_object_wrap.h: +/Users/nj/.node-gyp/0.10.20/src/node_buffer.h: +/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan/nan.h: diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/validation.node.d b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/validation.node.d new file mode 100644 index 00000000000..869c91e2a05 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/.deps/Release/validation.node.d @@ -0,0 +1 @@ +cmd_Release/validation.node := ./gyp-mac-tool flock ./Release/linker.lock c++ -shared -Wl,-search_paths_first -mmacosx-version-min=10.5 -arch x86_64 -L./Release -install_name @rpath/validation.node -o Release/validation.node Release/obj.target/validation/src/validation.o -undefined dynamic_lookup diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/bufferutil.node b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/bufferutil.node new file mode 100644 index 00000000000..b8bbb086346 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/bufferutil.node differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/linker.lock b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/linker.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/obj.target/bufferutil/src/bufferutil.o b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/obj.target/bufferutil/src/bufferutil.o new file mode 100644 index 00000000000..d11b6331eac Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/obj.target/bufferutil/src/bufferutil.o differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/obj.target/validation/src/validation.o b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/obj.target/validation/src/validation.o new file mode 100644 index 00000000000..e5c4b2db23b Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/obj.target/validation/src/validation.o differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/validation.node b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/validation.node new file mode 100644 index 00000000000..fe7a1fbdbf1 Binary files /dev/null and b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/Release/validation.node differ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/binding.Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/binding.Makefile new file mode 100644 index 00000000000..a69b3d2ceaf --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/binding.Makefile @@ -0,0 +1,6 @@ +# This file is generated by gyp; do not edit. + +export builddir_name ?= build/./. +.PHONY: all +all: + $(MAKE) bufferutil validation diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/bufferutil.target.mk b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/bufferutil.target.mk new file mode 100644 index 00000000000..acefd661877 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/bufferutil.target.mk @@ -0,0 +1,158 @@ +# This file is generated by gyp; do not edit. + +TOOLSET := target +TARGET := bufferutil +DEFS_Debug := \ + '-D_DARWIN_USE_64_BIT_INODE=1' \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' \ + '-DDEBUG' \ + '-D_DEBUG' + +# Flags passed to all source files. +CFLAGS_Debug := \ + -O0 \ + -gdwarf-2 \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -Wall \ + -Wendif-labels \ + -W \ + -Wno-unused-parameter + +# Flags passed to only C files. +CFLAGS_C_Debug := \ + -fno-strict-aliasing + +# Flags passed to only C++ files. +CFLAGS_CC_Debug := \ + -fno-rtti \ + -fno-exceptions \ + -fno-threadsafe-statics \ + -fno-strict-aliasing + +# Flags passed to only ObjC files. +CFLAGS_OBJC_Debug := + +# Flags passed to only ObjC++ files. +CFLAGS_OBJCC_Debug := + +INCS_Debug := \ + -I/Users/nj/.node-gyp/0.10.20/src \ + -I/Users/nj/.node-gyp/0.10.20/deps/uv/include \ + -I/Users/nj/.node-gyp/0.10.20/deps/v8/include \ + -I/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan + +DEFS_Release := \ + '-D_DARWIN_USE_64_BIT_INODE=1' \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' + +# Flags passed to all source files. +CFLAGS_Release := \ + -Os \ + -gdwarf-2 \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -Wall \ + -Wendif-labels \ + -W \ + -Wno-unused-parameter + +# Flags passed to only C files. +CFLAGS_C_Release := \ + -fno-strict-aliasing + +# Flags passed to only C++ files. +CFLAGS_CC_Release := \ + -fno-rtti \ + -fno-exceptions \ + -fno-threadsafe-statics \ + -fno-strict-aliasing + +# Flags passed to only ObjC files. +CFLAGS_OBJC_Release := + +# Flags passed to only ObjC++ files. +CFLAGS_OBJCC_Release := + +INCS_Release := \ + -I/Users/nj/.node-gyp/0.10.20/src \ + -I/Users/nj/.node-gyp/0.10.20/deps/uv/include \ + -I/Users/nj/.node-gyp/0.10.20/deps/v8/include \ + -I/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan + +OBJS := \ + $(obj).target/$(TARGET)/src/bufferutil.o + +# Add to the list of files we specially track dependencies for. +all_deps += $(OBJS) + +# CFLAGS et al overrides must be target-local. +# See "Target-specific Variable Values" in the GNU Make manual. +$(OBJS): TOOLSET := $(TOOLSET) +$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) +$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) +$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE)) +$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE)) + +# Suffix rules, putting all outputs into $(obj). + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# Try building from generated source, too. + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# End of this set of suffix rules +### Rules for final target. +LDFLAGS_Debug := \ + -Wl,-search_paths_first \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -L$(builddir) \ + -install_name @rpath/bufferutil.node + +LIBTOOLFLAGS_Debug := \ + -Wl,-search_paths_first + +LDFLAGS_Release := \ + -Wl,-search_paths_first \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -L$(builddir) \ + -install_name @rpath/bufferutil.node + +LIBTOOLFLAGS_Release := \ + -Wl,-search_paths_first + +LIBS := \ + -undefined dynamic_lookup + +$(builddir)/bufferutil.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) +$(builddir)/bufferutil.node: LIBS := $(LIBS) +$(builddir)/bufferutil.node: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE)) +$(builddir)/bufferutil.node: TOOLSET := $(TOOLSET) +$(builddir)/bufferutil.node: $(OBJS) FORCE_DO_CMD + $(call do_cmd,solink_module) + +all_deps += $(builddir)/bufferutil.node +# Add target alias +.PHONY: bufferutil +bufferutil: $(builddir)/bufferutil.node + +# Short alias for building this executable. +.PHONY: bufferutil.node +bufferutil.node: $(builddir)/bufferutil.node + +# Add executable to "all" target. +.PHONY: all +all: $(builddir)/bufferutil.node + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/config.gypi b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/config.gypi new file mode 100644 index 00000000000..e3256254956 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/config.gypi @@ -0,0 +1,112 @@ +# Do not edit. File was generated by node-gyp's "configure" step +{ + "target_defaults": { + "cflags": [], + "default_configuration": "Release", + "defines": [], + "include_dirs": [], + "libraries": [] + }, + "variables": { + "clang": 1, + "host_arch": "x64", + "node_install_npm": "true", + "node_prefix": "/", + "node_shared_cares": "false", + "node_shared_http_parser": "false", + "node_shared_libuv": "false", + "node_shared_openssl": "false", + "node_shared_v8": "false", + "node_shared_zlib": "false", + "node_tag": "", + "node_unsafe_optimizations": 0, + "node_use_dtrace": "true", + "node_use_etw": "false", + "node_use_openssl": "true", + "node_use_perfctr": "false", + "python": "/usr/bin/python", + "target_arch": "x64", + "v8_enable_gdbjit": 0, + "v8_no_strict_aliasing": 1, + "v8_use_snapshot": "false", + "nodedir": "/Users/nj/.node-gyp/0.10.20", + "copy_dev_lib": "true", + "standalone_static_library": 1, + "save_dev": "", + "browser": "", + "viewer": "man", + "rollback": "true", + "usage": "", + "globalignorefile": "/Users/nj/.nvm/v0.10.20/etc/npmignore", + "init_author_url": "", + "shell": "/bin/bash", + "parseable": "", + "shrinkwrap": "true", + "userignorefile": "/Users/nj/.npmignore", + "cache_max": "null", + "init_author_email": "", + "sign_git_tag": "", + "ignore": "", + "long": "", + "registry": "https://registry.npmjs.org/", + "fetch_retries": "2", + "npat": "", + "message": "%s", + "versions": "", + "globalconfig": "/Users/nj/.nvm/v0.10.20/etc/npmrc", + "always_auth": "", + "cache_lock_retries": "10", + "fetch_retry_mintimeout": "10000", + "proprietary_attribs": "true", + "coverage": "", + "json": "", + "pre": "", + "description": "true", + "engine_strict": "", + "https_proxy": "", + "init_module": "/Users/nj/.npm-init.js", + "userconfig": "/Users/nj/.npmrc", + "npaturl": "http://npat.npmjs.org/", + "node_version": "v0.10.20", + "user": "501", + "save": "true", + "editor": "vi", + "tag": "latest", + "global": "", + "optional": "true", + "username": "", + "bin_links": "true", + "force": "", + "searchopts": "", + "depth": "null", + "rebuild_bundle": "true", + "searchsort": "name", + "unicode": "true", + "yes": "", + "fetch_retry_maxtimeout": "60000", + "strict_ssl": "true", + "dev": "", + "fetch_retry_factor": "10", + "group": "20", + "cache_lock_stale": "60000", + "version": "", + "cache_min": "10", + "cache": "/Users/nj/.npm", + "searchexclude": "", + "color": "true", + "save_optional": "", + "user_agent": "node/v0.10.20 darwin x64", + "cache_lock_wait": "10000", + "production": "", + "save_bundle": "", + "init_version": "0.0.0", + "umask": "18", + "git": "git", + "init_author_name": "", + "onload_script": "", + "tmp": "/var/folders/rd/kwl1mvj93650p4qyrc_yqynw0000gn/T/", + "unsafe_perm": "true", + "link": "", + "prefix": "/Users/nj/.nvm/v0.10.20" + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/gyp-mac-tool b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/gyp-mac-tool new file mode 100644 index 00000000000..2f5e141f6b8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/gyp-mac-tool @@ -0,0 +1,224 @@ +#!/usr/bin/env python +# Generated by gyp. Do not edit. +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Utility functions to perform Xcode-style build steps. + +These functions are executed via gyp-mac-tool when using the Makefile generator. +""" + +import fcntl +import os +import plistlib +import re +import shutil +import string +import subprocess +import sys + + +def main(args): + executor = MacTool() + exit_code = executor.Dispatch(args) + if exit_code is not None: + sys.exit(exit_code) + + +class MacTool(object): + """This class performs all the Mac tooling steps. The methods can either be + executed directly, or dispatched from an argument list.""" + + def Dispatch(self, args): + """Dispatches a string command to a method.""" + if len(args) < 1: + raise Exception("Not enough arguments") + + method = "Exec%s" % self._CommandifyName(args[0]) + return getattr(self, method)(*args[1:]) + + def _CommandifyName(self, name_string): + """Transforms a tool name like copy-info-plist to CopyInfoPlist""" + return name_string.title().replace('-', '') + + def ExecCopyBundleResource(self, source, dest): + """Copies a resource file to the bundle/Resources directory, performing any + necessary compilation on each resource.""" + extension = os.path.splitext(source)[1].lower() + if os.path.isdir(source): + # Copy tree. + if os.path.exists(dest): + shutil.rmtree(dest) + shutil.copytree(source, dest) + elif extension == '.xib': + return self._CopyXIBFile(source, dest) + elif extension == '.strings': + self._CopyStringsFile(source, dest) + else: + shutil.copyfile(source, dest) + + def _CopyXIBFile(self, source, dest): + """Compiles a XIB file with ibtool into a binary plist in the bundle.""" + tools_dir = os.environ.get('DEVELOPER_BIN_DIR', '/usr/bin') + args = [os.path.join(tools_dir, 'ibtool'), '--errors', '--warnings', + '--notices', '--output-format', 'human-readable-text', '--compile', + dest, source] + ibtool_section_re = re.compile(r'/\*.*\*/') + ibtool_re = re.compile(r'.*note:.*is clipping its content') + ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE) + current_section_header = None + for line in ibtoolout.stdout: + if ibtool_section_re.match(line): + current_section_header = line + elif not ibtool_re.match(line): + if current_section_header: + sys.stdout.write(current_section_header) + current_section_header = None + sys.stdout.write(line) + return ibtoolout.returncode + + def _CopyStringsFile(self, source, dest): + """Copies a .strings file using iconv to reconvert the input into UTF-16.""" + input_code = self._DetectInputEncoding(source) or "UTF-8" + + # Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call + # CFPropertyListCreateFromXMLData() behind the scenes; at least it prints + # CFPropertyListCreateFromXMLData(): Old-style plist parser: missing + # semicolon in dictionary. + # on invalid files. Do the same kind of validation. + import CoreFoundation + s = open(source).read() + d = CoreFoundation.CFDataCreate(None, s, len(s)) + _, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None) + if error: + return + + fp = open(dest, 'w') + args = ['/usr/bin/iconv', '--from-code', input_code, '--to-code', + 'UTF-16', source] + subprocess.call(args, stdout=fp) + fp.close() + + def _DetectInputEncoding(self, file_name): + """Reads the first few bytes from file_name and tries to guess the text + encoding. Returns None as a guess if it can't detect it.""" + fp = open(file_name, 'rb') + try: + header = fp.read(3) + except e: + fp.close() + return None + fp.close() + if header.startswith("\xFE\xFF"): + return "UTF-16BE" + elif header.startswith("\xFF\xFE"): + return "UTF-16LE" + elif header.startswith("\xEF\xBB\xBF"): + return "UTF-8" + else: + return None + + def ExecCopyInfoPlist(self, source, dest): + """Copies the |source| Info.plist to the destination directory |dest|.""" + # Read the source Info.plist into memory. + fd = open(source, 'r') + lines = fd.read() + fd.close() + + # Go through all the environment variables and replace them as variables in + # the file. + for key in os.environ: + if key.startswith('_'): + continue + evar = '${%s}' % key + lines = string.replace(lines, evar, os.environ[key]) + + # Write out the file with variables replaced. + fd = open(dest, 'w') + fd.write(lines) + fd.close() + + # Now write out PkgInfo file now that the Info.plist file has been + # "compiled". + self._WritePkgInfo(dest) + + def _WritePkgInfo(self, info_plist): + """This writes the PkgInfo file from the data stored in Info.plist.""" + plist = plistlib.readPlist(info_plist) + if not plist: + return + + # Only create PkgInfo for executable types. + package_type = plist['CFBundlePackageType'] + if package_type != 'APPL': + return + + # The format of PkgInfo is eight characters, representing the bundle type + # and bundle signature, each four characters. If that is missing, four + # '?' characters are used instead. + signature_code = plist.get('CFBundleSignature', '????') + if len(signature_code) != 4: # Wrong length resets everything, too. + signature_code = '?' * 4 + + dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo') + fp = open(dest, 'w') + fp.write('%s%s' % (package_type, signature_code)) + fp.close() + + def ExecFlock(self, lockfile, *cmd_list): + """Emulates the most basic behavior of Linux's flock(1).""" + # Rely on exception handling to report errors. + fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666) + fcntl.flock(fd, fcntl.LOCK_EX) + return subprocess.call(cmd_list) + + def ExecFilterLibtool(self, *cmd_list): + """Calls libtool and filters out 'libtool: file: foo.o has no symbols'.""" + libtool_re = re.compile(r'^libtool: file: .* has no symbols$') + libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE) + _, err = libtoolout.communicate() + for line in err.splitlines(): + if not libtool_re.match(line): + print >>sys.stderr, line + return libtoolout.returncode + + def ExecPackageFramework(self, framework, version): + """Takes a path to Something.framework and the Current version of that and + sets up all the symlinks.""" + # Find the name of the binary based on the part before the ".framework". + binary = os.path.basename(framework).split('.')[0] + + CURRENT = 'Current' + RESOURCES = 'Resources' + VERSIONS = 'Versions' + + if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)): + # Binary-less frameworks don't seem to contain symlinks (see e.g. + # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle). + return + + # Move into the framework directory to set the symlinks correctly. + pwd = os.getcwd() + os.chdir(framework) + + # Set up the Current version. + self._Relink(version, os.path.join(VERSIONS, CURRENT)) + + # Set up the root symlinks. + self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary) + self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES) + + # Back to where we were before! + os.chdir(pwd) + + def _Relink(self, dest, link): + """Creates a symlink to |dest| named |link|. If |link| already exists, + it is overwritten.""" + if os.path.lexists(link): + os.remove(link) + os.symlink(dest, link) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/validation.target.mk b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/validation.target.mk new file mode 100644 index 00000000000..8fc3608586d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/build/validation.target.mk @@ -0,0 +1,158 @@ +# This file is generated by gyp; do not edit. + +TOOLSET := target +TARGET := validation +DEFS_Debug := \ + '-D_DARWIN_USE_64_BIT_INODE=1' \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' \ + '-DDEBUG' \ + '-D_DEBUG' + +# Flags passed to all source files. +CFLAGS_Debug := \ + -O0 \ + -gdwarf-2 \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -Wall \ + -Wendif-labels \ + -W \ + -Wno-unused-parameter + +# Flags passed to only C files. +CFLAGS_C_Debug := \ + -fno-strict-aliasing + +# Flags passed to only C++ files. +CFLAGS_CC_Debug := \ + -fno-rtti \ + -fno-exceptions \ + -fno-threadsafe-statics \ + -fno-strict-aliasing + +# Flags passed to only ObjC files. +CFLAGS_OBJC_Debug := + +# Flags passed to only ObjC++ files. +CFLAGS_OBJCC_Debug := + +INCS_Debug := \ + -I/Users/nj/.node-gyp/0.10.20/src \ + -I/Users/nj/.node-gyp/0.10.20/deps/uv/include \ + -I/Users/nj/.node-gyp/0.10.20/deps/v8/include \ + -I/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan + +DEFS_Release := \ + '-D_DARWIN_USE_64_BIT_INODE=1' \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' + +# Flags passed to all source files. +CFLAGS_Release := \ + -Os \ + -gdwarf-2 \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -Wall \ + -Wendif-labels \ + -W \ + -Wno-unused-parameter + +# Flags passed to only C files. +CFLAGS_C_Release := \ + -fno-strict-aliasing + +# Flags passed to only C++ files. +CFLAGS_CC_Release := \ + -fno-rtti \ + -fno-exceptions \ + -fno-threadsafe-statics \ + -fno-strict-aliasing + +# Flags passed to only ObjC files. +CFLAGS_OBJC_Release := + +# Flags passed to only ObjC++ files. +CFLAGS_OBJCC_Release := + +INCS_Release := \ + -I/Users/nj/.node-gyp/0.10.20/src \ + -I/Users/nj/.node-gyp/0.10.20/deps/uv/include \ + -I/Users/nj/.node-gyp/0.10.20/deps/v8/include \ + -I/Users/nj/github/LiveDev2/node/node_modules/ws/node_modules/nan + +OBJS := \ + $(obj).target/$(TARGET)/src/validation.o + +# Add to the list of files we specially track dependencies for. +all_deps += $(OBJS) + +# CFLAGS et al overrides must be target-local. +# See "Target-specific Variable Values" in the GNU Make manual. +$(OBJS): TOOLSET := $(TOOLSET) +$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) +$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) +$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE)) +$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE)) + +# Suffix rules, putting all outputs into $(obj). + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# Try building from generated source, too. + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# End of this set of suffix rules +### Rules for final target. +LDFLAGS_Debug := \ + -Wl,-search_paths_first \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -L$(builddir) \ + -install_name @rpath/validation.node + +LIBTOOLFLAGS_Debug := \ + -Wl,-search_paths_first + +LDFLAGS_Release := \ + -Wl,-search_paths_first \ + -mmacosx-version-min=10.5 \ + -arch x86_64 \ + -L$(builddir) \ + -install_name @rpath/validation.node + +LIBTOOLFLAGS_Release := \ + -Wl,-search_paths_first + +LIBS := \ + -undefined dynamic_lookup + +$(builddir)/validation.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) +$(builddir)/validation.node: LIBS := $(LIBS) +$(builddir)/validation.node: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE)) +$(builddir)/validation.node: TOOLSET := $(TOOLSET) +$(builddir)/validation.node: $(OBJS) FORCE_DO_CMD + $(call do_cmd,solink_module) + +all_deps += $(builddir)/validation.node +# Add target alias +.PHONY: validation +validation: $(builddir)/validation.node + +# Short alias for building this executable. +.PHONY: validation.node +validation.node: $(builddir)/validation.node + +# Add executable to "all" target. +.PHONY: all +all: $(builddir)/validation.node + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/builderror.log b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/builderror.log new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/doc/ws.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/doc/ws.md new file mode 100644 index 00000000000..d84fd6257a3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/doc/ws.md @@ -0,0 +1,181 @@ +# ws + +## Class: ws.Server + +This class is a WebSocket server. It is an `EventEmitter`. + +### new ws.Server([options], [callback]) + +* `options` Object + * `host` String + * `port` Number + * `server` http.Server + * `verifyClient` Function + * `path` String + * `noServer` Boolean + * `disableHixie` Boolean + * `clientTracking` Boolean +* `callback` Function + +Construct a new server object. + +Either `port` or `server` must be provided, otherwise you might enable +`noServer` if you want to pass the requests directly. Please note that the +`callback` is only used when you supply the a `port` number in the options. + +### server.close([code], [data]) + +Close the server and terminate all clients + +### server.handleUpgrade(request, socket, upgradeHead, callback) + +Handles a HTTP Upgrade request. `request` is an instance of `http.ServerRequest`, `socket` is an instance of `net.Socket`. + +When the Upgrade was successfully, the `callback` will be called with a `ws.WebSocket` object as parameter. + +### Event: 'error' + +`function (error) { }` + +If the underlying server emits an error, it will be forwarded here. + +### Event: 'headers' + +`function (headers) { }` + +Emitted with the object of HTTP headers that are going to be written to the `Stream` as part of the handshake. + +### Event: 'connection' + +`function (socket) { }` + +When a new WebSocket connection is established. `socket` is an object of type `ws.WebSocket`. + + +## Class: ws.WebSocket + +This class represents a WebSocket connection. It is an `EventEmitter`. + +### new ws.WebSocket(address, [options]) + +* `address` String|Array +* `options` Object + * `protocol` String + * `agent` Agent + * `headers` Object + * `protocolVersion` Number|String + -- the following only apply if `address` is a String + * `host` String + * `origin` String + * `pfx` String|Buffer + * `key` String|Buffer + * `passphrase` String + * `cert` String|Buffer + * `ca` Array + * `ciphers` String + * `rejectUnauthorized` Boolean + +Instantiating with an `address` creates a new WebSocket client object. If `address` is an Array (request, socket, rest), it is instantiated as a Server client (e.g. called from the `ws.Server`). + +### websocket.bytesReceived + +Received bytes count. + +### websocket.readyState + +Possible states are `WebSocket.CONNECTING`, `WebSocket.OPEN`, `WebSocket.CLOSING`, `WebSocket.CLOSED`. + +### websocket.protocolVersion + +The WebSocket protocol version used for this connection, `8`, `13` or `hixie-76` (the latter only for server clients). + +### websocket.url + +The URL of the WebSocket server (only for clients) + +### websocket.supports + +Describes the feature of the used protocol version. E.g. `supports.binary` is a boolean that describes if the connection supports binary messages. + +### websocket.close([code], [data]) + +Gracefully closes the connection, after sending a description message + +### websocket.pause() + +Pause the client stream + +### websocket.ping([data], [options], [dontFailWhenClosed]) + +Sends a ping. `data` is sent, `options` is an object with members `mask` and `binary`. `dontFailWhenClosed` indicates whether or not to throw if the connection isnt open. + +### websocket.pong([data], [options], [dontFailWhenClosed]) + +Sends a pong. `data` is sent, `options` is an object with members `mask` and `binary`. `dontFailWhenClosed` indicates whether or not to throw if the connection isnt open. + + +### websocket.resume() + +Resume the client stream + +### websocket.send(data, [options], [callback]) + +Sends `data` through the connection. `options` can be an object with members `mask` and `binary`. The optional `callback` is executed after the send completes. + +### websocket.stream([options], callback) + +Streams data through calls to a user supplied function. `options` can be an object with members `mask` and `binary`. `callback` is executed on successive ticks of which send is `function (data, final)`. + +### websocket.terminate() + +Immediately shuts down the connection + +### websocket.onopen +### websocket.onerror +### websocket.onclose +### websocket.onmessage + +Emulates the W3C Browser based WebSocket interface using function members. + +### websocket.addEventListener(method, listener) + +Emulates the W3C Browser based WebSocket interface using addEventListener. + +### Event: 'error' + +`function (error) { }` + +If the client emits an error, this event is emitted (errors from the underlying `net.Socket` are forwarded here). + +### Event: 'close' + +`function (code, message) { }` + +Is emitted when the connection is closed. `code` is defined in the WebSocket specification. + +The `close` event is also emitted when then underlying `net.Socket` closes the connection (`end` or `close`). + +### Event: 'message' + +`function (data, flags) { }` + +Is emitted when data is received. `flags` is an object with member `binary`. + +### Event: 'ping' + +`function (data, flags) { }` + +Is emitted when a ping is received. `flags` is an object with member `binary`. + +### Event: 'pong' + +`function (data, flags) { }` + +Is emitted when a pong is received. `flags` is an object with member `binary`. + +### Event: 'open' + +`function () { }` + +Emitted when the connection is established. + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/.npmignore new file mode 100644 index 00000000000..dcd57568856 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/.npmignore @@ -0,0 +1 @@ +uploaded diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/package.json new file mode 100644 index 00000000000..7816f2737b1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/package.json @@ -0,0 +1,18 @@ +{ + "author": "", + "name": "fileapi", + "version": "0.0.0", + "repository": { + "type": "git", + "url": "git://github.com/einaros/ws.git" + }, + "engines": { + "node": "~0.6.8" + }, + "dependencies": { + "express": "latest", + "ansi": "https://github.com/einaros/ansi.js/tarball/master" + }, + "devDependencies": {}, + "optionalDependencies": {} +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/app.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/app.js new file mode 100644 index 00000000000..e812cc3ea5f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/app.js @@ -0,0 +1,39 @@ +function onFilesSelected(e) { + var button = e.srcElement; + button.disabled = true; + var progress = document.querySelector('div#progress'); + progress.innerHTML = '0%'; + var files = e.target.files; + var totalFiles = files.length; + var filesSent = 0; + if (totalFiles) { + var uploader = new Uploader('ws://localhost:8080', function () { + Array.prototype.slice.call(files, 0).forEach(function(file) { + if (file.name == '.') { + --totalFiles; + return; + } + uploader.sendFile(file, function(error) { + if (error) { + console.log(error); + return; + } + ++filesSent; + progress.innerHTML = ~~(filesSent / totalFiles * 100) + '%'; + console.log('Sent: ' + file.name); + }); + }); + }); + } + uploader.ondone = function() { + uploader.close(); + progress.innerHTML = '100% done, ' + totalFiles + ' files sent.'; + } +} + +window.onload = function() { + var importButtons = document.querySelectorAll('[type="file"]'); + Array.prototype.slice.call(importButtons, 0).forEach(function(importButton) { + importButton.addEventListener('change', onFilesSelected, false); + }); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/index.html b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/index.html new file mode 100644 index 00000000000..0d463dd5a62 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/index.html @@ -0,0 +1,22 @@ + + + + + + + + +

    This example will upload an entire directory tree to the node.js server via a fast and persistent WebSocket connection.

    +

    Note that the example is Chrome only for now.

    +

    + Upload status: +
    Please select a directory to upload.
    + + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/uploader.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/uploader.js new file mode 100644 index 00000000000..0c34a7fae6e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/public/uploader.js @@ -0,0 +1,55 @@ +function Uploader(url, cb) { + this.ws = new WebSocket(url); + if (cb) this.ws.onopen = cb; + this.sendQueue = []; + this.sending = null; + this.sendCallback = null; + this.ondone = null; + var self = this; + this.ws.onmessage = function(event) { + var data = JSON.parse(event.data); + if (data.event == 'complete') { + if (data.path != self.sending.path) { + self.sendQueue = []; + self.sending = null; + self.sendCallback = null; + throw new Error('Got message for wrong file!'); + } + self.sending = null; + var callback = self.sendCallback; + self.sendCallback = null; + if (callback) callback(); + if (self.sendQueue.length === 0 && self.ondone) self.ondone(null); + if (self.sendQueue.length > 0) { + var args = self.sendQueue.pop(); + setTimeout(function() { self.sendFile.apply(self, args); }, 0); + } + } + else if (data.event == 'error') { + self.sendQueue = []; + self.sending = null; + var callback = self.sendCallback; + self.sendCallback = null; + var error = new Error('Server reported send error for file ' + data.path); + if (callback) callback(error); + if (self.ondone) self.ondone(error); + } + } +} + +Uploader.prototype.sendFile = function(file, cb) { + if (this.ws.readyState != WebSocket.OPEN) throw new Error('Not connected'); + if (this.sending) { + this.sendQueue.push(arguments); + return; + } + var fileData = { name: file.name, path: file.webkitRelativePath }; + this.sending = fileData; + this.sendCallback = cb; + this.ws.send(JSON.stringify(fileData)); + this.ws.send(file); +} + +Uploader.prototype.close = function() { + this.ws.close(); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/server.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/server.js new file mode 100644 index 00000000000..badfeba7a1a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/fileapi/server.js @@ -0,0 +1,103 @@ +var WebSocketServer = require('../../').Server + , express = require('express') + , fs = require('fs') + , http = require('http') + , util = require('util') + , path = require('path') + , app = express.createServer() + , events = require('events') + , ansi = require('ansi') + , cursor = ansi(process.stdout); + +function BandwidthSampler(ws, interval) { + interval = interval || 2000; + var previousByteCount = 0; + var self = this; + var intervalId = setInterval(function() { + var byteCount = ws.bytesReceived; + var bytesPerSec = (byteCount - previousByteCount) / (interval / 1000); + previousByteCount = byteCount; + self.emit('sample', bytesPerSec); + }, interval); + ws.on('close', function() { + clearInterval(intervalId); + }); +} +util.inherits(BandwidthSampler, events.EventEmitter); + +function makePathForFile(filePath, prefix, cb) { + if (typeof cb !== 'function') throw new Error('callback is required'); + filePath = path.dirname(path.normalize(filePath)).replace(/^(\/|\\)+/, ''); + var pieces = filePath.split(/(\\|\/)/); + var incrementalPath = prefix; + function step(error) { + if (error) return cb(error); + if (pieces.length == 0) return cb(null, incrementalPath); + incrementalPath += '/' + pieces.shift(); + fs.exists(incrementalPath, function(exists) { + if (!exists) fs.mkdir(incrementalPath, step); + else process.nextTick(step); + }); + } + step(); +} + +cursor.eraseData(2).goto(1, 1); +app.use(express.static(__dirname + '/public')); + +var clientId = 0; +var wss = new WebSocketServer({server: app}); +wss.on('connection', function(ws) { + var thisId = ++clientId; + cursor.goto(1, 4 + thisId).eraseLine(); + console.log('Client #%d connected', thisId); + + var sampler = new BandwidthSampler(ws); + sampler.on('sample', function(bps) { + cursor.goto(1, 4 + thisId).eraseLine(); + console.log('WebSocket #%d incoming bandwidth: %d MB/s', thisId, Math.round(bps / (1024*1024))); + }); + + var filesReceived = 0; + var currentFile = null; + ws.on('message', function(data, flags) { + if (!flags.binary) { + currentFile = JSON.parse(data); + // note: a real-world app would want to sanity check the data + } + else { + if (currentFile == null) return; + makePathForFile(currentFile.path, __dirname + '/uploaded', function(error, path) { + if (error) { + console.log(error); + ws.send(JSON.stringify({event: 'error', path: currentFile.path, message: error.message})); + return; + } + fs.writeFile(path + '/' + currentFile.name, data, function(error) { + ++filesReceived; + // console.log('received %d bytes long file, %s', data.length, currentFile.path); + ws.send(JSON.stringify({event: 'complete', path: currentFile.path})); + currentFile = null; + }); + }); + } + }); + + ws.on('close', function() { + cursor.goto(1, 4 + thisId).eraseLine(); + console.log('Client #%d disconnected. %d files received.', thisId, filesReceived); + }); + + ws.on('error', function(e) { + cursor.goto(1, 4 + thisId).eraseLine(); + console.log('Client #%d error: %s', thisId, e.message); + }); +}); + +fs.mkdir(__dirname + '/uploaded', function(error) { + // ignore errors, most likely means directory exists + console.log('Uploaded files will be saved to %s/uploaded.', __dirname); + console.log('Remember to wipe this directory if you upload lots and lots.'); + app.listen(8080); + console.log('Listening on http://localhost:8080'); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/package.json new file mode 100644 index 00000000000..99722c42217 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/package.json @@ -0,0 +1,17 @@ +{ + "author": "", + "name": "serverstats", + "version": "0.0.0", + "repository": { + "type": "git", + "url": "git://github.com/einaros/ws.git" + }, + "engines": { + "node": ">0.4.0" + }, + "dependencies": { + "express": "~3.0.0" + }, + "devDependencies": {}, + "optionalDependencies": {} +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/public/index.html b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/public/index.html new file mode 100644 index 00000000000..24d84e12009 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/public/index.html @@ -0,0 +1,33 @@ + + + + + + + + Server Stats
    + RSS:

    + Heap total:

    + Heap used:

    + + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/server.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/server.js new file mode 100644 index 00000000000..88bbc9ebfc0 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats-express_3/server.js @@ -0,0 +1,21 @@ +var WebSocketServer = require('../../').Server + , http = require('http') + , express = require('express') + , app = express(); + +app.use(express.static(__dirname + '/public')); + +var server = http.createServer(app); +server.listen(8080); + +var wss = new WebSocketServer({server: server}); +wss.on('connection', function(ws) { + var id = setInterval(function() { + ws.send(JSON.stringify(process.memoryUsage()), function() { /* ignore errors */ }); + }, 100); + console.log('started client interval'); + ws.on('close', function() { + console.log('stopping client interval'); + clearInterval(id); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/package.json new file mode 100644 index 00000000000..65c900ab115 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/package.json @@ -0,0 +1,17 @@ +{ + "author": "", + "name": "serverstats", + "version": "0.0.0", + "repository": { + "type": "git", + "url": "git://github.com/einaros/ws.git" + }, + "engines": { + "node": ">0.4.0" + }, + "dependencies": { + "express": "2.x" + }, + "devDependencies": {}, + "optionalDependencies": {} +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/public/index.html b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/public/index.html new file mode 100644 index 00000000000..24d84e12009 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/public/index.html @@ -0,0 +1,33 @@ + + + + + + + + Server Stats
    + RSS:

    + Heap total:

    + Heap used:

    + + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/server.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/server.js new file mode 100644 index 00000000000..0bbce3688ae --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/serverstats/server.js @@ -0,0 +1,19 @@ +var WebSocketServer = require('../../').Server + , http = require('http') + , express = require('express') + , app = express.createServer(); + +app.use(express.static(__dirname + '/public')); +app.listen(8080); + +var wss = new WebSocketServer({server: app}); +wss.on('connection', function(ws) { + var id = setInterval(function() { + ws.send(JSON.stringify(process.memoryUsage()), function() { /* ignore errors */ }); + }, 100); + console.log('started client interval'); + ws.on('close', function() { + console.log('stopping client interval'); + clearInterval(id); + }) +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/ssl.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/ssl.js new file mode 100644 index 00000000000..bf1bf5303f2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/examples/ssl.js @@ -0,0 +1,59 @@ + +(function(){ + + "use strict"; + + var fs = require('fs'); + + // you'll probably load configuration from config + var cfg = { + ssl: true, + port: 8080, + ssl_key: '/path/to/you/ssl.key', + ssl_cert: '/path/to/you/ssl.crt' + }; + + var httpServ = ( cfg.ssl ) ? require('https') : require('http'); + + var WebSocketServer = require('../').Server; + + var app = null; + + // dummy request processing + var processRequest = function( req, res ) { + + res.writeHead(200); + res.end("All glory to WebSockets!\n"); + }; + + if ( cfg.ssl ) { + + app = httpServ.createServer({ + + // providing server with SSL key/cert + key: fs.readFileSync( cfg.ssl_key ), + cert: fs.readFileSync( cfg.ssl_cert ) + + }, processRequest ).listen( cfg.port ); + + } else { + + app = httpServ.createServer( processRequest ).listen( cfg.port ); + } + + // passing or reference to web server so WS would knew port and SSL capabilities + var wss = new WebSocketServer( { server: app } ); + + + wss.on( 'connection', function ( wsConnect ) { + + wsConnect.on( 'message', function ( message ) { + + console.log( message ); + + }); + + }); + + +}()); \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/index.js new file mode 100644 index 00000000000..3423ff2323f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/index.js @@ -0,0 +1,26 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports = require('./lib/WebSocket'); +module.exports.Server = require('./lib/WebSocketServer'); +module.exports.Sender = require('./lib/Sender'); +module.exports.Receiver = require('./lib/Receiver'); + +module.exports.createServer = function (options, connectionListener) { + var server = new module.exports.Server(options); + if (typeof connectionListener === 'function') { + server.on('connection', connectionListener); + } + return server; +}; + +module.exports.connect = module.exports.createConnection = function (address, openListener) { + var client = new module.exports(address); + if (typeof openListener === 'function') { + client.on('open', openListener); + } + return client; +}; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferPool.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferPool.js new file mode 100644 index 00000000000..faf8637c04e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferPool.js @@ -0,0 +1,59 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util'); + +function BufferPool(initialSize, growStrategy, shrinkStrategy) { + if (typeof initialSize === 'function') { + shrinkStrategy = growStrategy; + growStrategy = initialSize; + initialSize = 0; + } + else if (typeof initialSize === 'undefined') { + initialSize = 0; + } + this._growStrategy = (growStrategy || function(db, size) { + return db.used + size; + }).bind(null, this); + this._shrinkStrategy = (shrinkStrategy || function(db) { + return initialSize; + }).bind(null, this); + this._buffer = initialSize ? new Buffer(initialSize) : null; + this._offset = 0; + this._used = 0; + this._changeFactor = 0; + this.__defineGetter__('size', function(){ + return this._buffer == null ? 0 : this._buffer.length; + }); + this.__defineGetter__('used', function(){ + return this._used; + }); +} + +BufferPool.prototype.get = function(length) { + if (this._buffer == null || this._offset + length > this._buffer.length) { + var newBuf = new Buffer(this._growStrategy(length)); + this._buffer = newBuf; + this._offset = 0; + } + this._used += length; + var buf = this._buffer.slice(this._offset, this._offset + length); + this._offset += length; + return buf; +} + +BufferPool.prototype.reset = function(forceNewBuffer) { + var len = this._shrinkStrategy(); + if (len < this.size) this._changeFactor -= 1; + if (forceNewBuffer || this._changeFactor < -2) { + this._changeFactor = 0; + this._buffer = len ? new Buffer(len) : null; + } + this._offset = 0; + this._used = 0; +} + +module.exports = BufferPool; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferUtil.fallback.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferUtil.fallback.js new file mode 100644 index 00000000000..508542c9e50 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferUtil.fallback.js @@ -0,0 +1,47 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports.BufferUtil = { + merge: function(mergedBuffer, buffers) { + var offset = 0; + for (var i = 0, l = buffers.length; i < l; ++i) { + var buf = buffers[i]; + buf.copy(mergedBuffer, offset); + offset += buf.length; + } + }, + mask: function(source, mask, output, offset, length) { + var maskNum = mask.readUInt32LE(0, true); + var i = 0; + for (; i < length - 3; i += 4) { + var num = maskNum ^ source.readUInt32LE(i, true); + if (num < 0) num = 4294967296 + num; + output.writeUInt32LE(num, offset + i, true); + } + switch (length % 4) { + case 3: output[offset + i + 2] = source[i + 2] ^ mask[2]; + case 2: output[offset + i + 1] = source[i + 1] ^ mask[1]; + case 1: output[offset + i] = source[i] ^ mask[0]; + case 0:; + } + }, + unmask: function(data, mask) { + var maskNum = mask.readUInt32LE(0, true); + var length = data.length; + var i = 0; + for (; i < length - 3; i += 4) { + var num = maskNum ^ data.readUInt32LE(i, true); + if (num < 0) num = 4294967296 + num; + data.writeUInt32LE(num, i, true); + } + switch (length % 4) { + case 3: data[i + 2] = data[i + 2] ^ mask[2]; + case 2: data[i + 1] = data[i + 1] ^ mask[1]; + case 1: data[i] = data[i] ^ mask[0]; + case 0:; + } + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferUtil.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferUtil.js new file mode 100644 index 00000000000..15d35b98f5c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/BufferUtil.js @@ -0,0 +1,16 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +try { + module.exports = require('../build/Release/bufferutil'); +} catch (e) { try { + module.exports = require('../build/default/bufferutil'); +} catch (e) { try { + module.exports = require('./BufferUtil.fallback'); +} catch (e) { + console.error('bufferutil.node seems to not have been built. Run npm install.'); + throw e; +}}} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/ErrorCodes.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/ErrorCodes.js new file mode 100644 index 00000000000..55ebd529b7c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/ErrorCodes.js @@ -0,0 +1,24 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports = { + isValidErrorCode: function(code) { + return (code >= 1000 && code <= 1011 && code != 1004 && code != 1005 && code != 1006) || + (code >= 3000 && code <= 4999); + }, + 1000: 'normal', + 1001: 'going away', + 1002: 'protocol error', + 1003: 'unsupported data', + 1004: 'reserved', + 1005: 'reserved for extensions', + 1006: 'reserved for extensions', + 1007: 'inconsistent or invalid data', + 1008: 'policy violation', + 1009: 'message too big', + 1010: 'extension handshake missing', + 1011: 'an unexpected condition prevented the request from being fulfilled', +}; \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Receiver.hixie.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Receiver.hixie.js new file mode 100644 index 00000000000..f54ad966bc9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Receiver.hixie.js @@ -0,0 +1,180 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util'); + +/** + * State constants + */ + +var EMPTY = 0 + , BODY = 1; +var BINARYLENGTH = 2 + , BINARYBODY = 3; + +/** + * Hixie Receiver implementation + */ + +function Receiver () { + this.state = EMPTY; + this.buffers = []; + this.messageEnd = -1; + this.spanLength = 0; + this.dead = false; + + this.onerror = function() {}; + this.ontext = function() {}; + this.onbinary = function() {}; + this.onclose = function() {}; + this.onping = function() {}; + this.onpong = function() {}; +} + +module.exports = Receiver; + +/** + * Add new data to the parser. + * + * @api public + */ + +Receiver.prototype.add = function(data) { + var self = this; + function doAdd() { + if (self.state === EMPTY) { + if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) { + self.reset(); + self.onclose(); + return; + } + if (data[0] === 0x80) { + self.messageEnd = 0; + self.state = BINARYLENGTH; + data = data.slice(1); + } else { + + if (data[0] !== 0x00) { + self.error('payload must start with 0x00 byte', true); + return; + } + data = data.slice(1); + self.state = BODY; + + } + } + if (self.state === BINARYLENGTH) { + var i = 0; + while ((i < data.length) && (data[i] & 0x80)) { + self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); + ++i; + } + if (i < data.length) { + self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); + self.state = BINARYBODY; + ++i; + } + if (i > 0) + data = data.slice(i); + } + if (self.state === BINARYBODY) { + var dataleft = self.messageEnd - self.spanLength; + if (data.length >= dataleft) { + // consume the whole buffer to finish the frame + self.buffers.push(data); + self.spanLength += dataleft; + self.messageEnd = dataleft; + return self.parse(); + } + // frame's not done even if we consume it all + self.buffers.push(data); + self.spanLength += data.length; + return; + } + self.buffers.push(data); + if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) { + self.spanLength += self.messageEnd; + return self.parse(); + } + else self.spanLength += data.length; + } + while(data) data = doAdd(); +} + +/** + * Releases all resources used by the receiver. + * + * @api public + */ + +Receiver.prototype.cleanup = function() { + this.dead = true; + this.state = EMPTY; + this.buffers = []; +} + +/** + * Process buffered data. + * + * @api public + */ + +Receiver.prototype.parse = function() { + var output = new Buffer(this.spanLength); + var outputIndex = 0; + for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) { + var buffer = this.buffers[bi]; + buffer.copy(output, outputIndex); + outputIndex += buffer.length; + } + var lastBuffer = this.buffers[this.buffers.length - 1]; + if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd); + if (this.state !== BODY) --this.messageEnd; + var tail = null; + if (this.messageEnd < lastBuffer.length - 1) { + tail = lastBuffer.slice(this.messageEnd + 1); + } + this.reset(); + this.ontext(output.toString('utf8')); + return tail; +} + +/** + * Handles an error + * + * @api private + */ + +Receiver.prototype.error = function (reason, terminate) { + this.reset(); + this.onerror(reason, terminate); + return this; +} + +/** + * Reset parser state + * + * @api private + */ + +Receiver.prototype.reset = function (reason) { + if (this.dead) return; + this.state = EMPTY; + this.buffers = []; + this.messageEnd = -1; + this.spanLength = 0; +} + +/** + * Internal api + */ + +function bufferIndex(buffer, byte) { + for (var i = 0, l = buffer.length; i < l; ++i) { + if (buffer[i] === byte) return i; + } + return -1; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Receiver.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Receiver.js new file mode 100644 index 00000000000..2752726fd3d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Receiver.js @@ -0,0 +1,591 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util') + , Validation = require('./Validation').Validation + , ErrorCodes = require('./ErrorCodes') + , BufferPool = require('./BufferPool') + , bufferUtil = require('./BufferUtil').BufferUtil; + +/** + * Node version 0.4 and 0.6 compatibility + */ + +var isNodeV4 = /^v0\.4/.test(process.version); + +/** + * HyBi Receiver implementation + */ + +function Receiver () { + // memory pool for fragmented messages + var fragmentedPoolPrevUsed = -1; + this.fragmentedBufferPool = new BufferPool(1024, function(db, length) { + return db.used + length; + }, function(db) { + return fragmentedPoolPrevUsed = fragmentedPoolPrevUsed >= 0 ? + (fragmentedPoolPrevUsed + db.used) / 2 : + db.used; + }); + + // memory pool for unfragmented messages + var unfragmentedPoolPrevUsed = -1; + this.unfragmentedBufferPool = new BufferPool(1024, function(db, length) { + return db.used + length; + }, function(db) { + return unfragmentedPoolPrevUsed = unfragmentedPoolPrevUsed >= 0 ? + (unfragmentedPoolPrevUsed + db.used) / 2 : + db.used; + }); + + this.state = { + activeFragmentedOperation: null, + lastFragment: false, + masked: false, + opcode: 0, + fragmentedOperation: false + }; + this.overflow = []; + this.headerBuffer = new Buffer(10); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + this.currentMessage = []; + this.expectHeader(2, this.processPacket); + this.dead = false; + + this.onerror = function() {}; + this.ontext = function() {}; + this.onbinary = function() {}; + this.onclose = function() {}; + this.onping = function() {}; + this.onpong = function() {}; +}; + +module.exports = Receiver; + +/** + * Add new data to the parser. + * + * @api public + */ + +Receiver.prototype.add = function(data) { + var dataLength = data.length; + if (dataLength == 0) return; + if (this.expectBuffer == null) { + this.overflow.push(data); + return; + } + var toRead = Math.min(dataLength, this.expectBuffer.length - this.expectOffset); + fastCopy(toRead, data, this.expectBuffer, this.expectOffset); + this.expectOffset += toRead; + if (toRead < dataLength) { + this.overflow.push(data.slice(toRead)); + } + while (this.expectBuffer && this.expectOffset == this.expectBuffer.length) { + var bufferForHandler = this.expectBuffer; + this.expectBuffer = null; + this.expectOffset = 0; + this.expectHandler.call(this, bufferForHandler); + } +} + +/** + * Releases all resources used by the receiver. + * + * @api public + */ + +Receiver.prototype.cleanup = function() { + this.dead = true; + this.overflow = null; + this.headerBuffer = null; + this.expectBuffer = null; + this.expectHandler = null; + this.unfragmentedBufferPool = null; + this.fragmentedBufferPool = null; + this.state = null; + this.currentMessage = null; + this.onerror = null; + this.ontext = null; + this.onbinary = null; + this.onclose = null; + this.onping = null; + this.onpong = null; +} + +/** + * Waits for a certain amount of header bytes to be available, then fires a callback. + * + * @api private + */ + +Receiver.prototype.expectHeader = function(length, handler) { + if (length == 0) { + handler(null); + return; + } + this.expectBuffer = this.headerBuffer.slice(this.expectOffset, this.expectOffset + length); + this.expectHandler = handler; + var toRead = length; + while (toRead > 0 && this.overflow.length > 0) { + var fromOverflow = this.overflow.pop(); + if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); + var read = Math.min(fromOverflow.length, toRead); + fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); + this.expectOffset += read; + toRead -= read; + } +} + +/** + * Waits for a certain amount of data bytes to be available, then fires a callback. + * + * @api private + */ + +Receiver.prototype.expectData = function(length, handler) { + if (length == 0) { + handler(null); + return; + } + this.expectBuffer = this.allocateFromPool(length, this.state.fragmentedOperation); + this.expectHandler = handler; + var toRead = length; + while (toRead > 0 && this.overflow.length > 0) { + var fromOverflow = this.overflow.pop(); + if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); + var read = Math.min(fromOverflow.length, toRead); + fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); + this.expectOffset += read; + toRead -= read; + } +} + +/** + * Allocates memory from the buffer pool. + * + * @api private + */ + +Receiver.prototype.allocateFromPool = !isNodeV4 + ? function(length, isFragmented) { return (isFragmented ? this.fragmentedBufferPool : this.unfragmentedBufferPool).get(length); } + : function(length) { return new Buffer(length); }; + +/** + * Start processing a new packet. + * + * @api private + */ + +Receiver.prototype.processPacket = function (data) { + if ((data[0] & 0x70) != 0) { + this.error('reserved fields must be empty', 1002); + return; + } + this.state.lastFragment = (data[0] & 0x80) == 0x80; + this.state.masked = (data[1] & 0x80) == 0x80; + var opcode = data[0] & 0xf; + if (opcode === 0) { + // continuation frame + this.state.fragmentedOperation = true; + this.state.opcode = this.state.activeFragmentedOperation; + if (!(this.state.opcode == 1 || this.state.opcode == 2)) { + this.error('continuation frame cannot follow current opcode', 1002); + return; + } + } + else { + if (opcode < 3 && this.state.activeFragmentedOperation != null) { + this.error('data frames after the initial data frame must have opcode 0', 1002); + return; + } + this.state.opcode = opcode; + if (this.state.lastFragment === false) { + this.state.fragmentedOperation = true; + this.state.activeFragmentedOperation = opcode; + } + else this.state.fragmentedOperation = false; + } + var handler = opcodes[this.state.opcode]; + if (typeof handler == 'undefined') this.error('no handler for opcode ' + this.state.opcode, 1002); + else { + handler.start.call(this, data); + } +} + +/** + * Endprocessing a packet. + * + * @api private + */ + +Receiver.prototype.endPacket = function() { + if (!this.state.fragmentedOperation) this.unfragmentedBufferPool.reset(true); + else if (this.state.lastFragment) this.fragmentedBufferPool.reset(false); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + if (this.state.lastFragment && this.state.opcode === this.state.activeFragmentedOperation) { + // end current fragmented operation + this.state.activeFragmentedOperation = null; + } + this.state.lastFragment = false; + this.state.opcode = this.state.activeFragmentedOperation != null ? this.state.activeFragmentedOperation : 0; + this.state.masked = false; + this.expectHeader(2, this.processPacket); +} + +/** + * Reset the parser state. + * + * @api private + */ + +Receiver.prototype.reset = function() { + if (this.dead) return; + this.state = { + activeFragmentedOperation: null, + lastFragment: false, + masked: false, + opcode: 0, + fragmentedOperation: false + }; + this.fragmentedBufferPool.reset(true); + this.unfragmentedBufferPool.reset(true); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + this.overflow = []; + this.currentMessage = []; +} + +/** + * Unmask received data. + * + * @api private + */ + +Receiver.prototype.unmask = function (mask, buf, binary) { + if (mask != null && buf != null) bufferUtil.unmask(buf, mask); + if (binary) return buf; + return buf != null ? buf.toString('utf8') : ''; +} + +/** + * Concatenates a list of buffers. + * + * @api private + */ + +Receiver.prototype.concatBuffers = function(buffers) { + var length = 0; + for (var i = 0, l = buffers.length; i < l; ++i) length += buffers[i].length; + var mergedBuffer = new Buffer(length); + bufferUtil.merge(mergedBuffer, buffers); + return mergedBuffer; +} + +/** + * Handles an error + * + * @api private + */ + +Receiver.prototype.error = function (reason, protocolErrorCode) { + this.reset(); + this.onerror(reason, protocolErrorCode); + return this; +} + +/** + * Buffer utilities + */ + +function readUInt16BE(start) { + return (this[start]<<8) + + this[start+1]; +} + +function readUInt32BE(start) { + return (this[start]<<24) + + (this[start+1]<<16) + + (this[start+2]<<8) + + this[start+3]; +} + +function fastCopy(length, srcBuffer, dstBuffer, dstOffset) { + switch (length) { + default: srcBuffer.copy(dstBuffer, dstOffset, 0, length); break; + case 16: dstBuffer[dstOffset+15] = srcBuffer[15]; + case 15: dstBuffer[dstOffset+14] = srcBuffer[14]; + case 14: dstBuffer[dstOffset+13] = srcBuffer[13]; + case 13: dstBuffer[dstOffset+12] = srcBuffer[12]; + case 12: dstBuffer[dstOffset+11] = srcBuffer[11]; + case 11: dstBuffer[dstOffset+10] = srcBuffer[10]; + case 10: dstBuffer[dstOffset+9] = srcBuffer[9]; + case 9: dstBuffer[dstOffset+8] = srcBuffer[8]; + case 8: dstBuffer[dstOffset+7] = srcBuffer[7]; + case 7: dstBuffer[dstOffset+6] = srcBuffer[6]; + case 6: dstBuffer[dstOffset+5] = srcBuffer[5]; + case 5: dstBuffer[dstOffset+4] = srcBuffer[4]; + case 4: dstBuffer[dstOffset+3] = srcBuffer[3]; + case 3: dstBuffer[dstOffset+2] = srcBuffer[2]; + case 2: dstBuffer[dstOffset+1] = srcBuffer[1]; + case 1: dstBuffer[dstOffset] = srcBuffer[0]; + } +} + +/** + * Opcode handlers + */ + +var opcodes = { + // text + '1': { + start: function(data) { + var self = this; + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['1'].getData.call(self, firstLength); + } + else if (firstLength == 126) { + self.expectHeader(2, function(data) { + opcodes['1'].getData.call(self, readUInt16BE.call(data, 0)); + }); + } + else if (firstLength == 127) { + self.expectHeader(8, function(data) { + if (readUInt32BE.call(data, 0) != 0) { + self.error('packets with length spanning more than 32 bit is currently not supported', 1008); + return; + } + opcodes['1'].getData.call(self, readUInt32BE.call(data, 4)); + }); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['1'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['1'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var packet = this.unmask(mask, data, true); + if (packet != null) this.currentMessage.push(packet); + if (this.state.lastFragment) { + var messageBuffer = this.concatBuffers(this.currentMessage); + if (!Validation.isValidUTF8(messageBuffer)) { + this.error('invalid utf8 sequence', 1007); + return; + } + this.ontext(messageBuffer.toString('utf8'), {masked: this.state.masked, buffer: messageBuffer}); + this.currentMessage = []; + } + this.endPacket(); + } + }, + // binary + '2': { + start: function(data) { + var self = this; + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['2'].getData.call(self, firstLength); + } + else if (firstLength == 126) { + self.expectHeader(2, function(data) { + opcodes['2'].getData.call(self, readUInt16BE.call(data, 0)); + }); + } + else if (firstLength == 127) { + self.expectHeader(8, function(data) { + if (readUInt32BE.call(data, 0) != 0) { + self.error('packets with length spanning more than 32 bit is currently not supported', 1008); + return; + } + opcodes['2'].getData.call(self, readUInt32BE.call(data, 4, true)); + }); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['2'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['2'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var packet = this.unmask(mask, data, true); + if (packet != null) this.currentMessage.push(packet); + if (this.state.lastFragment) { + var messageBuffer = this.concatBuffers(this.currentMessage); + this.onbinary(messageBuffer, {masked: this.state.masked, buffer: messageBuffer}); + this.currentMessage = []; + } + this.endPacket(); + } + }, + // close + '8': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented close is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['8'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['8'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['8'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + data = self.unmask(mask, data, true); + if (data && data.length == 1) { + self.error('close packets with data must be at least two bytes long', 1002); + return; + } + var code = data && data.length > 1 ? readUInt16BE.call(data, 0) : 1000; + if (!ErrorCodes.isValidErrorCode(code)) { + self.error('invalid error code', 1002); + return; + } + var message = ''; + if (data && data.length > 2) { + var messageBuffer = data.slice(2); + if (!Validation.isValidUTF8(messageBuffer)) { + self.error('invalid utf8 sequence', 1007); + return; + } + message = messageBuffer.toString('utf8'); + } + this.onclose(code, message, {masked: self.state.masked}); + this.reset(); + }, + }, + // ping + '9': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented ping is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['9'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['9'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['9'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + this.onping(this.unmask(mask, data, true), {masked: this.state.masked, binary: true}); + this.endPacket(); + } + }, + // pong + '10': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented pong is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['10'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (this.state.masked) { + this.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['10'].finish.call(self, mask, data); + }); + }); + } + else { + this.expectData(length, function(data) { + opcodes['10'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + this.onpong(this.unmask(mask, data, true), {masked: this.state.masked, binary: true}); + this.endPacket(); + } + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Sender.hixie.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Sender.hixie.js new file mode 100644 index 00000000000..1754afb65f9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Sender.hixie.js @@ -0,0 +1,123 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var events = require('events') + , util = require('util') + , EventEmitter = events.EventEmitter; + +/** + * Hixie Sender implementation + */ + +function Sender(socket) { + this.socket = socket; + this.continuationFrame = false; + this.isClosed = false; +} + +module.exports = Sender; + +/** + * Inherits from EventEmitter. + */ + +util.inherits(Sender, events.EventEmitter); + +/** + * Frames and writes data. + * + * @api public + */ + +Sender.prototype.send = function(data, options, cb) { + if (this.isClosed) return; +/* + if (options && options.binary) { + this.error('hixie websockets do not support binary'); + return; + } +*/ + var isString = typeof data == 'string' + , length = isString ? Buffer.byteLength(data) : data.length + , lengthbytes = (length > 127) ? 2 : 1 // assume less than 2**14 bytes + , writeStartMarker = this.continuationFrame == false + , writeEndMarker = !options || !(typeof options.fin != 'undefined' && !options.fin) + , buffer = new Buffer((writeStartMarker ? ((options && options.binary) ? (1 + lengthbytes) : 1) : 0) + length + ((writeEndMarker && !(options && options.binary)) ? 1 : 0)) + , offset = writeStartMarker ? 1 : 0; + + if (writeStartMarker) { + if (options && options.binary) { + buffer.write('\x80', 'binary'); + // assume length less than 2**14 bytes + if (lengthbytes > 1) + buffer.write(String.fromCharCode(128+length/128), offset++, 'binary'); + buffer.write(String.fromCharCode(length&0x7f), offset++, 'binary'); + } else + buffer.write('\x00', 'binary'); + } + + if (isString) buffer.write(data, offset, 'utf8'); + else data.copy(buffer, offset, 0); + + if (writeEndMarker) { + if (options && options.binary) { + // sending binary, not writing end marker + } else + buffer.write('\xff', offset + length, 'binary'); + this.continuationFrame = false; + } + else this.continuationFrame = true; + + try { + this.socket.write(buffer, 'binary', cb); + } catch (e) { + this.error(e.toString()); + } +} + +/** + * Sends a close instruction to the remote party. + * + * @api public + */ + +Sender.prototype.close = function(code, data, mask, cb) { + if (this.isClosed) return; + this.isClosed = true; + try { + if (this.continuationFrame) this.socket.write(new Buffer([0xff], 'binary')); + this.socket.write(new Buffer([0xff, 0x00]), 'binary', cb); + } catch (e) { + this.error(e.toString()); + } +} + +/** + * Sends a ping message to the remote party. Not available for hixie. + * + * @api public + */ + +Sender.prototype.ping = function(data, options) {} + +/** + * Sends a pong message to the remote party. Not available for hixie. + * + * @api public + */ + +Sender.prototype.pong = function(data, options) {} + +/** + * Handles an error + * + * @api private + */ + +Sender.prototype.error = function (reason) { + this.emit('error', reason); + return this; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Sender.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Sender.js new file mode 100644 index 00000000000..fc3b4378ffe --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Sender.js @@ -0,0 +1,227 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var events = require('events') + , util = require('util') + , EventEmitter = events.EventEmitter + , ErrorCodes = require('./ErrorCodes') + , bufferUtil = require('./BufferUtil').BufferUtil; + +/** + * HyBi Sender implementation + */ + +function Sender(socket) { + this._socket = socket; + this.firstFragment = true; +} + +/** + * Inherits from EventEmitter. + */ + +util.inherits(Sender, events.EventEmitter); + +/** + * Sends a close instruction to the remote party. + * + * @api public + */ + +Sender.prototype.close = function(code, data, mask) { + if (typeof code !== 'undefined') { + if (typeof code !== 'number' || + !ErrorCodes.isValidErrorCode(code)) throw new Error('first argument must be a valid error code number'); + } + code = code || 1000; + var dataBuffer = new Buffer(2 + (data ? Buffer.byteLength(data) : 0)); + writeUInt16BE.call(dataBuffer, code, 0); + if (dataBuffer.length > 2) dataBuffer.write(data, 2); + this.frameAndSend(0x8, dataBuffer, true, mask); +} + +/** + * Sends a ping message to the remote party. + * + * @api public + */ + +Sender.prototype.ping = function(data, options) { + var mask = options && options.mask; + this.frameAndSend(0x9, data || '', true, mask); +} + +/** + * Sends a pong message to the remote party. + * + * @api public + */ + +Sender.prototype.pong = function(data, options) { + var mask = options && options.mask; + this.frameAndSend(0xa, data || '', true, mask); +} + +/** + * Sends text or binary data to the remote party. + * + * @api public + */ + +Sender.prototype.send = function(data, options, cb) { + var finalFragment = options && options.fin === false ? false : true; + var mask = options && options.mask; + var opcode = options && options.binary ? 2 : 1; + if (this.firstFragment === false) opcode = 0; + else this.firstFragment = false; + if (finalFragment) this.firstFragment = true + this.frameAndSend(opcode, data, finalFragment, mask, cb); +} + +/** + * Frames and sends a piece of data according to the HyBi WebSocket protocol. + * + * @api private + */ + +Sender.prototype.frameAndSend = function(opcode, data, finalFragment, maskData, cb) { + var canModifyData = false; + + if (!data) { + try { + this._socket.write(new Buffer([opcode | (finalFragment ? 0x80 : 0), 0 | (maskData ? 0x80 : 0)].concat(maskData ? [0, 0, 0, 0] : [])), 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + return; + } + + if (!Buffer.isBuffer(data)) { + canModifyData = true; + if (data && (typeof data.byteLength !== 'undefined' || typeof data.buffer !== 'undefined')) { + data = getArrayBuffer(data); + } else { + data = new Buffer(data); + } + } + + var dataLength = data.length + , dataOffset = maskData ? 6 : 2 + , secondByte = dataLength; + + if (dataLength >= 65536) { + dataOffset += 8; + secondByte = 127; + } + else if (dataLength > 125) { + dataOffset += 2; + secondByte = 126; + } + + var mergeBuffers = dataLength < 32768 || (maskData && !canModifyData); + var totalLength = mergeBuffers ? dataLength + dataOffset : dataOffset; + var outputBuffer = new Buffer(totalLength); + outputBuffer[0] = finalFragment ? opcode | 0x80 : opcode; + + switch (secondByte) { + case 126: + writeUInt16BE.call(outputBuffer, dataLength, 2); + break; + case 127: + writeUInt32BE.call(outputBuffer, 0, 2); + writeUInt32BE.call(outputBuffer, dataLength, 6); + } + + if (maskData) { + outputBuffer[1] = secondByte | 0x80; + var mask = this._randomMask || (this._randomMask = getRandomMask()); + outputBuffer[dataOffset - 4] = mask[0]; + outputBuffer[dataOffset - 3] = mask[1]; + outputBuffer[dataOffset - 2] = mask[2]; + outputBuffer[dataOffset - 1] = mask[3]; + if (mergeBuffers) { + bufferUtil.mask(data, mask, outputBuffer, dataOffset, dataLength); + try { + this._socket.write(outputBuffer, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + else { + bufferUtil.mask(data, mask, data, 0, dataLength); + try { + this._socket.write(outputBuffer, 'binary'); + this._socket.write(data, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + } + else { + outputBuffer[1] = secondByte; + if (mergeBuffers) { + data.copy(outputBuffer, dataOffset); + try { + this._socket.write(outputBuffer, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + else { + try { + this._socket.write(outputBuffer, 'binary'); + this._socket.write(data, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + } +} + +module.exports = Sender; + +function writeUInt16BE(value, offset) { + this[offset] = (value & 0xff00)>>8; + this[offset+1] = value & 0xff; +} + +function writeUInt32BE(value, offset) { + this[offset] = (value & 0xff000000)>>24; + this[offset+1] = (value & 0xff0000)>>16; + this[offset+2] = (value & 0xff00)>>8; + this[offset+3] = value & 0xff; +} + +function getArrayBuffer(data) { + // data is either an ArrayBuffer or ArrayBufferView. + var array = new Uint8Array(data.buffer || data) + , l = data.byteLength || data.length + , o = data.byteOffset || 0 + , buffer = new Buffer(l); + for (var i = 0; i < l; ++i) { + buffer[i] = array[o+i]; + } + return buffer; +} + +function getRandomMask() { + return new Buffer([ + ~~(Math.random() * 255), + ~~(Math.random() * 255), + ~~(Math.random() * 255), + ~~(Math.random() * 255) + ]); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Validation.fallback.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Validation.fallback.js new file mode 100644 index 00000000000..2c7c4fd48b2 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Validation.fallback.js @@ -0,0 +1,12 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports.Validation = { + isValidUTF8: function(buffer) { + return true; + } +}; + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Validation.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Validation.js new file mode 100644 index 00000000000..0f3109a05a5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/Validation.js @@ -0,0 +1,16 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +try { + module.exports = require('../build/Release/validation'); +} catch (e) { try { + module.exports = require('../build/default/validation'); +} catch (e) { try { + module.exports = require('./Validation.fallback'); +} catch (e) { + console.error('validation.node seems to not have been built. Run npm install.'); + throw e; +}}} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/WebSocket.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/WebSocket.js new file mode 100644 index 00000000000..cce3cb41f4b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/WebSocket.js @@ -0,0 +1,818 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util') + , events = require('events') + , http = require('http') + , https = require('https') + , crypto = require('crypto') + , url = require('url') + , fs = require('fs') + , Options = require('options') + , Sender = require('./Sender') + , Receiver = require('./Receiver') + , SenderHixie = require('./Sender.hixie') + , ReceiverHixie = require('./Receiver.hixie'); + +/** + * Constants + */ + +// Default protocol version + +var protocolVersion = 13; + +// Close timeout + +var closeTimeout = 30000; // Allow 5 seconds to terminate the connection cleanly + +/** + * Node version 0.4 and 0.6 compatibility + */ + +var isNodeV4 = /^v0\.4/.test(process.version); + +/** + * WebSocket implementation + */ + +function WebSocket(address, protocols, options) { + + if (protocols && !Array.isArray(protocols) && 'object' == typeof protocols) { + // accept the "options" Object as the 2nd argument + options = protocols; + protocols = null; + } + if ('string' == typeof protocols) { + protocols = [ protocols ]; + } + if (!Array.isArray(protocols)) { + protocols = []; + } + // TODO: actually handle the `Sub-Protocols` part of the WebSocket client + + this._socket = null; + this.bytesReceived = 0; + this.readyState = null; + this.supports = {}; + + if (Array.isArray(address)) { + initAsServerClient.apply(this, address.concat(options)); + } else { + initAsClient.apply(this, [address, protocols, options]); + } +} + +/** + * Inherits from EventEmitter. + */ + +util.inherits(WebSocket, events.EventEmitter); + +/** + * Ready States + */ + +["CONNECTING", "OPEN", "CLOSING", "CLOSED"].forEach(function (state, index) { + WebSocket.prototype[state] = WebSocket[state] = index; +}); + +/** + * Gracefully closes the connection, after sending a description message to the server + * + * @param {Object} data to be sent to the server + * @api public + */ + +WebSocket.prototype.close = function(code, data) { + if (this.readyState == WebSocket.CLOSING || this.readyState == WebSocket.CLOSED) return; + if (this.readyState == WebSocket.CONNECTING) { + this.readyState = WebSocket.CLOSED; + return; + } + try { + this.readyState = WebSocket.CLOSING; + this._closeCode = code; + this._closeMessage = data; + var mask = !this._isServer; + this._sender.close(code, data, mask); + } + catch (e) { + this.emit('error', e); + } + finally { + this.terminate(); + } +} + +/** + * Pause the client stream + * + * @api public + */ + +WebSocket.prototype.pause = function() { + if (this.readyState != WebSocket.OPEN) throw new Error('not opened'); + return this._socket.pause(); +} + +/** + * Sends a ping + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean + * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open + * @api public + */ + +WebSocket.prototype.ping = function(data, options, dontFailWhenClosed) { + if (this.readyState != WebSocket.OPEN) { + if (dontFailWhenClosed === true) return; + throw new Error('not opened'); + } + options = options || {}; + if (typeof options.mask == 'undefined') options.mask = !this._isServer; + this._sender.ping(data, options); +} + +/** + * Sends a pong + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean + * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open + * @api public + */ + +WebSocket.prototype.pong = function(data, options, dontFailWhenClosed) { + if (this.readyState != WebSocket.OPEN) { + if (dontFailWhenClosed === true) return; + throw new Error('not opened'); + } + options = options || {}; + if (typeof options.mask == 'undefined') options.mask = !this._isServer; + this._sender.pong(data, options); +} + +/** + * Resume the client stream + * + * @api public + */ + +WebSocket.prototype.resume = function() { + if (this.readyState != WebSocket.OPEN) throw new Error('not opened'); + return this._socket.resume(); +} + +/** + * Sends a piece of data + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean + * @param {function} Optional callback which is executed after the send completes + * @api public + */ + +WebSocket.prototype.send = function(data, options, cb) { + if (typeof options == 'function') { + cb = options; + options = {}; + } + if (this.readyState != WebSocket.OPEN) { + if (typeof cb == 'function') cb(new Error('not opened')); + else throw new Error('not opened'); + return; + } + if (!data) data = ''; + if (this._queue) { + var self = this; + this._queue.push(function() { self.send(data, options, cb); }); + return; + } + options = options || {}; + options.fin = true; + if (typeof options.binary == 'undefined') { + options.binary = (data instanceof ArrayBuffer || data instanceof Buffer || + data instanceof Uint8Array || + data instanceof Uint16Array || + data instanceof Uint32Array || + data instanceof Int8Array || + data instanceof Int16Array || + data instanceof Int32Array || + data instanceof Float32Array || + data instanceof Float64Array); + } + if (typeof options.mask == 'undefined') options.mask = !this._isServer; + if (data instanceof fs.ReadStream) { + startQueue(this); + var self = this; + sendStream(this, data, options, function(error) { + process.nextTick(function() { executeQueueSends(self); }); + if (typeof cb == 'function') cb(error); + }); + } + else this._sender.send(data, options, cb); +} + +/** + * Streams data through calls to a user supplied function + * + * @param {Object} Members - mask: boolean, binary: boolean + * @param {function} 'function (error, send)' which is executed on successive ticks of which send is 'function (data, final)'. + * @api public + */ + +WebSocket.prototype.stream = function(options, cb) { + if (typeof options == 'function') { + cb = options; + options = {}; + } + var self = this; + if (typeof cb != 'function') throw new Error('callback must be provided'); + if (this.readyState != WebSocket.OPEN) { + if (typeof cb == 'function') cb(new Error('not opened')); + else throw new Error('not opened'); + return; + } + if (this._queue) { + this._queue.push(function() { self.stream(options, cb); }); + return; + } + options = options || {}; + if (typeof options.mask == 'undefined') options.mask = !this._isServer; + startQueue(this); + var send = function(data, final) { + try { + if (self.readyState != WebSocket.OPEN) throw new Error('not opened'); + options.fin = final === true; + self._sender.send(data, options); + if (!final) process.nextTick(cb.bind(null, null, send)); + else executeQueueSends(self); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else { + delete self._queue; + self.emit('error', e); + } + } + } + process.nextTick(cb.bind(null, null, send)); +} + +/** + * Immediately shuts down the connection + * + * @api public + */ + +WebSocket.prototype.terminate = function() { + if (this.readyState == WebSocket.CLOSED) return; + if (this._socket) { + try { + // End the connection + this._socket.end(); + } + catch (e) { + // Socket error during end() call, so just destroy it right now + cleanupWebsocketResources.call(this, true); + return; + } + + // Add a timeout to ensure that the connection is completely + // cleaned up within 30 seconds, even if the clean close procedure + // fails for whatever reason + this._closeTimer = setTimeout(cleanupWebsocketResources.bind(this, true), closeTimeout); + } + else if (this.readyState == WebSocket.CONNECTING) { + cleanupWebsocketResources.call(this, true); + } +}; + +/** + * Expose bufferedAmount + * + * @api public + */ + +Object.defineProperty(WebSocket.prototype, 'bufferedAmount', { + get: function get() { + var amount = 0; + if (this._socket) { + amount = this._socket.bufferSize || 0; + } + return amount; + } +}); + +/** + * Emulates the W3C Browser based WebSocket interface using function members. + * + * @see http://dev.w3.org/html5/websockets/#the-websocket-interface + * @api public + */ + +['open', 'error', 'close', 'message'].forEach(function(method) { + Object.defineProperty(WebSocket.prototype, 'on' + method, { + /** + * Returns the current listener + * + * @returns {Mixed} the set function or undefined + * @api public + */ + + get: function get() { + var listener = this.listeners(method)[0]; + return listener ? (listener._listener ? listener._listener : listener) : undefined; + }, + + /** + * Start listening for events + * + * @param {Function} listener the listener + * @returns {Mixed} the set function or undefined + * @api public + */ + + set: function set(listener) { + this.removeAllListeners(method); + this.addEventListener(method, listener); + } + }); +}); + +/** + * Emulates the W3C Browser based WebSocket interface using addEventListener. + * + * @see https://developer.mozilla.org/en/DOM/element.addEventListener + * @see http://dev.w3.org/html5/websockets/#the-websocket-interface + * @api public + */ +WebSocket.prototype.addEventListener = function(method, listener) { + var target = this; + if (typeof listener === 'function') { + if (method === 'message') { + function onMessage (data, flags) { + listener.call(this, new MessageEvent(data, flags.binary ? 'Binary' : 'Text', target)); + } + // store a reference so we can return the original function from the addEventListener hook + onMessage._listener = listener; + this.on(method, onMessage); + } else if (method === 'close') { + function onClose (code, message) { + listener.call(this, new CloseEvent(code, message, target)); + } + // store a reference so we can return the original function from the addEventListener hook + onClose._listener = listener; + this.on(method, onClose); + } else if (method === 'error') { + function onError (event) { + event.target = target; + listener.call(this, event); + } + // store a reference so we can return the original function from the addEventListener hook + onError._listener = listener; + this.on(method, onError); + } else if (method === 'open') { + function onOpen () { + listener.call(this, new OpenEvent(target)); + } + // store a reference so we can return the original function from the addEventListener hook + onOpen._listener = listener; + this.on(method, onOpen); + } else { + this.on(method, listener); + } + } +} + +module.exports = WebSocket; + +/** + * W3C MessageEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @api private + */ + +function MessageEvent(dataArg, typeArg, target) { + this.data = dataArg; + this.type = typeArg; + this.target = target; +} + +/** + * W3C CloseEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @api private + */ + +function CloseEvent(code, reason, target) { + this.wasClean = (typeof code == 'undefined' || code == 1000); + this.code = code; + this.reason = reason; + this.target = target; +} + +/** + * W3C OpenEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @api private + */ + +function OpenEvent(target) { + this.target = target; +} + +/** + * Entirely private apis, + * which may or may not be bound to a sepcific WebSocket instance. + */ + +function initAsServerClient(req, socket, upgradeHead, options) { + options = new Options({ + protocolVersion: protocolVersion, + protocol: null + }).merge(options); + + // expose state properties + this.protocol = options.value.protocol; + this.protocolVersion = options.value.protocolVersion; + this.supports.binary = (this.protocolVersion != 'hixie-76'); + this.upgradeReq = req; + this.readyState = WebSocket.CONNECTING; + this._isServer = true; + + // establish connection + if (options.value.protocolVersion == 'hixie-76') establishConnection.call(this, ReceiverHixie, SenderHixie, socket, upgradeHead); + else establishConnection.call(this, Receiver, Sender, socket, upgradeHead); +} + +function initAsClient(address, protocols, options) { + options = new Options({ + origin: null, + protocolVersion: protocolVersion, + host: null, + headers: null, + protocol: null, + agent: null, + + // ssl-related options + pfx: null, + key: null, + passphrase: null, + cert: null, + ca: null, + ciphers: null, + rejectUnauthorized: null + }).merge(options); + if (options.value.protocolVersion != 8 && options.value.protocolVersion != 13) { + throw new Error('unsupported protocol version'); + } + + // verify url and establish http class + var serverUrl = url.parse(address); + var isUnixSocket = serverUrl.protocol === 'ws+unix:'; + if (!serverUrl.host && !isUnixSocket) throw new Error('invalid url'); + var isSecure = serverUrl.protocol === 'wss:' || serverUrl.protocol === 'https:'; + var httpObj = isSecure ? https : http; + var port = serverUrl.port || (isSecure ? 443 : 80); + var auth = serverUrl.auth; + + // expose state properties + this._isServer = false; + this.url = address; + this.protocolVersion = options.value.protocolVersion; + this.supports.binary = (this.protocolVersion != 'hixie-76'); + + // begin handshake + var key = new Buffer(options.value.protocolVersion + '-' + Date.now()).toString('base64'); + var shasum = crypto.createHash('sha1'); + shasum.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'); + var expectedServerKey = shasum.digest('base64'); + + var agent = options.value.agent; + // node<=v0.4.x compatibility + if (!agent && isNodeV4) { + isNodeV4 = true; + agent = new httpObj.Agent({ + host: serverUrl.hostname, + port: port + }); + } + + var headerHost = serverUrl.hostname; + // Append port number to Host and Origin header, only if specified in the url and non-default + if(serverUrl.port) { + if((isSecure && (port != 443)) || (!isSecure && (port != 80))){ + headerHost = headerHost + ':' + port; + } + } + + var requestOptions = { + port: port, + host: serverUrl.hostname, + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Host': headerHost, + 'Origin': headerHost, + 'Sec-WebSocket-Version': options.value.protocolVersion, + 'Sec-WebSocket-Key': key + } + }; + + // If we have basic auth. + if (auth) { + requestOptions.headers['Authorization'] = 'Basic ' + new Buffer(auth).toString('base64'); + } + + if (options.value.protocol) { + requestOptions.headers['Sec-WebSocket-Protocol'] = options.value.protocol; + } + + if (options.value.host) { + requestOptions.headers['Host'] = options.value.host; + } + + if (options.value.headers) { + for (var header in options.value.headers) { + if (options.value.headers.hasOwnProperty(header)) { + requestOptions.headers[header] = options.value.headers[header]; + } + } + } + + if (options.isDefinedAndNonNull('pfx') + || options.isDefinedAndNonNull('key') + || options.isDefinedAndNonNull('passphrase') + || options.isDefinedAndNonNull('cert') + || options.isDefinedAndNonNull('ca') + || options.isDefinedAndNonNull('ciphers') + || options.isDefinedAndNonNull('rejectUnauthorized')) { + + if (isNodeV4) { + throw new Error('Client side certificates are not supported on Node 0.4.x'); + } + + if (options.isDefinedAndNonNull('pfx')) requestOptions.pfx = options.value.pfx; + if (options.isDefinedAndNonNull('key')) requestOptions.key = options.value.key; + if (options.isDefinedAndNonNull('passphrase')) requestOptions.passphrase = options.value.passphrase; + if (options.isDefinedAndNonNull('cert')) requestOptions.cert = options.value.cert; + if (options.isDefinedAndNonNull('ca')) requestOptions.ca = options.value.ca; + if (options.isDefinedAndNonNull('ciphers')) requestOptions.ciphers = options.value.ciphers; + if (options.isDefinedAndNonNull('rejectUnauthorized')) requestOptions.rejectUnauthorized = options.value.rejectUnauthorized; + + if (!agent) { + // global agent ignores client side certificates + agent = new httpObj.Agent(requestOptions); + } + } + + if (isNodeV4) { + requestOptions.path = (serverUrl.pathname || '/') + (serverUrl.search || ''); + } + else requestOptions.path = serverUrl.path || '/'; + + if (agent) { + requestOptions.agent = agent; + } + + if (isUnixSocket) { + requestOptions.socketPath = serverUrl.pathname; + } + if (options.value.origin) { + if (options.value.protocolVersion < 13) requestOptions.headers['Sec-WebSocket-Origin'] = options.value.origin; + else requestOptions.headers['Origin'] = options.value.origin; + } + + var self = this; + var req = httpObj.request(requestOptions); + + (isNodeV4 ? agent : req).on('error', function(error) { + self.emit('error', error); + cleanupWebsocketResources.call(this, error); + }); + (isNodeV4 ? agent : req).once('response', function(res) { + var error = new Error('unexpected server response (' + res.statusCode + ')'); + self.emit('error', error); + cleanupWebsocketResources.call(this, error); + }); + (isNodeV4 ? agent : req).once('upgrade', function(res, socket, upgradeHead) { + if (self.readyState == WebSocket.CLOSED) { + // client closed before server accepted connection + self.emit('close'); + removeAllListeners(self); + socket.end(); + return; + } + var serverKey = res.headers['sec-websocket-accept']; + if (typeof serverKey == 'undefined' || serverKey !== expectedServerKey) { + self.emit('error', 'invalid server key'); + removeAllListeners(self); + socket.end(); + return; + } + + var serverProt = res.headers['sec-websocket-protocol']; + var protList = (options.value.protocol || "").split(/, */); + var protError = null; + if (!options.value.protocol && serverProt) { + protError = 'server sent a subprotocol even though none requested'; + } else if (options.value.protocol && !serverProt) { + protError = 'server sent no subprotocol even though requested'; + } else if (serverProt && protList.indexOf(serverProt) === -1) { + protError = 'server responded with an invalid protocol'; + } + if (protError) { + self.emit('error', protError); + removeAllListeners(self); + socket.end(); + return; + } else if (serverProt) { + self.protocol = serverProt; + } + + establishConnection.call(self, Receiver, Sender, socket, upgradeHead); + + // perform cleanup on http resources + removeAllListeners(isNodeV4 ? agent : req); + req = null; + agent = null; + }); + + req.end(); + this.readyState = WebSocket.CONNECTING; +} + +function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) { + this._socket = socket; + socket.setTimeout(0); + socket.setNoDelay(true); + var self = this; + this._receiver = new ReceiverClass(); + + // socket cleanup handlers + socket.on('end', cleanupWebsocketResources.bind(this)); + socket.on('close', cleanupWebsocketResources.bind(this)); + socket.on('error', cleanupWebsocketResources.bind(this)); + + // ensure that the upgradeHead is added to the receiver + function firstHandler(data) { + if (self.readyState != WebSocket.OPEN) return; + if (upgradeHead && upgradeHead.length > 0) { + self.bytesReceived += upgradeHead.length; + var head = upgradeHead; + upgradeHead = null; + self._receiver.add(head); + } + dataHandler = realHandler; + if (data) { + self.bytesReceived += data.length; + self._receiver.add(data); + } + } + // subsequent packets are pushed straight to the receiver + function realHandler(data) { + if (data) self.bytesReceived += data.length; + self._receiver.add(data); + } + var dataHandler = firstHandler; + // if data was passed along with the http upgrade, + // this will schedule a push of that on to the receiver. + // this has to be done on next tick, since the caller + // hasn't had a chance to set event handlers on this client + // object yet. + process.nextTick(firstHandler); + + // receiver event handlers + self._receiver.ontext = function (data, flags) { + flags = flags || {}; + self.emit('message', data, flags); + }; + self._receiver.onbinary = function (data, flags) { + flags = flags || {}; + flags.binary = true; + self.emit('message', data, flags); + }; + self._receiver.onping = function(data, flags) { + flags = flags || {}; + self.pong(data, {mask: !self._isServer, binary: flags.binary === true}, true); + self.emit('ping', data, flags); + }; + self._receiver.onpong = function(data, flags) { + self.emit('pong', data, flags); + }; + self._receiver.onclose = function(code, data, flags) { + flags = flags || {}; + self.close(code, data); + }; + self._receiver.onerror = function(reason, errorCode) { + // close the connection when the receiver reports a HyBi error code + self.close(typeof errorCode != 'undefined' ? errorCode : 1002, ''); + self.emit('error', reason, errorCode); + }; + + // finalize the client + this._sender = new SenderClass(socket); + this._sender.on('error', function(error) { + self.close(1002, ''); + self.emit('error', error); + }); + this.readyState = WebSocket.OPEN; + this.emit('open'); + + socket.on('data', dataHandler); +} + +function startQueue(instance) { + instance._queue = instance._queue || []; +} + +function executeQueueSends(instance) { + var queue = instance._queue; + if (typeof queue == 'undefined') return; + delete instance._queue; + for (var i = 0, l = queue.length; i < l; ++i) { + queue[i](); + } +} + +function sendStream(instance, stream, options, cb) { + stream.on('data', function(data) { + if (instance.readyState != WebSocket.OPEN) { + if (typeof cb == 'function') cb(new Error('not opened')); + else { + delete instance._queue; + instance.emit('error', new Error('not opened')); + } + return; + } + options.fin = false; + instance._sender.send(data, options); + }); + stream.on('end', function() { + if (instance.readyState != WebSocket.OPEN) { + if (typeof cb == 'function') cb(new Error('not opened')); + else { + delete instance._queue; + instance.emit('error', new Error('not opened')); + } + return; + } + options.fin = true; + instance._sender.send(null, options); + if (typeof cb == 'function') cb(null); + }); +} + +function cleanupWebsocketResources(error) { + if (this.readyState == WebSocket.CLOSED) return; + var emitClose = this.readyState != WebSocket.CONNECTING; + this.readyState = WebSocket.CLOSED; + + clearTimeout(this._closeTimer); + this._closeTimer = null; + if (emitClose) this.emit('close', this._closeCode || 1000, this._closeMessage || ''); + + if (this._socket) { + removeAllListeners(this._socket); + // catch all socket error after removing all standard handlers + var socket = this._socket; + this._socket.on('error', function() { + try { socket.destroy(); } catch (e) {} + }); + try { + if (!error) this._socket.end(); + else this._socket.destroy(); + } + catch (e) { /* Ignore termination errors */ } + this._socket = null; + } + if (this._sender) { + removeAllListeners(this._sender); + this._sender = null; + } + if (this._receiver) { + this._receiver.cleanup(); + this._receiver = null; + } + removeAllListeners(this); + this.on('error', function() {}); // catch all errors after this + delete this._queue; +} + +function removeAllListeners(instance) { + if (isNodeV4) { + // node v4 doesn't *actually* remove all listeners globally, + // so we do that instead + instance._events = {}; + } + else instance.removeAllListeners(); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/WebSocketServer.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/WebSocketServer.js new file mode 100644 index 00000000000..da759f8b4ed --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/WebSocketServer.js @@ -0,0 +1,460 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util') + , events = require('events') + , http = require('http') + , crypto = require('crypto') + , url = require('url') + , Options = require('options') + , WebSocket = require('./WebSocket') + , tls = require('tls') + , url = require('url'); + +/** + * WebSocket Server implementation + */ + +function WebSocketServer(options, callback) { + options = new Options({ + host: '0.0.0.0', + port: null, + server: null, + verifyClient: null, + handleProtocols: null, + path: null, + noServer: false, + disableHixie: false, + clientTracking: true + }).merge(options); + + if (!options.isDefinedAndNonNull('port') && !options.isDefinedAndNonNull('server') && !options.value.noServer) { + throw new TypeError('`port` or a `server` must be provided'); + } + + var self = this; + + if (options.isDefinedAndNonNull('port')) { + this._server = http.createServer(function (req, res) { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('Not implemented'); + }); + this._server.listen(options.value.port, options.value.host, callback); + this._closeServer = function() { self._server.close(); }; + } + else if (options.value.server) { + this._server = options.value.server; + if (options.value.path) { + // take note of the path, to avoid collisions when multiple websocket servers are + // listening on the same http server + if (this._server._webSocketPaths && options.value.server._webSocketPaths[options.value.path]) { + throw new Error('two instances of WebSocketServer cannot listen on the same http server path'); + } + if (typeof this._server._webSocketPaths !== 'object') { + this._server._webSocketPaths = {}; + } + this._server._webSocketPaths[options.value.path] = 1; + } + } + if (this._server) this._server.once('listening', function() { self.emit('listening'); }); + + if (typeof this._server != 'undefined') { + this._server.on('error', function(error) { + self.emit('error', error) + }); + this._server.on('upgrade', function(req, socket, upgradeHead) { + //copy upgradeHead to avoid retention of large slab buffers used in node core + var head = new Buffer(upgradeHead.length); + upgradeHead.copy(head); + + self.handleUpgrade(req, socket, head, function(client) { + self.emit('connection'+req.url, client); + self.emit('connection', client); + }); + }); + } + + this.options = options.value; + this.path = options.value.path; + this.clients = []; +} + +/** + * Inherits from EventEmitter. + */ + +util.inherits(WebSocketServer, events.EventEmitter); + +/** + * Immediately shuts down the connection. + * + * @api public + */ + +WebSocketServer.prototype.close = function() { + // terminate all associated clients + var error = null; + try { + for (var i = 0, l = this.clients.length; i < l; ++i) { + this.clients[i].terminate(); + } + } + catch (e) { + error = e; + } + + // remove path descriptor, if any + if (this.path && this._server._webSocketPaths) { + delete this._server._webSocketPaths[this.path]; + if (Object.keys(this._server._webSocketPaths).length == 0) { + delete this._server._webSocketPaths; + } + } + + // close the http server if it was internally created + try { + if (typeof this._closeServer !== 'undefined') { + this._closeServer(); + } + } + finally { + delete this._server; + } + if (error) throw error; +} + +/** + * Handle a HTTP Upgrade request. + * + * @api public + */ + +WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead, cb) { + // check for wrong path + if (this.options.path) { + var u = url.parse(req.url); + if (u && u.pathname !== this.options.path) return; + } + + if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + if (req.headers['sec-websocket-key1']) handleHixieUpgrade.apply(this, arguments); + else handleHybiUpgrade.apply(this, arguments); +} + +module.exports = WebSocketServer; + +/** + * Entirely private apis, + * which may or may not be bound to a sepcific WebSocket instance. + */ + +function handleHybiUpgrade(req, socket, upgradeHead, cb) { + // handle premature socket errors + var errorHandler = function() { + try { socket.destroy(); } catch (e) {} + } + socket.on('error', errorHandler); + + // verify key presence + if (!req.headers['sec-websocket-key']) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + // verify version + var version = parseInt(req.headers['sec-websocket-version']); + if ([8, 13].indexOf(version) === -1) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + // verify protocol + var protocols = req.headers['sec-websocket-protocol']; + + // verify client + var origin = version < 13 ? + req.headers['sec-websocket-origin'] : + req.headers['origin']; + + // handler to call when the connection sequence completes + var self = this; + var completeHybiUpgrade2 = function(protocol) { + + // calc key + var key = req.headers['sec-websocket-key']; + var shasum = crypto.createHash('sha1'); + shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + key = shasum.digest('base64'); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: websocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Accept: ' + key + ]; + + if (typeof protocol != 'undefined') { + headers.push('Sec-WebSocket-Protocol: ' + protocol); + } + + // allows external modification/inspection of handshake headers + self.emit('headers', headers); + + socket.setTimeout(0); + socket.setNoDelay(true); + try { + socket.write(headers.concat('', '').join('\r\n')); + } + catch (e) { + // if the upgrade write fails, shut the connection down hard + try { socket.destroy(); } catch (e) {} + return; + } + + var client = new WebSocket([req, socket, upgradeHead], { + protocolVersion: version, + protocol: protocol + }); + + if (self.options.clientTracking) { + self.clients.push(client); + client.on('close', function() { + var index = self.clients.indexOf(client); + if (index != -1) { + self.clients.splice(index, 1); + } + }); + } + + // signal upgrade complete + socket.removeListener('error', errorHandler); + cb(client); + } + + // optionally call external protocol selection handler before + // calling completeHybiUpgrade2 + var completeHybiUpgrade1 = function() { + // choose from the sub-protocols + if (typeof self.options.handleProtocols == 'function') { + var protList = (protocols || "").split(/, */); + var callbackCalled = false; + var res = self.options.handleProtocols(protList, function(result, protocol) { + callbackCalled = true; + if (!result) abortConnection(socket, 404, 'Unauthorized') + else completeHybiUpgrade2(protocol); + }); + if (!callbackCalled) { + // the handleProtocols handler never called our callback + abortConnection(socket, 501, 'Could not process protocols'); + } + return; + } else { + if (typeof protocols !== 'undefined') { + completeHybiUpgrade2(protocols.split(/, */)[0]); + } + else { + completeHybiUpgrade2(); + } + } + } + + // optionally call external client verification handler + if (typeof this.options.verifyClient == 'function') { + var info = { + origin: origin, + secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', + req: req + }; + if (this.options.verifyClient.length == 2) { + this.options.verifyClient(info, function(result) { + if (!result) abortConnection(socket, 401, 'Unauthorized') + else completeHybiUpgrade1(); + }); + return; + } + else if (!this.options.verifyClient(info)) { + abortConnection(socket, 401, 'Unauthorized'); + return; + } + } + + completeHybiUpgrade1(); +} + +function handleHixieUpgrade(req, socket, upgradeHead, cb) { + // handle premature socket errors + var errorHandler = function() { + try { socket.destroy(); } catch (e) {} + } + socket.on('error', errorHandler); + + // bail if options prevent hixie + if (this.options.disableHixie) { + abortConnection(socket, 401, 'Hixie support disabled'); + return; + } + + // verify key presence + if (!req.headers['sec-websocket-key2']) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + var origin = req.headers['origin'] + , self = this; + + // setup handshake completion to run after client has been verified + var onClientVerified = function() { + var wshost; + if (!req.headers['x-forwarded-host']) + wshost = req.headers.host; + else + wshost = req.headers['x-forwarded-host']; + var location = ((req.headers['x-forwarded-proto'] === 'https' || socket.encrypted) ? 'wss' : 'ws') + '://' + wshost + req.url + , protocol = req.headers['sec-websocket-protocol']; + + // handshake completion code to run once nonce has been successfully retrieved + var completeHandshake = function(nonce, rest) { + // calculate key + var k1 = req.headers['sec-websocket-key1'] + , k2 = req.headers['sec-websocket-key2'] + , md5 = crypto.createHash('md5'); + + [k1, k2].forEach(function (k) { + var n = parseInt(k.replace(/[^\d]/g, '')) + , spaces = k.replace(/[^ ]/g, '').length; + if (spaces === 0 || n % spaces !== 0){ + abortConnection(socket, 400, 'Bad Request'); + return; + } + n /= spaces; + md5.update(String.fromCharCode( + n >> 24 & 0xFF, + n >> 16 & 0xFF, + n >> 8 & 0xFF, + n & 0xFF)); + }); + md5.update(nonce.toString('binary')); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: WebSocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Location: ' + location + ]; + if (typeof protocol != 'undefined') headers.push('Sec-WebSocket-Protocol: ' + protocol); + if (typeof origin != 'undefined') headers.push('Sec-WebSocket-Origin: ' + origin); + + socket.setTimeout(0); + socket.setNoDelay(true); + try { + // merge header and hash buffer + var headerBuffer = new Buffer(headers.concat('', '').join('\r\n')); + var hashBuffer = new Buffer(md5.digest('binary'), 'binary'); + var handshakeBuffer = new Buffer(headerBuffer.length + hashBuffer.length); + headerBuffer.copy(handshakeBuffer, 0); + hashBuffer.copy(handshakeBuffer, headerBuffer.length); + + // do a single write, which - upon success - causes a new client websocket to be setup + socket.write(handshakeBuffer, 'binary', function(err) { + if (err) return; // do not create client if an error happens + var client = new WebSocket([req, socket, rest], { + protocolVersion: 'hixie-76', + protocol: protocol + }); + if (self.options.clientTracking) { + self.clients.push(client); + client.on('close', function() { + var index = self.clients.indexOf(client); + if (index != -1) { + self.clients.splice(index, 1); + } + }); + } + + // signal upgrade complete + socket.removeListener('error', errorHandler); + cb(client); + }); + } + catch (e) { + try { socket.destroy(); } catch (e) {} + return; + } + } + + // retrieve nonce + var nonceLength = 8; + if (upgradeHead && upgradeHead.length >= nonceLength) { + var nonce = upgradeHead.slice(0, nonceLength); + var rest = upgradeHead.length > nonceLength ? upgradeHead.slice(nonceLength) : null; + completeHandshake.call(self, nonce, rest); + } + else { + // nonce not present in upgradeHead, so we must wait for enough data + // data to arrive before continuing + var nonce = new Buffer(nonceLength); + upgradeHead.copy(nonce, 0); + var received = upgradeHead.length; + var rest = null; + var handler = function (data) { + var toRead = Math.min(data.length, nonceLength - received); + if (toRead === 0) return; + data.copy(nonce, received, 0, toRead); + received += toRead; + if (received == nonceLength) { + socket.removeListener('data', handler); + if (toRead < data.length) rest = data.slice(toRead); + completeHandshake.call(self, nonce, rest); + } + } + socket.on('data', handler); + } + } + + // verify client + if (typeof this.options.verifyClient == 'function') { + var info = { + origin: origin, + secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', + req: req + }; + if (this.options.verifyClient.length == 2) { + var self = this; + this.options.verifyClient(info, function(result) { + if (!result) abortConnection(socket, 401, 'Unauthorized') + else onClientVerified.apply(self); + }); + return; + } + else if (!this.options.verifyClient(info)) { + abortConnection(socket, 401, 'Unauthorized'); + return; + } + } + + // no client verification required + onClientVerified(); +} + +function abortConnection(socket, code, name) { + try { + var response = [ + 'HTTP/1.1 ' + code + ' ' + name, + 'Content-type: text/html' + ]; + socket.write(response.concat('', '').join('\r\n')); + } + catch (e) { /* ignore errors - we've aborted this connection */ } + finally { + // ensure that an early aborted connection is shut down completely + try { socket.destroy(); } catch (e) {} + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/browser.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/browser.js new file mode 100644 index 00000000000..8d3a755cd57 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/lib/browser.js @@ -0,0 +1,43 @@ + +/** + * Module dependencies. + */ + +var global = (function() { return this; })(); + +/** + * WebSocket constructor. + */ + +var WebSocket = global.WebSocket || global.MozWebSocket; + +/** + * Module exports. + */ + +module.exports = WebSocket ? ws : null; + +/** + * WebSocket constructor. + * + * The third `opts` options object gets ignored in web browsers, since it's + * non-standard, and throws a TypeError if passed to the constructor. + * See: https://github.com/einaros/ws/issues/227 + * + * @param {String} uri + * @param {Array} protocols (optional) + * @param {Object) opts (optional) + * @api public + */ + +function ws(uri, protocols, opts) { + var instance; + if (protocols) { + instance = new WebSocket(uri, protocols); + } else { + instance = new WebSocket(uri); + } + return instance; +} + +if (WebSocket) ws.prototype = WebSocket.prototype; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/.npmignore new file mode 100644 index 00000000000..f1250e584c9 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/.travis.yml b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/.travis.yml new file mode 100644 index 00000000000..f1d0f13c8a5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.4 + - 0.6 diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/History.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/History.md new file mode 100644 index 00000000000..4961d2e272c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/History.md @@ -0,0 +1,107 @@ + +0.6.1 / 2012-06-01 +================== + + * Added: append (yes or no) on confirmation + * Added: allow node.js v0.7.x + +0.6.0 / 2012-04-10 +================== + + * Added `.prompt(obj, callback)` support. Closes #49 + * Added default support to .choose(). Closes #41 + * Fixed the choice example + +0.5.1 / 2011-12-20 +================== + + * Fixed `password()` for recent nodes. Closes #36 + +0.5.0 / 2011-12-04 +================== + + * Added sub-command option support [itay] + +0.4.3 / 2011-12-04 +================== + + * Fixed custom help ordering. Closes #32 + +0.4.2 / 2011-11-24 +================== + + * Added travis support + * Fixed: line-buffered input automatically trimmed. Closes #31 + +0.4.1 / 2011-11-18 +================== + + * Removed listening for "close" on --help + +0.4.0 / 2011-11-15 +================== + + * Added support for `--`. Closes #24 + +0.3.3 / 2011-11-14 +================== + + * Fixed: wait for close event when writing help info [Jerry Hamlet] + +0.3.2 / 2011-11-01 +================== + + * Fixed long flag definitions with values [felixge] + +0.3.1 / 2011-10-31 +================== + + * Changed `--version` short flag to `-V` from `-v` + * Changed `.version()` so it's configurable [felixge] + +0.3.0 / 2011-10-31 +================== + + * Added support for long flags only. Closes #18 + +0.2.1 / 2011-10-24 +================== + + * "node": ">= 0.4.x < 0.7.0". Closes #20 + +0.2.0 / 2011-09-26 +================== + + * Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs] + +0.1.0 / 2011-08-24 +================== + + * Added support for custom `--help` output + +0.0.5 / 2011-08-18 +================== + + * Changed: when the user enters nothing prompt for password again + * Fixed issue with passwords beginning with numbers [NuckChorris] + +0.0.4 / 2011-08-15 +================== + + * Fixed `Commander#args` + +0.0.3 / 2011-08-15 +================== + + * Added default option value support + +0.0.2 / 2011-08-15 +================== + + * Added mask support to `Command#password(str[, mask], fn)` + * Added `Command#password(str, fn)` + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/Makefile new file mode 100644 index 00000000000..00746255373 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/Makefile @@ -0,0 +1,7 @@ + +TESTS = $(shell find test/test.*.js) + +test: + @./test/run $(TESTS) + +.PHONY: test \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/Readme.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/Readme.md new file mode 100644 index 00000000000..b8328c37563 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/Readme.md @@ -0,0 +1,262 @@ +# Commander.js + + The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander). + + [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js) + +## Installation + + $ npm install commander + +## Option parsing + + Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .version('0.0.1') + .option('-p, --peppers', 'Add peppers') + .option('-P, --pineapple', 'Add pineapple') + .option('-b, --bbq', 'Add bbq sauce') + .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') + .parse(process.argv); + +console.log('you ordered a pizza with:'); +if (program.peppers) console.log(' - peppers'); +if (program.pineapple) console.log(' - pineappe'); +if (program.bbq) console.log(' - bbq'); +console.log(' - %s cheese', program.cheese); +``` + + Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. + +## Automated --help + + The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free: + +``` + $ ./examples/pizza --help + + Usage: pizza [options] + + Options: + + -V, --version output the version number + -p, --peppers Add peppers + -P, --pineapple Add pineappe + -b, --bbq Add bbq sauce + -c, --cheese Add the specified type of cheese [marble] + -h, --help output usage information + +``` + +## Coercion + +```js +function range(val) { + return val.split('..').map(Number); +} + +function list(val) { + return val.split(','); +} + +program + .version('0.0.1') + .usage('[options] ') + .option('-i, --integer ', 'An integer argument', parseInt) + .option('-f, --float ', 'A float argument', parseFloat) + .option('-r, --range ..', 'A range', range) + .option('-l, --list ', 'A list', list) + .option('-o, --optional [value]', 'An optional value') + .parse(process.argv); + +console.log(' int: %j', program.integer); +console.log(' float: %j', program.float); +console.log(' optional: %j', program.optional); +program.range = program.range || []; +console.log(' range: %j..%j', program.range[0], program.range[1]); +console.log(' list: %j', program.list); +console.log(' args: %j', program.args); +``` + +## Custom help + + You can display arbitrary `-h, --help` information + by listening for "--help". Commander will automatically + exit once you are done so that the remainder of your program + does not execute causing undesired behaviours, for example + in the following executable "stuff" will not output when + `--help` is used. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('../'); + +function list(val) { + return val.split(',').map(Number); +} + +program + .version('0.0.1') + .option('-f, --foo', 'enable some foo') + .option('-b, --bar', 'enable some bar') + .option('-B, --baz', 'enable some baz'); + +// must be before .parse() since +// node's emit() is immediate + +program.on('--help', function(){ + console.log(' Examples:'); + console.log(''); + console.log(' $ custom-help --help'); + console.log(' $ custom-help -h'); + console.log(''); +}); + +program.parse(process.argv); + +console.log('stuff'); +``` + +yielding the following help output: + +``` + +Usage: custom-help [options] + +Options: + + -h, --help output usage information + -V, --version output the version number + -f, --foo enable some foo + -b, --bar enable some bar + -B, --baz enable some baz + +Examples: + + $ custom-help --help + $ custom-help -h + +``` + +## .prompt(msg, fn) + + Single-line prompt: + +```js +program.prompt('name: ', function(name){ + console.log('hi %s', name); +}); +``` + + Multi-line prompt: + +```js +program.prompt('description:', function(name){ + console.log('hi %s', name); +}); +``` + + Coercion: + +```js +program.prompt('Age: ', Number, function(age){ + console.log('age: %j', age); +}); +``` + +```js +program.prompt('Birthdate: ', Date, function(date){ + console.log('date: %s', date); +}); +``` + +## .password(msg[, mask], fn) + +Prompt for password without echoing: + +```js +program.password('Password: ', function(pass){ + console.log('got "%s"', pass); + process.stdin.destroy(); +}); +``` + +Prompt for password with mask char "*": + +```js +program.password('Password: ', '*', function(pass){ + console.log('got "%s"', pass); + process.stdin.destroy(); +}); +``` + +## .confirm(msg, fn) + + Confirm with the given `msg`: + +```js +program.confirm('continue? ', function(ok){ + console.log(' got %j', ok); +}); +``` + +## .choose(list, fn) + + Let the user choose from a `list`: + +```js +var list = ['tobi', 'loki', 'jane', 'manny', 'luna']; + +console.log('Choose the coolest pet:'); +program.choose(list, function(i){ + console.log('you chose %d "%s"', i, list[i]); +}); +``` + +## Links + + - [API documentation](http://visionmedia.github.com/commander.js/) + - [ascii tables](https://github.com/LearnBoost/cli-table) + - [progress bars](https://github.com/visionmedia/node-progress) + - [more progress bars](https://github.com/substack/node-multimeter) + - [examples](https://github.com/visionmedia/commander.js/tree/master/examples) + +## License + +(The MIT License) + +Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> + +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. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/index.js new file mode 100644 index 00000000000..06ec1e4bcd8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/commander'); \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/lib/commander.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/lib/commander.js new file mode 100644 index 00000000000..5ba87ebb85d --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/lib/commander.js @@ -0,0 +1,1026 @@ + +/*! + * commander + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter + , path = require('path') + , tty = require('tty') + , basename = path.basename; + +/** + * Expose the root command. + */ + +exports = module.exports = new Command; + +/** + * Expose `Command`. + */ + +exports.Command = Command; + +/** + * Expose `Option`. + */ + +exports.Option = Option; + +/** + * Initialize a new `Option` with the given `flags` and `description`. + * + * @param {String} flags + * @param {String} description + * @api public + */ + +function Option(flags, description) { + this.flags = flags; + this.required = ~flags.indexOf('<'); + this.optional = ~flags.indexOf('['); + this.bool = !~flags.indexOf('-no-'); + flags = flags.split(/[ ,|]+/); + if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift(); + this.long = flags.shift(); + this.description = description; +} + +/** + * Return option name. + * + * @return {String} + * @api private + */ + +Option.prototype.name = function(){ + return this.long + .replace('--', '') + .replace('no-', ''); +}; + +/** + * Check if `arg` matches the short or long flag. + * + * @param {String} arg + * @return {Boolean} + * @api private + */ + +Option.prototype.is = function(arg){ + return arg == this.short + || arg == this.long; +}; + +/** + * Initialize a new `Command`. + * + * @param {String} name + * @api public + */ + +function Command(name) { + this.commands = []; + this.options = []; + this.args = []; + this.name = name; +} + +/** + * Inherit from `EventEmitter.prototype`. + */ + +Command.prototype.__proto__ = EventEmitter.prototype; + +/** + * Add command `name`. + * + * The `.action()` callback is invoked when the + * command `name` is specified via __ARGV__, + * and the remaining arguments are applied to the + * function for access. + * + * When the `name` is "*" an un-matched command + * will be passed as the first arg, followed by + * the rest of __ARGV__ remaining. + * + * Examples: + * + * program + * .version('0.0.1') + * .option('-C, --chdir ', 'change the working directory') + * .option('-c, --config ', 'set config path. defaults to ./deploy.conf') + * .option('-T, --no-tests', 'ignore test hook') + * + * program + * .command('setup') + * .description('run remote setup commands') + * .action(function(){ + * console.log('setup'); + * }); + * + * program + * .command('exec ') + * .description('run the given remote command') + * .action(function(cmd){ + * console.log('exec "%s"', cmd); + * }); + * + * program + * .command('*') + * .description('deploy the given env') + * .action(function(env){ + * console.log('deploying "%s"', env); + * }); + * + * program.parse(process.argv); + * + * @param {String} name + * @return {Command} the new command + * @api public + */ + +Command.prototype.command = function(name){ + var args = name.split(/ +/); + var cmd = new Command(args.shift()); + this.commands.push(cmd); + cmd.parseExpectedArgs(args); + cmd.parent = this; + return cmd; +}; + +/** + * Parse expected `args`. + * + * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. + * + * @param {Array} args + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parseExpectedArgs = function(args){ + if (!args.length) return; + var self = this; + args.forEach(function(arg){ + switch (arg[0]) { + case '<': + self.args.push({ required: true, name: arg.slice(1, -1) }); + break; + case '[': + self.args.push({ required: false, name: arg.slice(1, -1) }); + break; + } + }); + return this; +}; + +/** + * Register callback `fn` for the command. + * + * Examples: + * + * program + * .command('help') + * .description('display verbose help') + * .action(function(){ + * // output help here + * }); + * + * @param {Function} fn + * @return {Command} for chaining + * @api public + */ + +Command.prototype.action = function(fn){ + var self = this; + this.parent.on(this.name, function(args, unknown){ + // Parse any so-far unknown options + unknown = unknown || []; + var parsed = self.parseOptions(unknown); + + // Output help if necessary + outputHelpIfNecessary(self, parsed.unknown); + + // If there are still any unknown options, then we simply + // die, unless someone asked for help, in which case we give it + // to them, and then we die. + if (parsed.unknown.length > 0) { + self.unknownOption(parsed.unknown[0]); + } + + self.args.forEach(function(arg, i){ + if (arg.required && null == args[i]) { + self.missingArgument(arg.name); + } + }); + + // Always append ourselves to the end of the arguments, + // to make sure we match the number of arguments the user + // expects + if (self.args.length) { + args[self.args.length] = self; + } else { + args.push(self); + } + + fn.apply(this, args); + }); + return this; +}; + +/** + * Define option with `flags`, `description` and optional + * coercion `fn`. + * + * The `flags` string should contain both the short and long flags, + * separated by comma, a pipe or space. The following are all valid + * all will output this way when `--help` is used. + * + * "-p, --pepper" + * "-p|--pepper" + * "-p --pepper" + * + * Examples: + * + * // simple boolean defaulting to false + * program.option('-p, --pepper', 'add pepper'); + * + * --pepper + * program.pepper + * // => Boolean + * + * // simple boolean defaulting to false + * program.option('-C, --no-cheese', 'remove cheese'); + * + * program.cheese + * // => true + * + * --no-cheese + * program.cheese + * // => true + * + * // required argument + * program.option('-C, --chdir ', 'change the working directory'); + * + * --chdir /tmp + * program.chdir + * // => "/tmp" + * + * // optional argument + * program.option('-c, --cheese [type]', 'add cheese [marble]'); + * + * @param {String} flags + * @param {String} description + * @param {Function|Mixed} fn or default + * @param {Mixed} defaultValue + * @return {Command} for chaining + * @api public + */ + +Command.prototype.option = function(flags, description, fn, defaultValue){ + var self = this + , option = new Option(flags, description) + , oname = option.name() + , name = camelcase(oname); + + // default as 3rd arg + if ('function' != typeof fn) defaultValue = fn, fn = null; + + // preassign default value only for --no-*, [optional], or + if (false == option.bool || option.optional || option.required) { + // when --no-* we make sure default is true + if (false == option.bool) defaultValue = true; + // preassign only if we have a default + if (undefined !== defaultValue) self[name] = defaultValue; + } + + // register the option + this.options.push(option); + + // when it's passed assign the value + // and conditionally invoke the callback + this.on(oname, function(val){ + // coercion + if (null != val && fn) val = fn(val); + + // unassigned or bool + if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) { + // if no value, bool true, and we have a default, then use it! + if (null == val) { + self[name] = option.bool + ? defaultValue || true + : false; + } else { + self[name] = val; + } + } else if (null !== val) { + // reassign + self[name] = val; + } + }); + + return this; +}; + +/** + * Parse `argv`, settings options and invoking commands when defined. + * + * @param {Array} argv + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parse = function(argv){ + // store raw args + this.rawArgs = argv; + + // guess name + if (!this.name) this.name = basename(argv[1]); + + // process argv + var parsed = this.parseOptions(this.normalize(argv.slice(2))); + this.args = parsed.args; + return this.parseArgs(this.args, parsed.unknown); +}; + +/** + * Normalize `args`, splitting joined short flags. For example + * the arg "-abc" is equivalent to "-a -b -c". + * + * @param {Array} args + * @return {Array} + * @api private + */ + +Command.prototype.normalize = function(args){ + var ret = [] + , arg; + + for (var i = 0, len = args.length; i < len; ++i) { + arg = args[i]; + if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) { + arg.slice(1).split('').forEach(function(c){ + ret.push('-' + c); + }); + } else { + ret.push(arg); + } + } + + return ret; +}; + +/** + * Parse command `args`. + * + * When listener(s) are available those + * callbacks are invoked, otherwise the "*" + * event is emitted and those actions are invoked. + * + * @param {Array} args + * @return {Command} for chaining + * @api private + */ + +Command.prototype.parseArgs = function(args, unknown){ + var cmds = this.commands + , len = cmds.length + , name; + + if (args.length) { + name = args[0]; + if (this.listeners(name).length) { + this.emit(args.shift(), args, unknown); + } else { + this.emit('*', args); + } + } else { + outputHelpIfNecessary(this, unknown); + + // If there were no args and we have unknown options, + // then they are extraneous and we need to error. + if (unknown.length > 0) { + this.unknownOption(unknown[0]); + } + } + + return this; +}; + +/** + * Return an option matching `arg` if any. + * + * @param {String} arg + * @return {Option} + * @api private + */ + +Command.prototype.optionFor = function(arg){ + for (var i = 0, len = this.options.length; i < len; ++i) { + if (this.options[i].is(arg)) { + return this.options[i]; + } + } +}; + +/** + * Parse options from `argv` returning `argv` + * void of these options. + * + * @param {Array} argv + * @return {Array} + * @api public + */ + +Command.prototype.parseOptions = function(argv){ + var args = [] + , len = argv.length + , literal + , option + , arg; + + var unknownOptions = []; + + // parse options + for (var i = 0; i < len; ++i) { + arg = argv[i]; + + // literal args after -- + if ('--' == arg) { + literal = true; + continue; + } + + if (literal) { + args.push(arg); + continue; + } + + // find matching Option + option = this.optionFor(arg); + + // option is defined + if (option) { + // requires arg + if (option.required) { + arg = argv[++i]; + if (null == arg) return this.optionMissingArgument(option); + if ('-' == arg[0]) return this.optionMissingArgument(option, arg); + this.emit(option.name(), arg); + // optional arg + } else if (option.optional) { + arg = argv[i+1]; + if (null == arg || '-' == arg[0]) { + arg = null; + } else { + ++i; + } + this.emit(option.name(), arg); + // bool + } else { + this.emit(option.name()); + } + continue; + } + + // looks like an option + if (arg.length > 1 && '-' == arg[0]) { + unknownOptions.push(arg); + + // If the next argument looks like it might be + // an argument for this option, we pass it on. + // If it isn't, then it'll simply be ignored + if (argv[i+1] && '-' != argv[i+1][0]) { + unknownOptions.push(argv[++i]); + } + continue; + } + + // arg + args.push(arg); + } + + return { args: args, unknown: unknownOptions }; +}; + +/** + * Argument `name` is missing. + * + * @param {String} name + * @api private + */ + +Command.prototype.missingArgument = function(name){ + console.error(); + console.error(" error: missing required argument `%s'", name); + console.error(); + process.exit(1); +}; + +/** + * `Option` is missing an argument, but received `flag` or nothing. + * + * @param {String} option + * @param {String} flag + * @api private + */ + +Command.prototype.optionMissingArgument = function(option, flag){ + console.error(); + if (flag) { + console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag); + } else { + console.error(" error: option `%s' argument missing", option.flags); + } + console.error(); + process.exit(1); +}; + +/** + * Unknown option `flag`. + * + * @param {String} flag + * @api private + */ + +Command.prototype.unknownOption = function(flag){ + console.error(); + console.error(" error: unknown option `%s'", flag); + console.error(); + process.exit(1); +}; + +/** + * Set the program version to `str`. + * + * This method auto-registers the "-V, --version" flag + * which will print the version number when passed. + * + * @param {String} str + * @param {String} flags + * @return {Command} for chaining + * @api public + */ + +Command.prototype.version = function(str, flags){ + if (0 == arguments.length) return this._version; + this._version = str; + flags = flags || '-V, --version'; + this.option(flags, 'output the version number'); + this.on('version', function(){ + console.log(str); + process.exit(0); + }); + return this; +}; + +/** + * Set the description `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.description = function(str){ + if (0 == arguments.length) return this._description; + this._description = str; + return this; +}; + +/** + * Set / get the command usage `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.usage = function(str){ + var args = this.args.map(function(arg){ + return arg.required + ? '<' + arg.name + '>' + : '[' + arg.name + ']'; + }); + + var usage = '[options' + + (this.commands.length ? '] [command' : '') + + ']' + + (this.args.length ? ' ' + args : ''); + if (0 == arguments.length) return this._usage || usage; + this._usage = str; + + return this; +}; + +/** + * Return the largest option length. + * + * @return {Number} + * @api private + */ + +Command.prototype.largestOptionLength = function(){ + return this.options.reduce(function(max, option){ + return Math.max(max, option.flags.length); + }, 0); +}; + +/** + * Return help for options. + * + * @return {String} + * @api private + */ + +Command.prototype.optionHelp = function(){ + var width = this.largestOptionLength(); + + // Prepend the help information + return [pad('-h, --help', width) + ' ' + 'output usage information'] + .concat(this.options.map(function(option){ + return pad(option.flags, width) + + ' ' + option.description; + })) + .join('\n'); +}; + +/** + * Return command help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.commandHelp = function(){ + if (!this.commands.length) return ''; + return [ + '' + , ' Commands:' + , '' + , this.commands.map(function(cmd){ + var args = cmd.args.map(function(arg){ + return arg.required + ? '<' + arg.name + '>' + : '[' + arg.name + ']'; + }).join(' '); + + return cmd.name + + (cmd.options.length + ? ' [options]' + : '') + ' ' + args + + (cmd.description() + ? '\n' + cmd.description() + : ''); + }).join('\n\n').replace(/^/gm, ' ') + , '' + ].join('\n'); +}; + +/** + * Return program help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.helpInformation = function(){ + return [ + '' + , ' Usage: ' + this.name + ' ' + this.usage() + , '' + this.commandHelp() + , ' Options:' + , '' + , '' + this.optionHelp().replace(/^/gm, ' ') + , '' + , '' + ].join('\n'); +}; + +/** + * Prompt for a `Number`. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptForNumber = function(str, fn){ + var self = this; + this.promptSingleLine(str, function parseNumber(val){ + val = Number(val); + if (isNaN(val)) return self.promptSingleLine(str + '(must be a number) ', parseNumber); + fn(val); + }); +}; + +/** + * Prompt for a `Date`. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptForDate = function(str, fn){ + var self = this; + this.promptSingleLine(str, function parseDate(val){ + val = new Date(val); + if (isNaN(val.getTime())) return self.promptSingleLine(str + '(must be a date) ', parseDate); + fn(val); + }); +}; + +/** + * Single-line prompt. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptSingleLine = function(str, fn){ + if ('function' == typeof arguments[2]) { + return this['promptFor' + (fn.name || fn)](str, arguments[2]); + } + + process.stdout.write(str); + process.stdin.setEncoding('utf8'); + process.stdin.once('data', function(val){ + fn(val.trim()); + }).resume(); +}; + +/** + * Multi-line prompt. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptMultiLine = function(str, fn){ + var buf = []; + console.log(str); + process.stdin.setEncoding('utf8'); + process.stdin.on('data', function(val){ + if ('\n' == val || '\r\n' == val) { + process.stdin.removeAllListeners('data'); + fn(buf.join('\n')); + } else { + buf.push(val.trimRight()); + } + }).resume(); +}; + +/** + * Prompt `str` and callback `fn(val)` + * + * Commander supports single-line and multi-line prompts. + * To issue a single-line prompt simply add white-space + * to the end of `str`, something like "name: ", whereas + * for a multi-line prompt omit this "description:". + * + * + * Examples: + * + * program.prompt('Username: ', function(name){ + * console.log('hi %s', name); + * }); + * + * program.prompt('Description:', function(desc){ + * console.log('description was "%s"', desc.trim()); + * }); + * + * @param {String|Object} str + * @param {Function} fn + * @api public + */ + +Command.prototype.prompt = function(str, fn){ + var self = this; + + if ('string' == typeof str) { + if (/ $/.test(str)) return this.promptSingleLine.apply(this, arguments); + this.promptMultiLine(str, fn); + } else { + var keys = Object.keys(str) + , obj = {}; + + function next() { + var key = keys.shift() + , label = str[key]; + + if (!key) return fn(obj); + self.prompt(label, function(val){ + obj[key] = val; + next(); + }); + } + + next(); + } +}; + +/** + * Prompt for password with `str`, `mask` char and callback `fn(val)`. + * + * The mask string defaults to '', aka no output is + * written while typing, you may want to use "*" etc. + * + * Examples: + * + * program.password('Password: ', function(pass){ + * console.log('got "%s"', pass); + * process.stdin.destroy(); + * }); + * + * program.password('Password: ', '*', function(pass){ + * console.log('got "%s"', pass); + * process.stdin.destroy(); + * }); + * + * @param {String} str + * @param {String} mask + * @param {Function} fn + * @api public + */ + +Command.prototype.password = function(str, mask, fn){ + var self = this + , buf = ''; + + // default mask + if ('function' == typeof mask) { + fn = mask; + mask = ''; + } + + process.stdin.resume(); + tty.setRawMode(true); + process.stdout.write(str); + + // keypress + process.stdin.on('keypress', function(c, key){ + if (key && 'enter' == key.name) { + console.log(); + process.stdin.removeAllListeners('keypress'); + tty.setRawMode(false); + if (!buf.trim().length) return self.password(str, mask, fn); + fn(buf); + return; + } + + if (key && key.ctrl && 'c' == key.name) { + console.log('%s', buf); + process.exit(); + } + + process.stdout.write(mask); + buf += c; + }).resume(); +}; + +/** + * Confirmation prompt with `str` and callback `fn(bool)` + * + * Examples: + * + * program.confirm('continue? ', function(ok){ + * console.log(' got %j', ok); + * process.stdin.destroy(); + * }); + * + * @param {String} str + * @param {Function} fn + * @api public + */ + + +Command.prototype.confirm = function(str, fn, verbose){ + var self = this; + this.prompt(str, function(ok){ + if (!ok.trim()) { + if (!verbose) str += '(yes or no) '; + return self.confirm(str, fn, true); + } + fn(parseBool(ok)); + }); +}; + +/** + * Choice prompt with `list` of items and callback `fn(index, item)` + * + * Examples: + * + * var list = ['tobi', 'loki', 'jane', 'manny', 'luna']; + * + * console.log('Choose the coolest pet:'); + * program.choose(list, function(i){ + * console.log('you chose %d "%s"', i, list[i]); + * process.stdin.destroy(); + * }); + * + * @param {Array} list + * @param {Number|Function} index or fn + * @param {Function} fn + * @api public + */ + +Command.prototype.choose = function(list, index, fn){ + var self = this + , hasDefault = 'number' == typeof index; + + if (!hasDefault) { + fn = index; + index = null; + } + + list.forEach(function(item, i){ + if (hasDefault && i == index) { + console.log('* %d) %s', i + 1, item); + } else { + console.log(' %d) %s', i + 1, item); + } + }); + + function again() { + self.prompt(' : ', function(val){ + val = parseInt(val, 10) - 1; + if (hasDefault && isNaN(val)) val = index; + + if (null == list[val]) { + again(); + } else { + fn(val, list[val]); + } + }); + } + + again(); +}; + +/** + * Camel-case the given `flag` + * + * @param {String} flag + * @return {String} + * @api private + */ + +function camelcase(flag) { + return flag.split('-').reduce(function(str, word){ + return str + word[0].toUpperCase() + word.slice(1); + }); +} + +/** + * Parse a boolean `str`. + * + * @param {String} str + * @return {Boolean} + * @api private + */ + +function parseBool(str) { + return /^y|yes|ok|true$/i.test(str); +} + +/** + * Pad `str` to `width`. + * + * @param {String} str + * @param {Number} width + * @return {String} + * @api private + */ + +function pad(str, width) { + var len = Math.max(0, width - str.length); + return str + Array(len + 1).join(' '); +} + +/** + * Output help information if necessary + * + * @param {Command} command to output help for + * @param {Array} array of options to search for -h or --help + * @api private + */ + +function outputHelpIfNecessary(cmd, options) { + options = options || []; + for (var i = 0; i < options.length; i++) { + if (options[i] == '--help' || options[i] == '-h') { + process.stdout.write(cmd.helpInformation()); + cmd.emit('--help'); + process.exit(0); + } + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/package.json new file mode 100644 index 00000000000..bb8a2c28e92 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/commander/package.json @@ -0,0 +1,38 @@ +{ + "name": "commander", + "version": "0.6.1", + "description": "the complete solution for node.js command-line programs", + "keywords": [ + "command", + "option", + "parser", + "prompt", + "stdin" + ], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "repository": { + "type": "git", + "url": "https://github.com/visionmedia/commander.js.git" + }, + "dependencies": {}, + "devDependencies": { + "should": ">= 0.0.1" + }, + "scripts": { + "test": "make test" + }, + "main": "index", + "engines": { + "node": ">= 0.4.x" + }, + "readme": "# Commander.js\n\n The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander).\n\n [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js)\n\n## Installation\n\n $ npm install commander\n\n## Option parsing\n\n Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.\n\n```js\n#!/usr/bin/env node\n\n/**\n * Module dependencies.\n */\n\nvar program = require('commander');\n\nprogram\n .version('0.0.1')\n .option('-p, --peppers', 'Add peppers')\n .option('-P, --pineapple', 'Add pineapple')\n .option('-b, --bbq', 'Add bbq sauce')\n .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')\n .parse(process.argv);\n\nconsole.log('you ordered a pizza with:');\nif (program.peppers) console.log(' - peppers');\nif (program.pineapple) console.log(' - pineappe');\nif (program.bbq) console.log(' - bbq');\nconsole.log(' - %s cheese', program.cheese);\n```\n\n Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as \"--template-engine\" are camel-cased, becoming `program.templateEngine` etc.\n\n## Automated --help\n\n The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:\n\n``` \n $ ./examples/pizza --help\n\n Usage: pizza [options]\n\n Options:\n\n -V, --version output the version number\n -p, --peppers Add peppers\n -P, --pineapple Add pineappe\n -b, --bbq Add bbq sauce\n -c, --cheese Add the specified type of cheese [marble]\n -h, --help output usage information\n\n```\n\n## Coercion\n\n```js\nfunction range(val) {\n return val.split('..').map(Number);\n}\n\nfunction list(val) {\n return val.split(',');\n}\n\nprogram\n .version('0.0.1')\n .usage('[options] ')\n .option('-i, --integer ', 'An integer argument', parseInt)\n .option('-f, --float ', 'A float argument', parseFloat)\n .option('-r, --range ..', 'A range', range)\n .option('-l, --list ', 'A list', list)\n .option('-o, --optional [value]', 'An optional value')\n .parse(process.argv);\n\nconsole.log(' int: %j', program.integer);\nconsole.log(' float: %j', program.float);\nconsole.log(' optional: %j', program.optional);\nprogram.range = program.range || [];\nconsole.log(' range: %j..%j', program.range[0], program.range[1]);\nconsole.log(' list: %j', program.list);\nconsole.log(' args: %j', program.args);\n```\n\n## Custom help\n\n You can display arbitrary `-h, --help` information\n by listening for \"--help\". Commander will automatically\n exit once you are done so that the remainder of your program\n does not execute causing undesired behaviours, for example\n in the following executable \"stuff\" will not output when\n `--help` is used.\n\n```js\n#!/usr/bin/env node\n\n/**\n * Module dependencies.\n */\n\nvar program = require('../');\n\nfunction list(val) {\n return val.split(',').map(Number);\n}\n\nprogram\n .version('0.0.1')\n .option('-f, --foo', 'enable some foo')\n .option('-b, --bar', 'enable some bar')\n .option('-B, --baz', 'enable some baz');\n\n// must be before .parse() since\n// node's emit() is immediate\n\nprogram.on('--help', function(){\n console.log(' Examples:');\n console.log('');\n console.log(' $ custom-help --help');\n console.log(' $ custom-help -h');\n console.log('');\n});\n\nprogram.parse(process.argv);\n\nconsole.log('stuff');\n```\n\nyielding the following help output:\n\n```\n\nUsage: custom-help [options]\n\nOptions:\n\n -h, --help output usage information\n -V, --version output the version number\n -f, --foo enable some foo\n -b, --bar enable some bar\n -B, --baz enable some baz\n\nExamples:\n\n $ custom-help --help\n $ custom-help -h\n\n```\n\n## .prompt(msg, fn)\n\n Single-line prompt:\n\n```js\nprogram.prompt('name: ', function(name){\n console.log('hi %s', name);\n});\n```\n\n Multi-line prompt:\n\n```js\nprogram.prompt('description:', function(name){\n console.log('hi %s', name);\n});\n```\n\n Coercion:\n\n```js\nprogram.prompt('Age: ', Number, function(age){\n console.log('age: %j', age);\n});\n```\n\n```js\nprogram.prompt('Birthdate: ', Date, function(date){\n console.log('date: %s', date);\n});\n```\n\n## .password(msg[, mask], fn)\n\nPrompt for password without echoing:\n\n```js\nprogram.password('Password: ', function(pass){\n console.log('got \"%s\"', pass);\n process.stdin.destroy();\n});\n```\n\nPrompt for password with mask char \"*\":\n\n```js\nprogram.password('Password: ', '*', function(pass){\n console.log('got \"%s\"', pass);\n process.stdin.destroy();\n});\n```\n\n## .confirm(msg, fn)\n\n Confirm with the given `msg`:\n\n```js\nprogram.confirm('continue? ', function(ok){\n console.log(' got %j', ok);\n});\n```\n\n## .choose(list, fn)\n\n Let the user choose from a `list`:\n\n```js\nvar list = ['tobi', 'loki', 'jane', 'manny', 'luna'];\n\nconsole.log('Choose the coolest pet:');\nprogram.choose(list, function(i){\n console.log('you chose %d \"%s\"', i, list[i]);\n});\n```\n\n## Links\n\n - [API documentation](http://visionmedia.github.com/commander.js/)\n - [ascii tables](https://github.com/LearnBoost/cli-table)\n - [progress bars](https://github.com/visionmedia/node-progress)\n - [more progress bars](https://github.com/substack/node-multimeter)\n - [examples](https://github.com/visionmedia/commander.js/tree/master/examples)\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/visionmedia/commander.js/issues" + }, + "_id": "commander@0.6.1", + "_from": "commander@~0.6.1" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/.index.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/.index.js new file mode 100644 index 00000000000..68da1f34383 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/.index.js @@ -0,0 +1 @@ +//noop \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/LICENSE b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/LICENSE new file mode 100644 index 00000000000..352c2874542 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/LICENSE @@ -0,0 +1,43 @@ +Copyright 2013, NAN contributors: + - Rod Vagg + - Benjamin Byholm + - Trevor Norris +(the "Original Author") +All rights reserved. + +MIT +no-false-attribs License + +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. + +Distributions of all or part of the Software intended to be used +by the recipients as they would use the unmodified Software, +containing modifications that substantially alter, remove, or +disable functionality of the Software, outside of the documented +configuration mechanisms provided by the Software, shall be +modified such that the Original Author's bug reporting email +addresses and urls are either replaced with the contact information +of the parties responsible for the changes, or removed entirely. + +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. + + +Except where noted, this license applies to any and all software +programs and associated documentation files created by the +Original Author, when distributed with the Software. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/README.md new file mode 100644 index 00000000000..6ba57f7893a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/README.md @@ -0,0 +1,705 @@ +Native Abstractions for Node.js +=============================== + +**A header file filled with macro and utility goodness for making addon development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.** + +***Current version: 0.3.2*** *(See [nan.h](https://github.com/rvagg/nan/blob/master/nan.h) for changelog)* + +[![NPM](https://nodei.co/npm/nan.png?downloads=true&stars=true)](https://nodei.co/npm/nan/) [![NPM](https://nodei.co/npm-dl/nan.png?months=6)](https://nodei.co/npm/nan/) + +Thanks to the crazy changes in V8 (and some in Node core), keeping native addons compiling happily across versions, particularly 0.10 to 0.11/0.12, is a minor nightmare. The goal of this project is to store all logic necessary to develop native Node.js addons without having to inspect `NODE_MODULE_VERSION` and get yourself into a macro-tangle. + +This project also contains some helper utilities that make addon development a bit more pleasant. + + * **[Usage](#usage)** + * **[Example](#example)** + * **[API](#api)** + + +## Usage + +Simply add **NAN** as a dependency in the *package.json* of your Node addon: + +```js +"dependencies": { + ... + "nan" : "~0.3.1" + ... +} +``` + +Pull in the path to **NAN** in your *binding.gyp* so that you can use `#include "nan.h"` in your *.cpp*: + +```js +"include_dirs" : [ + ... + "` when compiling your addon. + + +## Example + +See **[LevelDOWN](https://github.com/rvagg/node-leveldown/pull/48)** for a full example of **NAN** in use. + +For a simpler example, see the **[async pi estimation example](https://github.com/rvagg/nan/tree/master/examples/async_pi_estimate)** in the examples directory for full code and an explanation of what this Monte Carlo Pi estimation example does. Below are just some parts of the full example that illustrate the use of **NAN**. + +Compare to the current 0.10 version of this example, found in the [node-addon-examples](https://github.com/rvagg/node-addon-examples/tree/master/9_async_work) repository and also a 0.11 version of the same found [here](https://github.com/kkoopa/node-addon-examples/tree/5c01f58fc993377a567812597e54a83af69686d7/9_async_work). + +Note that there is no embedded version sniffing going on here and also the async work is made much simpler, see below for details on the `NanAsyncWorker` class. + +```c++ +// addon.cc +#include +#include "nan.h" +// ... + +using namespace v8; + +void InitAll(Handle exports) { + exports->Set(NanSymbol("calculateSync"), + FunctionTemplate::New(CalculateSync)->GetFunction()); + + exports->Set(NanSymbol("calculateAsync"), + FunctionTemplate::New(CalculateAsync)->GetFunction()); +} + +NODE_MODULE(addon, InitAll) +``` + +```c++ +// sync.h +#include +#include "nan.h" + +NAN_METHOD(CalculateSync); +``` + +```c++ +// sync.cc +#include +#include "nan.h" +#include "sync.h" +// ... + +using namespace v8; + +// Simple synchronous access to the `Estimate()` function +NAN_METHOD(CalculateSync) { + NanScope(); + + // expect a number as the first argument + int points = args[0]->Uint32Value(); + double est = Estimate(points); + + NanReturnValue(Number::New(est)); +} +``` + +```c++ +// async.cc +#include +#include "nan.h" +#include "async.h" + +// ... + +using namespace v8; + +class PiWorker : public NanAsyncWorker { + public: + PiWorker(NanCallback *callback, int points) + : NanAsyncWorker(callback), points(points) {} + ~PiWorker() {} + + // Executed inside the worker-thread. + // It is not safe to access V8, or V8 data structures + // here, so everything we need for input and output + // should go on `this`. + void Execute () { + estimate = Estimate(points); + } + + // Executed when the async work is complete + // this function will be run inside the main event loop + // so it is safe to use V8 again + void HandleOKCallback () { + NanScope(); + + Local argv[] = { + Local::New(Null()) + , Number::New(estimate) + }; + + callback->Call(2, argv); + }; + + private: + int points; + double estimate; +}; + +// Asynchronous access to the `Estimate()` function +NAN_METHOD(CalculateAsync) { + NanScope(); + + int points = args[0]->Uint32Value(); + NanCallback *callback = new NanCallback(args[1].As()); + + NanAsyncQueueWorker(new PiWorker(callback, points)); + NanReturnUndefined(); +} +``` + + +## API + + * NAN_METHOD + * NAN_GETTER + * NAN_SETTER + * NAN_PROPERTY_GETTER + * NAN_PROPERTY_SETTER + * NAN_PROPERTY_ENUMERATOR + * NAN_PROPERTY_DELETER + * NAN_PROPERTY_QUERY + * NAN_WEAK_CALLBACK + * NanReturnValue + * NanReturnUndefined + * NanReturnNull + * NanReturnEmptyString + * NanScope + * NanLocker + * NanUnlocker + * NanGetInternalFieldPointer + * NanSetInternalFieldPointer + * NanObjectWrapHandle + * NanMakeWeak + * NanSymbol + * NanGetPointerSafe + * NanSetPointerSafe + * NanFromV8String + * NanBooleanOptionValue + * NanUInt32OptionValue + * NanThrowError, NanThrowTypeError, NanThrowRangeError, NanThrowError(Handle), NanThrowError(Handle, int) + * NanNewBufferHandle(char *, size_t, FreeCallback, void *), NanNewBufferHandle(char *, uint32_t), NanNewBufferHandle(uint32_t) + * NanBufferUse(char *, uint32_t) + * NanNewContextHandle + * NanHasInstance + * NanPersistentToLocal + * NanDispose + * NanAssignPersistent + * NanInitPersistent + * NanCallback + * NanAsyncWorker + * NanAsyncQueueWorker + + +### NAN_METHOD(methodname) + +Use `NAN_METHOD` to define your V8 accessible methods: + +```c++ +// .h: +class Foo : public node::ObjectWrap { + ... + + static NAN_METHOD(Bar); + static NAN_METHOD(Baz); +} + + +// .cc: +NAN_METHOD(Foo::Bar) { + ... +} + +NAN_METHOD(Foo::Baz) { + ... +} +``` + +The reason for this macro is because of the method signature change in 0.11: + +```c++ +// 0.10 and below: +Handle name(const Arguments& args) + +// 0.11 and above +void name(const FunctionCallbackInfo& args) +``` + +The introduction of `FunctionCallbackInfo` brings additional complications: + + +### NAN_GETTER(methodname) + +Use `NAN_GETTER` to declare your V8 accessible getters. You get a `Local` `property` and an appropriately typed `args` object that can act like the `args` argument to a `NAN_METHOD` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_GETTER`. + + +### NAN_SETTER(methodname) + +Use `NAN_SETTER` to declare your V8 accessible setters. Same as `NAN_GETTER` but you also get a `Local` `value` object to work with. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_SETTER`. + + +### NAN_PROPERTY_GETTER(cbname) +Use `NAN_PROPERTY_GETTER` to declare your V8 accessible property getters. You get a `Local` `property` and an appropriately typed `args` object that can act similar to the `args` argument to a `NAN_METHOD` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_GETTER`. + + +### NAN_PROPERTY_SETTER(cbname) +Use `NAN_PROPERTY_SETTER` to declare your V8 accessible property setters. Same as `NAN_PROPERTY_GETTER` but you also get a `Local` `value` object to work with. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_SETTER`. + + +### NAN_PROPERTY_ENUMERATOR(cbname) +Use `NAN_PROPERTY_ENUMERATOR` to declare your V8 accessible property enumerators. You get an appropriately typed `args` object like the `args` argument to a `NAN_PROPERTY_GETTER` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_ENUMERATOR`. + + +### NAN_PROPERTY_DELETER(cbname) +Use `NAN_PROPERTY_DELETER` to declare your V8 accessible property deleters. Same as `NAN_PROPERTY_GETTER`. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_DELETER`. + + +### NAN_PROPERTY_QUERY(cbname) +Use `NAN_PROPERTY_QUERY` to declare your V8 accessible property queries. Same as `NAN_PROPERTY_GETTER`. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_QUERY`. + + +### NAN_WEAK_CALLBACK(type, cbname) + +Use `NAN_WEAK_CALLBACK` to declare your V8 WeakReference callbacks. There is an object argument accessible through `NAN_WEAK_CALLBACK_OBJECT`. The `type` argument gives the type of the `data` argument, accessible through `NAN_WEAK_CALLBACK_DATA(type)`. + +```c++ +static NAN_WEAK_CALLBACK(BufferReference*, WeakCheck) { + if (NAN_WEAK_CALLBACK_DATA(BufferReference*)->noLongerNeeded_) { + delete NAN_WEAK_CALLBACK_DATA(BufferReference*); + } else { + // Still in use, revive, prevent GC + NanMakeWeak(NAN_WEAK_CALLBACK_OBJECT, NAN_WEAK_CALLBACK_DATA(BufferReference*), &WeakCheck); + } +} + +``` + +### NanReturnValue(Handle<Value>) + +Use `NanReturnValue` when you want to return a value from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Bar) { + ... + + NanReturnValue(String::New("FooBar!")); +} +``` + +No `return` statement required. + + +### NanReturnUndefined() + +Use `NanReturnUndefined` when you don't want to return anything from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Baz) { + ... + + NanReturnUndefined(); +} +``` + + +### NanReturnNull() + +Use `NanReturnNull` when you want to return `Null` from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Baz) { + ... + + NanReturnNull(); +} +``` + + +### NanReturnEmptyString() + +Use `NanReturnEmptyString` when you want to return an empty `String` from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Baz) { + ... + + NanReturnEmptyString(); +} +``` + + +### NanScope() + +The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanScope()` necessary, use it in place of `HandleScope scope`: + +```c++ +NAN_METHOD(Foo::Bar) { + NanScope(); + + NanReturnValue(String::New("FooBar!")); +} +``` + + +### NanLocker() + +The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanLocker()` necessary, use it in place of `Locker locker`: + +```c++ +NAN_METHOD(Foo::Bar) { + NanLocker(); + ... + NanUnlocker(); +} +``` + + +### NanUnlocker() + +The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanUnlocker()` necessary, use it in place of `Unlocker unlocker`: + +```c++ +NAN_METHOD(Foo::Bar) { + NanLocker(); + ... + NanUnlocker(); +} +``` + + +### void * NanGetInternalFieldPointer(Handle<Object>, int) + +Gets a pointer to the internal field with at `index` from a V8 `Object` handle. + +```c++ +Local obj; +... +NanGetInternalFieldPointer(obj, 0); +``` + +### void NanSetInternalFieldPointer(Handle<Object>, int, void *) + +Sets the value of the internal field at `index` on a V8 `Object` handle. + +```c++ +static Persistent dataWrapperCtor; +... +Local wrapper = NanPersistentToLocal(dataWrapperCtor)->NewInstance(); +NanSetInternalFieldPointer(wrapper, 0, this); +``` + + +### Local<Object> NanObjectWrapHandle(Object) + +When you want to fetch the V8 object handle from a native object you've wrapped with Node's `ObjectWrap`, you should use `NanObjectWrapHandle`: + +```c++ +NanObjectWrapHandle(iterator)->Get(String::NewSymbol("end")) +``` + + +### NanMakeWeak(Persistent<T>, parameter, callback) + +Make a persistent reference weak. + + +### String NanSymbol(char *) + +This isn't strictly about compatibility, it's just an easier way to create string symbol objects (i.e. `String::NewSymbol(x)`), for getting and setting object properties, or names of objects. + +```c++ +bool foo = false; +if (obj->Has(NanSymbol("foo"))) + foo = optionsObj->Get(NanSymbol("foo"))->BooleanValue() +``` + + +### Type NanGetPointerSafe(Type *[, Type]) + +A helper for getting values from optional pointers. If the pointer is `NULL`, the function returns the optional default value, which defaults to `0`. Otherwise, the function returns the value the pointer points to. + +```c++ +char *plugh(uint32_t *optional) { + char res[] = "xyzzy"; + uint32_t param = NanGetPointerSafe(optional, 0x1337); + switch (param) { + ... + } + NanSetPointerSafe(optional, 0xDEADBEEF); +} +``` + + +### bool NanSetPointerSafe(Type *, Type) + +A helper for setting optional argument pointers. If the pointer is `NULL`, the function simply return `false`. Otherwise, the value is assigned to the variable the pointer points to. + +```c++ +const char *plugh(size_t *outputsize) { + char res[] = "xyzzy"; + if !(NanSetPointerSafe(outputsize, strlen(res) + 1)) { + ... + } + + ... +} +``` + + +### char* NanFromV8String(Handle<Value>[, enum Nan::Encoding, size_t *, char *, size_t, int]) + +When you want to convert a V8 `String` to a `char*` use `NanFromV8String`. It is possible to define an encoding that defaults to `Nan::UTF8` as well as a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows optionally setting `String::WriteOptions`, which default to `String::HINT_MANY_WRITES_EXPECTED | String::NO_NULL_TERMINATION`. +Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer: + +```c++ +size_t count; +char* name = NanFromV8String(args[0]); +char* decoded = NanFromV8String(args[1], Nan::BASE64, &count, NULL, 0, String::HINT_MANY_WRITES_EXPECTED); +char param_copy[count]; +memcpy(param_copy, decoded, count); +delete[] decoded; +``` + + +### bool NanBooleanOptionValue(Handle<Value>, Handle<String>[, bool]) + +When you have an "options" object that you need to fetch properties from, boolean options can be fetched with this pair. They check first if the object exists (`IsEmpty`), then if the object has the given property (`Has`) then they get and convert/coerce the property to a `bool`. + +The optional last parameter is the *default* value, which is `false` if left off: + +```c++ +// `foo` is false unless the user supplies a truthy value for it +bool foo = NanBooleanOptionValue(optionsObj, NanSymbol("foo")); +// `bar` is true unless the user supplies a falsy value for it +bool bar = NanBooleanOptionValueDefTrue(optionsObj, NanSymbol("bar"), true); +``` + + +### uint32_t NanUInt32OptionValue(Handle<Value>, Handle<String>, uint32_t) + +Similar to `NanBooleanOptionValue`, use `NanUInt32OptionValue` to fetch an integer option from your options object. Can be any kind of JavaScript `Number` and it will be coerced to an unsigned 32-bit integer. + +Requires all 3 arguments as a default is not optional: + +```c++ +uint32_t count = NanUInt32OptionValue(optionsObj, NanSymbol("count"), 1024); +``` + + +### NanThrowError(message), NanThrowTypeError(message), NanThrowRangeError(message), NanThrowError(Local<Value>), NanThrowError(Local<Value>, int) + +For throwing `Error`, `TypeError` and `RangeError` objects. You should `return` this call: + +```c++ +return NanThrowError("you must supply a callback argument"); +``` + +Can also handle any custom object you may want to throw. If used with the error code argument, it will add the supplied error code to the error object as a property called `code`. + + +### Local<Object> NanNewBufferHandle(char *, uint32_t), Local<Object> NanNewBufferHandle(uint32_t) + +The `Buffer` API has changed a little in Node 0.11, this helper provides consistent access to `Buffer` creation: + +```c++ +NanNewBufferHandle((char*)value.data(), value.size()); +``` + +Can also be used to initialize a `Buffer` with just a `size` argument. + +Can also be supplied with a `NAN_WEAK_CALLBACK` and a hint for the garbage collector, when dealing with weak references. + + +### Local<Object> NanBufferUse(char*, uint32_t) + +`Buffer::New(char*, uint32_t)` prior to 0.11 would make a copy of the data. +While it was possible to get around this, it required a shim by passing a +callback. So the new API `Buffer::Use(char*, uint32_t)` was introduced to remove +needing to use this shim. + +`NanBufferUse` uses the `char*` passed as the backing data, and will free the +memory automatically when the weak callback is called. Keep this in mind, as +careless use can lead to "double free or corruption" and other cryptic failures. + + +### bool NanHasInstance(Persistent<FunctionTemplate>&, Handle<Value>) + +Can be used to check the type of an object to determine it is of a particular class you have already defined and have a `Persistent` handle for. + + +### Local<Type> NanPersistentToLocal(Persistent<Type>&) + +Aside from `FunctionCallbackInfo`, the biggest and most painful change to V8 in Node 0.11 is the many restrictions now placed on `Persistent` handles. They are difficult to assign and difficult to fetch the original value out of. + +Use `NanPersistentToLocal` to convert a `Persistent` handle back to a `Local` handle. + +```c++ +Local handle = NanPersistentToLocal(persistentHandle); +``` + + +### Local<Context> NanNewContextHandle([ExtensionConfiguration*, Handle<ObjectTemplate>, Handle<Value>]) +Creates a new `Local` handle. + +```c++ +Local ftmpl = FunctionTemplate::New(); +Local otmpl = ftmpl->InstanceTemplate(); +Local ctx = NanNewContextHandle(NULL, otmpl); +``` + + +### void NanDispose(Persistent<T> &) + +Use `NanDispose` to dispose a `Persistent` handle. + +```c++ +NanDispose(persistentHandle); +``` + + +### NanAssignPersistent(type, handle, object) + +Use `NanAssignPersistent` to assign a non-`Persistent` handle to a `Persistent` one. You can no longer just declare a `Persistent` handle and assign directly to it later, you have to `Reset` it in Node 0.11, so this makes it easier. + +In general it is now better to place anything you want to protect from V8's garbage collector as properties of a generic `Object` and then assign that to a `Persistent`. This works in older versions of Node also if you use `NanAssignPersistent`: + +```c++ +Persistent persistentHandle; + +... + +Local obj = Object::New(); +obj->Set(NanSymbol("key"), keyHandle); // where keyHandle might be a Local +NanAssignPersistent(Object, persistentHandle, obj) +``` + + +### NanInitPersistent(type, name, object) + +User `NanInitPersistent` to declare and initialize a new `Persistent` with the supplied object. The assignment operator for `Persistent` is no longer public in Node 0.11, so this macro makes it easier to declare and initializing a new `Persistent`. See NanAssignPersistent for more information. + +```c++ +Local obj = Object::New(); +obj->Set(NanSymbol("key"), keyHandle); // where keyHandle might be a Local +NanInitPersistent(Object, persistentHandle, obj); +``` + + +### NanCallback + +Because of the difficulties imposed by the changes to `Persistent` handles in V8 in Node 0.11, creating `Persistent` versions of your `Local` handles is annoyingly tricky. `NanCallback` makes it easier by taking your `Local` handle, making it persistent until the `NanCallback` is deleted and even providing a handy `Call()` method to fetch and execute the callback `Function`. + +```c++ +Local callbackHandle = callback = args[0].As(); +NanCallback *callback = new NanCallback(callbackHandle); +// pass `callback` around and it's safe from GC until you: +delete callback; +``` + +You can execute the callback like so: + +```c++ +// no arguments: +callback->Call(0, NULL); + +// an error argument: +Local argv[] = { + Exception::Error(String::New("fail!")) +}; +callback->Call(1, argv); + +// a success argument: +Local argv[] = { + Local::New(Null()), + String::New("w00t!") +}; +callback->Call(2, argv); +``` + +`NanCallback` also has a `Local GetCallback()` method that you can use to fetch a local handle to the underlying callback function if you need it. + + +### NanAsyncWorker + +`NanAsyncWorker` is an abstract class that you can subclass to have much of the annoying async queuing and handling taken care of for you. It can even store arbitrary V8 objects for you and have them persist while the async work is in progress. + +See a rough outline of the implementation: + +```c++ +class NanAsyncWorker { +public: + NanAsyncWorker (NanCallback *callback); + + // Clean up persistent handles and delete the *callback + virtual ~NanAsyncWorker (); + + // Check the `char *errmsg` property and call HandleOKCallback() + // or HandleErrorCallback depending on whether it has been set or not + virtual void WorkComplete (); + + // You must implement this to do some async work. If there is an + // error then allocate `errmsg` to to a message and the callback will + // be passed that string in an Error object + virtual void Execute (); + +protected: + // Set this if there is an error, otherwise it's NULL + const char *errmsg; + + // Save a V8 object in a Persistent handle to protect it from GC + void SavePersistent(const char *key, Local &obj); + + // Fetch a stored V8 object (don't call from within `Execute()`) + Local GetFromPersistent(const char *key); + + // Default implementation calls the callback function with no arguments. + // Override this to return meaningful data + virtual void HandleOKCallback (); + + // Default implementation calls the callback function with an Error object + // wrapping the `errmsg` string + virtual void HandleErrorCallback (); +}; +``` + + +### NanAsyncQueueWorker(NanAsyncWorker *) + +`NanAsyncQueueWorker` will run a `NanAsyncWorker` asynchronously via libuv. Both the *execute* and *after_work* steps are taken care of for you—most of the logic for this is embedded in `NanAsyncWorker`. + +### Contributors + +NAN is only possible due to the excellent work of the following contributors: + + + + + +
    Rod VaggGitHub/rvaggTwitter/@rvagg
    Benjamin ByholmGitHub/kkoopa
    Trevor NorrisGitHub/trevnorrisTwitter/@trevnorris
    + +Licence & copyright +----------------------- + +Copyright (c) 2013 Rod Vagg & NAN contributors (listed above). + +Native Abstractions for Node.js is licensed under an MIT +no-false-attribs license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/nan.h b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/nan.h new file mode 100644 index 00000000000..b3eb02db585 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/nan.h @@ -0,0 +1,884 @@ +/********************************************************************************** + * NAN - Native Abstractions for Node.js + * + * Copyright (c) 2013 NAN contributors: + * - Rod Vagg + * - Benjamin Byholm + * - Trevor Norris + * + * MIT +no-false-attribs License + * + * Version 0.3.2 (current Node unstable: 0.11.6, Node stable: 0.10.17) + * + * ChangeLog: + * * 0.3.2 Aug 30 2013 + * - Fix missing scope declaration in GetFromPersistent() and SaveToPersistent + * in NanAsyncWorker + * + * * 0.3.1 Aug 20 2013 + * - fix "not all control paths return a value" compile warning on some platforms + * + * * 0.3.0 Aug 19 2013 + * - Made NAN work with NPM + * - Lots of fixes to NanFromV8String, pulling in features from new Node core + * - Changed node::encoding to Nan::Encoding in NanFromV8String to unify the API + * - Added optional error number argument for NanThrowError() + * - Added NanInitPersistent() + * - Added NanReturnNull() and NanReturnEmptyString() + * - Added NanLocker and NanUnlocker + * - Added missing scopes + * - Made sure to clear disposed Persistent handles + * - Changed NanAsyncWorker to allocate error messages on the heap + * - Changed NanThrowError(Local) to NanThrowError(Handle) + * - Fixed leak in NanAsyncWorker when errmsg is used + * + * * 0.2.2 Aug 5 2013 + * - Fixed usage of undefined variable with node::BASE64 in NanFromV8String() + * + * * 0.2.1 Aug 5 2013 + * - Fixed 0.8 breakage, node::BUFFER encoding type not available in 0.8 for + * NanFromV8String() + * + * * 0.2.0 Aug 5 2013 + * - Added NAN_PROPERTY_GETTER, NAN_PROPERTY_SETTER, NAN_PROPERTY_ENUMERATOR, + * NAN_PROPERTY_DELETER, NAN_PROPERTY_QUERY + * - Extracted _NAN_METHOD_ARGS, _NAN_GETTER_ARGS, _NAN_SETTER_ARGS, + * _NAN_PROPERTY_GETTER_ARGS, _NAN_PROPERTY_SETTER_ARGS, + * _NAN_PROPERTY_ENUMERATOR_ARGS, _NAN_PROPERTY_DELETER_ARGS, + * _NAN_PROPERTY_QUERY_ARGS + * - Added NanGetInternalFieldPointer, NanSetInternalFieldPointer + * - Added NAN_WEAK_CALLBACK, NAN_WEAK_CALLBACK_OBJECT, + * NAN_WEAK_CALLBACK_DATA, NanMakeWeak + * - Renamed THROW_ERROR to _NAN_THROW_ERROR + * - Added NanNewBufferHandle(char*, size_t, node::smalloc::FreeCallback, void*) + * - Added NanBufferUse(char*, uint32_t) + * - Added NanNewContextHandle(v8::ExtensionConfiguration*, + * v8::Handle, v8::Handle) + * - Fixed broken NanCallback#GetFunction() + * - Added optional encoding and size arguments to NanFromV8String() + * - Added NanGetPointerSafe() and NanSetPointerSafe() + * - Added initial test suite (to be expanded) + * - Allow NanUInt32OptionValue to convert any Number object + * + * * 0.1.0 Jul 21 2013 + * - Added `NAN_GETTER`, `NAN_SETTER` + * - Added `NanThrowError` with single Local argument + * - Added `NanNewBufferHandle` with single uint32_t argument + * - Added `NanHasInstance(Persistent&, Handle)` + * - Added `Local NanCallback#GetFunction()` + * - Added `NanCallback#Call(int, Local[])` + * - Deprecated `NanCallback#Run(int, Local[])` in favour of Call + * + * See https://github.com/rvagg/nan for the latest update to this file + **********************************************************************************/ + +#ifndef NAN_H +#define NAN_H + +#include +#include +#include + +// some generic helpers + +template static inline bool NanSetPointerSafe(T *var, T val) { + if (var) { + *var = val; + return true; + } else { + return false; + } +} + +template static inline T NanGetPointerSafe( + T *var, + T fallback = reinterpret_cast(0)) { + if (var) { + return *var; + } else { + return fallback; + } +} + +#define NanSymbol(value) v8::String::NewSymbol(value) + +static inline bool NanBooleanOptionValue( + v8::Local optionsObj + , v8::Handle opt, bool def) { + + if (def) { + return optionsObj.IsEmpty() + || !optionsObj->Has(opt) + || optionsObj->Get(opt)->BooleanValue(); + } else { + return !optionsObj.IsEmpty() + && optionsObj->Has(opt) + && optionsObj->Get(opt)->BooleanValue(); + } +} + +static inline bool NanBooleanOptionValue( + v8::Local optionsObj + , v8::Handle opt) { + return NanBooleanOptionValue(optionsObj, opt, false); +} + +static inline uint32_t NanUInt32OptionValue( + v8::Local optionsObj + , v8::Handle opt + , uint32_t def) { + + return !optionsObj.IsEmpty() + && optionsObj->Has(opt) + && optionsObj->Get(opt)->IsNumber() + ? optionsObj->Get(opt)->Uint32Value() + : def; +} + +#if (NODE_MODULE_VERSION > 0x000B) +// Node 0.11+ (0.11.3 and below won't compile with these) + +static v8::Isolate* nan_isolate = v8::Isolate::GetCurrent(); + +# define _NAN_METHOD_ARGS const v8::FunctionCallbackInfo& args +# define NAN_METHOD(name) void name(_NAN_METHOD_ARGS) +# define _NAN_GETTER_ARGS const v8::PropertyCallbackInfo& args +# define NAN_GETTER(name) \ + void name(v8::Local property, _NAN_GETTER_ARGS) +# define _NAN_SETTER_ARGS const v8::PropertyCallbackInfo& args +# define NAN_SETTER(name) \ + void name( \ + v8::Local property \ + , v8::Local value \ + , _NAN_SETTER_ARGS) +# define _NAN_PROPERTY_GETTER_ARGS \ + const v8::PropertyCallbackInfo& args +# define NAN_PROPERTY_GETTER(name) \ + void name(v8::Local property \ + , _NAN_PROPERTY_GETTER_ARGS) +# define _NAN_PROPERTY_SETTER_ARGS \ + const v8::PropertyCallbackInfo& args +# define NAN_PROPERTY_SETTER(name) \ + void name(v8::Local property \ + , v8::Local value \ + , _NAN_PROPERTY_SETTER_ARGS) +# define _NAN_PROPERTY_ENUMERATOR_ARGS \ + const v8::PropertyCallbackInfo& args +# define NAN_PROPERTY_ENUMERATOR(name) \ + void name(_NAN_PROPERTY_ENUMERATOR_ARGS) +# define _NAN_PROPERTY_DELETER_ARGS \ + const v8::PropertyCallbackInfo& args +# define NAN_PROPERTY_DELETER(name) \ + void name( \ + v8::Local property \ + , _NAN_PROPERTY_DELETER_ARGS) +# define _NAN_PROPERTY_QUERY_ARGS \ + const v8::PropertyCallbackInfo& args +# define NAN_PROPERTY_QUERY(name) \ + void name(v8::Local property, _NAN_PROPERTY_QUERY_ARGS) +# define NanGetInternalFieldPointer(object, index) \ + object->GetAlignedPointerFromInternalField(index) +# define NanSetInternalFieldPointer(object, index, value) \ + object->SetAlignedPointerInInternalField(index, value) + +# define NAN_WEAK_CALLBACK(type, name) \ + void name( \ + v8::Isolate* isolate, \ + v8::Persistent* object, \ + type data) +# define NAN_WEAK_CALLBACK_OBJECT (*object) +# define NAN_WEAK_CALLBACK_DATA(type) ((type) data) + +# define NanScope() v8::HandleScope scope(nan_isolate) +# define NanLocker() v8::Locker locker(nan_isolate) +# define NanUnlocker() v8::Unlocker unlocker(nan_isolate) +# define NanReturnValue(value) return args.GetReturnValue().Set(value) +# define NanReturnUndefined() return +# define NanReturnNull() return args.GetReturnValue().SetNull() +# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString() +# define NanAssignPersistent(type, handle, obj) handle.Reset(nan_isolate, obj) +# define NanInitPersistent(type, name, obj) \ + v8::Persistent name(nan_isolate, obj) +# define NanObjectWrapHandle(obj) obj->handle() +# define NanMakeWeak(handle, parameter, callback) \ + handle.MakeWeak(nan_isolate, parameter, callback) + +# define _NAN_THROW_ERROR(fun, errmsg) \ + do { \ + NanScope(); \ + v8::ThrowException(fun(v8::String::New(errmsg))); \ + } while (0); + + inline static void NanThrowError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::Error, errmsg); + } + + inline static void NanThrowError(v8::Handle error) { + NanScope(); + v8::ThrowException(error); + } + + inline static void NanThrowError(const char *msg, const int errorNumber) { + v8::Local err = v8::Exception::Error(v8::String::New(msg)); + v8::Local obj = err.As(); + obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber)); + NanThrowError(err); + } + + inline static void NanThrowTypeError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); + } + + inline static void NanThrowRangeError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); + } + + template static inline void NanDispose(v8::Persistent &handle) { + handle.Dispose(nan_isolate); + handle.Clear(); + } + + static inline v8::Local NanNewBufferHandle ( + char *data, + size_t length, + node::smalloc::FreeCallback callback, + void *hint) { + return node::Buffer::New(data, length, callback, hint); + } + + static inline v8::Local NanNewBufferHandle ( + char *data, uint32_t size) { + return node::Buffer::New(data, size); + } + + static inline v8::Local NanNewBufferHandle (uint32_t size) { + return node::Buffer::New(size); + } + + static inline v8::Local NanBufferUse(char* data, uint32_t size) { + return node::Buffer::Use(data, size); + } + + template + inline v8::Local NanPersistentToLocal( + const v8::Persistent& persistent) { + if (persistent.IsWeak()) { + return v8::Local::New(nan_isolate, persistent); + } else { + return *reinterpret_cast*>( + const_cast*>(&persistent)); + } + } + + inline bool NanHasInstance( + v8::Persistent& function_template + , v8::Handle value) { + return NanPersistentToLocal(function_template)->HasInstance(value); + } + + static inline v8::Local NanNewContextHandle( + v8::ExtensionConfiguration* extensions = NULL, + v8::Handle tmpl = v8::Handle(), + v8::Handle obj = v8::Handle()) { + return v8::Local::New(nan_isolate, v8::Context::New( + nan_isolate, extensions, tmpl, obj)); + } + +#else +// Node 0.8 and 0.10 + +# define _NAN_METHOD_ARGS const v8::Arguments& args +# define NAN_METHOD(name) v8::Handle name(_NAN_METHOD_ARGS) +# define _NAN_GETTER_ARGS const v8::AccessorInfo &args +# define NAN_GETTER(name) \ + v8::Handle name(v8::Local property, _NAN_GETTER_ARGS) +# define _NAN_SETTER_ARGS const v8::AccessorInfo &args +# define NAN_SETTER(name) \ + void name( \ + v8::Local property \ + , v8::Local value \ + , _NAN_SETTER_ARGS) +# define _NAN_PROPERTY_GETTER_ARGS const v8::AccessorInfo& args +# define NAN_PROPERTY_GETTER(name) \ + v8::Handle name(v8::Local property \ + , _NAN_PROPERTY_GETTER_ARGS) +# define _NAN_PROPERTY_SETTER_ARGS const v8::AccessorInfo& args +# define NAN_PROPERTY_SETTER(name) \ + v8::Handle name(v8::Local property \ + , v8::Local value \ + , _NAN_PROPERTY_SETTER_ARGS) +# define _NAN_PROPERTY_ENUMERATOR_ARGS const v8::AccessorInfo& args +# define NAN_PROPERTY_ENUMERATOR(name) \ + v8::Handle name(_NAN_PROPERTY_ENUMERATOR_ARGS) +# define _NAN_PROPERTY_DELETER_ARGS const v8::AccessorInfo& args +# define NAN_PROPERTY_DELETER(name) \ + v8::Handle name( \ + v8::Local property \ + , _NAN_PROPERTY_DELETER_ARGS) +# define _NAN_PROPERTY_QUERY_ARGS const v8::AccessorInfo& args +# define NAN_PROPERTY_QUERY(name) \ + v8::Handle name( \ + v8::Local property \ + , _NAN_PROPERTY_QUERY_ARGS) + +# define NanGetInternalFieldPointer(object, index) \ + object->GetPointerFromInternalField(index) +# define NanSetInternalFieldPointer(object, index, value) \ + object->SetPointerInInternalField(index, value) +# define NAN_WEAK_CALLBACK(type, name) void name( \ + v8::Persistent object, \ + void *data) +# define NAN_WEAK_CALLBACK_OBJECT object +# define NAN_WEAK_CALLBACK_DATA(type) ((type) data) + +# define NanScope() v8::HandleScope scope +# define NanLocker() v8::Locker locker +# define NanUnlocker() v8::Unlocker unlocker +# define NanReturnValue(value) return scope.Close(value) +# define NanReturnUndefined() return v8::Undefined() +# define NanReturnNull() return v8::Null() +# define NanReturnEmptyString() return v8::String::Empty() +# define NanInitPersistent(type, name, obj) \ + v8::Persistent name = v8::Persistent::New(obj) +# define NanAssignPersistent(type, handle, obj) \ + handle = v8::Persistent::New(obj) +# define NanObjectWrapHandle(obj) obj->handle_ +# define NanMakeWeak(handle, parameters, callback) \ + handle.MakeWeak(parameters, callback) + +# define _NAN_THROW_ERROR(fun, errmsg) \ + do { \ + NanScope(); \ + return v8::ThrowException(fun(v8::String::New(errmsg))); \ + } while (0); + + inline static v8::Handle NanThrowError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::Error, errmsg); + } + + inline static v8::Handle NanThrowError( + v8::Handle error) { + NanScope(); + return v8::ThrowException(error); + } + + inline static v8::Handle NanThrowError( + const char *msg, + const int errorNumber) { + v8::Local err = v8::Exception::Error(v8::String::New(msg)); + v8::Local obj = err.As(); + obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber)); + return NanThrowError(err); + } + + inline static v8::Handle NanThrowTypeError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); + } + + inline static v8::Handle NanThrowRangeError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); + } + + template static inline void NanDispose(v8::Persistent &handle) { + handle.Dispose(); + handle.Clear(); + } + + static inline v8::Local NanNewBufferHandle ( + char *data, + size_t length, + node::Buffer::free_callback callback, + void *hint) { + return v8::Local::New( + node::Buffer::New(data, length, callback, hint)->handle_); + } + + static inline v8::Local NanNewBufferHandle ( + char *data, uint32_t size) { + return v8::Local::New(node::Buffer::New(data, size)->handle_); + } + + static inline v8::Local NanNewBufferHandle (uint32_t size) { + return v8::Local::New(node::Buffer::New(size)->handle_); + } + + static inline void FreeData(char *data, void *hint) { + delete[] data; + } + + static inline v8::Local NanBufferUse(char* data, uint32_t size) { + return v8::Local::New( + node::Buffer::New(data, size, FreeData, NULL)->handle_); + } + + template + inline v8::Local NanPersistentToLocal( + const v8::Persistent& persistent) { + if (persistent.IsWeak()) { + return v8::Local::New(persistent); + } else { + return *reinterpret_cast*>( + const_cast*>(&persistent)); + } + } + + inline bool NanHasInstance( + v8::Persistent& function_template + , v8::Handle value) { + return function_template->HasInstance(value); + } + + static inline v8::Local NanNewContextHandle( + v8::ExtensionConfiguration* extensions = NULL + , v8::Handle tmpl = + v8::Handle() + , v8::Handle obj = v8::Handle() + ) { + v8::Persistent ctx = + v8::Context::New(extensions, tmpl, obj); + v8::Local lctx = v8::Local::New(ctx); + ctx.Dispose(); + return lctx; + } + +#endif // node version + +class NanCallback { + public: + NanCallback(const v8::Local &fn) { + NanScope(); + v8::Local obj = v8::Object::New(); + obj->Set(NanSymbol("callback"), fn); + NanAssignPersistent(v8::Object, handle, obj); + } + + ~NanCallback() { + if (handle.IsEmpty()) return; + handle.Dispose(); + handle.Clear(); + } + + inline v8::Local GetFunction () { + return NanPersistentToLocal(handle)->Get(NanSymbol("callback")) + .As(); + } + + // deprecated + void Run(int argc, v8::Local argv[]) { + Call(argc, argv); + } + + void Call(int argc, v8::Local argv[]) { + NanScope(); + + v8::Local callback = NanPersistentToLocal(handle)-> + Get(NanSymbol("callback")).As(); + v8::TryCatch try_catch; + callback->Call(v8::Context::GetCurrent()->Global(), argc, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } + + private: + v8::Persistent handle; +}; + +/* abstract */ class NanAsyncWorker { +public: + NanAsyncWorker (NanCallback *callback) : callback(callback) { + request.data = this; + errmsg = NULL; + } + + virtual ~NanAsyncWorker () { + NanScope(); + + if (!persistentHandle.IsEmpty()) + NanDispose(persistentHandle); + if (callback) + delete callback; + if (errmsg) + delete errmsg; + } + + virtual void WorkComplete () { + NanScope(); + + if (errmsg == NULL) + HandleOKCallback(); + else + HandleErrorCallback(); + delete callback; + callback = NULL; + } + + virtual void Execute () =0; + + uv_work_t request; + +protected: + v8::Persistent persistentHandle; + NanCallback *callback; + const char *errmsg; + + void SavePersistent(const char *key, v8::Local &obj) { + NanScope(); + + v8::Local handle = NanPersistentToLocal(persistentHandle); + handle->Set(NanSymbol(key), obj); + } + + v8::Local GetFromPersistent(const char *key) { + NanScope(); + + v8::Local handle = NanPersistentToLocal(persistentHandle); + return handle->Get(NanSymbol(key)).As(); + } + + virtual void HandleOKCallback () { + NanScope(); + + callback->Call(0, NULL); + }; + + virtual void HandleErrorCallback () { + NanScope(); + + v8::Local argv[] = { + v8::Exception::Error(v8::String::New(errmsg)) + }; + callback->Call(1, argv); + } +}; + +inline void NanAsyncExecute (uv_work_t* req) { + NanAsyncWorker *worker = static_cast(req->data); + worker->Execute(); +} + +inline void NanAsyncExecuteComplete (uv_work_t* req) { + NanAsyncWorker* worker = static_cast(req->data); + worker->WorkComplete(); + delete worker; +} + +inline void NanAsyncQueueWorker (NanAsyncWorker* worker) { + uv_queue_work( + uv_default_loop() + , &worker->request + , NanAsyncExecute + , (uv_after_work_cb)NanAsyncExecuteComplete + ); +} + +//// Base 64 //// + +#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4) + + +// Doesn't check for padding at the end. Can be 1-2 bytes over. +static inline size_t _nan_base64_decoded_size_fast(size_t size) { + size_t remainder = size % 4; + + size = (size / 4) * 3; + if (remainder) { + if (size == 0 && remainder == 1) { + // special case: 1-byte input cannot be decoded + size = 0; + } else { + // non-padded input, add 1 or 2 extra bytes + size += 1 + (remainder == 3); + } + } + + return size; +} + +template +static size_t _nan_base64_decoded_size(const TypeName* src, size_t size) { + if (size == 0) + return 0; + + if (src[size - 1] == '=') + size--; + if (size > 0 && src[size - 1] == '=') + size--; + + return _nan_base64_decoded_size_fast(size); +} + + +// supports regular and URL-safe base64 +static const int _nan_unbase64_table[] = + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + +#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)] + + +template +static size_t _nan_base64_decode(char* buf, + size_t len, + const TypeName* src, + const size_t srcLen) { + char a, b, c, d; + char* dst = buf; + char* dstEnd = buf + len; + const TypeName* srcEnd = src + srcLen; + + while (src < srcEnd && dst < dstEnd) { + int remaining = srcEnd - src; + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining == 0 || *src == '=') break; + a = _nan_unbase64(*src++); + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining <= 1 || *src == '=') break; + b = _nan_unbase64(*src++); + + *dst++ = (a << 2) | ((b & 0x30) >> 4); + if (dst == dstEnd) break; + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining <= 2 || *src == '=') break; + c = _nan_unbase64(*src++); + + *dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2); + if (dst == dstEnd) break; + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining <= 3 || *src == '=') break; + d = _nan_unbase64(*src++); + + *dst++ = ((c & 0x03) << 6) | (d & 0x3F); + } + + return dst - buf; +} + +//// HEX //// + +template +unsigned _nan_hex2bin(TypeName c) { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); + if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); + return static_cast(-1); +} + + +template +static size_t _nan_hex_decode(char* buf, + size_t len, + const TypeName* src, + const size_t srcLen) { + size_t i; + for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) { + unsigned a = _nan_hex2bin(src[i * 2 + 0]); + unsigned b = _nan_hex2bin(src[i * 2 + 1]); + if (!~a || !~b) return i; + buf[i] = a * 16 + b; + } + + return i; +} + +static bool _NanGetExternalParts( + v8::Handle val + , const char** data + , size_t* len) { + + if (node::Buffer::HasInstance(val)) { + *data = node::Buffer::Data(val.As()); + *len = node::Buffer::Length(val.As()); + return true; + + } + + assert(val->IsString()); + v8::Local str = v8::Local::New(val.As()); + + if (str->IsExternalAscii()) { + const v8::String::ExternalAsciiStringResource* ext; + ext = str->GetExternalAsciiStringResource(); + *data = ext->data(); + *len = ext->length(); + return true; + + } else if (str->IsExternal()) { + const v8::String::ExternalStringResource* ext; + ext = str->GetExternalStringResource(); + *data = reinterpret_cast(ext->data()); + *len = ext->length(); + return true; + } + + return false; +} + +namespace Nan { + enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER}; +} + +static inline char* NanFromV8String( + v8::Handle from + , enum Nan::Encoding encoding = Nan::UTF8 + , size_t *datalen = NULL + , char *buf = NULL + , size_t buflen = 0 + , int flags = v8::String::NO_NULL_TERMINATION + | v8::String::HINT_MANY_WRITES_EXPECTED) { + + NanScope(); + + size_t sz_; + size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION); + char *data = NULL; + size_t len; + bool is_extern = _NanGetExternalParts( + from + , const_cast(&data) + , &len); + + if (is_extern && !term_len) { + NanSetPointerSafe(datalen, len); + return data; + } + + v8::Local toStr = from->ToString(); + + char *to = buf; + + v8::String::AsciiValue value(toStr); + switch(encoding) { + case Nan::ASCII: +#if NODE_MODULE_VERSION < 0x0C + sz_ = toStr->Length(); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len && "too small buffer"); + } + NanSetPointerSafe( + datalen + , toStr->WriteAscii(to, 0, sz_ + term_len, flags)); + return to; +#endif + case Nan::BINARY: + case Nan::BUFFER: + sz_ = toStr->Length(); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len && "too small buffer"); + } +#if NODE_MODULE_VERSION < 0x0C + // TODO(isaacs): THIS IS AWFUL!!! + // AGREE(kkoopa) + { + uint16_t* twobytebuf = new uint16_t[sz_ + term_len]; + + size_t len = toStr->Write(twobytebuf, 0, sz_ + term_len, flags); + + for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) { + unsigned char *b = reinterpret_cast(&twobytebuf[i]); + to[i] = *b; + } + + NanSetPointerSafe(datalen, len); + + delete[] twobytebuf; + return to; + } +#else + NanSetPointerSafe( + datalen, + toStr->WriteOneByte( + reinterpret_cast(to) + , 0 + , sz_ + term_len + , flags)); + return to; +#endif + case Nan::UTF8: + sz_ = toStr->Utf8Length(); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len && "too small buffer"); + } + NanSetPointerSafe( + datalen + , toStr->WriteUtf8(to, sz_ + term_len, NULL, flags) - term_len); + return to; + case Nan::BASE64: + sz_ = _nan_base64_decoded_size(*value, toStr->Length()); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len); + } + NanSetPointerSafe( + datalen + , _nan_base64_decode(to, sz_, *value, value.length())); + if (term_len) { + to[sz_] = '\0'; + } + return to; + case Nan::UCS2: + { + sz_ = toStr->Length(); + if (to == NULL) { + to = new char[(sz_ + term_len) * 2]; + } else { + assert(buflen >= (sz_ + term_len) * 2 && "too small buffer"); + } + + int bc = 2 * toStr->Write( + reinterpret_cast(to) + , 0 + , sz_ + term_len + , flags); + NanSetPointerSafe(datalen, bc); + return to; + } + case Nan::HEX: + sz_ = toStr->Length(); + assert(!(sz_ & 1) && "bad hex data"); + if (to == NULL) { + to = new char[sz_ / 2 + term_len]; + } else { + assert(buflen >= sz_ / 2 + term_len && "too small buffer"); + } + + NanSetPointerSafe( + datalen + , _nan_hex_decode(to, sz_ / 2, *value, value.length())); + if (term_len) { + to[sz_ / 2] = '\0'; + } + return to; + default: + assert(0 && "unknown encoding"); + } + return to; +} + +#endif diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/package.json new file mode 100644 index 00000000000..ae3679e70f1 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/nan/package.json @@ -0,0 +1,35 @@ +{ + "name": "nan", + "version": "0.3.2", + "description": "Native Abstractions for Node.js: C++ header for Node 0.8->0.12 compatibility", + "main": ".index.js", + "repository": { + "type": "git", + "url": "git://github.com/rvagg/nan.git" + }, + "contributors": [ + { + "name": "Rod Vagg", + "email": "r@va.gg", + "url": "https://github.com/rvagg" + }, + { + "name": "Benjamin Byholm", + "email": "bbyholm@abo.fi", + "url": "https://github.com/kkoopa/" + }, + { + "name": "Trevor Norris", + "email": "trev.norris@gmail.com", + "url": "https://github.com/trevnorris" + } + ], + "license": "MIT", + "readme": "Native Abstractions for Node.js\n===============================\n\n**A header file filled with macro and utility goodness for making addon development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.**\n\n***Current version: 0.3.2*** *(See [nan.h](https://github.com/rvagg/nan/blob/master/nan.h) for changelog)*\n\n[![NPM](https://nodei.co/npm/nan.png?downloads=true&stars=true)](https://nodei.co/npm/nan/) [![NPM](https://nodei.co/npm-dl/nan.png?months=6)](https://nodei.co/npm/nan/)\n\nThanks to the crazy changes in V8 (and some in Node core), keeping native addons compiling happily across versions, particularly 0.10 to 0.11/0.12, is a minor nightmare. The goal of this project is to store all logic necessary to develop native Node.js addons without having to inspect `NODE_MODULE_VERSION` and get yourself into a macro-tangle.\n\nThis project also contains some helper utilities that make addon development a bit more pleasant.\n\n * **[Usage](#usage)**\n * **[Example](#example)**\n * **[API](#api)**\n\n\n## Usage\n\nSimply add **NAN** as a dependency in the *package.json* of your Node addon:\n\n```js\n\"dependencies\": {\n ...\n \"nan\" : \"~0.3.1\"\n ...\n}\n```\n\nPull in the path to **NAN** in your *binding.gyp* so that you can use `#include \"nan.h\"` in your *.cpp*:\n\n```js\n\"include_dirs\" : [\n ...\n \"` when compiling your addon.\n\n\n## Example\n\nSee **[LevelDOWN](https://github.com/rvagg/node-leveldown/pull/48)** for a full example of **NAN** in use.\n\nFor a simpler example, see the **[async pi estimation example](https://github.com/rvagg/nan/tree/master/examples/async_pi_estimate)** in the examples directory for full code and an explanation of what this Monte Carlo Pi estimation example does. Below are just some parts of the full example that illustrate the use of **NAN**.\n\nCompare to the current 0.10 version of this example, found in the [node-addon-examples](https://github.com/rvagg/node-addon-examples/tree/master/9_async_work) repository and also a 0.11 version of the same found [here](https://github.com/kkoopa/node-addon-examples/tree/5c01f58fc993377a567812597e54a83af69686d7/9_async_work).\n\nNote that there is no embedded version sniffing going on here and also the async work is made much simpler, see below for details on the `NanAsyncWorker` class.\n\n```c++\n// addon.cc\n#include \n#include \"nan.h\"\n// ...\n\nusing namespace v8;\n\nvoid InitAll(Handle exports) {\n exports->Set(NanSymbol(\"calculateSync\"),\n FunctionTemplate::New(CalculateSync)->GetFunction());\n\n exports->Set(NanSymbol(\"calculateAsync\"),\n FunctionTemplate::New(CalculateAsync)->GetFunction());\n}\n\nNODE_MODULE(addon, InitAll)\n```\n\n```c++\n// sync.h\n#include \n#include \"nan.h\"\n\nNAN_METHOD(CalculateSync);\n```\n\n```c++\n// sync.cc\n#include \n#include \"nan.h\"\n#include \"sync.h\"\n// ...\n\nusing namespace v8;\n\n// Simple synchronous access to the `Estimate()` function\nNAN_METHOD(CalculateSync) {\n NanScope();\n\n // expect a number as the first argument\n int points = args[0]->Uint32Value();\n double est = Estimate(points);\n\n NanReturnValue(Number::New(est));\n}\n```\n\n```c++\n// async.cc\n#include \n#include \"nan.h\"\n#include \"async.h\"\n\n// ...\n\nusing namespace v8;\n\nclass PiWorker : public NanAsyncWorker {\n public:\n PiWorker(NanCallback *callback, int points)\n : NanAsyncWorker(callback), points(points) {}\n ~PiWorker() {}\n\n // Executed inside the worker-thread.\n // It is not safe to access V8, or V8 data structures\n // here, so everything we need for input and output\n // should go on `this`.\n void Execute () {\n estimate = Estimate(points);\n }\n\n // Executed when the async work is complete\n // this function will be run inside the main event loop\n // so it is safe to use V8 again\n void HandleOKCallback () {\n NanScope();\n\n Local argv[] = {\n Local::New(Null())\n , Number::New(estimate)\n };\n\n callback->Call(2, argv);\n };\n\n private:\n int points;\n double estimate;\n};\n\n// Asynchronous access to the `Estimate()` function\nNAN_METHOD(CalculateAsync) {\n NanScope();\n\n int points = args[0]->Uint32Value();\n NanCallback *callback = new NanCallback(args[1].As());\n\n NanAsyncQueueWorker(new PiWorker(callback, points));\n NanReturnUndefined();\n}\n```\n\n\n## API\n\n * NAN_METHOD\n * NAN_GETTER\n * NAN_SETTER\n * NAN_PROPERTY_GETTER\n * NAN_PROPERTY_SETTER\n * NAN_PROPERTY_ENUMERATOR\n * NAN_PROPERTY_DELETER\n * NAN_PROPERTY_QUERY\n * NAN_WEAK_CALLBACK\n * NanReturnValue\n * NanReturnUndefined\n * NanReturnNull\n * NanReturnEmptyString\n * NanScope\n * NanLocker\n * NanUnlocker\n * NanGetInternalFieldPointer\n * NanSetInternalFieldPointer\n * NanObjectWrapHandle\n * NanMakeWeak\n * NanSymbol\n * NanGetPointerSafe\n * NanSetPointerSafe\n * NanFromV8String\n * NanBooleanOptionValue\n * NanUInt32OptionValue\n * NanThrowError, NanThrowTypeError, NanThrowRangeError, NanThrowError(Handle), NanThrowError(Handle, int)\n * NanNewBufferHandle(char *, size_t, FreeCallback, void *), NanNewBufferHandle(char *, uint32_t), NanNewBufferHandle(uint32_t)\n * NanBufferUse(char *, uint32_t)\n * NanNewContextHandle\n * NanHasInstance\n * NanPersistentToLocal\n * NanDispose\n * NanAssignPersistent\n * NanInitPersistent\n * NanCallback\n * NanAsyncWorker\n * NanAsyncQueueWorker\n\n\n### NAN_METHOD(methodname)\n\nUse `NAN_METHOD` to define your V8 accessible methods:\n\n```c++\n// .h:\nclass Foo : public node::ObjectWrap {\n ...\n\n static NAN_METHOD(Bar);\n static NAN_METHOD(Baz);\n}\n\n\n// .cc:\nNAN_METHOD(Foo::Bar) {\n ...\n}\n\nNAN_METHOD(Foo::Baz) {\n ...\n}\n```\n\nThe reason for this macro is because of the method signature change in 0.11:\n\n```c++\n// 0.10 and below:\nHandle name(const Arguments& args)\n\n// 0.11 and above\nvoid name(const FunctionCallbackInfo& args)\n```\n\nThe introduction of `FunctionCallbackInfo` brings additional complications:\n\n\n### NAN_GETTER(methodname)\n\nUse `NAN_GETTER` to declare your V8 accessible getters. You get a `Local` `property` and an appropriately typed `args` object that can act like the `args` argument to a `NAN_METHOD` call.\n\nYou can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_GETTER`.\n\n\n### NAN_SETTER(methodname)\n\nUse `NAN_SETTER` to declare your V8 accessible setters. Same as `NAN_GETTER` but you also get a `Local` `value` object to work with.\n\nYou can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_SETTER`.\n\n\n### NAN_PROPERTY_GETTER(cbname)\nUse `NAN_PROPERTY_GETTER` to declare your V8 accessible property getters. You get a `Local` `property` and an appropriately typed `args` object that can act similar to the `args` argument to a `NAN_METHOD` call.\n\nYou can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_GETTER`.\n\n\n### NAN_PROPERTY_SETTER(cbname)\nUse `NAN_PROPERTY_SETTER` to declare your V8 accessible property setters. Same as `NAN_PROPERTY_GETTER` but you also get a `Local` `value` object to work with.\n\nYou can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_SETTER`.\n\n\n### NAN_PROPERTY_ENUMERATOR(cbname)\nUse `NAN_PROPERTY_ENUMERATOR` to declare your V8 accessible property enumerators. You get an appropriately typed `args` object like the `args` argument to a `NAN_PROPERTY_GETTER` call.\n\nYou can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_ENUMERATOR`.\n\n\n### NAN_PROPERTY_DELETER(cbname)\nUse `NAN_PROPERTY_DELETER` to declare your V8 accessible property deleters. Same as `NAN_PROPERTY_GETTER`.\n\nYou can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_DELETER`.\n\n\n### NAN_PROPERTY_QUERY(cbname)\nUse `NAN_PROPERTY_QUERY` to declare your V8 accessible property queries. Same as `NAN_PROPERTY_GETTER`.\n\nYou can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_QUERY`.\n\n\n### NAN_WEAK_CALLBACK(type, cbname)\n\nUse `NAN_WEAK_CALLBACK` to declare your V8 WeakReference callbacks. There is an object argument accessible through `NAN_WEAK_CALLBACK_OBJECT`. The `type` argument gives the type of the `data` argument, accessible through `NAN_WEAK_CALLBACK_DATA(type)`.\n\n```c++\nstatic NAN_WEAK_CALLBACK(BufferReference*, WeakCheck) {\n if (NAN_WEAK_CALLBACK_DATA(BufferReference*)->noLongerNeeded_) {\n delete NAN_WEAK_CALLBACK_DATA(BufferReference*);\n } else {\n // Still in use, revive, prevent GC\n NanMakeWeak(NAN_WEAK_CALLBACK_OBJECT, NAN_WEAK_CALLBACK_DATA(BufferReference*), &WeakCheck);\n }\n}\n\n```\n\n### NanReturnValue(Handle<Value>)\n\nUse `NanReturnValue` when you want to return a value from your V8 accessible method:\n\n```c++\nNAN_METHOD(Foo::Bar) {\n ...\n\n NanReturnValue(String::New(\"FooBar!\"));\n}\n```\n\nNo `return` statement required.\n\n\n### NanReturnUndefined()\n\nUse `NanReturnUndefined` when you don't want to return anything from your V8 accessible method:\n\n```c++\nNAN_METHOD(Foo::Baz) {\n ...\n\n NanReturnUndefined();\n}\n```\n\n\n### NanReturnNull()\n\nUse `NanReturnNull` when you want to return `Null` from your V8 accessible method:\n\n```c++\nNAN_METHOD(Foo::Baz) {\n ...\n\n NanReturnNull();\n}\n```\n\n\n### NanReturnEmptyString()\n\nUse `NanReturnEmptyString` when you want to return an empty `String` from your V8 accessible method:\n\n```c++\nNAN_METHOD(Foo::Baz) {\n ...\n\n NanReturnEmptyString();\n}\n```\n\n\n### NanScope()\n\nThe introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanScope()` necessary, use it in place of `HandleScope scope`:\n\n```c++\nNAN_METHOD(Foo::Bar) {\n NanScope();\n\n NanReturnValue(String::New(\"FooBar!\"));\n}\n```\n\n\n### NanLocker()\n\nThe introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanLocker()` necessary, use it in place of `Locker locker`:\n\n```c++\nNAN_METHOD(Foo::Bar) {\n NanLocker();\n ...\n NanUnlocker();\n}\n```\n\n\n### NanUnlocker()\n\nThe introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanUnlocker()` necessary, use it in place of `Unlocker unlocker`:\n\n```c++\nNAN_METHOD(Foo::Bar) {\n NanLocker();\n ...\n NanUnlocker();\n}\n```\n\n\n### void * NanGetInternalFieldPointer(Handle<Object>, int)\n\nGets a pointer to the internal field with at `index` from a V8 `Object` handle.\n\n```c++\nLocal obj;\n...\nNanGetInternalFieldPointer(obj, 0);\n```\n\n### void NanSetInternalFieldPointer(Handle<Object>, int, void *)\n\nSets the value of the internal field at `index` on a V8 `Object` handle.\n\n```c++\nstatic Persistent dataWrapperCtor;\n...\nLocal wrapper = NanPersistentToLocal(dataWrapperCtor)->NewInstance();\nNanSetInternalFieldPointer(wrapper, 0, this);\n```\n\n\n### Local<Object> NanObjectWrapHandle(Object)\n\nWhen you want to fetch the V8 object handle from a native object you've wrapped with Node's `ObjectWrap`, you should use `NanObjectWrapHandle`:\n\n```c++\nNanObjectWrapHandle(iterator)->Get(String::NewSymbol(\"end\"))\n```\n\n\n### NanMakeWeak(Persistent<T>, parameter, callback)\n\nMake a persistent reference weak.\n\n\n### String NanSymbol(char *)\n\nThis isn't strictly about compatibility, it's just an easier way to create string symbol objects (i.e. `String::NewSymbol(x)`), for getting and setting object properties, or names of objects.\n\n```c++\nbool foo = false;\nif (obj->Has(NanSymbol(\"foo\")))\n foo = optionsObj->Get(NanSymbol(\"foo\"))->BooleanValue()\n```\n\n\n### Type NanGetPointerSafe(Type *[, Type])\n\nA helper for getting values from optional pointers. If the pointer is `NULL`, the function returns the optional default value, which defaults to `0`. Otherwise, the function returns the value the pointer points to.\n\n```c++\nchar *plugh(uint32_t *optional) {\n char res[] = \"xyzzy\";\n uint32_t param = NanGetPointerSafe(optional, 0x1337);\n switch (param) {\n ...\n }\n NanSetPointerSafe(optional, 0xDEADBEEF);\n} \n```\n\n\n### bool NanSetPointerSafe(Type *, Type)\n\nA helper for setting optional argument pointers. If the pointer is `NULL`, the function simply return `false`. Otherwise, the value is assigned to the variable the pointer points to.\n\n```c++\nconst char *plugh(size_t *outputsize) {\n char res[] = \"xyzzy\";\n if !(NanSetPointerSafe(outputsize, strlen(res) + 1)) {\n ...\n }\n\n ...\n}\n```\n\n\n### char* NanFromV8String(Handle<Value>[, enum Nan::Encoding, size_t *, char *, size_t, int])\n\nWhen you want to convert a V8 `String` to a `char*` use `NanFromV8String`. It is possible to define an encoding that defaults to `Nan::UTF8` as well as a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows optionally setting `String::WriteOptions`, which default to `String::HINT_MANY_WRITES_EXPECTED | String::NO_NULL_TERMINATION`.\nJust remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer:\n\n```c++\nsize_t count;\nchar* name = NanFromV8String(args[0]);\nchar* decoded = NanFromV8String(args[1], Nan::BASE64, &count, NULL, 0, String::HINT_MANY_WRITES_EXPECTED);\nchar param_copy[count];\nmemcpy(param_copy, decoded, count);\ndelete[] decoded;\n```\n\n\n### bool NanBooleanOptionValue(Handle<Value>, Handle<String>[, bool])\n\nWhen you have an \"options\" object that you need to fetch properties from, boolean options can be fetched with this pair. They check first if the object exists (`IsEmpty`), then if the object has the given property (`Has`) then they get and convert/coerce the property to a `bool`.\n\nThe optional last parameter is the *default* value, which is `false` if left off:\n\n```c++\n// `foo` is false unless the user supplies a truthy value for it\nbool foo = NanBooleanOptionValue(optionsObj, NanSymbol(\"foo\"));\n// `bar` is true unless the user supplies a falsy value for it\nbool bar = NanBooleanOptionValueDefTrue(optionsObj, NanSymbol(\"bar\"), true);\n```\n\n\n### uint32_t NanUInt32OptionValue(Handle<Value>, Handle<String>, uint32_t)\n\nSimilar to `NanBooleanOptionValue`, use `NanUInt32OptionValue` to fetch an integer option from your options object. Can be any kind of JavaScript `Number` and it will be coerced to an unsigned 32-bit integer.\n\nRequires all 3 arguments as a default is not optional:\n\n```c++\nuint32_t count = NanUInt32OptionValue(optionsObj, NanSymbol(\"count\"), 1024);\n```\n\n\n### NanThrowError(message), NanThrowTypeError(message), NanThrowRangeError(message), NanThrowError(Local<Value>), NanThrowError(Local<Value>, int)\n\nFor throwing `Error`, `TypeError` and `RangeError` objects. You should `return` this call:\n\n```c++\nreturn NanThrowError(\"you must supply a callback argument\");\n```\n\nCan also handle any custom object you may want to throw. If used with the error code argument, it will add the supplied error code to the error object as a property called `code`.\n\n\n### Local<Object> NanNewBufferHandle(char *, uint32_t), Local<Object> NanNewBufferHandle(uint32_t)\n\nThe `Buffer` API has changed a little in Node 0.11, this helper provides consistent access to `Buffer` creation:\n\n```c++\nNanNewBufferHandle((char*)value.data(), value.size());\n```\n\nCan also be used to initialize a `Buffer` with just a `size` argument.\n\nCan also be supplied with a `NAN_WEAK_CALLBACK` and a hint for the garbage collector, when dealing with weak references.\n\n\n### Local<Object> NanBufferUse(char*, uint32_t)\n\n`Buffer::New(char*, uint32_t)` prior to 0.11 would make a copy of the data.\nWhile it was possible to get around this, it required a shim by passing a\ncallback. So the new API `Buffer::Use(char*, uint32_t)` was introduced to remove\nneeding to use this shim.\n\n`NanBufferUse` uses the `char*` passed as the backing data, and will free the\nmemory automatically when the weak callback is called. Keep this in mind, as\ncareless use can lead to \"double free or corruption\" and other cryptic failures.\n\n\n### bool NanHasInstance(Persistent<FunctionTemplate>&, Handle<Value>)\n\nCan be used to check the type of an object to determine it is of a particular class you have already defined and have a `Persistent` handle for.\n\n\n### Local<Type> NanPersistentToLocal(Persistent<Type>&)\n\nAside from `FunctionCallbackInfo`, the biggest and most painful change to V8 in Node 0.11 is the many restrictions now placed on `Persistent` handles. They are difficult to assign and difficult to fetch the original value out of.\n\nUse `NanPersistentToLocal` to convert a `Persistent` handle back to a `Local` handle.\n\n```c++\nLocal handle = NanPersistentToLocal(persistentHandle);\n```\n\n\n### Local<Context> NanNewContextHandle([ExtensionConfiguration*, Handle<ObjectTemplate>, Handle<Value>])\nCreates a new `Local` handle.\n\n```c++\nLocal ftmpl = FunctionTemplate::New();\nLocal otmpl = ftmpl->InstanceTemplate();\nLocal ctx = NanNewContextHandle(NULL, otmpl);\n```\n\n\n### void NanDispose(Persistent<T> &)\n\nUse `NanDispose` to dispose a `Persistent` handle.\n\n```c++\nNanDispose(persistentHandle);\n```\n\n\n### NanAssignPersistent(type, handle, object)\n\nUse `NanAssignPersistent` to assign a non-`Persistent` handle to a `Persistent` one. You can no longer just declare a `Persistent` handle and assign directly to it later, you have to `Reset` it in Node 0.11, so this makes it easier.\n\nIn general it is now better to place anything you want to protect from V8's garbage collector as properties of a generic `Object` and then assign that to a `Persistent`. This works in older versions of Node also if you use `NanAssignPersistent`:\n\n```c++\nPersistent persistentHandle;\n\n...\n\nLocal obj = Object::New();\nobj->Set(NanSymbol(\"key\"), keyHandle); // where keyHandle might be a Local\nNanAssignPersistent(Object, persistentHandle, obj)\n```\n\n\n### NanInitPersistent(type, name, object)\n\nUser `NanInitPersistent` to declare and initialize a new `Persistent` with the supplied object. The assignment operator for `Persistent` is no longer public in Node 0.11, so this macro makes it easier to declare and initializing a new `Persistent`. See NanAssignPersistent for more information.\n\n```c++\nLocal obj = Object::New();\nobj->Set(NanSymbol(\"key\"), keyHandle); // where keyHandle might be a Local\nNanInitPersistent(Object, persistentHandle, obj);\n```\n\n\n### NanCallback\n\nBecause of the difficulties imposed by the changes to `Persistent` handles in V8 in Node 0.11, creating `Persistent` versions of your `Local` handles is annoyingly tricky. `NanCallback` makes it easier by taking your `Local` handle, making it persistent until the `NanCallback` is deleted and even providing a handy `Call()` method to fetch and execute the callback `Function`.\n\n```c++\nLocal callbackHandle = callback = args[0].As();\nNanCallback *callback = new NanCallback(callbackHandle);\n// pass `callback` around and it's safe from GC until you:\ndelete callback;\n```\n\nYou can execute the callback like so:\n\n```c++\n// no arguments:\ncallback->Call(0, NULL);\n\n// an error argument:\nLocal argv[] = {\n Exception::Error(String::New(\"fail!\"))\n};\ncallback->Call(1, argv);\n\n// a success argument:\nLocal argv[] = {\n Local::New(Null()),\n String::New(\"w00t!\")\n};\ncallback->Call(2, argv);\n```\n\n`NanCallback` also has a `Local GetCallback()` method that you can use to fetch a local handle to the underlying callback function if you need it.\n\n\n### NanAsyncWorker\n\n`NanAsyncWorker` is an abstract class that you can subclass to have much of the annoying async queuing and handling taken care of for you. It can even store arbitrary V8 objects for you and have them persist while the async work is in progress.\n\nSee a rough outline of the implementation:\n\n```c++\nclass NanAsyncWorker {\npublic:\n NanAsyncWorker (NanCallback *callback);\n\n // Clean up persistent handles and delete the *callback\n virtual ~NanAsyncWorker ();\n\n // Check the `char *errmsg` property and call HandleOKCallback()\n // or HandleErrorCallback depending on whether it has been set or not\n virtual void WorkComplete ();\n\n // You must implement this to do some async work. If there is an\n // error then allocate `errmsg` to to a message and the callback will\n // be passed that string in an Error object\n virtual void Execute ();\n\nprotected:\n // Set this if there is an error, otherwise it's NULL\n const char *errmsg;\n\n // Save a V8 object in a Persistent handle to protect it from GC\n void SavePersistent(const char *key, Local &obj);\n\n // Fetch a stored V8 object (don't call from within `Execute()`)\n Local GetFromPersistent(const char *key);\n\n // Default implementation calls the callback function with no arguments.\n // Override this to return meaningful data\n virtual void HandleOKCallback ();\n\n // Default implementation calls the callback function with an Error object\n // wrapping the `errmsg` string\n virtual void HandleErrorCallback ();\n};\n```\n\n\n### NanAsyncQueueWorker(NanAsyncWorker *)\n\n`NanAsyncQueueWorker` will run a `NanAsyncWorker` asynchronously via libuv. Both the *execute* and *after_work* steps are taken care of for you—most of the logic for this is embedded in `NanAsyncWorker`.\n\n### Contributors\n\nNAN is only possible due to the excellent work of the following contributors:\n\n\n\n\n\n
    Rod VaggGitHub/rvaggTwitter/@rvagg
    Benjamin ByholmGitHub/kkoopa
    Trevor NorrisGitHub/trevnorrisTwitter/@trevnorris
    \n\nLicence & copyright\n-----------------------\n\nCopyright (c) 2013 Rod Vagg & NAN contributors (listed above).\n\nNative Abstractions for Node.js is licensed under an MIT +no-false-attribs license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/rvagg/nan/issues" + }, + "_id": "nan@0.3.2", + "_from": "nan@~0.3.0" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/.npmignore new file mode 100644 index 00000000000..6bfffbb79b5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/.npmignore @@ -0,0 +1,5 @@ +npm-debug.log +node_modules +.*.swp +.lock-* +build/ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/Makefile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/Makefile new file mode 100644 index 00000000000..7496b6fcc50 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/Makefile @@ -0,0 +1,12 @@ +ALL_TESTS = $(shell find test/ -name '*.test.js') + +run-tests: + @./node_modules/.bin/mocha \ + -t 2000 \ + $(TESTFLAGS) \ + $(TESTS) + +test: + @$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests + +.PHONY: test diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/README.md new file mode 100644 index 00000000000..4b39a2a7b7b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/README.md @@ -0,0 +1,28 @@ +# options.js # + +A very light-weight in-code option parsers for node.js. + +## License ## + +(The MIT License) + +Copyright (c) 2012 Einar Otto Stangvik <einaros@gmail.com> + +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. diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/lib/options.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/lib/options.js new file mode 100644 index 00000000000..4fc45e90a8c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/lib/options.js @@ -0,0 +1,86 @@ +/*! + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var fs = require('fs'); + +function Options(defaults) { + var internalValues = {}; + var values = this.value = {}; + Object.keys(defaults).forEach(function(key) { + internalValues[key] = defaults[key]; + Object.defineProperty(values, key, { + get: function() { return internalValues[key]; }, + configurable: false, + enumerable: true + }); + }); + this.reset = function() { + Object.keys(defaults).forEach(function(key) { + internalValues[key] = defaults[key]; + }); + return this; + }; + this.merge = function(options, required) { + options = options || {}; + if (Object.prototype.toString.call(required) === '[object Array]') { + var missing = []; + for (var i = 0, l = required.length; i < l; ++i) { + var key = required[i]; + if (!(key in options)) { + missing.push(key); + } + } + if (missing.length > 0) { + if (missing.length > 1) { + throw new Error('options ' + + missing.slice(0, missing.length - 1).join(', ') + ' and ' + + missing[missing.length - 1] + ' must be defined'); + } + else throw new Error('option ' + missing[0] + ' must be defined'); + } + } + Object.keys(options).forEach(function(key) { + if (key in internalValues) { + internalValues[key] = options[key]; + } + }); + return this; + }; + this.copy = function(keys) { + var obj = {}; + Object.keys(defaults).forEach(function(key) { + if (keys.indexOf(key) !== -1) { + obj[key] = values[key]; + } + }); + return obj; + }; + this.read = function(filename, cb) { + if (typeof cb == 'function') { + var self = this; + fs.readFile(filename, function(error, data) { + if (error) return cb(error); + var conf = JSON.parse(data); + self.merge(conf); + cb(); + }); + } + else { + var conf = JSON.parse(fs.readFileSync(filename)); + this.merge(conf); + } + return this; + }; + this.isDefined = function(key) { + return typeof values[key] != 'undefined'; + }; + this.isDefinedAndNonNull = function(key) { + return typeof values[key] != 'undefined' && values[key] !== null; + }; + Object.freeze(values); + Object.freeze(this); +} + +module.exports = Options; diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/package.json new file mode 100644 index 00000000000..04e8978df2f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/package.json @@ -0,0 +1,32 @@ +{ + "author": { + "name": "Einar Otto Stangvik", + "email": "einaros@gmail.com", + "url": "http://2x.io" + }, + "name": "options", + "description": "A very light-weight in-code option parsers for node.js.", + "version": "0.0.5", + "repository": { + "type": "git", + "url": "git://github.com/einaros/options.js.git" + }, + "main": "lib/options", + "scripts": { + "test": "make test" + }, + "engines": { + "node": ">=0.4.0" + }, + "dependencies": {}, + "devDependencies": { + "mocha": "latest" + }, + "readme": "# options.js #\n\nA very light-weight in-code option parsers for node.js.\n\n## License ##\n\n(The MIT License)\n\nCopyright (c) 2012 Einar Otto Stangvik <einaros@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/einaros/options.js/issues" + }, + "_id": "options@0.0.5", + "_from": "options@>=0.0.5" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/test/fixtures/test.conf b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/test/fixtures/test.conf new file mode 100644 index 00000000000..6e6244419a3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/test/fixtures/test.conf @@ -0,0 +1,4 @@ +{ + "a": "foobar", + "b": false +} \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/test/options.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/test/options.test.js new file mode 100644 index 00000000000..6a1d9f5b3d0 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/options/test/options.test.js @@ -0,0 +1,140 @@ +var Options = require('options') + , assert = require('assert'); + +describe('Options', function() { + describe('#ctor', function() { + it('initializes options', function() { + var option = new Options({a: true, b: false}); + assert.strictEqual(true, option.value.a); + assert.strictEqual(false, option.value.b); + }); + }); + + describe('#merge', function() { + it('merges options from another object', function() { + var option = new Options({a: true, b: false}); + option.merge({b: true}); + assert.strictEqual(true, option.value.a); + assert.strictEqual(true, option.value.b); + }); + it('does nothing when arguments are undefined', function() { + var option = new Options({a: true, b: false}); + option.merge(undefined); + assert.strictEqual(true, option.value.a); + assert.strictEqual(false, option.value.b); + }); + it('cannot set values that werent already there', function() { + var option = new Options({a: true, b: false}); + option.merge({c: true}); + assert.strictEqual('undefined', typeof option.value.c); + }); + it('can require certain options to be defined', function() { + var option = new Options({a: true, b: false, c: 3}); + var caughtException = false; + try { + option.merge({}, ['a', 'b', 'c']); + } + catch (e) { + caughtException = e.toString() == 'Error: options a, b and c must be defined'; + } + assert.strictEqual(true, caughtException); + }); + it('can require certain options to be defined, when options are undefined', function() { + var option = new Options({a: true, b: false, c: 3}); + var caughtException = false; + try { + option.merge(undefined, ['a', 'b', 'c']); + } + catch (e) { + caughtException = e.toString() == 'Error: options a, b and c must be defined'; + } + assert.strictEqual(true, caughtException); + }); + it('returns "this"', function() { + var option = new Options({a: true, b: false, c: 3}); + assert.strictEqual(option, option.merge()); + }); + }); + + describe('#copy', function() { + it('returns a new object with the indicated options', function() { + var option = new Options({a: true, b: false, c: 3}); + option.merge({c: 4}); + var obj = option.copy(['a', 'c']); + assert.strictEqual(true, obj.a); + assert.strictEqual(4, obj.c); + assert.strictEqual('undefined', typeof obj.b); + }); + }); + + describe('#value', function() { + it('can be enumerated', function() { + var option = new Options({a: true, b: false}); + assert.strictEqual(2, Object.keys(option.value).length); + }); + it('can not be used to set values', function() { + var option = new Options({a: true, b: false}); + option.value.b = true; + assert.strictEqual(false, option.value.b); + }); + it('can not be used to add values', function() { + var option = new Options({a: true, b: false}); + option.value.c = 3; + assert.strictEqual('undefined', typeof option.value.c); + }); + }); + + describe('#isDefined', function() { + it('returns true if the named value is defined', function() { + var option = new Options({a: undefined}); + assert.strictEqual(false, option.isDefined('a')); + option.merge({a: false}); + assert.strictEqual(true, option.isDefined('a')); + }); + }); + + describe('#isDefinedAndNonNull', function() { + it('returns true if the named value is defined and non-null', function() { + var option = new Options({a: undefined}); + assert.strictEqual(false, option.isDefinedAndNonNull('a')); + option.merge({a: null}); + assert.strictEqual(false, option.isDefinedAndNonNull('a')); + option.merge({a: 2}); + assert.strictEqual(true, option.isDefinedAndNonNull('a')); + }); + }); + + describe('#read', function() { + it('reads and merges config from a file', function() { + var option = new Options({a: true, b: true}); + option.read(__dirname + '/fixtures/test.conf'); + assert.strictEqual('foobar', option.value.a); + assert.strictEqual(false, option.value.b); + }); + + it('asynchronously reads and merges config from a file when a callback is passed', function(done) { + var option = new Options({a: true, b: true}); + option.read(__dirname + '/fixtures/test.conf', function(error) { + assert.strictEqual('foobar', option.value.a); + assert.strictEqual(false, option.value.b); + done(); + }); + }); + }); + + describe('#reset', function() { + it('resets options to defaults', function() { + var option = new Options({a: true, b: false}); + option.merge({b: true}); + assert.strictEqual(true, option.value.b); + option.reset(); + assert.strictEqual(false, option.value.b); + }); + }); + + it('is immutable', function() { + var option = new Options({a: true, b: false}); + option.foo = 2; + assert.strictEqual('undefined', typeof option.foo); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/.npmignore b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/.npmignore new file mode 100644 index 00000000000..6bfffbb79b5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/.npmignore @@ -0,0 +1,5 @@ +npm-debug.log +node_modules +.*.swp +.lock-* +build/ diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/README.md b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/README.md new file mode 100644 index 00000000000..55eb3c110a5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/README.md @@ -0,0 +1,3 @@ +# tinycolor # + +This is a no-fuzz, barebone, zero muppetry color module for node.js. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/example.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/example.js new file mode 100644 index 00000000000..f754046854b --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/example.js @@ -0,0 +1,3 @@ +require('./tinycolor'); +console.log('this should be red and have an underline!'.grey.underline); +console.log('this should have a blue background!'.bgBlue); \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/package.json new file mode 100644 index 00000000000..8c56dce1f51 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/package.json @@ -0,0 +1,27 @@ +{ + "author": { + "name": "Einar Otto Stangvik", + "email": "einaros@gmail.com", + "url": "http://2x.io" + }, + "name": "tinycolor", + "description": "a to-the-point color module for node", + "version": "0.0.1", + "repository": { + "type": "git", + "url": "git://github.com/einaros/tinycolor.git" + }, + "engines": { + "node": ">=0.4.0" + }, + "dependencies": {}, + "devDependencies": {}, + "main": "tinycolor", + "readme": "# tinycolor #\n\nThis is a no-fuzz, barebone, zero muppetry color module for node.js.", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/einaros/tinycolor/issues" + }, + "_id": "tinycolor@0.0.1", + "_from": "tinycolor@0.x" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/tinycolor.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/tinycolor.js new file mode 100644 index 00000000000..36e552c4ccb --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/node_modules/tinycolor/tinycolor.js @@ -0,0 +1,31 @@ +var styles = { + 'bold': ['\033[1m', '\033[22m'], + 'italic': ['\033[3m', '\033[23m'], + 'underline': ['\033[4m', '\033[24m'], + 'inverse': ['\033[7m', '\033[27m'], + 'black': ['\033[30m', '\033[39m'], + 'red': ['\033[31m', '\033[39m'], + 'green': ['\033[32m', '\033[39m'], + 'yellow': ['\033[33m', '\033[39m'], + 'blue': ['\033[34m', '\033[39m'], + 'magenta': ['\033[35m', '\033[39m'], + 'cyan': ['\033[36m', '\033[39m'], + 'white': ['\033[37m', '\033[39m'], + 'default': ['\033[39m', '\033[39m'], + 'grey': ['\033[90m', '\033[39m'], + 'bgBlack': ['\033[40m', '\033[49m'], + 'bgRed': ['\033[41m', '\033[49m'], + 'bgGreen': ['\033[42m', '\033[49m'], + 'bgYellow': ['\033[43m', '\033[49m'], + 'bgBlue': ['\033[44m', '\033[49m'], + 'bgMagenta': ['\033[45m', '\033[49m'], + 'bgCyan': ['\033[46m', '\033[49m'], + 'bgWhite': ['\033[47m', '\033[49m'], + 'bgDefault': ['\033[49m', '\033[49m'] +} +Object.keys(styles).forEach(function(style) { + Object.defineProperty(String.prototype, style, { + get: function() { return styles[style][0] + this + styles[style][1]; }, + enumerable: false + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/package.json new file mode 100644 index 00000000000..d3262379301 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/package.json @@ -0,0 +1,60 @@ +{ + "author": { + "name": "Einar Otto Stangvik", + "email": "einaros@gmail.com", + "url": "http://2x.io" + }, + "name": "ws", + "description": "simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455", + "version": "0.4.31", + "keywords": [ + "Hixie", + "HyBi", + "Push", + "RFC-6455", + "WebSocket", + "WebSockets", + "real-time" + ], + "repository": { + "type": "git", + "url": "git://github.com/einaros/ws.git" + }, + "bin": { + "wscat": "./bin/wscat" + }, + "scripts": { + "test": "make test", + "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)" + }, + "engines": { + "node": ">=0.4.0" + }, + "dependencies": { + "commander": "~0.6.1", + "nan": "~0.3.0", + "tinycolor": "0.x", + "options": ">=0.0.5" + }, + "devDependencies": { + "mocha": "1.12.0", + "should": "1.2.x", + "expect.js": "0.2.x", + "benchmark": "0.3.x", + "ansi": "latest" + }, + "browser": "./lib/browser.js", + "component": { + "scripts": { + "ws/index.js": "./lib/browser.js" + } + }, + "gypfile": true, + "readme": "[![Build Status](https://secure.travis-ci.org/einaros/ws.png)](http://travis-ci.org/einaros/ws)\n\n# ws: a node.js websocket library #\n\n`ws` is a simple to use websocket implementation, up-to-date against RFC-6455, and [probably the fastest WebSocket library for node.js](http://web.archive.org/web/20130314230536/http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs).\n\nPasses the quite extensive Autobahn test suite. See http://einaros.github.com/ws for the full reports.\n\nComes with a command line utility, `wscat`, which can either act as a server (--listen), or client (--connect); Use it to debug simple websocket services.\n\n## Protocol support ##\n\n* **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera. Added to ws version 0.4.2, but server only. Can be disabled by setting the `disableHixie` option to true.)\n* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`, or argument `-p 8` for wscat)\n* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`, or argument `-p 13` for wscat)\n\n_See the echo.websocket.org example below for how to use the `protocolVersion` option._\n\n## Usage ##\n\n### Installing ###\n\n`npm install ws`\n\n### Sending and receiving text data ###\n\n```js\nvar WebSocket = require('ws');\nvar ws = new WebSocket('ws://www.host.com/path');\nws.on('open', function() {\n ws.send('something');\n});\nws.on('message', function(data, flags) {\n // flags.binary will be set if a binary data is received\n // flags.masked will be set if the data was masked\n});\n```\n\n### Sending binary data ###\n\n```js\nvar WebSocket = require('ws');\nvar ws = new WebSocket('ws://www.host.com/path');\nws.on('open', function() {\n var array = new Float32Array(5);\n for (var i = 0; i < array.length; ++i) array[i] = i / 2;\n ws.send(array, {binary: true, mask: true});\n});\n```\n\nSetting `mask`, as done for the send options above, will cause the data to be masked according to the websocket protocol. The same option applies for text data.\n\n### Server example ###\n\n```js\nvar WebSocketServer = require('ws').Server\n , wss = new WebSocketServer({port: 8080});\nwss.on('connection', function(ws) {\n ws.on('message', function(message) {\n console.log('received: %s', message);\n });\n ws.send('something');\n});\n```\n\n### Server sending broadcast data ###\n\n```js\nvar WebSocketServer = require('ws').Server\n , wss = new WebSocketServer({port: 8080});\n \nwss.broadcast = function(data) {\n\tfor(var i in this.clients)\n\t\tthis.clients[i].send(data);\n};\n```\n\n### Error handling best practices ###\n\n```js\n// If the WebSocket is closed before the following send is attempted\nws.send('something');\n\n// Errors (both immediate and async write errors) can be detected in an optional callback.\n// The callback is also the only way of being notified that data has actually been sent.\nws.send('something', function(error) {\n // if error is null, the send has been completed,\n // otherwise the error object will indicate what failed.\n});\n\n// Immediate errors can also be handled with try/catch-blocks, but **note**\n// that since sends are inherently asynchronous, socket write failures will *not*\n// be captured when this technique is used.\ntry {\n ws.send('something');\n}\ncatch (e) {\n // handle error\n}\n```\n\n### echo.websocket.org demo ###\n\n```js\nvar WebSocket = require('ws');\nvar ws = new WebSocket('ws://echo.websocket.org/', {protocolVersion: 8, origin: 'http://websocket.org'});\nws.on('open', function() {\n console.log('connected');\n ws.send(Date.now().toString(), {mask: true});\n});\nws.on('close', function() {\n console.log('disconnected');\n});\nws.on('message', function(data, flags) {\n console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags);\n setTimeout(function() {\n ws.send(Date.now().toString(), {mask: true});\n }, 500);\n});\n```\n\n### wscat against echo.websocket.org ###\n\n $ npm install -g ws\n $ wscat -c ws://echo.websocket.org -p 8\n connected (press CTRL+C to quit)\n > hi there\n < hi there\n > are you a happy parrot?\n < are you a happy parrot?\n\n### Other examples ###\n\nFor a full example with a browser client communicating with a ws server, see the examples folder.\n\nNote that the usage together with Express 3.0 is quite different from Express 2.x. The difference is expressed in the two different serverstats-examples.\n\nOtherwise, see the test cases.\n\n### Running the tests ###\n\n`make test`\n\n## API Docs ##\n\nSee the doc/ directory for Node.js-like docs for the ws classes.\n\n## License ##\n\n(The MIT License)\n\nCopyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/einaros/ws/issues" + }, + "_id": "ws@0.4.31", + "_from": "ws@" +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/src/bufferutil.cc b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/src/bufferutil.cc new file mode 100644 index 00000000000..f06777f4e74 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/src/bufferutil.cc @@ -0,0 +1,117 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "nan.h" + +using namespace v8; +using namespace node; + +class BufferUtil : public ObjectWrap +{ +public: + + static void Initialize(v8::Handle target) + { + NanScope(); + Local t = FunctionTemplate::New(New); + t->InstanceTemplate()->SetInternalFieldCount(1); + NODE_SET_METHOD(t, "unmask", BufferUtil::Unmask); + NODE_SET_METHOD(t, "mask", BufferUtil::Mask); + NODE_SET_METHOD(t, "merge", BufferUtil::Merge); + target->Set(String::NewSymbol("BufferUtil"), t->GetFunction()); + } + +protected: + + static NAN_METHOD(New) + { + NanScope(); + BufferUtil* bufferUtil = new BufferUtil(); + bufferUtil->Wrap(args.This()); + NanReturnValue(args.This()); + } + + static NAN_METHOD(Merge) + { + NanScope(); + Local bufferObj = args[0]->ToObject(); + char* buffer = Buffer::Data(bufferObj); + Local array = Local::Cast(args[1]); + unsigned int arrayLength = array->Length(); + size_t offset = 0; + unsigned int i; + for (i = 0; i < arrayLength; ++i) { + Local src = array->Get(i)->ToObject(); + size_t length = Buffer::Length(src); + memcpy(buffer + offset, Buffer::Data(src), length); + offset += length; + } + NanReturnValue(True()); + } + + static NAN_METHOD(Unmask) + { + NanScope(); + Local buffer_obj = args[0]->ToObject(); + size_t length = Buffer::Length(buffer_obj); + Local mask_obj = args[1]->ToObject(); + unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); + unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj); + size_t len32 = length / 4; + unsigned int i; + for (i = 0; i < len32; ++i) *(from + i) ^= *mask; + from += i; + switch (length % 4) { + case 3: *((unsigned char*)from+2) = *((unsigned char*)from+2) ^ ((unsigned char*)mask)[2]; + case 2: *((unsigned char*)from+1) = *((unsigned char*)from+1) ^ ((unsigned char*)mask)[1]; + case 1: *((unsigned char*)from ) = *((unsigned char*)from ) ^ ((unsigned char*)mask)[0]; + case 0:; + } + NanReturnValue(True()); + } + + static NAN_METHOD(Mask) + { + NanScope(); + Local buffer_obj = args[0]->ToObject(); + Local mask_obj = args[1]->ToObject(); + unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); + Local output_obj = args[2]->ToObject(); + unsigned int dataOffset = args[3]->Int32Value(); + unsigned int length = args[4]->Int32Value(); + unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset); + unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj); + unsigned int len32 = length / 4; + unsigned int i; + for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask; + to += i; + from += i; + switch (length % 4) { + case 3: *((unsigned char*)to+2) = *((unsigned char*)from+2) ^ *((unsigned char*)mask+2); + case 2: *((unsigned char*)to+1) = *((unsigned char*)from+1) ^ *((unsigned char*)mask+1); + case 1: *((unsigned char*)to ) = *((unsigned char*)from ) ^ *((unsigned char*)mask); + case 0:; + } + NanReturnValue(True()); + } +}; + +extern "C" void init (Handle target) +{ + NanScope(); + BufferUtil::Initialize(target); +} + +NODE_MODULE(bufferutil, init) + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/src/validation.cc b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/src/validation.cc new file mode 100644 index 00000000000..528eda1f0dc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/src/validation.cc @@ -0,0 +1,145 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +#include +#include +#include +#include +#include +#include +#include +#include "nan.h" + +using namespace v8; +using namespace node; + +#define UNI_SUR_HIGH_START (uint32_t) 0xD800 +#define UNI_SUR_LOW_END (uint32_t) 0xDFFF +#define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD +#define UNI_MAX_LEGAL_UTF32 (uint32_t) 0x0010FFFF + +static const uint8_t trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +static const uint32_t offsetsFromUTF8[6] = { + 0x00000000, 0x00003080, 0x000E2080, + 0x03C82080, 0xFA082080, 0x82082080 +}; + +static int isLegalUTF8(const uint8_t *source, const int length) +{ + uint8_t a; + const uint8_t *srcptr = source+length; + switch (length) { + default: return 0; + /* Everything else falls through when "true"... */ + /* RFC3629 makes 5 & 6 bytes UTF-8 illegal + case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; + case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */ + case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; + case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; + case 2: if ((a = (*--srcptr)) > 0xBF) return 0; + switch (*source) { + /* no fall-through in this inner switch */ + case 0xE0: if (a < 0xA0) return 0; break; + case 0xED: if (a > 0x9F) return 0; break; + case 0xF0: if (a < 0x90) return 0; break; + case 0xF4: if (a > 0x8F) return 0; break; + default: if (a < 0x80) return 0; + } + + case 1: if (*source >= 0x80 && *source < 0xC2) return 0; + } + if (*source > 0xF4) return 0; + return 1; +} + +int is_valid_utf8 (size_t len, char *value) +{ + /* is the string valid UTF-8? */ + for (unsigned int i = 0; i < len; i++) { + uint32_t ch = 0; + uint8_t extrabytes = trailingBytesForUTF8[(uint8_t) value[i]]; + + if (extrabytes + i >= len) + return 0; + + if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0) return 0; + + switch (extrabytes) { + case 5 : ch += (uint8_t) value[i++]; ch <<= 6; + case 4 : ch += (uint8_t) value[i++]; ch <<= 6; + case 3 : ch += (uint8_t) value[i++]; ch <<= 6; + case 2 : ch += (uint8_t) value[i++]; ch <<= 6; + case 1 : ch += (uint8_t) value[i++]; ch <<= 6; + case 0 : ch += (uint8_t) value[i]; + } + + ch -= offsetsFromUTF8[extrabytes]; + + if (ch <= UNI_MAX_LEGAL_UTF32) { + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) + return 0; + } else { + return 0; + } + } + + return 1; +} + +class Validation : public ObjectWrap +{ +public: + + static void Initialize(v8::Handle target) + { + HandleScope scope; + Local t = FunctionTemplate::New(New); + t->InstanceTemplate()->SetInternalFieldCount(1); + NODE_SET_METHOD(t, "isValidUTF8", Validation::IsValidUTF8); + target->Set(String::NewSymbol("Validation"), t->GetFunction()); + } + +protected: + + static NAN_METHOD(New) + { + NanScope(); + Validation* validation = new Validation(); + validation->Wrap(args.This()); + NanReturnValue(args.This()); + } + + static NAN_METHOD(IsValidUTF8) + { + NanScope(); + if (!Buffer::HasInstance(args[0])) { + return NanThrowTypeError("First argument needs to be a buffer"); + } + Local buffer_obj = args[0]->ToObject(); + char *buffer_data = Buffer::Data(buffer_obj); + size_t buffer_length = Buffer::Length(buffer_obj); + NanReturnValue(is_valid_utf8(buffer_length, buffer_data) == 1 ? True() : False()); + } +}; + +extern "C" void init (Handle target) +{ + NanScope(); + Validation::Initialize(target); +} + +NODE_MODULE(validation, init) + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/BufferPool.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/BufferPool.test.js new file mode 100644 index 00000000000..1ee7ff0fe32 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/BufferPool.test.js @@ -0,0 +1,63 @@ +var BufferPool = require('../lib/BufferPool'); +require('should'); + +describe('BufferPool', function() { + describe('#ctor', function() { + it('allocates pool', function() { + var db = new BufferPool(1000); + db.size.should.eql(1000); + }); + }); + describe('#get', function() { + it('grows the pool if necessary', function() { + var db = new BufferPool(1000); + var buf = db.get(2000); + db.size.should.be.above(1000); + db.used.should.eql(2000); + buf.length.should.eql(2000); + }); + it('grows the pool after the first call, if necessary', function() { + var db = new BufferPool(1000); + var buf = db.get(1000); + db.used.should.eql(1000); + db.size.should.eql(1000); + buf.length.should.eql(1000); + var buf2 = db.get(1000); + db.used.should.eql(2000); + db.size.should.be.above(1000); + buf2.length.should.eql(1000); + }); + it('grows the pool according to the growStrategy if necessary', function() { + var db = new BufferPool(1000, function(db, length) { + return db.size + 2345; + }); + var buf = db.get(2000); + db.size.should.eql(3345); + buf.length.should.eql(2000); + }); + it('doesnt grow the pool if theres enough room available', function() { + var db = new BufferPool(1000); + var buf = db.get(1000); + db.size.should.eql(1000); + buf.length.should.eql(1000); + }); + }); + describe('#reset', function() { + it('shinks the pool', function() { + var db = new BufferPool(1000); + var buf = db.get(2000); + db.reset(true); + db.size.should.eql(1000); + }); + it('shrinks the pool according to the shrinkStrategy', function() { + var db = new BufferPool(1000, function(db, length) { + return db.used + length; + }, function(db) { + return 0; + }); + var buf = db.get(2000); + db.reset(true); + db.size.should.eql(0); + }); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Receiver.hixie.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Receiver.hixie.test.js new file mode 100644 index 00000000000..043d3bc409a --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Receiver.hixie.test.js @@ -0,0 +1,158 @@ +var assert = require('assert') + , expect = require('expect.js') + , Receiver = require('../lib/Receiver.hixie'); +require('./hybi-common'); + +describe('Receiver', function() { + it('can parse text message', function() { + var p = new Receiver(); + var packet = '00 48 65 6c 6c 6f ff'; + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal('Hello', data); + }; + + p.add(getBufferFromHexString(packet)); + expect(gotData).to.equal(true); + }); + + it('can parse multiple text messages', function() { + var p = new Receiver(); + var packet = '00 48 65 6c 6c 6f ff 00 48 65 6c 6c 6f ff'; + + var gotData = false; + var messages = []; + p.ontext = function(data) { + gotData = true; + messages.push(data); + }; + + p.add(getBufferFromHexString(packet)); + expect(gotData).to.equal(true); + for (var i = 0; i < 2; ++i) { + expect(messages[i]).to.equal('Hello'); + } + }); + + it('can parse empty message', function() { + var p = new Receiver(); + var packet = '00 ff'; + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal('', data); + }; + + p.add(getBufferFromHexString(packet)); + expect(gotData).to.equal(true); + }); + + it('can parse text messages delivered over multiple frames', function() { + var p = new Receiver(); + var packets = [ + '00 48', + '65 6c 6c', + '6f ff 00 48', + '65', + '6c 6c 6f', + 'ff' + ]; + + var gotData = false; + var messages = []; + p.ontext = function(data) { + gotData = true; + messages.push(data); + }; + + for (var i = 0; i < packets.length; ++i) { + p.add(getBufferFromHexString(packets[i])); + } + expect(gotData).to.equal(true); + for (var i = 0; i < 2; ++i) { + expect(messages[i]).to.equal('Hello'); + } + }); + + it('emits an error if a payload doesnt start with 0x00', function() { + var p = new Receiver(); + var packets = [ + '00 6c ff', + '00 6c ff ff', + 'ff 00 6c ff 00 6c ff', + '00', + '6c 6c 6f', + 'ff' + ]; + + var gotData = false; + var gotError = false; + var messages = []; + p.ontext = function(data) { + gotData = true; + messages.push(data); + }; + p.onerror = function(reason, code) { + gotError = code == true; + }; + + for (var i = 0; i < packets.length && !gotError; ++i) { + p.add(getBufferFromHexString(packets[i])); + } + expect(gotError).to.equal(true); + expect(messages[0]).to.equal('l'); + expect(messages[1]).to.equal('l'); + expect(messages.length).to.equal(2); + }); + + it('can parse close messages', function() { + var p = new Receiver(); + var packets = [ + 'ff 00' + ]; + + var gotClose = false; + var gotError = false; + p.onclose = function() { + gotClose = true; + }; + p.onerror = function(reason, code) { + gotError = code == true; + }; + + for (var i = 0; i < packets.length && !gotError; ++i) { + p.add(getBufferFromHexString(packets[i])); + } + expect(gotClose).to.equal(true); + expect(gotError).to.equal(false); + }); + + it('can parse binary messages delivered over multiple frames', function() { + var p = new Receiver(); + var packets = [ + '80 05 48', + '65 6c 6c', + '6f 80 80 05 48', + '65', + '6c 6c 6f' + ]; + + var gotData = false; + var messages = []; + p.ontext = function(data) { + gotData = true; + messages.push(data); + }; + + for (var i = 0; i < packets.length; ++i) { + p.add(getBufferFromHexString(packets[i])); + } + expect(gotData).to.equal(true); + for (var i = 0; i < 2; ++i) { + expect(messages[i]).to.equal('Hello'); + } + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Receiver.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Receiver.test.js new file mode 100644 index 00000000000..b0b5c0a4cee --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Receiver.test.js @@ -0,0 +1,255 @@ +var assert = require('assert') + , Receiver = require('../lib/Receiver'); +require('should'); +require('./hybi-common'); + +describe('Receiver', function() { + it('can parse unmasked text message', function() { + var p = new Receiver(); + var packet = '81 05 48 65 6c 6c 6f'; + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal('Hello', data); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); + it('can parse close message', function() { + var p = new Receiver(); + var packet = '88 00'; + + var gotClose = false; + p.onclose = function(data) { + gotClose = true; + }; + + p.add(getBufferFromHexString(packet)); + gotClose.should.be.ok; + }); + it('can parse masked text message', function() { + var p = new Receiver(); + var packet = '81 93 34 83 a8 68 01 b9 92 52 4f a1 c6 09 59 e6 8a 52 16 e6 cb 00 5b a1 d5'; + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal('5:::{"name":"echo"}', data); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); + it('can parse a masked text message longer than 125 bytes', function() { + var p = new Receiver(); + var message = 'A'; + for (var i = 0; i < 300; ++i) message += (i % 5).toString(); + var packet = '81 FE ' + pack(4, message.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68')); + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal(message, data); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); + it('can parse a really long masked text message', function() { + var p = new Receiver(); + var message = 'A'; + for (var i = 0; i < 64*1024; ++i) message += (i % 5).toString(); + var packet = '81 FF ' + pack(16, message.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68')); + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal(message, data); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); + it('can parse a fragmented masked text message of 300 bytes', function() { + var p = new Receiver(); + var message = 'A'; + for (var i = 0; i < 300; ++i) message += (i % 5).toString(); + var msgpiece1 = message.substr(0, 150); + var msgpiece2 = message.substr(150); + var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68')); + var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68')); + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal(message, data); + }; + + p.add(getBufferFromHexString(packet1)); + p.add(getBufferFromHexString(packet2)); + gotData.should.be.ok; + }); + it('can parse a ping message', function() { + var p = new Receiver(); + var message = 'Hello'; + var packet = '89 ' + getHybiLengthAsHexString(message.length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68')); + + var gotPing = false; + p.onping = function(data) { + gotPing = true; + assert.equal(message, data); + }; + + p.add(getBufferFromHexString(packet)); + gotPing.should.be.ok; + }); + it('can parse a ping with no data', function() { + var p = new Receiver(); + var packet = '89 00'; + + var gotPing = false; + p.onping = function(data) { + gotPing = true; + }; + + p.add(getBufferFromHexString(packet)); + gotPing.should.be.ok; + }); + it('can parse a fragmented masked text message of 300 bytes with a ping in the middle', function() { + var p = new Receiver(); + var message = 'A'; + for (var i = 0; i < 300; ++i) message += (i % 5).toString(); + + var msgpiece1 = message.substr(0, 150); + var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68')); + + var pingMessage = 'Hello'; + var pingPacket = '89 ' + getHybiLengthAsHexString(pingMessage.length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68')); + + var msgpiece2 = message.substr(150); + var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68')); + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal(message, data); + }; + var gotPing = false; + p.onping = function(data) { + gotPing = true; + assert.equal(pingMessage, data); + }; + + p.add(getBufferFromHexString(packet1)); + p.add(getBufferFromHexString(pingPacket)); + p.add(getBufferFromHexString(packet2)); + gotData.should.be.ok; + gotPing.should.be.ok; + }); + it('can parse a fragmented masked text message of 300 bytes with a ping in the middle, which is delievered over sevaral tcp packets', function() { + var p = new Receiver(); + var message = 'A'; + for (var i = 0; i < 300; ++i) message += (i % 5).toString(); + + var msgpiece1 = message.substr(0, 150); + var packet1 = '01 FE ' + pack(4, msgpiece1.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece1, '34 83 a8 68')); + + var pingMessage = 'Hello'; + var pingPacket = '89 ' + getHybiLengthAsHexString(pingMessage.length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68')); + + var msgpiece2 = message.substr(150); + var packet2 = '80 FE ' + pack(4, msgpiece2.length) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(msgpiece2, '34 83 a8 68')); + + var gotData = false; + p.ontext = function(data) { + gotData = true; + assert.equal(message, data); + }; + var gotPing = false; + p.onping = function(data) { + gotPing = true; + assert.equal(pingMessage, data); + }; + + var buffers = []; + buffers = buffers.concat(splitBuffer(getBufferFromHexString(packet1))); + buffers = buffers.concat(splitBuffer(getBufferFromHexString(pingPacket))); + buffers = buffers.concat(splitBuffer(getBufferFromHexString(packet2))); + for (var i = 0; i < buffers.length; ++i) { + p.add(buffers[i]); + } + gotData.should.be.ok; + gotPing.should.be.ok; + }); + it('can parse a 100 byte long masked binary message', function() { + var p = new Receiver(); + var length = 100; + var message = new Buffer(length); + for (var i = 0; i < length; ++i) message[i] = i % 256; + var originalMessage = getHexStringFromBuffer(message); + var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68')); + + var gotData = false; + p.onbinary = function(data) { + gotData = true; + assert.equal(originalMessage, getHexStringFromBuffer(data)); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); + it('can parse a 256 byte long masked binary message', function() { + var p = new Receiver(); + var length = 256; + var message = new Buffer(length); + for (var i = 0; i < length; ++i) message[i] = i % 256; + var originalMessage = getHexStringFromBuffer(message); + var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68')); + + var gotData = false; + p.onbinary = function(data) { + gotData = true; + assert.equal(originalMessage, getHexStringFromBuffer(data)); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); + it('can parse a 200kb long masked binary message', function() { + var p = new Receiver(); + var length = 200 * 1024; + var message = new Buffer(length); + for (var i = 0; i < length; ++i) message[i] = i % 256; + var originalMessage = getHexStringFromBuffer(message); + var packet = '82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' + getHexStringFromBuffer(mask(message, '34 83 a8 68')); + + var gotData = false; + p.onbinary = function(data) { + gotData = true; + assert.equal(originalMessage, getHexStringFromBuffer(data)); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); + it('can parse a 200kb long unmasked binary message', function() { + var p = new Receiver(); + var length = 200 * 1024; + var message = new Buffer(length); + for (var i = 0; i < length; ++i) message[i] = i % 256; + var originalMessage = getHexStringFromBuffer(message); + var packet = '82 ' + getHybiLengthAsHexString(length, false) + ' ' + getHexStringFromBuffer(message); + + var gotData = false; + p.onbinary = function(data) { + gotData = true; + assert.equal(originalMessage, getHexStringFromBuffer(data)); + }; + + p.add(getBufferFromHexString(packet)); + gotData.should.be.ok; + }); +}); + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Sender.hixie.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Sender.hixie.test.js new file mode 100644 index 00000000000..783f89227b5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Sender.hixie.test.js @@ -0,0 +1,134 @@ +var assert = require('assert') + , Sender = require('../lib/Sender.hixie'); +require('should'); +require('./hybi-common'); + +describe('Sender', function() { + describe('#send', function() { + it('frames and sends a text message', function(done) { + var message = 'Hello world'; + var received; + var socket = { + write: function(data, encoding, cb) { + received = data; + process.nextTick(cb); + } + }; + var sender = new Sender(socket, {}); + sender.send(message, {}, function() { + received.toString('utf8').should.eql('\u0000' + message + '\ufffd'); + done(); + }); + }); + + it('frames and sends an empty message', function(done) { + var socket = { + write: function(data, encoding, cb) { + done(); + } + }; + var sender = new Sender(socket, {}); + sender.send('', {}, function() {}); + }); + + it('frames and sends a buffer', function(done) { + var received; + var socket = { + write: function(data, encoding, cb) { + received = data; + process.nextTick(cb); + } + }; + var sender = new Sender(socket, {}); + sender.send(new Buffer('foobar'), {}, function() { + received.toString('utf8').should.eql('\u0000foobar\ufffd'); + done(); + }); + }); + + it('frames and sends a binary message', function(done) { + var message = 'Hello world'; + var received; + var socket = { + write: function(data, encoding, cb) { + received = data; + process.nextTick(cb); + } + }; + var sender = new Sender(socket, {}); + sender.send(message, {binary: true}, function() { + received.toString('hex').should.eql( + // 0x80 0x0b H e l l o w o r l d + '800b48656c6c6f20776f726c64'); + done(); + }); + }); +/* + it('throws an exception for binary data', function(done) { + var socket = { + write: function(data, encoding, cb) { + process.nextTick(cb); + } + }; + var sender = new Sender(socket, {}); + sender.on('error', function() { + done(); + }); + sender.send(new Buffer(100), {binary: true}, function() {}); + }); +*/ + it('can fauxe stream data', function(done) { + var received = []; + var socket = { + write: function(data, encoding, cb) { + received.push(data); + process.nextTick(cb); + } + }; + var sender = new Sender(socket, {}); + sender.send(new Buffer('foobar'), { fin: false }, function() {}); + sender.send('bazbar', { fin: false }, function() {}); + sender.send(new Buffer('end'), { fin: true }, function() { + received[0].toString('utf8').should.eql('\u0000foobar'); + received[1].toString('utf8').should.eql('bazbar'); + received[2].toString('utf8').should.eql('end\ufffd'); + done(); + }); + }); + }); + + describe('#close', function() { + it('sends a hixie close frame', function(done) { + var received; + var socket = { + write: function(data, encoding, cb) { + received = data; + process.nextTick(cb); + } + }; + var sender = new Sender(socket, {}); + sender.close(null, null, null, function() { + received.toString('utf8').should.eql('\ufffd\u0000'); + done(); + }); + }); + + it('sends a message end marker if fauxe streaming has started, before hixie close frame', function(done) { + var received = []; + var socket = { + write: function(data, encoding, cb) { + received.push(data); + if (cb) process.nextTick(cb); + } + }; + var sender = new Sender(socket, {}); + sender.send(new Buffer('foobar'), { fin: false }, function() {}); + sender.close(null, null, null, function() { + received[0].toString('utf8').should.eql('\u0000foobar'); + received[1].toString('utf8').should.eql('\ufffd'); + received[2].toString('utf8').should.eql('\ufffd\u0000'); + done(); + }); + }); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Sender.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Sender.test.js new file mode 100644 index 00000000000..43b4864ddea --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Sender.test.js @@ -0,0 +1,24 @@ +var Sender = require('../lib/Sender'); +require('should'); + +describe('Sender', function() { + describe('#frameAndSend', function() { + it('does not modify a masked binary buffer', function() { + var sender = new Sender({ write: function() {} }); + var buf = new Buffer([1, 2, 3, 4, 5]); + sender.frameAndSend(2, buf, true, true); + buf[0].should.eql(1); + buf[1].should.eql(2); + buf[2].should.eql(3); + buf[3].should.eql(4); + buf[4].should.eql(5); + }); + + it('does not modify a masked text buffer', function() { + var sender = new Sender({ write: function() {} }); + var text = 'hi there'; + sender.frameAndSend(1, text, true, true); + text.should.eql('hi there'); + }); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Validation.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Validation.test.js new file mode 100644 index 00000000000..37c339935f5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/Validation.test.js @@ -0,0 +1,23 @@ +var Validation = require('../lib/Validation').Validation; +require('should'); + +describe('Validation', function() { + describe('isValidUTF8', function() { + it('should return true for a valid utf8 string', function() { + var validBuffer = new Buffer('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque gravida mattis rhoncus. Donec iaculis, metus quis varius accumsan, erat mauris condimentum diam, et egestas erat enim ut ligula. Praesent sollicitudin tellus eget dolor euismod euismod. Nullam ac augue nec neque varius luctus. Curabitur elit mi, consequat ultricies adipiscing mollis, scelerisque in erat. Phasellus facilisis fermentum ullamcorper. Nulla et sem eu arcu pharetra pellentesque. Praesent consectetur tempor justo, vel iaculis dui ullamcorper sit amet. Integer tristique viverra ullamcorper. Vivamus laoreet, nulla eget suscipit eleifend, lacus lectus feugiat libero, non fermentum erat nisi at risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut pulvinar dignissim tellus, eu dignissim lorem vulputate quis. Morbi ut pulvinar augue.'); + Validation.isValidUTF8(validBuffer).should.be.ok; + }); + it('should return false for an erroneous string', function() { + var invalidBuffer = new Buffer([0xce, 0xba, 0xe1, 0xbd, 0xb9, 0xcf, 0x83, 0xce, 0xbc, 0xce, 0xb5, 0xed, 0xa0, 0x80, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64]); + Validation.isValidUTF8(invalidBuffer).should.not.be.ok; + }); + it('should return true for valid cases from the autobahn test suite', function() { + Validation.isValidUTF8(new Buffer('\xf0\x90\x80\x80')).should.be.ok; + Validation.isValidUTF8(new Buffer([0xf0, 0x90, 0x80, 0x80])).should.be.ok; + }); + it('should return false for erroneous autobahn strings', function() { + Validation.isValidUTF8(new Buffer([0xce, 0xba, 0xe1, 0xbd])).should.not.be.ok; + }); + }); +}); + diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocket.integration.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocket.integration.js new file mode 100644 index 00000000000..5d4f426f4d3 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocket.integration.js @@ -0,0 +1,44 @@ +var assert = require('assert') + , WebSocket = require('../') + , server = require('./testserver'); + +var port = 20000; + +function getArrayBuffer(buf) { + var l = buf.length; + var arrayBuf = new ArrayBuffer(l); + var uint8View = new Uint8Array(arrayBuf); + + for (var i = 0; i < l; i++) { + uint8View[i] = buf[i]; + } + return uint8View.buffer; +} + +function areArraysEqual(x, y) { + if (x.length != y.length) return false; + for (var i = 0, l = x.length; i < l; ++i) { + if (x[i] !== y[i]) return false; + } + return true; +} + +describe('WebSocket', function() { + it('communicates successfully with echo service', function(done) { + var ws = new WebSocket('ws://echo.websocket.org/', {protocolVersion: 13, origin: 'http://websocket.org'}); + var str = Date.now().toString(); + var dataReceived = false; + ws.on('open', function() { + ws.send(str, {mask: true}); + }); + ws.on('close', function() { + assert.equal(true, dataReceived); + done(); + }); + ws.on('message', function(data, flags) { + assert.equal(str, data); + ws.terminate(); + dataReceived = true; + }); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocket.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocket.test.js new file mode 100644 index 00000000000..91336b9340c --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocket.test.js @@ -0,0 +1,1724 @@ +var assert = require('assert') + , https = require('https') + , http = require('http') + , should = require('should') + , WebSocket = require('../') + , WebSocketServer = require('../').Server + , fs = require('fs') + , server = require('./testserver') + , crypto = require('crypto'); + +var port = 20000; + +function getArrayBuffer(buf) { + var l = buf.length; + var arrayBuf = new ArrayBuffer(l); + var uint8View = new Uint8Array(arrayBuf); + for (var i = 0; i < l; i++) { + uint8View[i] = buf[i]; + } + return uint8View.buffer; +} + + +function areArraysEqual(x, y) { + if (x.length != y.length) return false; + for (var i = 0, l = x.length; i < l; ++i) { + if (x[i] !== y[i]) return false; + } + return true; +} + +describe('WebSocket', function() { + describe('#ctor', function() { + it('throws exception for invalid url', function(done) { + try { + var ws = new WebSocket('echo.websocket.org'); + } + catch (e) { + done(); + } + }); + }); + + describe('options', function() { + it('should accept an `agent` option', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var agent = { + addRequest: function() { + wss.close(); + done(); + } + }; + var ws = new WebSocket('ws://localhost:' + port, { agent: agent }); + }); + }); + // GH-227 + it('should accept the `options` object as the 3rd argument', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var agent = { + addRequest: function() { + wss.close(); + done(); + } + }; + var ws = new WebSocket('ws://localhost:' + port, [], { agent: agent }); + }); + }); + }); + + describe('properties', function() { + it('#bytesReceived exposes number of bytes received', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('message', function() { + ws.bytesReceived.should.eql(8); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + ws.send('foobar'); + }); + }); + + it('#url exposes the server url', function(done) { + server.createServer(++port, function(srv) { + var url = 'ws://localhost:' + port; + var ws = new WebSocket(url); + assert.equal(url, ws.url); + ws.terminate(); + ws.on('close', function() { + srv.close(); + done(); + }); + }); + }); + + it('#protocolVersion exposes the protocol version', function(done) { + server.createServer(++port, function(srv) { + var url = 'ws://localhost:' + port; + var ws = new WebSocket(url); + assert.equal(13, ws.protocolVersion); + ws.terminate(); + ws.on('close', function() { + srv.close(); + done(); + }); + }); + }); + + describe('#bufferedAmount', function() { + it('defaults to zero', function(done) { + server.createServer(++port, function(srv) { + var url = 'ws://localhost:' + port; + var ws = new WebSocket(url); + assert.equal(0, ws.bufferedAmount); + ws.terminate(); + ws.on('close', function() { + srv.close(); + done(); + }); + }); + }); + + it('defaults to zero upon "open"', function(done) { + server.createServer(++port, function(srv) { + var url = 'ws://localhost:' + port; + var ws = new WebSocket(url); + ws.onopen = function() { + assert.equal(0, ws.bufferedAmount); + ws.terminate(); + ws.on('close', function() { + srv.close(); + done(); + }); + }; + }); + }); + + it('stress kernel write buffer', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(ws) { + while (true) { + if (ws.bufferedAmount > 0) break; + ws.send((new Array(10000)).join('hello')); + } + ws.terminate(); + ws.on('close', function() { + wss.close(); + done(); + }); + }); + }); + }); + + describe('Custom headers', function() { + it('request has an authorization header', function (done) { + var auth = 'test:testpass'; + var srv = http.createServer(function (req, res) {}); + var wss = new WebSocketServer({server: srv}); + srv.listen(++port); + var ws = new WebSocket('ws://' + auth + '@localhost:' + port); + srv.on('upgrade', function (req, socket, head) { + assert(req.headers.authorization, 'auth header exists'); + assert.equal(req.headers.authorization, 'Basic ' + new Buffer(auth).toString('base64')); + ws.terminate(); + ws.on('close', function () { + srv.close(); + wss.close(); + done(); + }); + }); + }); + + it('accepts custom headers', function (done) { + var srv = http.createServer(function (req, res) {}); + var wss = new WebSocketServer({server: srv}); + srv.listen(++port); + + var ws = new WebSocket('ws://localhost:' + port, { + headers: { + 'Cookie': 'foo=bar' + } + }); + + srv.on('upgrade', function (req, socket, head) { + assert(req.headers.cookie, 'auth header exists'); + assert.equal(req.headers.cookie, 'foo=bar'); + + ws.terminate(); + ws.on('close', function () { + srv.close(); + wss.close(); + done(); + }); + }); + }); + }); + + describe('#readyState', function() { + it('defaults to connecting', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + assert.equal(WebSocket.CONNECTING, ws.readyState); + ws.terminate(); + ws.on('close', function() { + srv.close(); + done(); + }); + }); + }); + + it('set to open once connection is established', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + assert.equal(WebSocket.OPEN, ws.readyState); + srv.close(); + done(); + }); + }); + }); + + it('set to closed once connection is closed', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.close(1001); + ws.on('close', function() { + assert.equal(WebSocket.CLOSED, ws.readyState); + srv.close(); + done(); + }); + }); + }); + + it('set to closed once connection is terminated', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.terminate(); + ws.on('close', function() { + assert.equal(WebSocket.CLOSED, ws.readyState); + srv.close(); + done(); + }); + }); + }); + }); + + /* + * Ready state constants + */ + + var readyStates = { + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3 + }; + + /* + * Ready state constant tests + */ + + Object.keys(readyStates).forEach(function(state) { + describe('.' + state, function() { + it('is enumerable property of class', function() { + var propertyDescripter = Object.getOwnPropertyDescriptor(WebSocket, state) + assert.equal(readyStates[state], propertyDescripter.value); + assert.equal(true, propertyDescripter.enumerable); + }); + }); + }); + + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + Object.keys(readyStates).forEach(function(state) { + describe('.' + state, function() { + it('is property of instance', function() { + assert.equal(readyStates[state], ws[state]); + }); + }); + }); + }); + }); + + describe('events', function() { + it('emits a ping event', function(done) { + var wss = new WebSocketServer({port: ++port}); + wss.on('connection', function(client) { + client.ping(); + }); + var ws = new WebSocket('ws://localhost:' + port); + ws.on('ping', function() { + ws.terminate(); + wss.close(); + done(); + }); + }); + + it('emits a pong event', function(done) { + var wss = new WebSocketServer({port: ++port}); + wss.on('connection', function(client) { + client.pong(); + }); + var ws = new WebSocket('ws://localhost:' + port); + ws.on('pong', function() { + ws.terminate(); + wss.close(); + done(); + }); + }); + }); + + describe('connection establishing', function() { + it('can disconnect before connection is established', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.terminate(); + ws.on('open', function() { + assert.fail('connect shouldnt be raised here'); + }); + ws.on('close', function() { + srv.close(); + done(); + }); + }); + }); + + it('can close before connection is established', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.close(1001); + ws.on('open', function() { + assert.fail('connect shouldnt be raised here'); + }); + ws.on('close', function() { + srv.close(); + done(); + }); + }); + }); + + it('invalid server key is denied', function(done) { + server.createServer(++port, server.handlers.invalidKey, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() { + srv.close(); + done(); + }); + }); + }); + + it('close event is raised when server closes connection', function(done) { + server.createServer(++port, server.handlers.closeAfterConnect, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('close', function() { + srv.close(); + done(); + }); + }); + }); + + it('error is emitted if server aborts connection', function(done) { + server.createServer(++port, server.handlers.return401, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + assert.fail('connect shouldnt be raised here'); + }); + ws.on('error', function() { + srv.close(); + done(); + }); + }); + }); + }); + + describe('#pause and #resume', function() { + it('pauses the underlying stream', function(done) { + // this test is sort-of racecondition'y, since an unlikely slow connection + // to localhost can cause the test to succeed even when the stream pausing + // isn't working as intended. that is an extremely unlikely scenario, though + // and an acceptable risk for the test. + var client; + var serverClient; + var openCount = 0; + function onOpen() { + if (++openCount == 2) { + var paused = true; + serverClient.on('message', function() { + paused.should.not.be.ok; + wss.close(); + done(); + }); + serverClient.pause(); + setTimeout(function() { + paused = false; + serverClient.resume(); + }, 200); + client.send('foo'); + } + } + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + serverClient = ws; + serverClient.on('open', onOpen); + }); + wss.on('connection', function(ws) { + client = ws; + onOpen(); + }); + }); + }); + + describe('#ping', function() { + it('before connect should fail', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() {}); + try { + ws.ping(); + } + catch (e) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + + it('before connect can silently fail', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() {}); + ws.ping('', {}, true); + srv.close(); + ws.terminate(); + done(); + }); + }); + + it('without message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.ping(); + }); + srv.on('ping', function(message) { + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.ping('hi'); + }); + srv.on('ping', function(message) { + assert.equal('hi', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with encoded message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.ping('hi', {mask: true}); + }); + srv.on('ping', function(message, flags) { + assert.ok(flags.masked); + assert.equal('hi', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + }); + + describe('#pong', function() { + it('before connect should fail', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() {}); + try { + ws.pong(); + } + catch (e) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + + it('before connect can silently fail', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() {}); + ws.pong('', {}, true); + srv.close(); + ws.terminate(); + done(); + }); + }); + + it('without message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.pong(); + }); + srv.on('pong', function(message) { + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.pong('hi'); + }); + srv.on('pong', function(message) { + assert.equal('hi', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with encoded message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.pong('hi', {mask: true}); + }); + srv.on('pong', function(message, flags) { + assert.ok(flags.masked); + assert.equal('hi', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + }); + + describe('#send', function() { + it('very long binary data can be sent and received (with echoing server)', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var array = new Float32Array(5 * 1024 * 1024); + for (var i = 0; i < array.length; ++i) array[i] = i / 5; + ws.on('open', function() { + ws.send(array, {binary: true}); + }); + ws.on('message', function(message, flags) { + assert.ok(flags.binary); + assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message)))); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('can send and receive text data', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.send('hi'); + }); + ws.on('message', function(message, flags) { + assert.equal('hi', message); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('send and receive binary data as an array', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var array = new Float32Array(6); + for (var i = 0; i < array.length; ++i) array[i] = i / 2; + var partial = array.subarray(2, 5); + ws.on('open', function() { + ws.send(partial, {binary: true}); + }); + ws.on('message', function(message, flags) { + assert.ok(flags.binary); + assert.ok(areArraysEqual(partial, new Float32Array(getArrayBuffer(message)))); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('binary data can be sent and received as buffer', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var buf = new Buffer('foobar'); + ws.on('open', function() { + ws.send(buf, {binary: true}); + }); + ws.on('message', function(message, flags) { + assert.ok(flags.binary); + assert.ok(areArraysEqual(buf, message)); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('ArrayBuffer is auto-detected without binary flag', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var array = new Float32Array(5); + for (var i = 0; i < array.length; ++i) array[i] = i / 2; + ws.on('open', function() { + ws.send(array.buffer); + }); + ws.onmessage = function (event) { + assert.ok(event.type = 'Binary'); + assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(event.data)))); + ws.terminate(); + srv.close(); + done(); + }; + }); + }); + + it('Buffer is auto-detected without binary flag', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var buf = new Buffer('foobar'); + ws.on('open', function() { + ws.send(buf); + }); + ws.onmessage = function (event) { + assert.ok(event.type = 'Binary'); + assert.ok(areArraysEqual(event.data, buf)); + ws.terminate(); + srv.close(); + done(); + }; + }); + }); + + it('before connect should fail', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() {}); + try { + ws.send('hi'); + } + catch (e) { + ws.terminate(); + srv.close(); + done(); + } + }); + }); + + it('before connect should pass error through callback, if present', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() {}); + ws.send('hi', function(error) { + assert.ok(error instanceof Error); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('without data should be successful', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.send(); + }); + srv.on('message', function(message, flags) { + assert.equal('', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('calls optional callback when flushed', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.send('hi', function() { + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + }); + + it('with unencoded message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.send('hi'); + }); + srv.on('message', function(message, flags) { + assert.equal('hi', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with encoded message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.send('hi', {mask: true}); + }); + srv.on('message', function(message, flags) { + assert.ok(flags.masked); + assert.equal('hi', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with unencoded binary message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var array = new Float32Array(5); + for (var i = 0; i < array.length; ++i) array[i] = i / 2; + ws.on('open', function() { + ws.send(array, {binary: true}); + }); + srv.on('message', function(message, flags) { + assert.ok(flags.binary); + assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message)))); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with encoded binary message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var array = new Float32Array(5); + for (var i = 0; i < array.length; ++i) array[i] = i / 2; + ws.on('open', function() { + ws.send(array, {mask: true, binary: true}); + }); + srv.on('message', function(message, flags) { + assert.ok(flags.binary); + assert.ok(flags.masked); + assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message)))); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with binary stream will send fragmented data', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var callbackFired = false; + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.bufferSize = 100; + ws.send(fileStream, {binary: true}, function(error) { + assert.equal(null, error); + callbackFired = true; + }); + }); + srv.on('message', function(data, flags) { + assert.ok(flags.binary); + assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile'), data)); + ws.terminate(); + }); + ws.on('close', function() { + assert.ok(callbackFired); + srv.close(); + done(); + }); + }); + }); + + it('with text stream will send fragmented data', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var callbackFired = false; + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.setEncoding('utf8'); + fileStream.bufferSize = 100; + ws.send(fileStream, {binary: false}, function(error) { + assert.equal(null, error); + callbackFired = true; + }); + }); + srv.on('message', function(data, flags) { + assert.ok(!flags.binary); + assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data)); + ws.terminate(); + }); + ws.on('close', function() { + assert.ok(callbackFired); + srv.close(); + done(); + }); + }); + }); + + it('will cause intermittent send to be delayed in order', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.setEncoding('utf8'); + fileStream.bufferSize = 100; + ws.send(fileStream); + ws.send('foobar'); + ws.send('baz'); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + ++receivedIndex; + if (receivedIndex == 1) { + assert.ok(!flags.binary); + assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data)); + } + else if (receivedIndex == 2) { + assert.ok(!flags.binary); + assert.equal('foobar', data); + } + else { + assert.ok(!flags.binary); + assert.equal('baz', data); + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent stream to be delayed in order', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.setEncoding('utf8'); + fileStream.bufferSize = 100; + ws.send(fileStream); + var i = 0; + ws.stream(function(error, send) { + assert.ok(!error); + if (++i == 1) send('foo'); + else send('bar', true); + }); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + ++receivedIndex; + if (receivedIndex == 1) { + assert.ok(!flags.binary); + assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data)); + } + else if (receivedIndex == 2) { + assert.ok(!flags.binary); + assert.equal('foobar', data); + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent ping to be delivered', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.setEncoding('utf8'); + fileStream.bufferSize = 100; + ws.send(fileStream); + ws.ping('foobar'); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + assert.ok(!flags.binary); + assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data)); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + srv.on('ping', function(data) { + assert.equal('foobar', data); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent pong to be delivered', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.setEncoding('utf8'); + fileStream.bufferSize = 100; + ws.send(fileStream); + ws.pong('foobar'); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + assert.ok(!flags.binary); + assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data)); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + srv.on('pong', function(data) { + assert.equal('foobar', data); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent close to be delivered', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.setEncoding('utf8'); + fileStream.bufferSize = 100; + ws.send(fileStream); + ws.close(1000, 'foobar'); + }); + ws.on('close', function() { + srv.close(); + ws.terminate(); + done(); + }); + ws.on('error', function() { /* That's quite alright -- a send was attempted after close */ }); + srv.on('message', function(data, flags) { + assert.ok(!flags.binary); + assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data)); + }); + srv.on('close', function(code, data) { + assert.equal(1000, code); + assert.equal('foobar', data); + }); + }); + }); + }); + + describe('#stream', function() { + it('very long binary data can be streamed', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var buffer = new Buffer(10 * 1024); + for (var i = 0; i < buffer.length; ++i) buffer[i] = i % 0xff; + ws.on('open', function() { + var i = 0; + var blockSize = 800; + var bufLen = buffer.length; + ws.stream({binary: true}, function(error, send) { + assert.ok(!error); + var start = i * blockSize; + var toSend = Math.min(blockSize, bufLen - (i * blockSize)); + var end = start + toSend; + var isFinal = toSend < blockSize; + send(buffer.slice(start, end), isFinal); + i += 1; + }); + }); + srv.on('message', function(data, flags) { + assert.ok(flags.binary); + assert.ok(areArraysEqual(buffer, data)); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('before connect should pass error through callback', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('error', function() {}); + ws.stream(function(error) { + assert.ok(error instanceof Error); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('without callback should fail', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var payload = 'HelloWorld'; + ws.on('open', function() { + try { + ws.stream(); + } + catch (e) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent send to be delayed in order', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var payload = 'HelloWorld'; + ws.on('open', function() { + var i = 0; + ws.stream(function(error, send) { + assert.ok(!error); + if (++i == 1) { + send(payload.substr(0, 5)); + ws.send('foobar'); + ws.send('baz'); + } + else { + send(payload.substr(5, 5), true); + } + }); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + ++receivedIndex; + if (receivedIndex == 1) { + assert.ok(!flags.binary); + assert.equal(payload, data); + } + else if (receivedIndex == 2) { + assert.ok(!flags.binary); + assert.equal('foobar', data); + } + else { + assert.ok(!flags.binary); + assert.equal('baz', data); + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent stream to be delayed in order', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var payload = 'HelloWorld'; + ws.on('open', function() { + var i = 0; + ws.stream(function(error, send) { + assert.ok(!error); + if (++i == 1) { + send(payload.substr(0, 5)); + var i2 = 0; + ws.stream(function(error, send) { + assert.ok(!error); + if (++i2 == 1) send('foo'); + else send('bar', true); + }); + ws.send('baz'); + } + else send(payload.substr(5, 5), true); + }); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + ++receivedIndex; + if (receivedIndex == 1) { + assert.ok(!flags.binary); + assert.equal(payload, data); + } + else if (receivedIndex == 2) { + assert.ok(!flags.binary); + assert.equal('foobar', data); + } + else if (receivedIndex == 3){ + assert.ok(!flags.binary); + assert.equal('baz', data); + setTimeout(function() { + srv.close(); + ws.terminate(); + done(); + }, 1000); + } + else throw new Error('more messages than we actually sent just arrived'); + }); + }); + }); + + it('will cause intermittent ping to be delivered', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var payload = 'HelloWorld'; + ws.on('open', function() { + var i = 0; + ws.stream(function(error, send) { + assert.ok(!error); + if (++i == 1) { + send(payload.substr(0, 5)); + ws.ping('foobar'); + } + else { + send(payload.substr(5, 5), true); + } + }); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + assert.ok(!flags.binary); + assert.equal(payload, data); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + srv.on('ping', function(data) { + assert.equal('foobar', data); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent pong to be delivered', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var payload = 'HelloWorld'; + ws.on('open', function() { + var i = 0; + ws.stream(function(error, send) { + assert.ok(!error); + if (++i == 1) { + send(payload.substr(0, 5)); + ws.pong('foobar'); + } + else { + send(payload.substr(5, 5), true); + } + }); + }); + var receivedIndex = 0; + srv.on('message', function(data, flags) { + assert.ok(!flags.binary); + assert.equal(payload, data); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + srv.on('pong', function(data) { + assert.equal('foobar', data); + if (++receivedIndex == 2) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('will cause intermittent close to be delivered', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var payload = 'HelloWorld'; + var errorGiven = false; + ws.on('open', function() { + var i = 0; + ws.stream(function(error, send) { + if (++i == 1) { + send(payload.substr(0, 5)); + ws.close(1000, 'foobar'); + } + else if(i == 2) { + send(payload.substr(5, 5), true); + } + else if (i == 3) { + assert.ok(error); + errorGiven = true; + } + }); + }); + ws.on('close', function() { + assert.ok(errorGiven); + srv.close(); + ws.terminate(); + done(); + }); + srv.on('message', function(data, flags) { + assert.ok(!flags.binary); + assert.equal(payload, data); + }); + srv.on('close', function(code, data) { + assert.equal(1000, code); + assert.equal('foobar', data); + }); + }); + }); + }); + + describe('#close', function() { + it('will raise error callback, if any, if called during send stream', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var errorGiven = false; + ws.on('open', function() { + var fileStream = fs.createReadStream('test/fixtures/textfile'); + fileStream.setEncoding('utf8'); + fileStream.bufferSize = 100; + ws.send(fileStream, function(error) { + errorGiven = error != null; + }); + ws.close(1000, 'foobar'); + }); + ws.on('close', function() { + setTimeout(function() { + assert.ok(errorGiven); + srv.close(); + ws.terminate(); + done(); + }, 1000); + }); + }); + }); + + it('without invalid first argument throws exception', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + try { + ws.close('error'); + } + catch (e) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('without reserved error code 1004 throws exception', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + try { + ws.close(1004); + } + catch (e) { + srv.close(); + ws.terminate(); + done(); + } + }); + }); + }); + + it('without message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.close(1000); + }); + srv.on('close', function(code, message, flags) { + assert.equal('', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.close(1000, 'some reason'); + }); + srv.on('close', function(code, message, flags) { + assert.ok(flags.masked); + assert.equal('some reason', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('with encoded message is successfully transmitted to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('open', function() { + ws.close(1000, 'some reason', {mask: true}); + }); + srv.on('close', function(code, message, flags) { + assert.ok(flags.masked); + assert.equal('some reason', message); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + + it('ends connection to the server', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var connectedOnce = false; + ws.on('open', function() { + connectedOnce = true; + ws.close(1000, 'some reason', {mask: true}); + }); + ws.on('close', function() { + assert.ok(connectedOnce); + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + }); + + describe('W3C API emulation', function() { + it('should not throw errors when getting and setting', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var listener = function () {}; + + ws.onmessage = listener; + ws.onerror = listener; + ws.onclose = listener; + ws.onopen = listener; + + assert.ok(ws.onopen === listener); + assert.ok(ws.onmessage === listener); + assert.ok(ws.onclose === listener); + assert.ok(ws.onerror === listener); + + srv.close(); + ws.terminate(); + done(); + }); + }); + + it('should work the same as the EventEmitter api', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + var listener = function() {}; + var message = 0; + var close = 0; + var open = 0; + + ws.onmessage = function(messageEvent) { + assert.ok(!!messageEvent.data); + ++message; + ws.close(); + }; + + ws.onopen = function() { + ++open; + } + + ws.onclose = function() { + ++close; + } + + ws.on('open', function() { + ws.send('foo'); + }); + + ws.on('close', function() { + process.nextTick(function() { + assert.ok(message === 1); + assert.ok(open === 1); + assert.ok(close === 1); + + srv.close(); + ws.terminate(); + done(); + }); + }); + }); + }); + + it('should receive text data wrapped in a MessageEvent when using addEventListener', function(done) { + server.createServer(++port, function(srv) { + var ws = new WebSocket('ws://localhost:' + port); + ws.addEventListener('open', function() { + ws.send('hi'); + }); + ws.addEventListener('message', function(messageEvent) { + assert.equal('hi', messageEvent.data); + ws.terminate(); + srv.close(); + done(); + }); + }); + }); + + it('should receive valid CloseEvent when server closes with code 1000', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + ws.addEventListener('close', function(closeEvent) { + assert.equal(true, closeEvent.wasClean); + assert.equal(1000, closeEvent.code); + ws.terminate(); + wss.close(); + done(); + }); + }); + wss.on('connection', function(client) { + client.close(1000); + }); + }); + + it('should receive valid CloseEvent when server closes with code 1001', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + ws.addEventListener('close', function(closeEvent) { + assert.equal(false, closeEvent.wasClean); + assert.equal(1001, closeEvent.code); + assert.equal('some daft reason', closeEvent.reason); + ws.terminate(); + wss.close(); + done(); + }); + }); + wss.on('connection', function(client) { + client.close(1001, 'some daft reason'); + }); + }); + + it('should have target set on Events', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + ws.addEventListener('open', function(openEvent) { + assert.equal(ws, openEvent.target); + }); + ws.addEventListener('message', function(messageEvent) { + assert.equal(ws, messageEvent.target); + wss.close(); + }); + ws.addEventListener('close', function(closeEvent) { + assert.equal(ws, closeEvent.target); + ws.emit('error', new Error('forced')); + }); + ws.addEventListener('error', function(errorEvent) { + assert.equal(errorEvent.message, 'forced'); + assert.equal(ws, errorEvent.target); + ws.terminate(); + done(); + }); + }); + wss.on('connection', function(client) { + client.send('hi') + }); + }); + }); + + describe('ssl', function() { + it('can connect to secure websocket server', function(done) { + var options = { + key: fs.readFileSync('test/fixtures/key.pem'), + cert: fs.readFileSync('test/fixtures/certificate.pem') + }; + var app = https.createServer(options, function (req, res) { + res.writeHead(200); + res.end(); + }); + var wss = new WebSocketServer({server: app}); + app.listen(++port, function() { + var ws = new WebSocket('wss://localhost:' + port); + }); + wss.on('connection', function(ws) { + app.close(); + ws.terminate(); + wss.close(); + done(); + }); + }); + + it('can connect to secure websocket server with client side certificate', function(done) { + var options = { + key: fs.readFileSync('test/fixtures/key.pem'), + cert: fs.readFileSync('test/fixtures/certificate.pem'), + ca: [fs.readFileSync('test/fixtures/ca1-cert.pem')], + requestCert: true + }; + var clientOptions = { + key: fs.readFileSync('test/fixtures/agent1-key.pem'), + cert: fs.readFileSync('test/fixtures/agent1-cert.pem') + }; + var app = https.createServer(options, function (req, res) { + res.writeHead(200); + res.end(); + }); + var success = false; + var wss = new WebSocketServer({ + server: app, + verifyClient: function(info) { + success = !!info.req.client.authorized; + return true; + } + }); + app.listen(++port, function() { + var ws = new WebSocket('wss://localhost:' + port, clientOptions); + }); + wss.on('connection', function(ws) { + app.close(); + ws.terminate(); + wss.close(); + success.should.be.ok; + done(); + }); + }); + + it('cannot connect to secure websocket server via ws://', function(done) { + var options = { + key: fs.readFileSync('test/fixtures/key.pem'), + cert: fs.readFileSync('test/fixtures/certificate.pem') + }; + var app = https.createServer(options, function (req, res) { + res.writeHead(200); + res.end(); + }); + var wss = new WebSocketServer({server: app}); + app.listen(++port, function() { + var ws = new WebSocket('ws://localhost:' + port, { rejectUnauthorized :false }); + ws.on('error', function() { + app.close(); + ws.terminate(); + wss.close(); + done(); + }); + }); + }); + + it('can send and receive text data', function(done) { + var options = { + key: fs.readFileSync('test/fixtures/key.pem'), + cert: fs.readFileSync('test/fixtures/certificate.pem') + }; + var app = https.createServer(options, function (req, res) { + res.writeHead(200); + res.end(); + }); + var wss = new WebSocketServer({server: app}); + app.listen(++port, function() { + var ws = new WebSocket('wss://localhost:' + port); + ws.on('open', function() { + ws.send('foobar'); + }); + }); + wss.on('connection', function(ws) { + ws.on('message', function(message, flags) { + message.should.eql('foobar'); + app.close(); + ws.terminate(); + wss.close(); + done(); + }); + }); + }); + + it('can send and receive very long binary data', function(done) { + var options = { + key: fs.readFileSync('test/fixtures/key.pem'), + cert: fs.readFileSync('test/fixtures/certificate.pem') + } + var app = https.createServer(options, function (req, res) { + res.writeHead(200); + res.end(); + }); + crypto.randomBytes(5 * 1024 * 1024, function(ex, buf) { + if (ex) throw ex; + var wss = new WebSocketServer({server: app}); + app.listen(++port, function() { + var ws = new WebSocket('wss://localhost:' + port); + ws.on('open', function() { + ws.send(buf, {binary: true}); + }); + ws.on('message', function(message, flags) { + flags.binary.should.be.ok; + areArraysEqual(buf, message).should.be.ok; + app.close(); + ws.terminate(); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + ws.on('message', function(message, flags) { + ws.send(message, {binary: true}); + }); + }); + }); + }); + }); + + describe('protocol support discovery', function() { + describe('#supports', function() { + describe('#binary', function() { + it('returns true for hybi transport', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(client) { + assert.equal(true, client.supports.binary); + wss.close(); + done(); + }); + }); + + it('returns false for hixie transport', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + }); + wss.on('connection', function(client) { + assert.equal(false, client.supports.binary); + wss.close(); + done(); + }); + }); + }); + }); + }); + + describe('host and origin headers', function() { + it('includes the host header with port number', function(done) { + var srv = http.createServer(); + srv.listen(++port, function(){ + srv.on('upgrade', function(req, socket, upgradeHeade) { + assert.equal('localhost:' + port, req.headers['host']); + srv.close(); + done(); + }); + var ws = new WebSocket('ws://localhost:' + port); + }); + }); + + it('includes the origin header with port number', function(done) { + var srv = http.createServer(); + srv.listen(++port, function() { + srv.on('upgrade', function(req, socket, upgradeHeade) { + assert.equal('localhost:' + port, req.headers['origin']); + srv.close(); + done(); + }); + var ws = new WebSocket('ws://localhost:' + port); + }); + }); + }); + +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocketServer.test.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocketServer.test.js new file mode 100644 index 00000000000..c21fd97f19f --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/WebSocketServer.test.js @@ -0,0 +1,1103 @@ +var http = require('http') + , https = require('https') + , WebSocket = require('../') + , WebSocketServer = WebSocket.Server + , fs = require('fs') + , should = require('should'); + +var port = 8000; + +function getArrayBuffer(buf) { + var l = buf.length; + var arrayBuf = new ArrayBuffer(l); + for (var i = 0; i < l; ++i) { + arrayBuf[i] = buf[i]; + } + return arrayBuf; +} + +function areArraysEqual(x, y) { + if (x.length != y.length) return false; + for (var i = 0, l = x.length; i < l; ++i) { + if (x[i] !== y[i]) return false; + } + return true; +} + +describe('WebSocketServer', function() { + describe('#ctor', function() { + it('throws an error if no option object is passed', function() { + var gotException = false; + try { + var wss = new WebSocketServer(); + } + catch (e) { + gotException = true; + } + gotException.should.be.ok; + }); + + it('throws an error if no port or server is specified', function() { + var gotException = false; + try { + var wss = new WebSocketServer({}); + } + catch (e) { + gotException = true; + } + gotException.should.be.ok; + }); + + it('does not throw an error if no port or server is specified, when the noServer option is true', function() { + var gotException = false; + try { + var wss = new WebSocketServer({noServer: true}); + } + catch (e) { + gotException = true; + } + gotException.should.eql(false); + }); + + it('emits an error if http server bind fails', function(done) { + var wss = new WebSocketServer({port: 1}); + wss.on('error', function() { done(); }); + }); + + it('starts a server on a given port', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(client) { + wss.close(); + done(); + }); + }); + + it('uses a precreated http server', function (done) { + var srv = http.createServer(); + srv.listen(++port, function () { + var wss = new WebSocketServer({server: srv}); + var ws = new WebSocket('ws://localhost:' + port); + + wss.on('connection', function(client) { + wss.close(); + srv.close(); + done(); + }); + }); + }); + + it('uses a precreated http server listening on unix socket', function (done) { + var srv = http.createServer(); + var sockPath = '/tmp/ws_socket_'+new Date().getTime()+'.'+Math.floor(Math.random() * 1000); + srv.listen(sockPath, function () { + var wss = new WebSocketServer({server: srv}); + var ws = new WebSocket('ws+unix://'+sockPath); + + wss.on('connection', function(client) { + wss.close(); + srv.close(); + done(); + }); + }); + }); + + it('emits path specific connection event', function (done) { + var srv = http.createServer(); + srv.listen(++port, function () { + var wss = new WebSocketServer({server: srv}); + var ws = new WebSocket('ws://localhost:' + port+'/endpointName'); + + wss.on('connection/endpointName', function(client) { + wss.close(); + srv.close(); + done(); + }); + }); + }); + + it('can have two different instances listening on the same http server with two different paths', function(done) { + var srv = http.createServer(); + srv.listen(++port, function () { + var wss1 = new WebSocketServer({server: srv, path: '/wss1'}) + , wss2 = new WebSocketServer({server: srv, path: '/wss2'}); + var doneCount = 0; + wss1.on('connection', function(client) { + wss1.close(); + if (++doneCount == 2) { + srv.close(); + done(); + } + }); + wss2.on('connection', function(client) { + wss2.close(); + if (++doneCount == 2) { + srv.close(); + done(); + } + }); + var ws1 = new WebSocket('ws://localhost:' + port + '/wss1'); + var ws2 = new WebSocket('ws://localhost:' + port + '/wss2?foo=1'); + }); + }); + + it('cannot have two different instances listening on the same http server with the same path', function(done) { + var srv = http.createServer(); + srv.listen(++port, function () { + var wss1 = new WebSocketServer({server: srv, path: '/wss1'}); + try { + var wss2 = new WebSocketServer({server: srv, path: '/wss1'}); + } + catch (e) { + wss1.close(); + srv.close(); + done(); + } + }); + }); + }); + + describe('#close', function() { + it('will close all clients', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('close', function() { + if (++closes == 2) done(); + }); + }); + var closes = 0; + wss.on('connection', function(client) { + client.on('close', function() { + if (++closes == 2) done(); + }); + wss.close(); + }); + }); + + it('does not close a precreated server', function(done) { + var srv = http.createServer(); + var realClose = srv.close; + srv.close = function() { + should.fail('must not close pre-created server'); + } + srv.listen(++port, function () { + var wss = new WebSocketServer({server: srv}); + var ws = new WebSocket('ws://localhost:' + port); + wss.on('connection', function(client) { + wss.close(); + srv.close = realClose; + srv.close(); + done(); + }); + }); + }); + + it('cleans up websocket data on a precreated server', function(done) { + var srv = http.createServer(); + srv.listen(++port, function () { + var wss1 = new WebSocketServer({server: srv, path: '/wss1'}) + , wss2 = new WebSocketServer({server: srv, path: '/wss2'}); + (typeof srv._webSocketPaths).should.eql('object'); + Object.keys(srv._webSocketPaths).length.should.eql(2); + wss1.close(); + Object.keys(srv._webSocketPaths).length.should.eql(1); + wss2.close(); + (typeof srv._webSocketPaths).should.eql('undefined'); + srv.close(); + done(); + }); + }); + }); + + describe('#clients', function() { + it('returns a list of connected clients', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + wss.clients.length.should.eql(0); + var ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(client) { + wss.clients.length.should.eql(1); + wss.close(); + done(); + }); + }); + + it('can be disabled', function(done) { + var wss = new WebSocketServer({port: ++port, clientTracking: false}, function() { + wss.clients.length.should.eql(0); + var ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(client) { + wss.clients.length.should.eql(0); + wss.close(); + done(); + }); + }); + + it('is updated when client terminates the connection', function(done) { + var ws; + var wss = new WebSocketServer({port: ++port}, function() { + ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(client) { + client.on('close', function() { + wss.clients.length.should.eql(0); + wss.close(); + done(); + }); + ws.terminate(); + }); + }); + + it('is updated when client closes the connection', function(done) { + var ws; + var wss = new WebSocketServer({port: ++port}, function() { + ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(client) { + client.on('close', function() { + wss.clients.length.should.eql(0); + wss.close(); + done(); + }); + ws.close(); + }); + }); + }); + + describe('#options', function() { + it('exposes options passed to constructor', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + wss.options.port.should.eql(port); + wss.close(); + done(); + }); + }); + }); + + describe('#handleUpgrade', function() { + it('can be used for a pre-existing server', function (done) { + var srv = http.createServer(); + srv.listen(++port, function () { + var wss = new WebSocketServer({noServer: true}); + srv.on('upgrade', function(req, socket, upgradeHead) { + wss.handleUpgrade(req, socket, upgradeHead, function(client) { + client.send('hello'); + }); + }); + var ws = new WebSocket('ws://localhost:' + port); + ws.on('message', function(message) { + message.should.eql('hello'); + wss.close(); + srv.close(); + done(); + }); + }); + }); + }); + + describe('hybi mode', function() { + describe('connection establishing', function() { + it('does not accept connections with no sec-websocket-key', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(400); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('does not accept connections with no sec-websocket-version', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(400); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('does not accept connections with invalid sec-websocket-version', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 12 + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(400); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('client can be denied', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { + return false; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 8, + 'Sec-WebSocket-Origin': 'http://foobar.com' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(401); + process.nextTick(function() { + wss.close(); + done(); + }); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('client can be accepted', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { + return true; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 13, + 'Origin': 'http://foobar.com' + } + }; + var req = http.request(options); + req.end(); + }); + wss.on('connection', function(ws) { + ws.terminate(); + wss.close(); + done(); + }); + wss.on('error', function() {}); + }); + + it('verifyClient gets client origin', function(done) { + var verifyClientCalled = false; + var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { + info.origin.should.eql('http://foobarbaz.com'); + verifyClientCalled = true; + return false; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 13, + 'Origin': 'http://foobarbaz.com' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + verifyClientCalled.should.be.ok; + wss.close(); + done(); + }); + }); + wss.on('error', function() {}); + }); + + it('verifyClient gets original request', function(done) { + var verifyClientCalled = false; + var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { + info.req.headers['sec-websocket-key'].should.eql('dGhlIHNhbXBsZSBub25jZQ=='); + verifyClientCalled = true; + return false; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 13, + 'Origin': 'http://foobarbaz.com' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + verifyClientCalled.should.be.ok; + wss.close(); + done(); + }); + }); + wss.on('error', function() {}); + }); + + it('verifyClient has secure:true for ssl connections', function(done) { + var options = { + key: fs.readFileSync('test/fixtures/key.pem'), + cert: fs.readFileSync('test/fixtures/certificate.pem') + }; + var app = https.createServer(options, function (req, res) { + res.writeHead(200); + res.end(); + }); + var success = false; + var wss = new WebSocketServer({ + server: app, + verifyClient: function(info) { + success = info.secure === true; + return true; + } + }); + app.listen(++port, function() { + var ws = new WebSocket('wss://localhost:' + port); + }); + wss.on('connection', function(ws) { + app.close(); + ws.terminate(); + wss.close(); + success.should.be.ok; + done(); + }); + }); + + it('verifyClient has secure:false for non-ssl connections', function(done) { + var app = http.createServer(function (req, res) { + res.writeHead(200); + res.end(); + }); + var success = false; + var wss = new WebSocketServer({ + server: app, + verifyClient: function(info) { + success = info.secure === false; + return true; + } + }); + app.listen(++port, function() { + var ws = new WebSocket('ws://localhost:' + port); + }); + wss.on('connection', function(ws) { + app.close(); + ws.terminate(); + wss.close(); + success.should.be.ok; + done(); + }); + }); + + it('client can be denied asynchronously', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { + process.nextTick(function() { + cb(false); + }); + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 8, + 'Sec-WebSocket-Origin': 'http://foobar.com' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(401); + process.nextTick(function() { + wss.close(); + done(); + }); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('client can be accepted asynchronously', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { + process.nextTick(function() { + cb(true); + }); + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 13, + 'Origin': 'http://foobar.com' + } + }; + var req = http.request(options); + req.end(); + }); + wss.on('connection', function(ws) { + ws.terminate(); + wss.close(); + done(); + }); + wss.on('error', function() {}); + }); + + it('handles messages passed along with the upgrade request (upgrade head)', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { + return true; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 13, + 'Origin': 'http://foobar.com' + } + }; + var req = http.request(options); + req.write(new Buffer([0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f], 'binary')); + req.end(); + }); + wss.on('connection', function(ws) { + ws.on('message', function(data) { + data.should.eql('Hello'); + ws.terminate(); + wss.close(); + done(); + }); + }); + wss.on('error', function() {}); + }); + + it('selects the first protocol by default', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); + ws.on('open', function(client) { + ws.protocol.should.eql('prot1'); + wss.close(); + done(); + }); + }); + }); + + it('selects the last protocol via protocol handler', function(done) { + var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { + cb(true, ps[ps.length-1]); }}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); + ws.on('open', function(client) { + ws.protocol.should.eql('prot2'); + wss.close(); + done(); + }); + }); + }); + + it('client detects invalid server protocol', function(done) { + var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { + cb(true, 'prot3'); }}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); + ws.on('open', function(client) { + done(new Error('connection must not be established')); + }); + ws.on('error', function() { + done(); + }); + }); + }); + + it('client detects no server protocol', function(done) { + var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { + cb(true); }}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); + ws.on('open', function(client) { + done(new Error('connection must not be established')); + }); + ws.on('error', function() { + done(); + }); + }); + }); + + it('client refuses server protocols', function(done) { + var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { + cb(false); }}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocol: 'prot1, prot2'}); + ws.on('open', function(client) { + done(new Error('connection must not be established')); + }); + ws.on('error', function() { + done(); + }); + }); + }); + + it('server detects invalid protocol handler', function(done) { + var wss = new WebSocketServer({port: ++port, handleProtocols: function(ps, cb) { + // not calling callback is an error and shouldn't timeout + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ==', + 'Sec-WebSocket-Version': 13, + 'Sec-WebSocket-Origin': 'http://foobar.com' + } + }; + options.port = port; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(501); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + }); + + describe('messaging', function() { + it('can send and receive data', function(done) { + var data = new Array(65*1024); + for (var i = 0; i < data.length; ++i) { + data[i] = String.fromCharCode(65 + ~~(25 * Math.random())); + } + data = data.join(''); + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port); + ws.on('message', function(message, flags) { + ws.send(message); + }); + }); + wss.on('connection', function(client) { + client.on('message', function(message) { + message.should.eql(data); + wss.close(); + done(); + }); + client.send(data); + }); + }); + }); + }); + + describe('hixie mode', function() { + it('can be disabled', function(done) { + var wss = new WebSocketServer({port: ++port, disableHixie: true}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(401); + process.nextTick(function() { + wss.close(); + done(); + }); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + describe('connection establishing', function() { + it('does not accept connections with no sec-websocket-key1', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(400); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('does not accept connections with no sec-websocket-key2', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(400); + wss.close(); + done(); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('accepts connections with valid handshake', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + }); + wss.on('connection', function(ws) { + ws.terminate(); + wss.close(); + done(); + }); + wss.on('error', function() {}); + }); + + it('client can be denied', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { + return false; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(401); + process.nextTick(function() { + wss.close(); + done(); + }); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('client can be accepted', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { + return true; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + }); + wss.on('connection', function(ws) { + ws.terminate(); + wss.close(); + done(); + }); + wss.on('error', function() {}); + }); + + it('verifyClient gets client origin', function(done) { + var verifyClientCalled = false; + var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { + info.origin.should.eql('http://foobarbaz.com'); + verifyClientCalled = true; + return false; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Origin': 'http://foobarbaz.com', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + req.on('response', function(res) { + verifyClientCalled.should.be.ok; + wss.close(); + done(); + }); + }); + wss.on('error', function() {}); + }); + + it('verifyClient gets original request', function(done) { + var verifyClientCalled = false; + var wss = new WebSocketServer({port: ++port, verifyClient: function(info) { + info.req.headers['sec-websocket-key1'].should.eql('3e6b263 4 17 80'); + verifyClientCalled = true; + return false; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Origin': 'http://foobarbaz.com', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + req.on('response', function(res) { + verifyClientCalled.should.be.ok; + wss.close(); + done(); + }); + }); + wss.on('error', function() {}); + }); + + it('client can be denied asynchronously', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { + cb(false); + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Origin': 'http://foobarbaz.com', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + req.on('response', function(res) { + res.statusCode.should.eql(401); + process.nextTick(function() { + wss.close(); + done(); + }); + }); + }); + wss.on('connection', function(ws) { + done(new Error('connection must not be established')); + }); + wss.on('error', function() {}); + }); + + it('client can be accepted asynchronously', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o, cb) { + cb(true); + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Origin': 'http://foobarbaz.com', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.end(); + }); + wss.on('connection', function(ws) { + wss.close(); + done(); + }); + wss.on('error', function() {}); + }); + + it('handles messages passed along with the upgrade request (upgrade head)', function(done) { + var wss = new WebSocketServer({port: ++port, verifyClient: function(o) { + return true; + }}, function() { + var options = { + port: port, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Key1': '3e6b263 4 17 80', + 'Sec-WebSocket-Key2': '17 9 G`ZD9 2 2b 7X 3 /r90', + 'Origin': 'http://foobar.com' + } + }; + var req = http.request(options); + req.write('WjN}|M(6'); + req.write(new Buffer([0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff], 'binary')); + req.end(); + }); + wss.on('connection', function(ws) { + ws.on('message', function(data) { + data.should.eql('Hello'); + ws.terminate(); + wss.close(); + done(); + }); + }); + wss.on('error', function() {}); + }); + }); + }); + + describe('client properties', function() { + it('protocol is exposed', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocol: 'hi'}); + }); + wss.on('connection', function(client) { + client.protocol.should.eql('hi'); + wss.close(); + done(); + }); + }); + + it('protocolVersion is exposed', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocolVersion: 8}); + }); + wss.on('connection', function(client) { + client.protocolVersion.should.eql(8); + wss.close(); + done(); + }); + }); + + it('upgradeReq is the original request object', function(done) { + var wss = new WebSocketServer({port: ++port}, function() { + var ws = new WebSocket('ws://localhost:' + port, {protocolVersion: 8}); + }); + wss.on('connection', function(client) { + client.upgradeReq.httpVersion.should.eql('1.1'); + wss.close(); + done(); + }); + }); + }); + +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/autobahn-server.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/autobahn-server.js new file mode 100644 index 00000000000..36fe0c24630 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/autobahn-server.js @@ -0,0 +1,29 @@ +var WebSocketServer = require('../').Server; + +process.on('uncaughtException', function(err) { + console.log('Caught exception: ', err, err.stack); +}); + +process.on('SIGINT', function () { + try { + console.log('Updating reports and shutting down'); + var ws = new WebSocket('ws://localhost:9001/updateReports?agent=ws'); + ws.on('close', function() { + process.exit(); + }); + } + catch(e) { + process.exit(); + } +}); + +var wss = new WebSocketServer({port: 8181}); +wss.on('connection', function(ws) { + console.log('new connection'); + ws.on('message', function(data, flags) { + ws.send(flags.buffer, {binary: flags.binary === true}); + }); + ws.on('error', function() { + console.log('error', arguments); + }); +}); diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/autobahn.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/autobahn.js new file mode 100644 index 00000000000..048cc904165 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/autobahn.js @@ -0,0 +1,52 @@ +var WebSocket = require('../'); +var currentTest = 1; +var lastTest = -1; +var testCount = null; + +process.on('uncaughtException', function(err) { + console.log('Caught exception: ', err, err.stack); +}); + +process.on('SIGINT', function () { + try { + console.log('Updating reports and shutting down'); + var ws = new WebSocket('ws://localhost:9001/updateReports?agent=ws'); + ws.on('close', function() { + process.exit(); + }); + } + catch(e) { + process.exit(); + } +}); + +function nextTest() { + if (currentTest > testCount || (lastTest != -1 && currentTest > lastTest)) { + console.log('Updating reports and shutting down'); + var ws = new WebSocket('ws://localhost:9001/updateReports?agent=ws'); + ws.on('close', function() { + process.exit(); + }); + return; + }; + console.log('Running test case ' + currentTest + '/' + testCount); + var ws = new WebSocket('ws://localhost:9001/runCase?case=' + currentTest + '&agent=ws'); + ws.on('message', function(data, flags) { + ws.send(flags.buffer, {binary: flags.binary === true, mask: true}); + }); + ws.on('close', function(data) { + currentTest += 1; + process.nextTick(nextTest); + }); + ws.on('error', function(e) {}); +} + +var ws = new WebSocket('ws://localhost:9001/getCaseCount'); +ws.on('message', function(data, flags) { + testCount = parseInt(data); +}); +ws.on('close', function() { + if (testCount > 0) { + nextTest(); + } +}); \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/agent1-cert.pem b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/agent1-cert.pem new file mode 100644 index 00000000000..cccb9fb4d35 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/agent1-cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICbjCCAdcCCQCVvok5oeLpqzANBgkqhkiG9w0BAQUFADB6MQswCQYDVQQGEwJV +UzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZKb3llbnQxEDAO +BgNVBAsTB05vZGUuanMxDDAKBgNVBAMTA2NhMTEgMB4GCSqGSIb3DQEJARYRcnlA +dGlueWNsb3Vkcy5vcmcwHhcNMTMwMzA4MDAzMDIyWhcNNDAwNzIzMDAzMDIyWjB9 +MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQK +EwZKb3llbnQxEDAOBgNVBAsTB05vZGUuanMxDzANBgNVBAMTBmFnZW50MTEgMB4G +CSqGSIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmcwgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBAL6GwKosYb0Yc3Qo0OtQVlCJ4208Idw11ij+t2W5sfYbCil5tyQo +jnhGM1CJhEXynQpXXwjKJuIeTQCkeUibTyFKa0bs8+li2FiGoKYbb4G81ovnqkmE +2iDVb8Gw3rrM4zeZ0ZdFnjMsAZac8h6+C4sB/pS9BiMOo6qTl15RQlcJAgMBAAEw +DQYJKoZIhvcNAQEFBQADgYEAOtmLo8DwTPnI4wfQbQ3hWlTS/9itww6IsxH2ODt9 +ggB7wi7N3uAdIWRZ54ke0NEAO5CW1xNTwsWcxQbiHrDOqX1vfVCjIenI76jVEEap +/Ay53ydHNBKdsKkib61Me14Mu0bA3lUul57VXwmH4NUEFB3w973Q60PschUhOEXj +7DY= +-----END CERTIFICATE----- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/agent1-key.pem b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/agent1-key.pem new file mode 100644 index 00000000000..cbd5f0c26ae --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/agent1-key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC+hsCqLGG9GHN0KNDrUFZQieNtPCHcNdYo/rdlubH2Gwopebck +KI54RjNQiYRF8p0KV18IyibiHk0ApHlIm08hSmtG7PPpYthYhqCmG2+BvNaL56pJ +hNog1W/BsN66zOM3mdGXRZ4zLAGWnPIevguLAf6UvQYjDqOqk5deUUJXCQIDAQAB +AoGANu/CBA+SCyVOvRK70u4yRTzNMAUjukxnuSBhH1rg/pajYnwvG6T6F6IeT72n +P0gKkh3JUE6B0bds+p9yPUZTFUXghxjcF33wlIY44H6gFE4K5WutsFJ9c450wtuu +8rXZTsIg7lAXWjTFVmdtOEPetcGlO2Hpi1O7ZzkzHgB2w9ECQQDksCCYx78or1zY +ZSokm8jmpIjG3VLKdvI9HAoJRN40ldnwFoigrFa1AHwsFtWNe8bKyVRPDoLDUjpB +dkPWgweVAkEA1UfgqguQ2KIkbtp9nDBionu3QaajksrRHwIa8vdfRfLxszfHk2fh +NGY3dkRZF8HUAbzYLrd9poVhCBAEjWekpQJASOM6AHfpnXYHCZF01SYx6hEW5wsz +kARJQODm8f1ZNTlttO/5q/xBxn7ZFNRSTD3fJlL05B2j380ddC/Vf1FT4QJAP1BC +GliqnBSuGhZUWYxni3KMeTm9rzL0F29pjpzutHYlWB2D6ndY/FQnvL0XcZ0Bka58 +womIDGnl3x3aLBwLXQJBAJv6h5CHbXHx7VyDJAcNfppAqZGcEaiVg8yf2F33iWy2 +FLthhJucx7df7SO2aw5h06bRDRAhb9br0R9/3mLr7RE= +-----END RSA PRIVATE KEY----- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/ca1-cert.pem b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/ca1-cert.pem new file mode 100644 index 00000000000..1d0c0d68882 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/ca1-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICazCCAdQCCQC9/g69HtxXRzANBgkqhkiG9w0BAQUFADB6MQswCQYDVQQGEwJV +UzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZKb3llbnQxEDAO +BgNVBAsTB05vZGUuanMxDDAKBgNVBAMTA2NhMTEgMB4GCSqGSIb3DQEJARYRcnlA +dGlueWNsb3Vkcy5vcmcwHhcNMTMwMzA4MDAzMDIyWhcNNDAwNzIzMDAzMDIyWjB6 +MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQK +EwZKb3llbnQxEDAOBgNVBAsTB05vZGUuanMxDDAKBgNVBAMTA2NhMTEgMB4GCSqG +SIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0A +MIGJAoGBAKxr1mARUcv7zaqx5y4AxJPK6c1jdbSg7StcL4vg8klaPAlfNO6o+/Cl +w5CdQD3ukaVUwUOJ4T/+b3Xf7785XcWBC33GdjVQkfbHATJYcka7j7JDw3qev5Jk +1rAbRw48hF6rYlSGcx1mccAjoLoa3I8jgxCNAYHIjUQXgdmU893rAgMBAAEwDQYJ +KoZIhvcNAQEFBQADgYEAis05yxjCtJRuv8uX/DK6TX/j9C9Lzp1rKDNFTaTZ0iRw +KCw1EcNx4OXSj9gNblW4PWxpDvygrt1AmH9h2cb8K859NSHa9JOBFw6MA5C2A4Sj +NQfNATqUl4T6cdORlcDEZwHtT8b6D4A6Er31G/eJF4Sen0TUFpjdjd+l9RBjHlo= +-----END CERTIFICATE----- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/ca1-key.pem b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/ca1-key.pem new file mode 100644 index 00000000000..df1495083e8 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/ca1-key.pem @@ -0,0 +1,17 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIFeWxJE1BrRECAggA +MBQGCCqGSIb3DQMHBAgu9PlMSQ+BOASCAoDEZN2tX0xWo/N+Jg+PrvCrFDk3P+3x +5xG/PEDjtMCAWPBEwbnaYHDzYmhNcAmxzGqEHGMDiWYs46LbO560VS3uMvFbEWPo +KYYVb13vkxl2poXdonCb5cHZA5GUYzTIVVJFptl4LHwBczHoMHtA4FqAhKlYvlWw +EOrdLB8XcwMmGPFabbbGxno0+EWWM27uNjlogfoxj35mQqSW4rOlhZ460XjOB1Zx +LjXMuZeONojkGYQRG5EUMchBoctQpCOM6cAi9r1B9BvtFCBpDV1c1zEZBzTEUd8o +kLn6tjLmY+QpTdylFjEWc7U3ppLY/pkoTBv4r85a2sEMWqkhSJboLaTboWzDJcU3 +Ke61pMpovt/3yCUd3TKgwduVwwQtDVTlBe0p66aN9QVj3CrFy/bKAGO3vxlli24H +aIjZf+OVoBY21ESlW3jLvNlBf7Ezf///2E7j4SCDLyZSFMTpFoAG/jDRyvi+wTKX +Kh485Bptnip6DCSuoH4u2SkOqwz3gJS/6s02YKe4m311QT4Pzne5/FwOFaS/HhQg +Xvyh2/d00OgJ0Y0PYQsHILPRgTUCKUXvj1O58opn3fxSacsPxIXwj6Z4FYAjUTaV +2B85k1lpant/JJEilDqMjqzx4pHZ/Z3Uto1lSM1JZs9SNL/0UR+6F0TXZTULVU9V +w8jYzz4sPr7LEyrrTbzmjQgnQFVbhAN/eKgRZK/SpLjxpmBV5MfpbPKsPUZqT4UC +4nXa8a/NYUQ9e+QKK8enq9E599c2W442W7Z1uFRZTWReMx/lF8wwA6G8zOPG0bdj +d+T5Gegzd5mvRiXMBklCo8RLxOOvgxun1n3PY4a63aH6mqBhdfhiLp5j +-----END ENCRYPTED PRIVATE KEY----- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/certificate.pem b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/certificate.pem new file mode 100644 index 00000000000..0efc2ef5b71 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/certificate.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAWoCCQDPufXH86n2QzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJu +bzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTEyMDEwMTE0NDQwMFoXDTIwMDMxOTE0NDQwMFowRTELMAkG +A1UEBhMCbm8xEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtrQ7 ++r//2iV/B6F+4boH0XqFn7alcV9lpjvAmwRXNKnxAoa0f97AjYPGNLKrjpkNXXhB +JROIdbRbZnCNeC5fzX1a+JCo7KStzBXuGSZr27TtFmcV4H+9gIRIcNHtZmJLnxbJ +sIhkGR8yVYdmJZe4eT5ldk1zoB1adgPF1hZhCBMCAwEAATANBgkqhkiG9w0BAQUF +AAOBgQCeWBEHYJ4mCB5McwSSUox0T+/mJ4W48L/ZUE4LtRhHasU9hiW92xZkTa7E +QLcoJKQiWfiLX2ysAro0NX4+V8iqLziMqvswnPzz5nezaOLE/9U/QvH3l8qqNkXu +rNbsW1h/IO6FV8avWFYVFoutUwOaZ809k7iMh2F2JMgXQ5EymQ== +-----END CERTIFICATE----- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/key.pem b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/key.pem new file mode 100644 index 00000000000..176fe320bb7 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC2tDv6v//aJX8HoX7hugfReoWftqVxX2WmO8CbBFc0qfEChrR/ +3sCNg8Y0squOmQ1deEElE4h1tFtmcI14Ll/NfVr4kKjspK3MFe4ZJmvbtO0WZxXg +f72AhEhw0e1mYkufFsmwiGQZHzJVh2Yll7h5PmV2TXOgHVp2A8XWFmEIEwIDAQAB +AoGAAlVY8sHi/aE+9xT77twWX3mGHV0SzdjfDnly40fx6S1Gc7bOtVdd9DC7pk6l +3ENeJVR02IlgU8iC5lMHq4JEHPE272jtPrLlrpWLTGmHEqoVFv9AITPqUDLhB9Kk +Hjl7h8NYBKbr2JHKICr3DIPKOT+RnXVb1PD4EORbJ3ooYmkCQQDfknUnVxPgxUGs +ouABw1WJIOVgcCY/IFt4Ihf6VWTsxBgzTJKxn3HtgvE0oqTH7V480XoH0QxHhjLq +DrgobWU9AkEA0TRJ8/ouXGnFEPAXjWr9GdPQRZ1Use2MrFjneH2+Sxc0CmYtwwqL +Kr5kS6mqJrxprJeluSjBd+3/ElxURrEXjwJAUvmlN1OPEhXDmRHd92mKnlkyKEeX +OkiFCiIFKih1S5Y/sRJTQ0781nyJjtJqO7UyC3pnQu1oFEePL+UEniRztQJAMfav +AtnpYKDSM+1jcp7uu9BemYGtzKDTTAYfoiNF42EzSJiGrWJDQn4eLgPjY0T0aAf/ +yGz3Z9ErbhMm/Ysl+QJBAL4kBxRT8gM4ByJw4sdOvSeCCANFq8fhbgm8pGWlCPb5 +JGmX3/GHFM8x2tbWMGpyZP1DLtiNEFz7eCGktWK5rqE= +-----END RSA PRIVATE KEY----- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/request.pem b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/request.pem new file mode 100644 index 00000000000..51bc7f6254e --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/request.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBhDCB7gIBADBFMQswCQYDVQQGEwJubzETMBEGA1UECAwKU29tZS1TdGF0ZTEh +MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQC2tDv6v//aJX8HoX7hugfReoWftqVxX2WmO8CbBFc0qfEC +hrR/3sCNg8Y0squOmQ1deEElE4h1tFtmcI14Ll/NfVr4kKjspK3MFe4ZJmvbtO0W +ZxXgf72AhEhw0e1mYkufFsmwiGQZHzJVh2Yll7h5PmV2TXOgHVp2A8XWFmEIEwID +AQABoAAwDQYJKoZIhvcNAQEFBQADgYEAjsUXEARgfxZNkMjuUcudgU2w4JXS0gGI +JQ0U1LmU0vMDSKwqndMlvCbKzEgPbJnGJDI8D4MeINCJHa5Ceyb8c+jaJYUcCabl +lQW5Psn3+eWp8ncKlIycDRj1Qk615XuXtV0fhkrgQM2ZCm9LaQ1O1Gd/CzLihLjF +W0MmgMKMMRk= +-----END CERTIFICATE REQUEST----- diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/textfile b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/textfile new file mode 100644 index 00000000000..a10483b0ecc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/fixtures/textfile @@ -0,0 +1,9 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam egestas, massa at aliquam luctus, sapien erat viverra elit, nec pulvinar turpis eros sagittis urna. Pellentesque imperdiet tempor varius. Pellentesque blandit, ipsum in imperdiet venenatis, mi elit faucibus odio, id condimentum ante enim sed lectus. Aliquam et odio non odio pellentesque pulvinar. Vestibulum a erat dolor. Integer pretium risus sit amet nisl volutpat nec venenatis magna egestas. Ut bibendum felis eu tellus laoreet eleifend. Nam pulvinar auctor tortor, eu iaculis leo vestibulum quis. In euismod risus ac purus vehicula et fermentum ligula consectetur. Vivamus condimentum tempus lacinia. + +Curabitur sodales condimentum urna id dictum. Sed quis justo sit amet quam ultrices tincidunt vel laoreet nulla. Nullam quis ipsum sed nisi mollis bibendum at sit amet nisi. Donec laoreet consequat velit sit amet mollis. Nam sed sapien a massa iaculis dapibus. Sed dui nunc, ultricies et pellentesque ullamcorper, aliquet vitae ligula. Integer eu velit in neque iaculis venenatis. Ut rhoncus cursus est, ac dignissim leo vehicula a. Nulla ullamcorper vulputate mauris id blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eleifend, nisi a tempor sollicitudin, odio massa pretium urna, quis congue sapien elit at tortor. Curabitur ipsum orci, vehicula non commodo molestie, laoreet id enim. Pellentesque convallis ultrices congue. Pellentesque nec iaculis lorem. In sagittis pharetra ipsum eget sodales. + +Fusce id nulla odio. Nunc nibh justo, placerat vel tincidunt sed, ornare et enim. Nulla vel urna vel ante commodo bibendum in vitae metus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis erat nunc, semper eget sagittis sit amet, ullamcorper eget lacus. Donec hendrerit ipsum vitae eros vestibulum eu gravida neque tincidunt. Ut molestie lacinia nulla. Donec mattis odio at magna egestas at pellentesque eros accumsan. Praesent interdum sem sit amet nibh commodo dignissim. Duis laoreet, enim ultricies fringilla suscipit, enim libero cursus nulla, sollicitudin adipiscing erat velit ut dui. Nulla eleifend mauris at velit fringilla a molestie lorem venenatis. + +Donec sit amet scelerisque metus. Cras ac felis a nulla venenatis vulputate. Duis porttitor eros ac neque rhoncus eget aliquet neque egestas. Quisque sed nunc est, vitae dapibus quam. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In vehicula, est vitae posuere ultricies, diam purus pretium sapien, nec rhoncus dolor nisl eget arcu. Aliquam et nisi vitae risus tincidunt auctor. In vehicula, erat a cursus adipiscing, lorem orci congue est, nec ultricies elit dui in nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + +Duis congue tempus elit sit amet auctor. Duis dignissim, risus ut sollicitudin ultricies, dolor ligula gravida odio, nec congue orci purus ut ligula. Fusce pretium dictum lectus at volutpat. Sed non auctor mauris. Etiam placerat vestibulum massa id blandit. Quisque consequat lacus ut nulla euismod facilisis. Sed aliquet ipsum nec mi imperdiet viverra. Pellentesque ullamcorper, lectus nec varius gravida, odio justo cursus risus, eu sagittis metus arcu quis felis. Phasellus consectetur vehicula libero, at condimentum orci euismod vel. Nunc purus tortor, suscipit nec fringilla nec, vulputate et nibh. Nam porta vehicula neque. Praesent porttitor, sapien eu auctor euismod, arcu quam elementum urna, sed hendrerit magna augue sed quam. \ No newline at end of file diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/hybi-common.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/hybi-common.js new file mode 100644 index 00000000000..006f9c693bc --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/hybi-common.js @@ -0,0 +1,99 @@ +/** + * Returns a Buffer from a "ff 00 ff"-type hex string. + */ + +getBufferFromHexString = function(byteStr) { + var bytes = byteStr.split(' '); + var buf = new Buffer(bytes.length); + for (var i = 0; i < bytes.length; ++i) { + buf[i] = parseInt(bytes[i], 16); + } + return buf; +} + +/** + * Returns a hex string from a Buffer. + */ + +getHexStringFromBuffer = function(data) { + var s = ''; + for (var i = 0; i < data.length; ++i) { + s += padl(data[i].toString(16), 2, '0') + ' '; + } + return s.trim(); +} + +/** + * Splits a buffer in two parts. + */ + +splitBuffer = function(buffer) { + var b1 = new Buffer(Math.ceil(buffer.length / 2)); + buffer.copy(b1, 0, 0, b1.length); + var b2 = new Buffer(Math.floor(buffer.length / 2)); + buffer.copy(b2, 0, b1.length, b1.length + b2.length); + return [b1, b2]; +} + +/** + * Performs hybi07+ type masking on a hex string or buffer. + */ + +mask = function(buf, maskString) { + if (typeof buf == 'string') buf = new Buffer(buf); + var mask = getBufferFromHexString(maskString || '34 83 a8 68'); + for (var i = 0; i < buf.length; ++i) { + buf[i] ^= mask[i % 4]; + } + return buf; +} + +/** + * Returns a hex string representing the length of a message + */ + +getHybiLengthAsHexString = function(len, masked) { + if (len < 126) { + var buf = new Buffer(1); + buf[0] = (masked ? 0x80 : 0) | len; + } + else if (len < 65536) { + var buf = new Buffer(3); + buf[0] = (masked ? 0x80 : 0) | 126; + getBufferFromHexString(pack(4, len)).copy(buf, 1); + } + else { + var buf = new Buffer(9); + buf[0] = (masked ? 0x80 : 0) | 127; + getBufferFromHexString(pack(16, len)).copy(buf, 1); + } + return getHexStringFromBuffer(buf); +} + +/** + * Unpacks a Buffer into a number. + */ + +unpack = function(buffer) { + var n = 0; + for (var i = 0; i < buffer.length; ++i) { + n = (i == 0) ? buffer[i] : (n * 256) + buffer[i]; + } + return n; +} + +/** + * Returns a hex string, representing a specific byte count 'length', from a number. + */ + +pack = function(length, number) { + return padl(number.toString(16), length, '0').replace(/([0-9a-f][0-9a-f])/gi, '$1 ').trim(); +} + +/** + * Left pads the string 's' to a total length of 'n' with char 'c'. + */ + +padl = function(s, n, c) { + return new Array(1 + n - s.length).join(c) + s; +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/testserver.js b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/testserver.js new file mode 100644 index 00000000000..3e7a96674b5 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/node_modules/ws/test/testserver.js @@ -0,0 +1,180 @@ +var http = require('http') + , util = require('util') + , crypto = require('crypto') + , events = require('events') + , Sender = require('../lib/Sender') + , Receiver = require('../lib/Receiver'); + +module.exports = { + handlers: { + valid: validServer, + invalidKey: invalidRequestHandler, + closeAfterConnect: closeAfterConnectHandler, + return401: return401 + }, + createServer: function(port, handler, cb) { + if (handler && !cb) { + cb = handler; + handler = null; + } + var webServer = http.createServer(function (req, res) { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('okay'); + }); + var srv = new Server(webServer); + webServer.on('upgrade', function(req, socket) { + webServer._socket = socket; + (handler || validServer)(srv, req, socket); + }); + webServer.listen(port, '127.0.0.1', function() { cb(srv); }); + } +}; + +/** + * Test strategies + */ + +function validServer(server, req, socket) { + if (typeof req.headers.upgrade === 'undefined' || + req.headers.upgrade.toLowerCase() !== 'websocket') { + throw new Error('invalid headers'); + return; + } + + if (!req.headers['sec-websocket-key']) { + socket.end(); + throw new Error('websocket key is missing'); + } + + // calc key + var key = req.headers['sec-websocket-key']; + var shasum = crypto.createHash('sha1'); + shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + key = shasum.digest('base64'); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: websocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Accept: ' + key + ]; + + socket.write(headers.concat('', '').join('\r\n')); + socket.setTimeout(0); + socket.setNoDelay(true); + + var sender = new Sender(socket); + var receiver = new Receiver(); + receiver.ontext = function (message, flags) { + server.emit('message', message, flags); + sender.send(message); + }; + receiver.onbinary = function (message, flags) { + flags = flags || {}; + flags.binary = true; + server.emit('message', message, flags); + sender.send(message, {binary: true}); + }; + receiver.onping = function (message, flags) { + flags = flags || {}; + server.emit('ping', message, flags); + }; + receiver.onpong = function (message, flags) { + flags = flags || {}; + server.emit('pong', message, flags); + }; + receiver.onclose = function (code, message, flags) { + flags = flags || {}; + server.emit('close', code, message, flags); + }; + socket.on('data', function (data) { + receiver.add(data); + }); + socket.on('end', function() { + socket.end(); + }); +} + +function invalidRequestHandler(server, req, socket) { + if (typeof req.headers.upgrade === 'undefined' || + req.headers.upgrade.toLowerCase() !== 'websocket') { + throw new Error('invalid headers'); + return; + } + + if (!req.headers['sec-websocket-key']) { + socket.end(); + throw new Error('websocket key is missing'); + } + + // calc key + var key = req.headers['sec-websocket-key']; + var shasum = crypto.createHash('sha1'); + shasum.update(key + "bogus"); + key = shasum.digest('base64'); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: websocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Accept: ' + key + ]; + + socket.write(headers.concat('', '').join('\r\n')); + socket.end(); +} + +function closeAfterConnectHandler(server, req, socket) { + if (typeof req.headers.upgrade === 'undefined' || + req.headers.upgrade.toLowerCase() !== 'websocket') { + throw new Error('invalid headers'); + return; + } + + if (!req.headers['sec-websocket-key']) { + socket.end(); + throw new Error('websocket key is missing'); + } + + // calc key + var key = req.headers['sec-websocket-key']; + var shasum = crypto.createHash('sha1'); + shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + key = shasum.digest('base64'); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: websocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Accept: ' + key + ]; + + socket.write(headers.concat('', '').join('\r\n')); + socket.end(); +} + + +function return401(server, req, socket) { + var headers = [ + 'HTTP/1.1 401 Unauthorized' + , 'Content-type: text/html' + ]; + + socket.write(headers.concat('', '').join('\r\n')); + socket.end(); +} + +/** + * Server object, which will do the actual emitting + */ + +function Server(webServer) { + this.webServer = webServer; +} + +util.inherits(Server, events.EventEmitter); + +Server.prototype.close = function() { + this.webServer.close(); + if (this._socket) this._socket.end(); +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/node/package.json b/src/LiveDevelopment/impls/livedev2/transports/node/package.json new file mode 100644 index 00000000000..6e4a682f0d6 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/node/package.json @@ -0,0 +1,9 @@ +{ + "name": "brackets-livedev2-server", + "dependencies": { + "ws": "~0.4.31", + "connect": "~2.14.3", + "open": "0.0.4", + "lodash": "~2.4.1" + } +} diff --git a/src/LiveDevelopment/impls/livedev2/transports/remote/NodeSocketTransportRemote.js b/src/LiveDevelopment/impls/livedev2/transports/remote/NodeSocketTransportRemote.js new file mode 100644 index 00000000000..02b2dacad50 --- /dev/null +++ b/src/LiveDevelopment/impls/livedev2/transports/remote/NodeSocketTransportRemote.js @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014 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 browser: true, vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ +/*global WebSocket */ + +// This is a transport injected into the browser via a script that handles the low +// level communication between the live development protocol handlers on both sides. +// This transport provides a web socket mechanism. It's injected separately from the +// protocol handler so that the transport can be changed separately. + +(function (global) { + "use strict"; + + var WebSocketTransport = { + /** + * @private + * The WebSocket that we communicate with Brackets over. + * @type {?WebSocket} + */ + _ws: null, + + /** + * @private + * An object that contains callbacks to handle various transport events. See `setCallbacks()`. + * @type {?{connect: ?function, message: ?function(string), close: ?function}} + */ + _callbacks: null, + + /** + * Sets the callbacks that should be called when various transport events occur. All callbacks + * are optional, but you should at least implement "message" or nothing interesting will happen :) + * @param {?{connect: ?function, message: ?function(string), close: ?function}} callbacks + * The callbacks to set. + * connect - called when a connection is established to Brackets + * message(msgStr) - called with a string message sent from Brackets + * close - called when Brackets closes the connection + */ + setCallbacks: function (callbacks) { + if (!global._Brackets_LiveDev_Socket_Transport_URL) { + console.error("[Brackets LiveDev] No socket transport URL injected"); + } else { + this._callbacks = callbacks; + } + }, + + /** + * Connects to the NodeSocketTransport in Brackets at the given WebSocket URL. + * @param {string} url + */ + connect: function (url) { + var self = this; + this._ws = new WebSocket(url); + + // One potential source of confusion: the transport sends two "types" of messages - + // these are distinct from the protocol's own messages. This is because this transport + // needs to send an initial "connect" message telling the Brackets side of the transport + // the URL of the page that it's connecting from, distinct from the actual protocol + // message traffic. Actual protocol messages are sent as a JSON payload in a message of + // type "message". + // + // Other transports might not need to do this - for example, a transport that simply + // talks to an iframe within the same process already knows what URL that iframe is + // pointing to, so the only comunication that needs to happen via postMessage() is the + // actual protocol message strings, and no extra wrapping is necessary. + + this._ws.onopen = function (event) { + // Send the initial "connect" message to tell the other end what URL we're from. + self._ws.send(JSON.stringify({ + type: "connect", + url: global.location.href + })); + console.log("[Brackets LiveDev] Connected to Brackets at " + url); + if (self._callbacks && self._callbacks.connect) { + self._callbacks.connect(); + } + }; + this._ws.onmessage = function (event) { + console.log("[Brackets LiveDev] Got message: " + event.data); + if (self._callbacks && self._callbacks.message) { + self._callbacks.message(event.data); + } + }; + this._ws.onclose = function (event) { + self._ws = null; + if (self._callbacks && self._callbacks.close) { + self._callbacks.close(); + } + }; + // TODO: onerror + }, + + /** + * Sends a message over the transport. + * @param {string} msgStr The message to send. + */ + send: function (msgStr) { + if (this._ws) { + // See comment in `connect()` above about why we wrap the message in a transport message + // object. + this._ws.send(JSON.stringify({ + type: "message", + message: msgStr + })); + } else { + console.log("[Brackets LiveDev] Tried to send message over closed connection: " + msgStr); + } + }, + + /** + * Establish web socket connection. + */ + enable: function() { + this.connect(global._Brackets_LiveDev_Socket_Transport_URL); + } + }; + global._Brackets_LiveDev_Transport = WebSocketTransport; +}(this)); diff --git a/src/LiveDevelopment/main.js b/src/LiveDevelopment/main.js index 0c8c7f68eb0..ba830a470f8 100644 --- a/src/LiveDevelopment/main.js +++ b/src/LiveDevelopment/main.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved. + * Copyright (c) 2013 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"), @@ -21,267 +21,48 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $, less, window */ +/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ +/*global define */ /** - * main integrates LiveDevelopment into Brackets - * - * This module creates two menu items: - * - * "Go Live": open or close a Live Development session and visualize the status - * "Highlight": toggle source highlighting + * main loads a LiveDevelopment implementation: + * + * LiveDevelopment implementation its being set by 'livedev.impl' preference. + * There are currently two alternative values: + * + * 'default' : current default implementation based on CDT + * 'livedev2' : experimental implementation (CDT-independent) + * + * See impls/livedev2/README.md for more details on livedev2 implemetantion. + * */ + define(function main(require, exports, module) { "use strict"; - - var DocumentManager = require("document/DocumentManager"), - Commands = require("command/Commands"), - AppInit = require("utils/AppInit"), - LiveDevelopment = require("LiveDevelopment/LiveDevelopment"), - Inspector = require("LiveDevelopment/Inspector/Inspector"), - CommandManager = require("command/CommandManager"), - PreferencesManager = require("preferences/PreferencesManager"), - Dialogs = require("widgets/Dialogs"), - DefaultDialogs = require("widgets/DefaultDialogs"), - UrlParams = require("utils/UrlParams").UrlParams, - Strings = require("strings"), - ExtensionUtils = require("utils/ExtensionUtils"), - StringUtils = require("utils/StringUtils"); - - var params = new UrlParams(); - var config = { - experimental: false, // enable experimental features - debug: true, // enable debug output and helpers - autoconnect: false, // go live automatically after startup? - highlight: true, // enable highlighting? - highlightConfig: { // the highlight configuration for the Inspector - borderColor: {r: 255, g: 229, b: 153, a: 0.66}, - contentColor: {r: 111, g: 168, b: 220, a: 0.55}, - marginColor: {r: 246, g: 178, b: 107, a: 0.66}, - paddingColor: {r: 147, g: 196, b: 125, a: 0.66}, - showInfo: true - } - }; - // Status labels/styles are ordered: error, not connected, progress1, progress2, connected. - var _statusTooltip = [ - Strings.LIVE_DEV_STATUS_TIP_NOT_CONNECTED, - Strings.LIVE_DEV_STATUS_TIP_NOT_CONNECTED, - Strings.LIVE_DEV_STATUS_TIP_PROGRESS1, - Strings.LIVE_DEV_STATUS_TIP_PROGRESS2, - Strings.LIVE_DEV_STATUS_TIP_CONNECTED, - Strings.LIVE_DEV_STATUS_TIP_OUT_OF_SYNC, - Strings.LIVE_DEV_STATUS_TIP_SYNC_ERROR - ]; - - var _statusStyle = ["warning", "", "info", "info", "success", "out-of-sync", "sync-error"]; // Status indicator's CSS class - var _allStatusStyles = _statusStyle.join(" "); - - var _$btnGoLive; // reference to the GoLive button - - /** Load Live Development LESS Style */ - function _loadStyles() { - var lessText = require("text!LiveDevelopment/main.less"), - parser = new less.Parser(); - - parser.parse(lessText, function onParse(err, tree) { - console.assert(!err, err); - ExtensionUtils.addEmbeddedStyleSheet(tree.toCSS()); - }); - } - - /** - * Change the appearance of a button. Omit text to remove any extra text; omit style to return to default styling; - * omit tooltip to leave tooltip unchanged. - */ - function _setLabel($btn, text, style, tooltip) { - // Clear text/styles from previous status - $("span", $btn).remove(); - $btn.removeClass(_allStatusStyles); - - // Set text/styles for new status - if (text && text.length > 0) { - $("") - .addClass(style) - .text(text) - .appendTo($btn); - } else { - $btn.addClass(style); - } - - if (tooltip) { - $btn.attr("title", tooltip); - } - } - - /** - * Toggles LiveDevelopment and synchronizes the state of UI elements that reports LiveDevelopment status - * - * Stop Live Dev when in an active state (ACTIVE, OUT_OF_SYNC, SYNC_ERROR). - * Start Live Dev when in an inactive state (ERROR, INACTIVE). - * Do nothing when in a connecting state (CONNECTING, LOADING_AGENTS). - */ - function _handleGoLiveCommand() { - if (LiveDevelopment.status >= LiveDevelopment.STATUS_ACTIVE) { - LiveDevelopment.close(); - } else if (LiveDevelopment.status <= LiveDevelopment.STATUS_INACTIVE) { - if (!params.get("skipLiveDevelopmentInfo") && !PreferencesManager.getViewState("livedev.afterFirstLaunch")) { - PreferencesManager.setViewState("livedev.afterFirstLaunch", "true"); - Dialogs.showModalDialog( - DefaultDialogs.DIALOG_ID_INFO, - Strings.LIVE_DEVELOPMENT_INFO_TITLE, - Strings.LIVE_DEVELOPMENT_INFO_MESSAGE - ).done(function (id) { - LiveDevelopment.open(); - }); - } else { - LiveDevelopment.open(); - } - } - } - - /** Called on status change */ - function _showStatusChangeReason(reason) { - // Destroy the previous twipsy (options are not updated otherwise) - _$btnGoLive.twipsy("hide").removeData("twipsy"); - - // If there was no reason or the action was an explicit request by the user, don't show a twipsy - if (!reason || reason === "explicit_close") { - return; - } - - // Translate the reason - var translatedReason = Strings["LIVE_DEV_" + reason.toUpperCase()]; - if (!translatedReason) { - translatedReason = StringUtils.format(Strings.LIVE_DEV_CLOSED_UNKNOWN_REASON, reason); - } + + var AppInit = require("utils/AppInit"), + PreferencesManager = require("preferences/PreferencesManager"); - // Configure the twipsy - var options = { - placement: "left", - trigger: "manual", - autoHideDelay: 5000, - title: function () { - return translatedReason; - } + // pre-loaded implementations + var liveDevImpls = { + 'default' : require("LiveDevelopment/impls/default/main"), + 'livedev2' : require("LiveDevelopment/impls/livedev2/main") }; - - // Show the twipsy with the explanation - _$btnGoLive.twipsy(options).twipsy("show"); - } - /** Create the menu item "Go Live" */ - function _setupGoLiveButton() { - _$btnGoLive = $("#toolbar-go-live"); - _$btnGoLive.click(function onGoLive() { - _handleGoLiveCommand(); - }); - $(LiveDevelopment).on("statusChange", function statusChange(event, status, reason) { - // status starts at -1 (error), so add one when looking up name and style - // See the comments at the top of LiveDevelopment.js for details on the - // various status codes. - _setLabel(_$btnGoLive, null, _statusStyle[status + 1], _statusTooltip[status + 1]); - _showStatusChangeReason(reason); - if (config.autoconnect) { - window.sessionStorage.setItem("live.enabled", status === 3); - } - }); - - // Initialize tooltip for 'not connected' state - _setLabel(_$btnGoLive, null, _statusStyle[1], _statusTooltip[1]); - } - - /** Maintains state of the Live Preview menu item */ - function _setupGoLiveMenu() { - $(LiveDevelopment).on("statusChange", function statusChange(event, status) { - // Update the checkmark next to 'Live Preview' menu item - // Add checkmark when status is STATUS_ACTIVE; otherwise remove it - CommandManager.get(Commands.FILE_LIVE_FILE_PREVIEW).setChecked(status === LiveDevelopment.STATUS_ACTIVE); - CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setEnabled(status === LiveDevelopment.STATUS_ACTIVE); - }); - } - - function _updateHighlightCheckmark() { - CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setChecked(config.highlight); - } - - function _handlePreviewHighlightCommand() { - config.highlight = !config.highlight; - _updateHighlightCheckmark(); - if (config.highlight) { - LiveDevelopment.showHighlight(); - } else { - LiveDevelopment.hideHighlight(); - } - PreferencesManager.setViewState("livedev.highlight", config.highlight); - } - - /** Setup window references to useful LiveDevelopment modules */ - function _setupDebugHelpers() { - window.ld = LiveDevelopment; - window.i = Inspector; - window.report = function report(params) { window.params = params; console.info(params); }; - } - - /** force reload the live preview */ - function _handleReloadLivePreviewCommand() { - if (LiveDevelopment.status >= LiveDevelopment.STATUS_ACTIVE) { - LiveDevelopment.reload(); - } - } + // current active implementation + var LiveDevelopment; /** Initialize LiveDevelopment */ AppInit.appReady(function () { - params.parse(); - - Inspector.init(config); - LiveDevelopment.init(config); - _loadStyles(); - _setupGoLiveButton(); - _setupGoLiveMenu(); - - _updateHighlightCheckmark(); - - if (config.debug) { - _setupDebugHelpers(); - } - - // trigger autoconnect - if (config.autoconnect && - window.sessionStorage.getItem("live.enabled") === "true" && - DocumentManager.getCurrentDocument()) { - _handleGoLiveCommand(); + PreferencesManager.definePreference('livedev.impl', 'string', 'default'); + // get choose LiveDevelopment implementation based on preference value + LiveDevelopment = liveDevImpls[PreferencesManager.get('livedev.impl')]; + if (!LiveDevelopment) { + // preference value doesn't match any implementation, switching to 'default' + console.log("invalid livedev.impl value - switching to default implemenation"); + LiveDevelopment = liveDevImpls['default']; } - - // Redraw highlights when window gets focus. This ensures that the highlights - // will be in sync with any DOM changes that may have occurred. - $(window).focus(function () { - if (Inspector.connected() && config.highlight) { - LiveDevelopment.redrawHighlight(); - } - }); + // init + LiveDevelopment.init(); }); - - // init prefs - PreferencesManager.stateManager.definePreference("livedev.highlight", "boolean", true) - .on("change", function () { - config.highlight = PreferencesManager.getViewState("livedev.highlight"); - _updateHighlightCheckmark(); - }); - - PreferencesManager.convertPreferences(module, { - "highlight": "user livedev.highlight", - "afterFirstLaunch": "user livedev.afterFirstLaunch" - }, true); - - config.highlight = PreferencesManager.getViewState("livedev.highlight"); - - // init commands - CommandManager.register(Strings.CMD_LIVE_FILE_PREVIEW, Commands.FILE_LIVE_FILE_PREVIEW, _handleGoLiveCommand); - CommandManager.register(Strings.CMD_LIVE_HIGHLIGHT, Commands.FILE_LIVE_HIGHLIGHT, _handlePreviewHighlightCommand); - CommandManager.register(Strings.CMD_RELOAD_LIVE_PREVIEW, Commands.CMD_RELOAD_LIVE_PREVIEW, _handleReloadLivePreviewCommand); - CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setEnabled(false); - - // Export public functions -}); +}); \ No newline at end of file diff --git a/src/brackets.js b/src/brackets.js index e0d5e728334..d96334ef714 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -171,7 +171,7 @@ define(function (require, exports, module) { DocumentCommandHandlers : DocumentCommandHandlers, DocumentManager : DocumentManager, DocumentModule : require("document/Document"), - DOMAgent : require("LiveDevelopment/Agents/DOMAgent"), + DOMAgent : require("LiveDevelopment/impls/default/Agents/DOMAgent"), DragAndDrop : DragAndDrop, EditorManager : EditorManager, ExtensionLoader : ExtensionLoader, @@ -185,12 +185,12 @@ define(function (require, exports, module) { FindInFiles : require("search/FindInFiles"), FindInFilesUI : require("search/FindInFilesUI"), HTMLInstrumentation : require("language/HTMLInstrumentation"), - Inspector : require("LiveDevelopment/Inspector/Inspector"), + Inspector : require("LiveDevelopment/impls/default/Inspector/Inspector"), InstallExtensionDialog : require("extensibility/InstallExtensionDialog"), JSUtils : JSUtils, KeyBindingManager : KeyBindingManager, LanguageManager : LanguageManager, - LiveDevelopment : require("LiveDevelopment/LiveDevelopment"), + LiveDevelopment : require("LiveDevelopment/impls/default/LiveDevelopment"), LiveDevServerManager : require("LiveDevelopment/LiveDevServerManager"), MainViewManager : MainViewManager, MainViewFactory : require("view/MainViewFactory"), @@ -200,7 +200,7 @@ define(function (require, exports, module) { PerfUtils : PerfUtils, PreferencesManager : PreferencesManager, ProjectManager : ProjectManager, - RemoteAgent : require("LiveDevelopment/Agents/RemoteAgent"), + RemoteAgent : require("LiveDevelopment/impls/default/Agents/RemoteAgent"), ScrollTrackMarkers : require("search/ScrollTrackMarkers"), UpdateNotification : require("utils/UpdateNotification"), WorkingSetView : WorkingSetView, diff --git a/src/command/Commands.js b/src/command/Commands.js index 87d0466caec..f736f9b7253 100644 --- a/src/command/Commands.js +++ b/src/command/Commands.js @@ -47,9 +47,9 @@ define(function (require, exports, module) { exports.FILE_CLOSE_ALL = "file.close_all"; // DocumentCommandHandlers.js handleFileCloseAll() exports.FILE_CLOSE_LIST = "file.close_list"; // DocumentCommandHandlers.js handleFileCloseList() exports.FILE_OPEN_DROPPED_FILES = "file.openDroppedFiles"; // DragAndDrop.js openDroppedFiles() - exports.FILE_LIVE_FILE_PREVIEW = "file.liveFilePreview"; // LiveDevelopment/main.js _handleGoLiveCommand() - exports.CMD_RELOAD_LIVE_PREVIEW = "file.reloadLivePreview"; // LiveDevelopment/main.js _handleReloadLivePreviewCommand() - exports.FILE_LIVE_HIGHLIGHT = "file.previewHighlight"; // LiveDevelopment/main.js _handlePreviewHighlightCommand() + exports.FILE_LIVE_FILE_PREVIEW = "file.liveFilePreview"; // LiveDevelopment/impls/default/main.js _handleGoLiveCommand() + exports.CMD_RELOAD_LIVE_PREVIEW = "file.reloadLivePreview"; // LiveDevelopment/impls/default/main.js _handleReloadLivePreviewCommand() + exports.FILE_LIVE_HIGHLIGHT = "file.previewHighlight"; // LiveDevelopment/impls/default/main.js _handlePreviewHighlightCommand() exports.FILE_PROJECT_SETTINGS = "file.projectSettings"; // ProjectManager.js _projectSettings() exports.FILE_RENAME = "file.rename"; // DocumentCommandHandlers.js handleFileRename() exports.FILE_DELETE = "file.delete"; // DocumentCommandHandlers.js handleFileDelete() diff --git a/src/document/DocumentCommandHandlers.js b/src/document/DocumentCommandHandlers.js index 25f1fff634f..dad5217a267 100644 --- a/src/document/DocumentCommandHandlers.js +++ b/src/document/DocumentCommandHandlers.js @@ -53,7 +53,7 @@ define(function (require, exports, module) { PreferencesManager = require("preferences/PreferencesManager"), PerfUtils = require("utils/PerfUtils"), KeyEvent = require("utils/KeyEvent"), - Inspector = require("LiveDevelopment/Inspector/Inspector"), + Inspector = require("LiveDevelopment/impls/default/Inspector/Inspector"), Menus = require("command/Menus"), UrlParams = require("utils/UrlParams").UrlParams, StatusBar = require("widgets/StatusBar"), diff --git a/test/spec/FileFilters-test.js b/test/spec/FileFilters-test.js index b4241ca7b61..97e47d1891f 100644 --- a/test/spec/FileFilters-test.js +++ b/test/spec/FileFilters-test.js @@ -396,7 +396,7 @@ define(function (require, exports, module) { expectEquivalent("node_*", "**node_***"); expectEquivalent("node_?", "**node_?**"); expectEquivalent("*-test-files/", "***-test-files/**"); - expectEquivalent("LiveDevelopment/**/Inspector", "**LiveDevelopment/**/Inspector**"); + expectEquivalent("LiveDevelopment/impls/default/**/Inspector", "**LiveDevelopment/impls/default/**/Inspector**"); }); it("shouldn't add ** suffix", function () { diff --git a/test/spec/HTMLInstrumentation-test.js b/test/spec/HTMLInstrumentation-test.js index 380d457c6f3..0f583bb0935 100644 --- a/test/spec/HTMLInstrumentation-test.js +++ b/test/spec/HTMLInstrumentation-test.js @@ -32,7 +32,7 @@ define(function (require, exports, module) { // Load dependent modules var HTMLInstrumentation = require("language/HTMLInstrumentation"), HTMLSimpleDOM = require("language/HTMLSimpleDOM"), - RemoteFunctions = require("text!LiveDevelopment/Agents/RemoteFunctions.js"), + RemoteFunctions = require("text!LiveDevelopment/impls/default/Agents/RemoteFunctions.js"), SpecRunnerUtils = require("spec/SpecRunnerUtils"), WellFormedDoc = require("text!spec/HTMLInstrumentation-test-files/wellformed.html"), NotWellFormedDoc = require("text!spec/HTMLInstrumentation-test-files/omitEndTags.html"), diff --git a/test/spec/LiveDevelopment-test.js b/test/spec/LiveDevelopment-test.js index 97ae366250f..e637fe4518a 100644 --- a/test/spec/LiveDevelopment-test.js +++ b/test/spec/LiveDevelopment-test.js @@ -50,18 +50,18 @@ define(function (require, exports, module) { ProjectManager; // Used as mocks - require("LiveDevelopment/main"); + require("LiveDevelopment/impls/default/main"); var CommandsModule = require("command/Commands"), CommandsManagerModule = require("command/CommandManager"), - LiveDevelopmentModule = require("LiveDevelopment/LiveDevelopment"), - InspectorModule = require("LiveDevelopment/Inspector/Inspector"), - CSSDocumentModule = require("LiveDevelopment/Documents/CSSDocument"), - CSSAgentModule = require("LiveDevelopment/Agents/CSSAgent"), - HighlightAgentModule = require("LiveDevelopment/Agents/HighlightAgent"), - HTMLDocumentModule = require("LiveDevelopment/Documents/HTMLDocument"), + LiveDevelopmentModule = require("LiveDevelopment/impls/default/LiveDevelopment"), + InspectorModule = require("LiveDevelopment/impls/default/Inspector/Inspector"), + CSSDocumentModule = require("LiveDevelopment/impls/default/Documents/CSSDocument"), + CSSAgentModule = require("LiveDevelopment/impls/default/Agents/CSSAgent"), + HighlightAgentModule = require("LiveDevelopment/impls/default/Agents/HighlightAgent"), + HTMLDocumentModule = require("LiveDevelopment/impls/default/Documents/HTMLDocument"), HTMLInstrumentationModule = require("language/HTMLInstrumentation"), NativeAppModule = require("utils/NativeApp"), - CSSPreprocessorDocumentModule = require("LiveDevelopment/Documents/CSSPreprocessorDocument"); + CSSPreprocessorDocumentModule = require("LiveDevelopment/impls/default/Documents/CSSPreprocessorDocument"); var testPath = SpecRunnerUtils.getTestPath("/spec/LiveDevelopment-test-files"), tempDir = SpecRunnerUtils.getTempDirectory(), diff --git a/test/spec/RemoteFunctions-test.js b/test/spec/RemoteFunctions-test.js index ae3ba0fd1c3..fd1c47253aa 100644 --- a/test/spec/RemoteFunctions-test.js +++ b/test/spec/RemoteFunctions-test.js @@ -27,7 +27,7 @@ define(function (require, exports, module) { 'use strict'; - var RemoteFunctions = require("text!LiveDevelopment/Agents/RemoteFunctions.js"); + var RemoteFunctions = require("text!LiveDevelopment/impls/default/Agents/RemoteFunctions.js"); // "load" RemoteFunctions RemoteFunctions = eval("(" + RemoteFunctions.trim() + ")()");