From 85d2e8715450bb6bf8079b16f588486ed84e065c Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Mon, 25 Feb 2013 18:15:32 +0100 Subject: [PATCH 1/2] added new package option --- arangod/V8Server/ApplicationV8.cpp | 8 +- arangod/V8Server/ApplicationV8.h | 11 + arangosh/V8Client/arangosh.cpp | 9 +- js/common/bootstrap/module-internal.js | 72 +-- js/common/bootstrap/modules.js | 604 ++++++++++++++++++++----- js/common/tests/shell-database.js | 0 lib/V8/v8-utils.cpp | 41 +- lib/V8/v8-utils.h | 5 +- 8 files changed, 557 insertions(+), 193 deletions(-) mode change 100755 => 100644 js/common/tests/shell-database.js diff --git a/arangod/V8Server/ApplicationV8.cpp b/arangod/V8Server/ApplicationV8.cpp index cde0bb233d..0609d5e292 100644 --- a/arangod/V8Server/ApplicationV8.cpp +++ b/arangod/V8Server/ApplicationV8.cpp @@ -169,6 +169,7 @@ ApplicationV8::ApplicationV8 (string const& binaryPath) : ApplicationFeature("V8"), _startupPath(), _startupModules(), + _startupNodeModules(), _actionPath(), _useActions(true), _performUpgrade(false), @@ -511,6 +512,7 @@ void ApplicationV8::setupOptions (map ("javascript.gc-frequency", &_gcFrequency, "JavaScript time-based garbage collection frequency (each x seconds)") ("javascript.action-directory", &_actionPath, "path to the JavaScript action directory") ("javascript.modules-path", &_startupModules, "one or more directories separated by (semi-) colons") + ("javascript.package-path", &_startupNodeModules, "one or more directories separated by (semi-) colons") ("javascript.startup-directory", &_startupPath, "path to the directory containing alternate JavaScript startup scripts") ("javascript.v8-options", &_v8Options, "options to pass to v8") ; @@ -536,6 +538,10 @@ bool ApplicationV8::prepare () { LOGGER_INFO("using JavaScript modules path '" << _startupModules << "'"); } + if (! _startupNodeModules.empty()) { + LOGGER_INFO("using Node modules path '" << _startupNodeModules << "'"); + } + // set up the startup loader if (_startupPath.empty()) { LOGGER_FATAL_AND_EXIT("no 'javascript.startup-directory' has been supplied, giving up"); @@ -678,7 +684,7 @@ bool ApplicationV8::prepareV8Instance (const size_t i) { } TRI_InitV8Conversions(context->_context); - TRI_InitV8Utils(context->_context, _startupModules); + TRI_InitV8Utils(context->_context, _startupModules, _startupNodeModules); TRI_InitV8Shell(context->_context); // set global flag before loading system files diff --git a/arangod/V8Server/ApplicationV8.h b/arangod/V8Server/ApplicationV8.h index 950872c783..84ff3299a8 100644 --- a/arangod/V8Server/ApplicationV8.h +++ b/arangod/V8Server/ApplicationV8.h @@ -357,6 +357,17 @@ namespace triagens { string _startupModules; +//////////////////////////////////////////////////////////////////////////////// +/// @brief semicolon separated list of module directories +/// +/// @CMDOPT{\--javascript.package-path @CA{directory}} +/// +/// Specifies the @CA{directory} path with user defined Node modules. +/// Multiple paths can be specified separated with commas. +//////////////////////////////////////////////////////////////////////////////// + + string _startupNodeModules; + //////////////////////////////////////////////////////////////////////////////// /// @brief path to the system action directory /// diff --git a/arangosh/V8Client/arangosh.cpp b/arangosh/V8Client/arangosh.cpp index 6e83a5689a..4ac043b8d3 100755 --- a/arangosh/V8Client/arangosh.cpp +++ b/arangosh/V8Client/arangosh.cpp @@ -109,6 +109,12 @@ static JSLoader StartupLoader; static string StartupModules = ""; +//////////////////////////////////////////////////////////////////////////////// +/// @brief path for Node modules files +//////////////////////////////////////////////////////////////////////////////// + +static string StartupNodeModules = ""; + //////////////////////////////////////////////////////////////////////////////// /// @brief path for JavaScript bootstrap files //////////////////////////////////////////////////////////////////////////////// @@ -427,6 +433,7 @@ static void ParseProgramOptions (int argc, char* argv[]) { ("javascript.execute", &ExecuteScripts, "execute Javascript code from file") ("javascript.check", &CheckScripts, "syntax check code Javascript code from file") ("javascript.modules-path", &StartupModules, "one or more directories separated by cola") + ("javascript.package-path", &StartupNodeModules, "one or more directories separated by cola") ("javascript.startup-directory", &StartupPath, "startup paths containing the JavaScript files; multiple directories can be separated by cola") ("javascript.unit-tests", &UnitTests, "do not start as shell, run unit tests instead") ("jslint", &JsLint, "do not start as shell, run jslint instead") @@ -1395,7 +1402,7 @@ int main (int argc, char* argv[]) { v8::FunctionTemplate::New(JS_PagerOutput)->GetFunction(), v8::ReadOnly); - TRI_InitV8Utils(context, StartupModules); + TRI_InitV8Utils(context, StartupModules, StartupNodeModules); TRI_InitV8Shell(context); // reset the prompt error flag (will determine prompt colors) diff --git a/js/common/bootstrap/module-internal.js b/js/common/bootstrap/module-internal.js index e968d06832..69b0d6f521 100644 --- a/js/common/bootstrap/module-internal.js +++ b/js/common/bootstrap/module-internal.js @@ -2,7 +2,7 @@ /*global require, module, Module, FS_MOVE, FS_REMOVE, FS_EXISTS, FS_IS_DIRECTORY, FS_LIST_TREE, SYS_EXECUTE, SYS_LOAD, SYS_LOG, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STAT, SYS_RAND, SYS_READ, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER, SYS_SHA256, SYS_WAIT, - SYS_GETLINE, SYS_PARSE, SYS_SAVE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, + SYS_GETLINE, SYS_PARSE, SYS_SAVE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, PACKAGE_PATH, SYS_PROCESS_CSV_FILE, SYS_PROCESS_JSON_FILE, ARANGO_QUIET, MODULES_PATH, COLORS, COLOR_OUTPUT, COLOR_OUTPUT_RESET, COLOR_BRIGHT, COLOR_BLACK, COLOR_BOLD_BLACK, COLOR_BLINK, COLOR_BLUE, COLOR_BOLD_BLUE, COLOR_BOLD_GREEN, COLOR_RED, COLOR_BOLD_RED, COLOR_GREEN, COLOR_WHITE, @@ -203,6 +203,17 @@ delete MODULES_PATH; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief node modules path +//////////////////////////////////////////////////////////////////////////////// + + internal.PACKAGE_PATH = ""; + + if (typeof PACKAGE_PATH !== "undefined") { + internal.PACKAGE_PATH = PACKAGE_PATH; + delete PACKAGE_PATH; + } + //////////////////////////////////////////////////////////////////////////////// /// @brief quiet flag //////////////////////////////////////////////////////////////////////////////// @@ -823,63 +834,6 @@ return target; }; -//////////////////////////////////////////////////////////////////////////////// -/// @brief reads a file from the module path or the database -//////////////////////////////////////////////////////////////////////////////// - - internal.loadDatabaseFile = function (path) { - var i; - var mc; - var n; - - // try to load the file - var paths = internal.MODULES_PATH; - - for (i = 0; i < paths.length; ++i) { - var p = paths[i]; - - if (p === "") { - n = "." + path + ".js"; - } - else { - n = p + "/" + path + ".js"; - } - - if (internal.exists(n)) { - module.ModuleExistsCache[path] = true; - return { path : n, content : internal.read(n) }; - } - } - - // try to load the module from the database - if (internal.db !== undefined) { - mc = internal.db._collection("_modules"); - - if (mc !== null && typeof mc.firstExample === "function") { - n = mc.firstExample({ path: path }); - - if (n !== null) { - if (n.hasOwnProperty('content')) { - module.ModuleExistsCache[path] = true; - return { path : "_collection/" + path, content : n.content }; - } - - if (module.ModuleExistsCache.hasOwnProperty("/console")) { - var console = module.ModuleExistsCache["/console"]; - console.error("found empty content in '%s'", JSON.stringify(n)); - } - } - } - } - - module.ModuleExistsCache[path] = false; - - throw "cannot find a file named '" - + path - + "' using the module path(s) '" - + internal.MODULES_PATH + "'"; - }; - //////////////////////////////////////////////////////////////////////////////// /// @brief loads a file from the file-system //////////////////////////////////////////////////////////////////////////////// @@ -929,7 +883,7 @@ mc = internal.db._create("_modules", { isSystem: true }); } - path = module.normalise(path); + path = module.normalize(path); m = mc.firstExample({ path: path }); if (m === null) { diff --git a/js/common/bootstrap/modules.js b/js/common/bootstrap/modules.js index 7886e46f86..8e4509a0b1 100644 --- a/js/common/bootstrap/modules.js +++ b/js/common/bootstrap/modules.js @@ -1,5 +1,5 @@ /*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */ -/*global require, module: true */ +/*global require, module: true, PACKAGE_PATH */ //////////////////////////////////////////////////////////////////////////////// /// @brief JavaScript server functions @@ -179,13 +179,54 @@ function stop_color_print () { /// @brief module constructor //////////////////////////////////////////////////////////////////////////////// - function Module (id) { - this.id = id; // commonjs Module/1.1.1 - this.exports = {}; // commonjs Module/1.1.1 + function Module (id, type, pkg) { + this.id = id; // commonjs Module/1.1.1 + this.exports = {}; // commonjs Module/1.1.1 - this._normalized = {}; + this._type = type; // module type: 'system', 'user' + this._origin = 'unknown'; // 'file:///{path}' + // 'database:///_document/{collection}/{key}' + + this._package = pkg; // package to which this module belongs } +//////////////////////////////////////////////////////////////////////////////// +/// @brief package constructor +//////////////////////////////////////////////////////////////////////////////// + + function Package (id, description, parent, paths) { + var i; + + this.id = id; // same of the corresponding module + this._description = description; // the package.json file + this._parent = parent; // parent package + this._moduleCache = {}; // module cache for package modules + + this._paths = paths; // path to the package + } + + var GlobalPackage = new Package("/", {name: "ArangoDB"}, undefined, PACKAGE_PATH); + + Package.prototype.defineSystemModule = function (path) { + this._moduleCache[path] = new Module(path, 'system', GlobalPackage); + }; + + Package.prototype.defineModule = function (path, module) { + this._moduleCache[path] = module; + }; + + Package.prototype.clearModule = function (path) { + delete this._moduleCache[path]; + }; + + Package.prototype.module = function (path) { + if (this._moduleCache.hasOwnProperty(path)) { + return this._moduleCache[path]; + } + + return null; + }; + //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// @@ -200,28 +241,21 @@ function stop_color_print () { //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -/// @brief module cache +/// @brief global module cache //////////////////////////////////////////////////////////////////////////////// - var ModuleCache = {}; + var ModuleExistsCache = {}; - ModuleCache["/"] = new Module("/"); - ModuleCache["/internal"] = new Module("/internal"); - ModuleCache["/fs"] = new Module("/fs"); - ModuleCache["/console"] = new Module("/console"); - -//////////////////////////////////////////////////////////////////////////////// -/// @brief file exists cache -//////////////////////////////////////////////////////////////////////////////// - - Module.prototype.ModuleExistsCache = {}; + GlobalPackage.defineSystemModule("/"); + GlobalPackage.defineSystemModule("/internal"); + GlobalPackage.defineSystemModule("/fs"); + GlobalPackage.defineSystemModule("/console"); //////////////////////////////////////////////////////////////////////////////// /// @brief top-level-module //////////////////////////////////////////////////////////////////////////////// - Module.prototype.root = ModuleCache["/"]; - module = Module.prototype.root; + module = Module.prototype.root = GlobalPackage.module("/"); //////////////////////////////////////////////////////////////////////////////// /// @} @@ -236,86 +270,22 @@ function stop_color_print () { /// @{ //////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// @brief loads a file and creates a new module descriptor -//////////////////////////////////////////////////////////////////////////////// - - Module.prototype.require = function (unormalizedPath) { - var content; - var f; - var internal; - var module; - var path; - var paths; - var raw; - var sandbox; - - internal = ModuleCache["/internal"].exports; - - // check if you already know the module - if (this._normalized.hasOwnProperty(unormalizedPath)) { - return this._normalized[unormalizedPath]; - } - - // first get rid of any ".." and "." - path = this.normalise(unormalizedPath); - - // check if you already know the module, return the exports - if (ModuleCache.hasOwnProperty(path)) { - module = ModuleCache[path]; - this._normalized[unormalizedPath] = module.exports; - return module.exports; - } - - // locate file and read content - raw = internal.loadDatabaseFile(path); - - // test for parse errors first and fail early if a parse error detected - if (! internal.parse(raw.content, path)) { - throw "Javascript parse error in file '" + path + "'"; - } - - // create a new sandbox and execute - module = ModuleCache[path] = new Module(path); - - content = "(function (module, exports, require, print) {" - + raw.content - + "\n});"; - - f = internal.execute(content, undefined, path); - - if (f === undefined) { - throw "cannot create context function"; - } - - try { - f(module, - module.exports, - function(path) { return module.require(path); }, - ModuleCache["/internal"].exports.print); - } - catch (err) { - delete ModuleCache[path]; - throw "Javascript exception in file '" + path + "': " + err + " - " + err.stack; - } - - this._normalized[unormalizedPath] = module.exports; - return module.exports; - }; + var internal = GlobalPackage.module("/internal").exports; + var console = GlobalPackage.module("/console").exports; //////////////////////////////////////////////////////////////////////////////// -/// @brief returns true if require found a file +/// @brief normalizes a module name +/// +/// If @FA{path} starts with "." or "..", then it is a relative path. +/// Otherwise it is an absolute path. +/// +/// @FA{prefix} must not end in `/` unless it is equal to `"/"`. +/// +/// The normalized name will start with a `/`, but not end in `/' unless it +/// is equal to `"/"`. //////////////////////////////////////////////////////////////////////////////// - Module.prototype.exists = function (path) { - return this.ModuleExistsCache[path]; - }; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief normalises a path -//////////////////////////////////////////////////////////////////////////////// - - Module.prototype.normalise = function (path) { + internal.normalizeModuleName = function (prefix, path) { var i; var n; var p; @@ -323,14 +293,14 @@ function stop_color_print () { var x; if (path === "") { - return this.id; + return prefix; } p = path.split('/'); // relative path if (p[0] === "." || p[0] === "..") { - q = this.id.split('/'); + q = prefix.split('/'); q.pop(); q = q.concat(p); } @@ -348,7 +318,7 @@ function stop_color_print () { if (x === "..") { if (n.length === 0) { - throw "cannot cross module top"; + throw "cannot use '..' to escape top-level-directory"; } n.pop(); @@ -361,6 +331,376 @@ function stop_color_print () { return "/" + n.join('/'); }; +//////////////////////////////////////////////////////////////////////////////// +/// @brief reads a module package description file +//////////////////////////////////////////////////////////////////////////////// + + internal.loadPackageDescription = function (main, pkg) { + var paths; + var i; + + paths = pkg._paths; + + for (i = 0; i < paths.length; ++i) { + var p = paths[i]; + var n; + var m; + + if (p === "") { + m = "./node_modules" + main; + } + else if (p[p.length - 1] === '/') { + m = p + "node_modules" + main; + } + else { + m = p + "/node_modules" + main; + } + + n = m + "/package.json"; + + if (internal.exists(n)) { + try { + var desc = JSON.parse(internal.read(n)); + var mainfile = m + internal.normalizeModuleName("", desc.main) + ".js"; + + if (internal.exists(mainfile)) { + var content = internal.read(mainfile); + + return { name: main, + description: desc, + packagePath: m, + path: 'file://' + mainfile, + content: content }; + } + } + catch (err) { + if ('error' in console) { + console.error("cannot load package '%s': %s - %s", main, String(err), String(err.stack)); + } + } + } + } + + return null; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief reads a file from the package path +//////////////////////////////////////////////////////////////////////////////// + + internal.loadPackageFile = function (main, pkg) { + var n; + var i; + var mc; + var paths; + + paths = pkg._paths; + + // ----------------------------------------------------------------------------- + // normal modules, file based + // ----------------------------------------------------------------------------- + + // try to load the file + for (i = 0; i < paths.length; ++i) { + var p = paths[i]; + + if (p === "") { + n = "." + main + ".js"; + } + else if (p[p.length - 1] === '/') { + n = p + main.substr(1) + ".js"; + } + else { + n = p + main + ".js"; + } + + if (internal.exists(n)) { + return { name: main, + path: 'file://' + n, + content: internal.read(n) }; + } + } + + return null; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief reads a file from the module path or the database +//////////////////////////////////////////////////////////////////////////////// + + internal.loadModuleFile = function (main) { + var n; + var i; + var mc; + var paths; + + paths = internal.MODULES_PATH; + + // ----------------------------------------------------------------------------- + // normal modules, file based + // ----------------------------------------------------------------------------- + + // try to load the file + for (i = 0; i < paths.length; ++i) { + var p = paths[i]; + + if (p === "") { + n = "." + main + ".js"; + } + else if (p[p.length - 1] === '/') { + n = p + main.substr(1) + ".js"; + } + else { + n = p + main + ".js"; + } + + if (internal.exists(n)) { + return { name: main, + path: 'file://' + n, + content: internal.read(n) }; + } + } + + // ----------------------------------------------------------------------------- + // normal modules, database based + // ----------------------------------------------------------------------------- + + if (internal.db !== undefined) { + mc = internal.db._collection("_modules"); + + if (mc !== null && typeof mc.firstExample === "function") { + n = mc.firstExample({ path: main }); + + if (n !== null) { + if (n.hasOwnProperty('content')) { + return { name: main, + path: "database:///_document/" + n._id, + content: n.content }; + } + + if ('error' in console) { + console.error("found empty content in '%s'", JSON.stringify(n)); + } + } + } + } + + return null; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief loads a module +//////////////////////////////////////////////////////////////////////////////// + + Module.prototype.createModule = function (description, type, pkg) { + var content; + var fun; + var module; + + // mark that we have seen the definition, used for debugging only + ModuleExistsCache[description.name] = true; + + // test for parse errors first and fail early if a parse error detected + if (! internal.parse(description.content)) { + throw "Javascript parse error in file '" + description.path + "'"; + } + + // create a new sandbox and execute + module = new Module(description.name, type, pkg); + module._origin = description.path; + + pkg.defineModule(description.name, module); + + // try to execute the module source code + content = "(function (module, exports, require, print) {" + + description.content + + "\n});"; + + fun = internal.execute(content, undefined, description.name); + + if (fun === undefined) { + pkg.clearModule(description.name); + throw "cannot create context function"; + } + + try { + fun(module, + module.exports, + function(path) { return module.require(path); }, + internal.print); + } + catch (err) { + pkg.clearModule(description.name); + throw "Javascript exception in file '" + description.name + "': " + err + " - " + err.stack; + } + + return module; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief loads a package +//////////////////////////////////////////////////////////////////////////////// + + Module.prototype.createPackage = function (parent, description) { + var path; + var module; + var pkg; + + path = description.name; + + pkg = new Package(path, + description.description, + parent, + [description.packagePath]); + + module = this.createModule(description, 'package', pkg); + + if (module !== null) { + parent.defineModule(path, module); + } + + return module; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief requires a package +//////////////////////////////////////////////////////////////////////////////// + + Module.prototype.requirePackage = function (unormalizedPath) { + var current; + var module; + var path; + + // first get rid of any ".." and "." + path = this.normalize(unormalizedPath); + + if (this._package.id === "/" && path === "/internal") { + return null; + } + + // try to locate the package file starting with the current package + current = this._package; + + while (current !== undefined) { + + // check if already know a package with that name + module = current.module(path); + + if (module !== null && module._type === 'package') { + return module; + } + + var description = internal.loadPackageDescription(path, current); + + if (description !== null) { + module = this.createPackage(current, description); + + if (module !== null) { + return module; + } + } + + current = current._parent; + } + + return null; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief requires a module +//////////////////////////////////////////////////////////////////////////////// + + Module.prototype.requireModule = function (unormalizedPath) { + var description; + var module; + var path; + + // first get rid of any ".." and "." + path = this.normalize(unormalizedPath); + + // check if already know a module with that name + module = this._package.module(path); + + if (module) { + if (module.type !== 'package') { + return module; + } + else { + return null; + } + } + + // first check: we are talking about module within a package + description = internal.loadPackageFile(path, this._package); + + if (description !== null) { + module = this.createModule(description, 'module', this._package); + + if (module !== null) { + this._package.defineModule(path, module); + return module; + } + } + + // second check: we are talking about a global module + description = internal.loadModuleFile(path); + + if (description !== null) { + module = this.createModule(description, 'module', GlobalPackage); + + if (module !== null) { + this._package.defineModule(path, module); + return module; + } + } + + return null; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief loads a file and creates a new module descriptor +//////////////////////////////////////////////////////////////////////////////// + + Module.prototype.require = function (unormalizedPath) { + var module; + var path; + + // check if path points to a package or a module in a package + module = this.requirePackage(unormalizedPath); + + if (module !== null) { + return module.exports; + } + + // try to load a global module into the current package + module = this.requireModule(unormalizedPath); + + if (module !== null) { + return module.exports; + } + + throw "cannot locate module '" + unormalizedPath + "'" + + " for package '" + this._package.id + "'" + + " using module path '" + internal.MODULES_PATH + "'" + + " and package path '" + this._package._paths + "'"; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns true if require found a file +//////////////////////////////////////////////////////////////////////////////// + + Module.prototype.exists = function (path) { + return ModuleExistsCache[path]; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief normalizes a path +//////////////////////////////////////////////////////////////////////////////// + + Module.prototype.normalize = function (path) { + return internal.normalizeModuleName(this.id, path); + }; + //////////////////////////////////////////////////////////////////////////////// /// @brief unloads module //////////////////////////////////////////////////////////////////////////////// @@ -370,23 +710,29 @@ function stop_color_print () { return; } - var norm = module.normalise(path); + var norm = module.normalize(path); - if ( norm === "/" - || norm === "/console" - || norm === "/fs" - || norm === "/internal" - || norm === "/org/arangodb" - || norm === "/org/arangodb/actions" - || norm === "/org/arangodb/arango-collection" - || norm === "/org/arangodb/arango-database" - || norm === "/org/arangodb/arango-error" - || norm === "/org/arangodb/arango-statement" - || norm === "/org/arangodb/shaped-json") { - return; + if (norm in ModuleCache) { + var m = ModuleCache[norm]; + + m._normalized = {}; + + if (m._type === 'system') { + return; + } + + if ( norm === "/org/arangodb" + || norm === "/org/arangodb/actions" + || norm === "/org/arangodb/arango-collection" + || norm === "/org/arangodb/arango-database" + || norm === "/org/arangodb/arango-error" + || norm === "/org/arangodb/arango-statement" + || norm === "/org/arangodb/shaped-json") { + return; + } + + delete ModuleCache[norm]; } - - delete ModuleCache[norm]; }; //////////////////////////////////////////////////////////////////////////////// @@ -401,7 +747,6 @@ function stop_color_print () { for (path in ModuleCache) { if (ModuleCache.hasOwnProperty(path)) { unload.push(path); - ModuleCache[path]._normalized = {}; } } @@ -415,8 +760,35 @@ function stop_color_print () { //////////////////////////////////////////////////////////////////////////////// Module.prototype._PRINT = function () { - var internal = require("internal"); - internal.output('[module "' + this.id + '"]'); + var parent = ""; + + if (this._package._parent !== undefined) { + parent = ', parent package "' + this._package._parent.id + '"'; + } + + internal.output('[module "' + this.id + '"' + + ', type "' + this._type + '"' + + ', package "' + this._package.id + '"' + + parent + + ', origin "' + this._origin + '"' + + ']'); + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints a package +//////////////////////////////////////////////////////////////////////////////// + + Package.prototype._PRINT = function () { + var parent = ""; + + if (this._parent !== undefined) { + parent = ', parent "' + this._package._parent.id + '"'; + } + + internal.output('[module "' + this.id + '"' + + ', path "' + this._path + '"' + + parent + + ']'); }; //////////////////////////////////////////////////////////////////////////////// diff --git a/js/common/tests/shell-database.js b/js/common/tests/shell-database.js old mode 100755 new mode 100644 diff --git a/lib/V8/v8-utils.cpp b/lib/V8/v8-utils.cpp index b89e9f9e69..11952d0bc8 100644 --- a/lib/V8/v8-utils.cpp +++ b/lib/V8/v8-utils.cpp @@ -199,6 +199,28 @@ static bool LoadJavaScriptDirectory (char const* path, return result; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief creates the path list +//////////////////////////////////////////////////////////////////////////////// + +v8::Handle pathList (string const& modules) { + v8::HandleScope scope; + +#ifdef _WIN32 + vector paths = StringUtils::split(modules, ";",'\0'); +#else + vector paths = StringUtils::split(modules, ";:"); +#endif + + v8::Handle modulesPaths = v8::Array::New(); + + for (uint32_t i = 0; i < (uint32_t) paths.size(); ++i) { + modulesPaths->Set(i, v8::String::New(paths[i].c_str())); + } + + return scope.Close(modulesPaths); +} + //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// @@ -1446,7 +1468,9 @@ v8::Handle TRI_CreateErrorObject (int errorNumber, string const& mes /// @brief stores the V8 utils functions inside the global variable //////////////////////////////////////////////////////////////////////////////// -void TRI_InitV8Utils (v8::Handle context, string const& path) { +void TRI_InitV8Utils (v8::Handle context, + string const& modules, + string const& nodes) { v8::HandleScope scope; v8::Handle ft; @@ -1494,25 +1518,14 @@ void TRI_InitV8Utils (v8::Handle context, string const& path) { // create the global variables // ............................................................................. - // ............................................................................. // The spilt has been modified -- only except semicolon, previously we excepted // a colon as well. So as not to break existing configurations, we only // make the modification for windows version -- since there isn't one yet! // ............................................................................. -#ifdef _WIN32 - vector paths = StringUtils::split(path, ";",'\0'); -#else - vector paths = StringUtils::split(path, ";:"); -#endif - v8::Handle modulesPaths = v8::Array::New(); - - for (uint32_t i = 0; i < (uint32_t) paths.size(); ++i) { - modulesPaths->Set(i, v8::String::New(paths[i].c_str())); - } - - context->Global()->Set(v8::String::New("MODULES_PATH"), modulesPaths); + context->Global()->Set(v8::String::New("MODULES_PATH"), pathList(modules)); + context->Global()->Set(v8::String::New("PACKAGE_PATH"), pathList(nodes)); } #ifdef TRI_HAVE_ICU diff --git a/lib/V8/v8-utils.h b/lib/V8/v8-utils.h index 64566df188..fa3abd5167 100644 --- a/lib/V8/v8-utils.h +++ b/lib/V8/v8-utils.h @@ -166,8 +166,9 @@ v8::Handle TRI_CreateErrorObject (int errorNumber, std::string const /// @brief stores the V8 utils function inside the global variable //////////////////////////////////////////////////////////////////////////////// -void TRI_InitV8Utils (v8::Handle, std::string const&); - +void TRI_InitV8Utils (v8::Handle, + std::string const& modules, + std::string const& nodes); //////////////////////////////////////////////////////////////////////////////// /// @brief Converts an object to a UTF-8-encoded and normalized character array. From c9226054fc7e8c52937109b430be35b128532cfe Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Tue, 26 Feb 2013 18:12:28 +0100 Subject: [PATCH 2/2] added tests, fixed unloadAll --- UnitTests/Makefile.unittests | 5 +- js/common/bootstrap/modules.js | 73 +- .../test-data/modules/commonjs/.gitignore | 7 + .../test-data/modules/commonjs/README.txt | 1 + .../test-data/modules/commonjs/bootstrap.py | 1268 +++++++++++++++++ .../modules/commonjs/docs/_hooks/extend_md.py | 12 + .../commonjs/docs/_hooks/transformers.py | 1 + .../commonjs/docs/_layout/default.html | 104 ++ .../commonjs/docs/contributors.html.markdown | 35 + .../modules/commonjs/docs/css/colorful.css | 61 + .../modules/commonjs/docs/css/default.css | 62 + .../modules/commonjs/docs/css/styles.css | 209 +++ .../commonjs/docs/history.html.markdown | 12 + .../commonjs/docs/images/banner_blue.jpg | Bin 0 -> 16604 bytes .../commonjs/docs/images/banner_gray.jpg | Bin 0 -> 13995 bytes .../commonjs/docs/images/banner_green.jpg | Bin 0 -> 13134 bytes .../commonjs/docs/images/banner_home.jpg | Bin 0 -> 21665 bytes .../commonjs/docs/images/banner_orange.jpg | Bin 0 -> 14994 bytes .../commonjs/docs/images/banner_red.jpg | Bin 0 -> 16865 bytes .../docs/images/content-wrapper_bg.png | Bin 0 -> 985 bytes .../commonjs/docs/images/content_bg.png | Bin 0 -> 775 bytes .../commonjs/docs/images/explosion.jpg | Bin 0 -> 27839 bytes .../commonjs/docs/images/header_gradient.jpg | Bin 0 -> 3178 bytes .../docs/images/header_wrapper_bg.png | Bin 0 -> 270 bytes .../modules/commonjs/docs/images/logo.png | Bin 0 -> 1543 bytes .../commonjs/docs/images/nav_browsers.png | Bin 0 -> 266 bytes .../commonjs/docs/images/nav_browsers_on.png | Bin 0 -> 399 bytes .../commonjs/docs/images/nav_commonjs.png | Bin 0 -> 264 bytes .../commonjs/docs/images/nav_commonjs_on.png | Bin 0 -> 352 bytes .../modules/commonjs/docs/images/nav_div.png | Bin 0 -> 172 bytes .../modules/commonjs/docs/images/nav_js.png | Bin 0 -> 321 bytes .../commonjs/docs/images/nav_js_on.png | Bin 0 -> 434 bytes .../commonjs/docs/images/news_bg-btm.png | Bin 0 -> 2203 bytes .../commonjs/docs/images/news_bg-top.png | Bin 0 -> 970 bytes .../docs/impl/flusspferd.html.markdown | 0 .../commonjs/docs/impl/gpsee.html.markdown | 0 .../commonjs/docs/impl/helma.html.markdown | 0 .../commonjs/docs/impl/index.html.markdown | 10 + .../commonjs/docs/impl/narwhal.html.markdown | 0 .../docs/impl/persevere.html.markdown | 0 .../commonjs/docs/impl/v8cgi.html.markdown | 0 .../modules/commonjs/docs/index.html.markdown | 45 + .../commonjs/docs/interp/jsc.html.markdown | 0 .../docs/interp/mozilla.html.markdown | 0 .../commonjs/docs/interp/rhino.html.markdown | 0 .../docs/interp/spidermonkey.html.markdown | 0 .../commonjs/docs/interp/v8.html.markdown | 0 .../commonjs/docs/license.html.markdown | 32 + .../commonjs/docs/process.html.markdown | 34 + .../commonjs/docs/specs/0.1.html.markdown | 13 + .../commonjs/docs/specs/0.5.html.markdown | 21 + .../docs/specs/modules/1.0.html.markdown | 74 + .../test-data/modules/commonjs/pavement.py | 34 + .../modules/commonjs/requirements.txt | 4 + .../commonjs/tests/modules/1.0/absolute/b.js | 1 + .../tests/modules/1.0/absolute/program.js | 5 + .../tests/modules/1.0/absolute/submodule/a.js | 3 + .../tests/modules/1.0/absolute/test.js | 15 + .../commonjs/tests/modules/1.0/cyclic/a.js | 4 + .../commonjs/tests/modules/1.0/cyclic/b.js | 4 + .../tests/modules/1.0/cyclic/program.js | 10 + .../commonjs/tests/modules/1.0/cyclic/test.js | 15 + .../tests/modules/1.0/determinism/program.js | 3 + .../modules/1.0/determinism/submodule/a.js | 9 + .../modules/1.0/determinism/submodule/b.js | 2 + .../tests/modules/1.0/determinism/test.js | 15 + .../tests/modules/1.0/exactExports/a.js | 3 + .../tests/modules/1.0/exactExports/program.js | 4 + .../tests/modules/1.0/exactExports/test.js | 15 + .../1.0/hasOwnProperty/hasOwnProperty.js | 0 .../modules/1.0/hasOwnProperty/program.js | 4 + .../tests/modules/1.0/hasOwnProperty/test.js | 15 + .../modules/1.0/hasOwnProperty/toString.js | 0 .../commonjs/tests/modules/1.0/method/a.js | 12 + .../tests/modules/1.0/method/program.js | 8 + .../commonjs/tests/modules/1.0/method/test.js | 15 + .../tests/modules/1.0/missing/program.js | 8 + .../tests/modules/1.0/missing/test.js | 15 + .../commonjs/tests/modules/1.0/monkeys/a.js | 1 + .../tests/modules/1.0/monkeys/program.js | 4 + .../tests/modules/1.0/monkeys/test.js | 15 + .../tests/modules/1.0/nested/a/b/c/d.js | 3 + .../tests/modules/1.0/nested/program.js | 3 + .../commonjs/tests/modules/1.0/nested/test.js | 15 + .../tests/modules/1.0/relative/program.js | 5 + .../tests/modules/1.0/relative/submodule/a.js | 1 + .../tests/modules/1.0/relative/submodule/b.js | 2 + .../tests/modules/1.0/relative/test.js | 15 + .../tests/modules/1.0/transitive/a.js | 1 + .../tests/modules/1.0/transitive/b.js | 1 + .../tests/modules/1.0/transitive/c.js | 3 + .../tests/modules/1.0/transitive/program.js | 3 + .../tests/modules/1.0/transitive/test.js | 15 + .../tests/unit-testing/1.0/program.js | 162 +++ .../modules/node_modules/TestA/index.js | 5 + .../TestA/node_modules/TestB/index.js | 1 + .../TestA/node_modules/TestB/package.json | 6 + .../TestA/node_modules/TestC/index.js | 2 + .../TestA/node_modules/TestC/package.json | 6 + .../modules/node_modules/TestA/package.json | 6 + .../test-data/modules/node_modules/TestA/x.js | 1 + .../modules/node_modules/TestB/index.js | 1 + .../modules/node_modules/TestB/package.json | 6 + .../modules/node_modules/TestD/index.js | 1 + .../modules/node_modules/TestD/package.json | 6 + js/common/tests/shell-require.js | 151 ++ 106 files changed, 2712 insertions(+), 31 deletions(-) create mode 100644 js/common/test-data/modules/commonjs/.gitignore create mode 100644 js/common/test-data/modules/commonjs/README.txt create mode 100644 js/common/test-data/modules/commonjs/bootstrap.py create mode 100644 js/common/test-data/modules/commonjs/docs/_hooks/extend_md.py create mode 100644 js/common/test-data/modules/commonjs/docs/_hooks/transformers.py create mode 100644 js/common/test-data/modules/commonjs/docs/_layout/default.html create mode 100644 js/common/test-data/modules/commonjs/docs/contributors.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/css/colorful.css create mode 100644 js/common/test-data/modules/commonjs/docs/css/default.css create mode 100644 js/common/test-data/modules/commonjs/docs/css/styles.css create mode 100644 js/common/test-data/modules/commonjs/docs/history.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/images/banner_blue.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/banner_gray.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/banner_green.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/banner_home.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/banner_orange.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/banner_red.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/content-wrapper_bg.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/content_bg.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/explosion.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/header_gradient.jpg create mode 100644 js/common/test-data/modules/commonjs/docs/images/header_wrapper_bg.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/logo.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/nav_browsers.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/nav_browsers_on.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/nav_commonjs.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/nav_commonjs_on.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/nav_div.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/nav_js.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/nav_js_on.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/news_bg-btm.png create mode 100644 js/common/test-data/modules/commonjs/docs/images/news_bg-top.png create mode 100644 js/common/test-data/modules/commonjs/docs/impl/flusspferd.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/impl/gpsee.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/impl/helma.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/impl/index.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/impl/narwhal.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/impl/persevere.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/impl/v8cgi.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/index.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/interp/jsc.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/interp/mozilla.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/interp/rhino.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/interp/spidermonkey.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/interp/v8.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/license.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/process.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/specs/0.1.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/specs/0.5.html.markdown create mode 100644 js/common/test-data/modules/commonjs/docs/specs/modules/1.0.html.markdown create mode 100644 js/common/test-data/modules/commonjs/pavement.py create mode 100644 js/common/test-data/modules/commonjs/requirements.txt create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/b.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/submodule/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/b.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/b.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/hasOwnProperty.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/toString.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/method/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/method/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/method/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/missing/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/missing/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/nested/a/b/c/d.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/nested/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/nested/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/relative/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/b.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/relative/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/a.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/b.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/c.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/program.js create mode 100644 js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/test.js create mode 100644 js/common/test-data/modules/commonjs/tests/unit-testing/1.0/program.js create mode 100644 js/common/test-data/modules/node_modules/TestA/index.js create mode 100644 js/common/test-data/modules/node_modules/TestA/node_modules/TestB/index.js create mode 100644 js/common/test-data/modules/node_modules/TestA/node_modules/TestB/package.json create mode 100644 js/common/test-data/modules/node_modules/TestA/node_modules/TestC/index.js create mode 100644 js/common/test-data/modules/node_modules/TestA/node_modules/TestC/package.json create mode 100644 js/common/test-data/modules/node_modules/TestA/package.json create mode 100644 js/common/test-data/modules/node_modules/TestA/x.js create mode 100644 js/common/test-data/modules/node_modules/TestB/index.js create mode 100644 js/common/test-data/modules/node_modules/TestB/package.json create mode 100644 js/common/test-data/modules/node_modules/TestD/index.js create mode 100644 js/common/test-data/modules/node_modules/TestD/package.json create mode 100644 js/common/tests/shell-require.js diff --git a/UnitTests/Makefile.unittests b/UnitTests/Makefile.unittests index 4f40c095ad..60b65784b2 100755 --- a/UnitTests/Makefile.unittests +++ b/UnitTests/Makefile.unittests @@ -80,6 +80,7 @@ SERVER_OPT := \ --javascript.action-directory @top_srcdir@/js/actions/system \ --javascript.gc-interval 1 \ --javascript.modules-path @top_srcdir@/js/server/modules:@top_srcdir@/js/common/modules \ + --javascript.package-path @top_srcdir@/js/common/test-data/modules \ --javascript.startup-directory @top_srcdir@/js \ --ruby.action-directory @top_srcdir@/mr/actions/system \ --ruby.modules-path @top_srcdir@/mr/server/modules:@top_srcdir@/mr/common/modules \ @@ -91,6 +92,7 @@ CLIENT_OPT := \ --configuration none \ --javascript.startup-directory @top_srcdir@/js \ --javascript.modules-path @top_srcdir@/js/client/modules:@top_srcdir@/js/common/modules \ + --javascript.package-path @top_srcdir@/js/common/test-data/modules \ --no-colors \ --quiet @@ -206,7 +208,8 @@ endif ### @brief SHELL SERVER TESTS (BASICS) ################################################################################ -SHELL_COMMON = @top_srcdir@/js/common/tests/shell-document.js \ +SHELL_COMMON = @top_srcdir@/js/common/tests/shell-require.js \ + @top_srcdir@/js/common/tests/shell-document.js \ @top_srcdir@/js/common/tests/shell-edge.js \ @top_srcdir@/js/common/tests/shell-database.js \ @top_srcdir@/js/common/tests/shell-collection.js \ diff --git a/js/common/bootstrap/modules.js b/js/common/bootstrap/modules.js index 8e4509a0b1..46f6a8855a 100644 --- a/js/common/bootstrap/modules.js +++ b/js/common/bootstrap/modules.js @@ -208,11 +208,15 @@ function stop_color_print () { var GlobalPackage = new Package("/", {name: "ArangoDB"}, undefined, PACKAGE_PATH); Package.prototype.defineSystemModule = function (path) { - this._moduleCache[path] = new Module(path, 'system', GlobalPackage); + var result = this._moduleCache[path] = new Module(path, 'system', GlobalPackage); + + return result; }; Package.prototype.defineModule = function (path, module) { this._moduleCache[path] = module; + + return module; }; Package.prototype.clearModule = function (path) { @@ -227,6 +231,19 @@ function stop_color_print () { return null; }; + Package.prototype.moduleNames = function () { + var name; + var names = []; + + for (name in this._moduleCache) { + if (this._moduleCache.hasOwnProperty(name)) { + names.push(name); + } + } + + return names; + }; + //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// @@ -273,6 +290,8 @@ function stop_color_print () { var internal = GlobalPackage.module("/internal").exports; var console = GlobalPackage.module("/console").exports; + internal.GlobalPackage = GlobalPackage; + //////////////////////////////////////////////////////////////////////////////// /// @brief normalizes a module name /// @@ -711,28 +730,27 @@ function stop_color_print () { } var norm = module.normalize(path); + var m = GlobalPackage.module(norm); - if (norm in ModuleCache) { - var m = ModuleCache[norm]; - - m._normalized = {}; - - if (m._type === 'system') { - return; - } - - if ( norm === "/org/arangodb" - || norm === "/org/arangodb/actions" - || norm === "/org/arangodb/arango-collection" - || norm === "/org/arangodb/arango-database" - || norm === "/org/arangodb/arango-error" - || norm === "/org/arangodb/arango-statement" - || norm === "/org/arangodb/shaped-json") { - return; - } - - delete ModuleCache[norm]; + if (m === null) { + return; } + + if (m._type === 'system') { + return; + } + + if ( norm === "/org/arangodb" + || norm === "/org/arangodb/actions" + || norm === "/org/arangodb/arango-collection" + || norm === "/org/arangodb/arango-database" + || norm === "/org/arangodb/arango-error" + || norm === "/org/arangodb/arango-statement" + || norm === "/org/arangodb/shaped-json") { + return; + } + + GlobalPackage.clearModule(norm); }; //////////////////////////////////////////////////////////////////////////////// @@ -741,17 +759,12 @@ function stop_color_print () { Module.prototype.unloadAll = function () { var i; - var path; - var unload = []; + var names; - for (path in ModuleCache) { - if (ModuleCache.hasOwnProperty(path)) { - unload.push(path); - } - } + names = GlobalPackage.moduleNames(); - for (i = 0; i < unload.length; ++i) { - this.unload(unload[i]); + for (i = 0; i < names.length; ++i) { + this.unload(names[i]); } }; diff --git a/js/common/test-data/modules/commonjs/.gitignore b/js/common/test-data/modules/commonjs/.gitignore new file mode 100644 index 0000000000..5dbf9b7977 --- /dev/null +++ b/js/common/test-data/modules/commonjs/.gitignore @@ -0,0 +1,7 @@ +lib +_site +include +bin +src +.Python + diff --git a/js/common/test-data/modules/commonjs/README.txt b/js/common/test-data/modules/commonjs/README.txt new file mode 100644 index 0000000000..dfa3fce78f --- /dev/null +++ b/js/common/test-data/modules/commonjs/README.txt @@ -0,0 +1 @@ +The Official Specs for CommonJS diff --git a/js/common/test-data/modules/commonjs/bootstrap.py b/js/common/test-data/modules/commonjs/bootstrap.py new file mode 100644 index 0000000000..49012e352f --- /dev/null +++ b/js/common/test-data/modules/commonjs/bootstrap.py @@ -0,0 +1,1268 @@ +#!/usr/bin/env python +## WARNING: This file is generated +#!/usr/bin/env python +"""Create a "virtual" Python installation +""" + +import sys +import os +import optparse +import shutil +import logging +import distutils.sysconfig +try: + import subprocess +except ImportError, e: + if sys.version_info <= (2, 3): + print 'ERROR: %s' % e + print 'ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.' + print 'If you copy subprocess.py from a newer version of Python this script will probably work' + sys.exit(101) + else: + raise +try: + set +except NameError: + from sets import Set as set + +join = os.path.join +py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) +is_jython = sys.platform.startswith('java') +expected_exe = is_jython and 'jython' or 'python' + +REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'ntpath', 'genericpath', + 'fnmatch', 'locale', 'encodings', 'codecs', + 'stat', 'UserDict', 'readline', 'copy_reg', 'types', + 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile', + 'lib-dynload', 'config', 'zlib'] + +if sys.version_info[:2] == (2, 6): + REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc']) +if sys.version_info[:2] <= (2, 3): + REQUIRED_MODULES.extend(['sets', '__future__']) + +class Logger(object): + + """ + Logging object for use in command-line script. Allows ranges of + levels, to avoid some redundancy of displayed information. + """ + + DEBUG = logging.DEBUG + INFO = logging.INFO + NOTIFY = (logging.INFO+logging.WARN)/2 + WARN = WARNING = logging.WARN + ERROR = logging.ERROR + FATAL = logging.FATAL + + LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] + + def __init__(self, consumers): + self.consumers = consumers + self.indent = 0 + self.in_progress = None + self.in_progress_hanging = False + + def debug(self, msg, *args, **kw): + self.log(self.DEBUG, msg, *args, **kw) + def info(self, msg, *args, **kw): + self.log(self.INFO, msg, *args, **kw) + def notify(self, msg, *args, **kw): + self.log(self.NOTIFY, msg, *args, **kw) + def warn(self, msg, *args, **kw): + self.log(self.WARN, msg, *args, **kw) + def error(self, msg, *args, **kw): + self.log(self.WARN, msg, *args, **kw) + def fatal(self, msg, *args, **kw): + self.log(self.FATAL, msg, *args, **kw) + def log(self, level, msg, *args, **kw): + if args: + if kw: + raise TypeError( + "You may give positional or keyword arguments, not both") + args = args or kw + rendered = None + for consumer_level, consumer in self.consumers: + if self.level_matches(level, consumer_level): + if (self.in_progress_hanging + and consumer in (sys.stdout, sys.stderr)): + self.in_progress_hanging = False + sys.stdout.write('\n') + sys.stdout.flush() + if rendered is None: + if args: + rendered = msg % args + else: + rendered = msg + rendered = ' '*self.indent + rendered + if hasattr(consumer, 'write'): + consumer.write(rendered+'\n') + else: + consumer(rendered) + + def start_progress(self, msg): + assert not self.in_progress, ( + "Tried to start_progress(%r) while in_progress %r" + % (msg, self.in_progress)) + if self.level_matches(self.NOTIFY, self._stdout_level()): + sys.stdout.write(msg) + sys.stdout.flush() + self.in_progress_hanging = True + else: + self.in_progress_hanging = False + self.in_progress = msg + + def end_progress(self, msg='done.'): + assert self.in_progress, ( + "Tried to end_progress without start_progress") + if self.stdout_level_matches(self.NOTIFY): + if not self.in_progress_hanging: + # Some message has been printed out since start_progress + sys.stdout.write('...' + self.in_progress + msg + '\n') + sys.stdout.flush() + else: + sys.stdout.write(msg + '\n') + sys.stdout.flush() + self.in_progress = None + self.in_progress_hanging = False + + def show_progress(self): + """If we are in a progress scope, and no log messages have been + shown, write out another '.'""" + if self.in_progress_hanging: + sys.stdout.write('.') + sys.stdout.flush() + + def stdout_level_matches(self, level): + """Returns true if a message at this level will go to stdout""" + return self.level_matches(level, self._stdout_level()) + + def _stdout_level(self): + """Returns the level that stdout runs at""" + for level, consumer in self.consumers: + if consumer is sys.stdout: + return level + return self.FATAL + + def level_matches(self, level, consumer_level): + """ + >>> l = Logger() + >>> l.level_matches(3, 4) + False + >>> l.level_matches(3, 2) + True + >>> l.level_matches(slice(None, 3), 3) + False + >>> l.level_matches(slice(None, 3), 2) + True + >>> l.level_matches(slice(1, 3), 1) + True + >>> l.level_matches(slice(2, 3), 1) + False + """ + if isinstance(level, slice): + start, stop = level.start, level.stop + if start is not None and start > consumer_level: + return False + if stop is not None or stop <= consumer_level: + return False + return True + else: + return level >= consumer_level + + #@classmethod + def level_for_integer(cls, level): + levels = cls.LEVELS + if level < 0: + return levels[0] + if level >= len(levels): + return levels[-1] + return levels[level] + + level_for_integer = classmethod(level_for_integer) + +def mkdir(path): + if not os.path.exists(path): + logger.info('Creating %s', path) + os.makedirs(path) + else: + logger.info('Directory %s already exists', path) + +def copyfile(src, dest, symlink=True): + if not os.path.exists(src): + # Some bad symlink in the src + logger.warn('Cannot find file %s (bad symlink)', src) + return + if os.path.exists(dest): + logger.debug('File %s already exists', dest) + return + if not os.path.exists(os.path.dirname(dest)): + logger.info('Creating parent directories for %s' % os.path.dirname(dest)) + os.makedirs(os.path.dirname(dest)) + if symlink and hasattr(os, 'symlink'): + logger.info('Symlinking %s', dest) + os.symlink(os.path.abspath(src), dest) + else: + logger.info('Copying to %s', dest) + if os.path.isdir(src): + shutil.copytree(src, dest, True) + else: + shutil.copy2(src, dest) + +def writefile(dest, content, overwrite=True): + if not os.path.exists(dest): + logger.info('Writing %s', dest) + f = open(dest, 'wb') + f.write(content) + f.close() + return + else: + f = open(dest, 'rb') + c = f.read() + f.close() + if c != content: + if not overwrite: + logger.notify('File %s exists with different content; not overwriting', dest) + return + logger.notify('Overwriting %s with new content', dest) + f = open(dest, 'wb') + f.write(content) + f.close() + else: + logger.info('Content %s already in place', dest) + +def rmtree(dir): + if os.path.exists(dir): + logger.notify('Deleting tree %s', dir) + shutil.rmtree(dir) + else: + logger.info('Do not need to delete %s; already gone', dir) + +def make_exe(fn): + if hasattr(os, 'chmod'): + oldmode = os.stat(fn).st_mode & 07777 + newmode = (oldmode | 0555) & 07777 + os.chmod(fn, newmode) + logger.info('Changed mode of %s to %s', fn, oct(newmode)) + +def install_setuptools(py_executable, unzip=False): + setup_fn = 'setuptools-0.6c9-py%s.egg' % sys.version[:3] + search_dirs = ['.', os.path.dirname(__file__), join(os.path.dirname(__file__), 'support-files')] + if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv': + # Probably some boot script; just in case virtualenv is installed... + try: + import virtualenv + except ImportError: + pass + else: + search_dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'support-files')) + for dir in search_dirs: + if os.path.exists(join(dir, setup_fn)): + setup_fn = join(dir, setup_fn) + break + if is_jython and os._name == 'nt': + # Jython's .bat sys.executable can't handle a command line + # argument with newlines + import tempfile + fd, ez_setup = tempfile.mkstemp('.py') + os.write(fd, EZ_SETUP_PY) + os.close(fd) + cmd = [py_executable, ez_setup] + else: + cmd = [py_executable, '-c', EZ_SETUP_PY] + if unzip: + cmd.append('--always-unzip') + env = {} + if logger.stdout_level_matches(logger.DEBUG): + cmd.append('-v') + if os.path.exists(setup_fn): + logger.info('Using existing Setuptools egg: %s', setup_fn) + cmd.append(setup_fn) + if os.environ.get('PYTHONPATH'): + env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH'] + else: + env['PYTHONPATH'] = setup_fn + else: + logger.info('No Setuptools egg found; downloading') + cmd.extend(['--always-copy', '-U', 'setuptools']) + logger.start_progress('Installing setuptools...') + logger.indent += 2 + cwd = None + if not os.access(os.getcwd(), os.W_OK): + cwd = '/tmp' + try: + call_subprocess(cmd, show_stdout=False, + filter_stdout=filter_ez_setup, + extra_env=env, + cwd=cwd) + finally: + logger.indent -= 2 + logger.end_progress() + if is_jython and os._name == 'nt': + os.remove(ez_setup) + +def filter_ez_setup(line): + if not line.strip(): + return Logger.DEBUG + for prefix in ['Reading ', 'Best match', 'Processing setuptools', + 'Copying setuptools', 'Adding setuptools', + 'Installing ', 'Installed ']: + if line.startswith(prefix): + return Logger.DEBUG + return Logger.INFO + +def main(): + parser = optparse.OptionParser( + version="1.3.4dev", + usage="%prog [OPTIONS] DEST_DIR") + + parser.add_option( + '-v', '--verbose', + action='count', + dest='verbose', + default=0, + help="Increase verbosity") + + parser.add_option( + '-q', '--quiet', + action='count', + dest='quiet', + default=0, + help='Decrease verbosity') + + parser.add_option( + '-p', '--python', + dest='python', + metavar='PYTHON_EXE', + help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 ' + 'interpreter to create the new environment. The default is the interpreter that ' + 'virtualenv was installed with (%s)' % sys.executable) + + parser.add_option( + '--clear', + dest='clear', + action='store_true', + help="Clear out the non-root install and start from scratch") + + parser.add_option( + '--no-site-packages', + dest='no_site_packages', + action='store_true', + help="Don't give access to the global site-packages dir to the " + "virtual environment") + + parser.add_option( + '--unzip-setuptools', + dest='unzip_setuptools', + action='store_true', + help="Unzip Setuptools when installing it") + + parser.add_option( + '--relocatable', + dest='relocatable', + action='store_true', + help='Make an EXISTING virtualenv environment relocatable. ' + 'This fixes up scripts and makes all .pth files relative') + + if 'extend_parser' in globals(): + extend_parser(parser) + + options, args = parser.parse_args() + + global logger + + if 'adjust_options' in globals(): + adjust_options(options, args) + + verbosity = options.verbose - options.quiet + logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)]) + + if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): + env = os.environ.copy() + interpreter = resolve_interpreter(options.python) + if interpreter == sys.executable: + logger.warn('Already using interpreter %s' % interpreter) + else: + logger.notify('Running virtualenv with interpreter %s' % interpreter) + env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true' + file = __file__ + if file.endswith('.pyc'): + file = file[:-1] + os.execvpe(interpreter, [interpreter, file] + sys.argv[1:], env) + + if not args: + print 'You must provide a DEST_DIR' + parser.print_help() + sys.exit(2) + if len(args) > 1: + print 'There must be only one argument: DEST_DIR (you gave %s)' % ( + ' '.join(args)) + parser.print_help() + sys.exit(2) + + home_dir = args[0] + + if os.environ.get('WORKING_ENV'): + logger.fatal('ERROR: you cannot run virtualenv while in a workingenv') + logger.fatal('Please deactivate your workingenv, then re-run this script') + sys.exit(3) + + if os.environ.get('PYTHONHOME'): + if sys.platform == 'win32': + name = '%PYTHONHOME%' + else: + name = '$PYTHONHOME' + logger.warn('%s is set; this can cause problems creating environments' % name) + + if options.relocatable: + make_environment_relocatable(home_dir) + return + + create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear, + unzip_setuptools=options.unzip_setuptools) + if 'after_install' in globals(): + after_install(options, home_dir) + +def call_subprocess(cmd, show_stdout=True, + filter_stdout=None, cwd=None, + raise_on_returncode=True, extra_env=None): + cmd_parts = [] + for part in cmd: + if len(part) > 40: + part = part[:30]+"..."+part[-5:] + if ' ' in part or '\n' in part or '"' in part or "'" in part: + part = '"%s"' % part.replace('"', '\\"') + cmd_parts.append(part) + cmd_desc = ' '.join(cmd_parts) + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE + logger.debug("Running command %s" % cmd_desc) + if extra_env: + env = os.environ.copy() + env.update(extra_env) + else: + env = None + try: + proc = subprocess.Popen( + cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, + cwd=cwd, env=env) + except Exception, e: + logger.fatal( + "Error %s while executing command %s" % (e, cmd_desc)) + raise + all_output = [] + if stdout is not None: + stdout = proc.stdout + while 1: + line = stdout.readline() + if not line: + break + line = line.rstrip() + all_output.append(line) + if filter_stdout: + level = filter_stdout(line) + if isinstance(level, tuple): + level, line = level + logger.log(level, line) + if not logger.stdout_level_matches(level): + logger.show_progress() + else: + logger.info(line) + else: + proc.communicate() + proc.wait() + if proc.returncode: + if raise_on_returncode: + if all_output: + logger.notify('Complete output from command %s:' % cmd_desc) + logger.notify('\n'.join(all_output) + '\n----------------------------------------') + raise OSError( + "Command %s failed with error code %s" + % (cmd_desc, proc.returncode)) + else: + logger.warn( + "Command %s had error code %s" + % (cmd_desc, proc.returncode)) + + +def create_environment(home_dir, site_packages=True, clear=False, + unzip_setuptools=False): + """ + Creates a new environment in ``home_dir``. + + If ``site_packages`` is true (the default) then the global + ``site-packages/`` directory will be on the path. + + If ``clear`` is true (default False) then the environment will + first be cleared. + """ + home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) + + py_executable = install_python( + home_dir, lib_dir, inc_dir, bin_dir, + site_packages=site_packages, clear=clear) + + install_distutils(lib_dir, home_dir) + + install_setuptools(py_executable, unzip=unzip_setuptools) + + install_activate(home_dir, bin_dir) + +def path_locations(home_dir): + """Return the path locations for the environment (where libraries are, + where scripts go, etc)""" + # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its + # prefix arg is broken: http://bugs.python.org/issue3386 + if sys.platform == 'win32': + # Windows has lots of problems with executables with spaces in + # the name; this function will remove them (using the ~1 + # format): + mkdir(home_dir) + if ' ' in home_dir: + try: + import win32api + except ImportError: + print 'Error: the path "%s" has a space in it' % home_dir + print 'To handle these kinds of paths, the win32api module must be installed:' + print ' http://sourceforge.net/projects/pywin32/' + sys.exit(3) + home_dir = win32api.GetShortPathName(home_dir) + lib_dir = join(home_dir, 'Lib') + inc_dir = join(home_dir, 'Include') + bin_dir = join(home_dir, 'Scripts') + elif is_jython: + lib_dir = join(home_dir, 'Lib') + inc_dir = join(home_dir, 'Include') + bin_dir = join(home_dir, 'bin') + else: + lib_dir = join(home_dir, 'lib', py_version) + inc_dir = join(home_dir, 'include', py_version) + bin_dir = join(home_dir, 'bin') + return home_dir, lib_dir, inc_dir, bin_dir + +def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear): + """Install just the base environment, no distutils patches etc""" + if sys.executable.startswith(bin_dir): + print 'Please use the *system* python to run this script' + return + + if clear: + rmtree(lib_dir) + ## FIXME: why not delete it? + ## Maybe it should delete everything with #!/path/to/venv/python in it + logger.notify('Not deleting %s', bin_dir) + + if hasattr(sys, 'real_prefix'): + logger.notify('Using real prefix %r' % sys.real_prefix) + prefix = sys.real_prefix + else: + prefix = sys.prefix + mkdir(lib_dir) + fix_lib64(lib_dir) + stdlib_dirs = [os.path.dirname(os.__file__)] + if sys.platform == 'win32': + stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs')) + elif sys.platform == 'darwin': + stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages')) + for stdlib_dir in stdlib_dirs: + if not os.path.isdir(stdlib_dir): + continue + if hasattr(os, 'symlink'): + logger.info('Symlinking Python bootstrap modules') + else: + logger.info('Copying Python bootstrap modules') + logger.indent += 2 + try: + for fn in os.listdir(stdlib_dir): + if fn != 'site-packages' and os.path.splitext(fn)[0] in REQUIRED_MODULES: + copyfile(join(stdlib_dir, fn), join(lib_dir, fn)) + finally: + logger.indent -= 2 + mkdir(join(lib_dir, 'site-packages')) + writefile(join(lib_dir, 'site.py'), SITE_PY) + writefile(join(lib_dir, 'orig-prefix.txt'), prefix) + site_packages_filename = join(lib_dir, 'no-global-site-packages.txt') + if not site_packages: + writefile(site_packages_filename, '') + else: + if os.path.exists(site_packages_filename): + logger.info('Deleting %s' % site_packages_filename) + os.unlink(site_packages_filename) + + stdinc_dir = join(prefix, 'include', py_version) + if os.path.exists(stdinc_dir): + copyfile(stdinc_dir, inc_dir) + else: + logger.debug('No include dir %s' % stdinc_dir) + + if sys.exec_prefix != prefix: + if sys.platform == 'win32': + exec_dir = join(sys.exec_prefix, 'lib') + elif is_jython: + exec_dir = join(sys.exec_prefix, 'Lib') + else: + exec_dir = join(sys.exec_prefix, 'lib', py_version) + for fn in os.listdir(exec_dir): + copyfile(join(exec_dir, fn), join(lib_dir, fn)) + + if is_jython: + # Jython has either jython-dev.jar and javalib/ dir, or just + # jython.jar + for name in 'jython-dev.jar', 'javalib', 'jython.jar': + src = join(prefix, name) + if os.path.exists(src): + copyfile(src, join(home_dir, name)) + # XXX: registry should always exist after Jython 2.5rc1 + src = join(prefix, 'registry') + if os.path.exists(src): + copyfile(src, join(home_dir, 'registry'), symlink=False) + copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'), + symlink=False) + + mkdir(bin_dir) + py_executable = join(bin_dir, os.path.basename(sys.executable)) + if 'Python.framework' in prefix: + if py_executable.endswith('/Python'): + # The name of the python executable is not quite what + # we want, rename it. + py_executable = os.path.join( + os.path.dirname(py_executable), 'python') + + logger.notify('New %s executable in %s', expected_exe, py_executable) + if sys.executable != py_executable: + ## FIXME: could I just hard link? + executable = sys.executable + if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'): + # Cygwin misreports sys.executable sometimes + executable += '.exe' + py_executable += '.exe' + logger.info('Executable actually exists in %s' % executable) + shutil.copyfile(executable, py_executable) + make_exe(py_executable) + if sys.platform == 'win32' or sys.platform == 'cygwin': + pythonw = os.path.join(os.path.dirname(sys.executable, 'pythonw.exe')) + if os.path.exists(pythonw): + logger.info('Also created pythonw.exe') + shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable, 'pythonw.exe'))) + + if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe: + secondary_exe = os.path.join(os.path.dirname(py_executable), + expected_exe) + py_executable_ext = os.path.splitext(py_executable)[1] + if py_executable_ext == '.exe': + # python2.4 gives an extension of '.4' :P + secondary_exe += py_executable_ext + if os.path.exists(secondary_exe): + logger.warn('Not overwriting existing %s script %s (you must use %s)' + % (expected_exe, secondary_exe, py_executable)) + else: + logger.notify('Also creating executable in %s' % secondary_exe) + shutil.copyfile(sys.executable, secondary_exe) + make_exe(secondary_exe) + + if 'Python.framework' in prefix: + logger.debug('MacOSX Python framework detected') + + # Copy the framework's dylib into the virtual + # environment + virtual_lib = os.path.join(home_dir, '.Python') + + if os.path.exists(virtual_lib): + os.unlink(virtual_lib) + copyfile( + os.path.join(prefix, 'Python'), + virtual_lib) + + # And then change the install_name of the copied python executable + try: + call_subprocess( + ["install_name_tool", "-change", + os.path.join(prefix, 'Python'), + '@executable_path/../.Python', + py_executable]) + except: + logger.fatal( + "Could not call install_name_tool -- you must have Apple's development tools installed") + raise + + # Some tools depend on pythonX.Y being present + pth = py_executable + '%s.%s' % ( + sys.version_info[0], sys.version_info[1]) + if os.path.exists(pth): + os.unlink(pth) + os.symlink('python', pth) + + if sys.platform == 'win32' and ' ' in py_executable: + # There's a bug with subprocess on Windows when using a first + # argument that has a space in it. Instead we have to quote + # the value: + py_executable = '"%s"' % py_executable + cmd = [py_executable, '-c', 'import sys; print sys.prefix'] + logger.info('Testing executable with %s %s "%s"' % tuple(cmd)) + proc = subprocess.Popen(cmd, + stdout=subprocess.PIPE) + proc_stdout, proc_stderr = proc.communicate() + proc_stdout = os.path.normcase(os.path.abspath(proc_stdout.strip())) + if proc_stdout != os.path.normcase(os.path.abspath(home_dir)): + logger.fatal( + 'ERROR: The executable %s is not functioning' % py_executable) + logger.fatal( + 'ERROR: It thinks sys.prefix is %r (should be %r)' + % (proc_stdout, os.path.normcase(os.path.abspath(home_dir)))) + logger.fatal( + 'ERROR: virtualenv is not compatible with this system or executable') + sys.exit(100) + else: + logger.info('Got sys.prefix result: %r' % proc_stdout) + + pydistutils = os.path.expanduser('~/.pydistutils.cfg') + if os.path.exists(pydistutils): + logger.notify('Please make sure you remove any previous custom paths from ' + 'your %s file.' % pydistutils) + ## FIXME: really this should be calculated earlier + return py_executable + +def install_activate(home_dir, bin_dir): + if sys.platform == 'win32' or is_jython and os._name == 'nt': + files = {'activate.bat': ACTIVATE_BAT, + 'deactivate.bat': DEACTIVATE_BAT} + if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin': + files['activate'] = ACTIVATE_SH + else: + files = {'activate': ACTIVATE_SH} + files['activate_this.py'] = ACTIVATE_THIS + for name, content in files.items(): + content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir)) + content = content.replace('__VIRTUAL_NAME__', os.path.basename(os.path.abspath(home_dir))) + content = content.replace('__BIN_NAME__', os.path.basename(bin_dir)) + writefile(os.path.join(bin_dir, name), content) + +def install_distutils(lib_dir, home_dir): + distutils_path = os.path.join(lib_dir, 'distutils') + mkdir(distutils_path) + ## FIXME: maybe this prefix setting should only be put in place if + ## there's a local distutils.cfg with a prefix setting? + home_dir = os.path.abspath(home_dir) + ## FIXME: this is breaking things, removing for now: + #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir + writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT) + writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False) + +def fix_lib64(lib_dir): + """ + Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y + instead of lib/pythonX.Y. If this is such a platform we'll just create a + symlink so lib64 points to lib + """ + if [p for p in distutils.sysconfig.get_config_vars().values() + if isinstance(p, basestring) and 'lib64' in p]: + logger.debug('This system uses lib64; symlinking lib64 to lib') + assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], ( + "Unexpected python lib dir: %r" % lib_dir) + lib_parent = os.path.dirname(lib_dir) + assert os.path.basename(lib_parent) == 'lib', ( + "Unexpected parent dir: %r" % lib_parent) + copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64')) + +def resolve_interpreter(exe): + """ + If the executable given isn't an absolute path, search $PATH for the interpreter + """ + if os.path.abspath(exe) != exe: + paths = os.environ.get('PATH', '').split(os.pathsep) + for path in paths: + if os.path.exists(os.path.join(path, exe)): + exe = os.path.join(path, exe) + break + if not os.path.exists(exe): + logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe)) + sys.exit(3) + return exe + +############################################################ +## Relocating the environment: + +def make_environment_relocatable(home_dir): + """ + Makes the already-existing environment use relative paths, and takes out + the #!-based environment selection in scripts. + """ + activate_this = os.path.join(home_dir, 'bin', 'activate_this.py') + if not os.path.exists(activate_this): + logger.fatal( + 'The environment doesn\'t have a file %s -- please re-run virtualenv ' + 'on this environment to update it' % activate_this) + fixup_scripts(home_dir) + fixup_pth_and_egg_link(home_dir) + ## FIXME: need to fix up distutils.cfg + +OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3], + 'activate', 'activate.bat', 'activate_this.py'] + +def fixup_scripts(home_dir): + # This is what we expect at the top of scripts: + shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir)) + # This is what we'll put: + new_shebang = '#!/usr/bin/env python%s' % sys.version[:3] + activate = "import os; activate_this=os.path.join(os.path.dirname(__file__), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this" + bin_dir = os.path.join(home_dir, 'bin') + for filename in os.listdir(bin_dir): + filename = os.path.join(bin_dir, filename) + f = open(filename, 'rb') + lines = f.readlines() + f.close() + if not lines: + logger.warn('Script %s is an empty file' % filename) + continue + if lines[0].strip() != shebang: + if os.path.basename(filename) in OK_ABS_SCRIPTS: + logger.debug('Cannot make script %s relative' % filename) + elif lines[0].strip() == new_shebang: + logger.info('Script %s has already been made relative' % filename) + else: + logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)' + % (filename, shebang)) + continue + logger.notify('Making script %s relative' % filename) + lines = [new_shebang+'\n', activate+'\n'] + lines[1:] + f = open(filename, 'wb') + f.writelines(lines) + f.close() + +def fixup_pth_and_egg_link(home_dir): + """Makes .pth and .egg-link files use relative paths""" + home_dir = os.path.normcase(os.path.abspath(home_dir)) + for path in sys.path: + if not path: + path = '.' + if not os.path.isdir(path): + continue + path = os.path.normcase(os.path.abspath(path)) + if not path.startswith(home_dir): + logger.debug('Skipping system (non-environment) directory %s' % path) + continue + for filename in os.listdir(path): + filename = os.path.join(path, filename) + if filename.endswith('.pth'): + if not os.access(filename, os.W_OK): + logger.warn('Cannot write .pth file %s, skipping' % filename) + else: + fixup_pth_file(filename) + if filename.endswith('.egg-link'): + if not os.access(filename, os.W_OK): + logger.warn('Cannot write .egg-link file %s, skipping' % filename) + else: + fixup_egg_link(filename) + +def fixup_pth_file(filename): + lines = [] + prev_lines = [] + f = open(filename) + prev_lines = f.readlines() + f.close() + for line in prev_lines: + line = line.strip() + if (not line or line.startswith('#') or line.startswith('import ') + or os.path.abspath(line) != line): + lines.append(line) + else: + new_value = make_relative_path(filename, line) + if line != new_value: + logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename)) + lines.append(new_value) + if lines == prev_lines: + logger.info('No changes to .pth file %s' % filename) + return + logger.notify('Making paths in .pth file %s relative' % filename) + f = open(filename, 'w') + f.write('\n'.join(lines) + '\n') + f.close() + +def fixup_egg_link(filename): + f = open(filename) + link = f.read().strip() + f.close() + if os.path.abspath(link) != link: + logger.debug('Link in %s already relative' % filename) + return + new_link = make_relative_path(filename, link) + logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link)) + f = open(filename, 'w') + f.write(new_link) + f.close() + +def make_relative_path(source, dest, dest_is_directory=True): + """ + Make a filename relative, where the filename is dest, and it is + being referred to from the filename source. + + >>> make_relative_path('/usr/share/something/a-file.pth', + ... '/usr/share/another-place/src/Directory') + '../another-place/src/Directory' + >>> make_relative_path('/usr/share/something/a-file.pth', + ... '/home/user/src/Directory') + '../../../home/user/src/Directory' + >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/') + './' + """ + source = os.path.dirname(source) + if not dest_is_directory: + dest_filename = os.path.basename(dest) + dest = os.path.dirname(dest) + dest = os.path.normpath(os.path.abspath(dest)) + source = os.path.normpath(os.path.abspath(source)) + dest_parts = dest.strip(os.path.sep).split(os.path.sep) + source_parts = source.strip(os.path.sep).split(os.path.sep) + while dest_parts and source_parts and dest_parts[0] == source_parts[0]: + dest_parts.pop(0) + source_parts.pop(0) + full_parts = ['..']*len(source_parts) + dest_parts + if not dest_is_directory: + full_parts.append(dest_filename) + if not full_parts: + # Special case for the current directory (otherwise it'd be '') + return './' + return os.path.sep.join(full_parts) + + + +############################################################ +## Bootstrap script creation: + +def create_bootstrap_script(extra_text, python_version=''): + """ + Creates a bootstrap script, which is like this script but with + extend_parser, adjust_options, and after_install hooks. + + This returns a string that (written to disk of course) can be used + as a bootstrap script with your own customizations. The script + will be the standard virtualenv.py script, with your extra text + added (your extra text should be Python code). + + If you include these functions, they will be called: + + ``extend_parser(optparse_parser)``: + You can add or remove options from the parser here. + + ``adjust_options(options, args)``: + You can change options here, or change the args (if you accept + different kinds of arguments, be sure you modify ``args`` so it is + only ``[DEST_DIR]``). + + ``after_install(options, home_dir)``: + + After everything is installed, this function is called. This + is probably the function you are most likely to use. An + example would be:: + + def after_install(options, home_dir): + subprocess.call([join(home_dir, 'bin', 'easy_install'), + 'MyPackage']) + subprocess.call([join(home_dir, 'bin', 'my-package-script'), + 'setup', home_dir]) + + This example immediately installs a package, and runs a setup + script from that package. + + If you provide something like ``python_version='2.4'`` then the + script will start with ``#!/usr/bin/env python2.4`` instead of + ``#!/usr/bin/env python``. You can use this when the script must + be run with a particular Python version. + """ + filename = __file__ + if filename.endswith('.pyc'): + filename = filename[:-1] + f = open(filename, 'rb') + content = f.read() + f.close() + py_exe = 'python%s' % python_version + content = (('#!/usr/bin/env %s\n' % py_exe) + + '## WARNING: This file is generated\n' + + content) + return content.replace('##EXT' 'END##', extra_text) + +def adjust_options(options, args): + args[:] = ['.'] + +def after_install(options, home_dir): + if sys.platform == 'win32': + bin_dir = join(home_dir, 'Scripts') + else: + bin_dir = join(home_dir, 'bin') + subprocess.call([join(bin_dir, 'easy_install'), 'paver==1.0.1']) + subprocess.call([join(bin_dir, 'easy_install'), 'pip']) + subprocess.call([join(bin_dir, 'paver'),'initial']) + +##file site.py +SITE_PY = """ +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 ++D/cC/Pm +""".decode("base64").decode("zlib") + +##file ez_setup.py +EZ_SETUP_PY = """ +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 +woheJi7S138BSGV4QQ== +""".decode("base64").decode("zlib") + +##file activate.sh +ACTIVATE_SH = """ +eJytU99P2zAQfvdfcaQ8ABqN+srUh6IhUYmViXSdNECum1waS6ld2U6zgva/75ykNP0xpGnkIYl9 +n8/fffddB8aZtJDKHGFRWAczhMJiAqV0GQRWFyZGmEkVitjJlXAYwEVq9AJmwmYXrANrXUAslNIO +TKFAOkikwdjla8YS3JyCs3N4ZUCPTOERLhUEp/z+7gufDB/G3wd3/NtgfBvAM3wGl6GqkP7x2/1j +0DcE/lpq4yrg216hLDo4OFTFU8mqb6eu3Ga6yBNI0BHnqigQKoEXm32CMpNxBplYIQj6UCjWi4UP +u0y4Sq8mFakWizwn3ZyGOd1NMtBfqo1fLAUJ2xy1XYAfpK0uXBN2Us2bNDtALwScet4QZ0LN0UJJ +TRKJf63BC07XGrRLYo7JnrjXg4j0vNT16md0yyc3D9HwfnRE5Kq0S7Mjz9/aFPWOdSnqHTSJgAc9 +inrvtqgJbyjUkE30ZjTZEjshXkSkD4HSKkHrTOGNhnvcOhBhnsIGcLJ3+9aem3t/M3J0HZTGYE6t +Vw5Wwkgxy9G2Db17MWMtnv2A89aS84A1CrSLYQf+JA1rbzeLFjrk/Ho44qPB1xvOrxpY2/psX0qf +zPeg0iuYkrNRiQXC007ep2BayUgc96XzvpIiJ2Nb9FaFAe0o8t5cxs2MayNJlAaOCJlzy6swLMuy ++4KOnLrqkptDq1NXCoOh8BlC9maZxxatKaU8SvBpOn2GuhbMLW5Pn71T1Hl9gFra8h77oJn/gHn/ +z1n/9znfzDgp8gduuMqz +""".decode("base64").decode("zlib") + +##file activate.bat +ACTIVATE_BAT = """ +eJx9kMsOgjAQRfdN+g+zoAn8goZEDESJPBpEViSzkFbZ0IX8f+RRaVW0u5mee3PanbjeFSgpKXmI +Hqq4KC9BglFW+YjWhEgJJa2ETvXQCNl2ogFe5CkvwaUEhjPm543vcOdAiacjLxzzJFw6f2bZCsZ0 +2YitXPtswawi1zwgC9II0QPD/RELyuOb1jB/Sg0rNhM31Ss4n2I+7ibLb8epQGco2Rja1Fs/zeoa +cR9nWnprJaMspOQJdBR1/g== +""".decode("base64").decode("zlib") + +##file deactivate.bat +DEACTIVATE_BAT = """ +eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q +FlWqXJpcICVYpGzx2OAY4oFsPpCLbjpQCLvZILVcXFaufi5cACHzOrI= +""".decode("base64").decode("zlib") + +##file distutils-init.py +DISTUTILS_INIT = """ +eJytVl2r4zYQfdevGBKKbcia0r5dCPvQD7jQlkILLZRF6NpyrK4jGUm+SfrrO2M5tmQnbR9qSJCl +o9HMmZljqXNvrAfjmAojd5uHF2G10icH94lvjG7U6WdhnbSwT1+VA208CHhX1g+ik/odzqYeOnkA +Z+AioRIaBidBefAGGqVr8K0E5+tOvTFWK6vFWcIRnSl74dtymqEl5wevOsdpPkL8aZTOV/A8dqvk +vFGd5Lw4QDabyQqmmtmINvZMgzw9poDjxpV8s2e2X7wwwOfOWUmDfJyiZ/crRhoxMx8Fvag+i5ME +4eELB6LvJTpOBL0hUzowRLR0phJeGQ3Chcmb8/K8GPq4K5jsnAxu8DEEzkulkQWff3mAVXQjTF5l +BaaXC4kjoykUmeNcaeXRXH/LiqK0UtR5we5lQfCofKqRf8bYfo/R+aqFt0F1NZdXD4tpqI10OvPw +WZsLtPjDmE/Sj8FhQSBAWVl5Y2+ToRYw+guWjbk4+EBl1ApbV6aWgRGCIIPWDFNljYfLmnwqeysb +dSWfm/DeCd9gEinJGRr9+qssMNdYE7FaVuZ8FroulxCmQJcJTIjB4Twxmqk64dwCyhPEVCv01LKh +VhCd+kty01OGHeROdk0Eoof8xtkSqbHC3jiy46jpfjJapkh6ttAj/PEpgbF/xEeFk5QGcYfp73gg +9AC7HzBXu6JIzCXRluv4QnhbZx5T/5Dw+YUHjQkG1rNR1o7L4liYyzE0mkrFvTBGrpM28VDGY3sT +ewQrv8U/q94GCqPcoNiUzHQ2TmYz1uYRHh4S0RKamy/NspK8TYNGrDWnLBjZRxonrwhw+dru5NZ+ +9i1K+wY7J2wPv7ViFPFKdF1oNWk/DPQZCAEBBcSmskUfgrBjp/XGqWu21CvtGaOfpH+HCpPEsgs6 +NQvbw00P96xRmzK+V3ACLCKvR7hytJSnoMUX1BBUIhRi1OoOnchHGre9S5hS6tpdFH41spXHWbFt +4ZAPK8/mXea0vWDpEn0rdJ0/cN9KP1gdYOw/FC6ysy3mtEtmXV+1Cio272++NRo/ERUamoFlujQ2 +x7y42peTHHPXy0o1qjpi9YXkHEndJm6QxDC5Vb1pfjw8VqeYjK2z6aH3Iwv2zEm8S9Sm4nzq38eL +7Fn8MTWrvRsmUYifMUlXpadM4uKWSedRRPFDSatPmY1BQKL7P1K98Sr16V+IR8Rz4qPFx8SvmFzt +pRr//vX3H797gV9aM3Q1vE43ltTYtPmdbmYfqS/C80o3ELxx4N0Mb9BE4tA0B7z1uvH10iq0dL/m +OIkiEa512LF1yf4GZEHtwg== +""".decode("base64").decode("zlib") + +##file distutils.cfg +DISTUTILS_CFG = """ +eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH +xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg +9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q= +""".decode("base64").decode("zlib") + +##file activate_this.py +ACTIVATE_THIS = """ +eJx1UsGOnDAMvecrIlYriDRlKvU20h5aaY+teuilGo1QALO4CwlKAjP8fe1QGGalRoLEefbzs+Mk +Sb7NcvRo3iTcoGqwgyy06As+HWSNVciKaBTFywYoJWc7yit2ndBVwEkHkIzKCV0YdQdmkvShs6YH +E3IhfjFaaSNLoHxQy2sLJrL0ow98JQmEG/rAYn7OobVGogngBgf0P0hjgwgt7HOUaI5DdBVJkggR +3HwSktaqWcCtgiHIH7qHV+esW2CnkRJ+9R5cQGsikkWEV/J7leVGs9TV4TvcO5QOOrTHYI+xeCjY +JR/m9GPDHv2oSZunUokS2A/WBelnvx6tF6LUJO2FjjlH5zU6Q+Kz/9m69LxvSZVSwiOlGnT1rt/A +77j+WDQZ8x9k2mFJetOle88+lc8sJJ/AeerI+fTlQigTfVqJUiXoKaaC3AqmI+KOnivjMLbvBVFU +1JDruuadNGcPmkgiBTnQXUGUDd6IK9JEQ9yPdM96xZP8bieeMRqTuqbxIbbey2DjVUNzRs1rosFS +TsLAdS/0fBGNdTGKhuqD7mUmsFlgGjN2eSj1tM3GnjfXwwCmzjhMbR4rLZXXk+Z/6Hp7Pn2+kJ49 +jfgLHgI4Jg== +""".decode("base64").decode("zlib") + +if __name__ == '__main__': + main() + +## TODO: +## Copy python.exe.manifest +## Monkeypatch distutils.sysconfig diff --git a/js/common/test-data/modules/commonjs/docs/_hooks/extend_md.py b/js/common/test-data/modules/commonjs/docs/_hooks/extend_md.py new file mode 100644 index 0000000000..0b083dbaa1 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/_hooks/extend_md.py @@ -0,0 +1,12 @@ +import markdown + +MARKDOWN_EXTENSIONS = ["def_list", "fenced_code", "codehilite", "tables"] + +def extended_markdown(text): + if isinstance(text, str): + text = text.decode("utf8") + return markdown.markdown(text, extensions=MARKDOWN_EXTENSIONS, + output_format="html") + +Config.transformers['markdown'] = extended_markdown + diff --git a/js/common/test-data/modules/commonjs/docs/_hooks/transformers.py b/js/common/test-data/modules/commonjs/docs/_hooks/transformers.py new file mode 100644 index 0000000000..b816a467f0 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/_hooks/transformers.py @@ -0,0 +1 @@ +Config.transformers['noop'] = lambda source: source diff --git a/js/common/test-data/modules/commonjs/docs/_layout/default.html b/js/common/test-data/modules/commonjs/docs/_layout/default.html new file mode 100644 index 0000000000..d11ea6a64c --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/_layout/default.html @@ -0,0 +1,104 @@ + + + + +CommonJS: JavaScript Standard Library + + + + + + +
+
+ + +
javascript: not just for browsers any more!
+
+
+
+
+
+
+ {{content}} +
+
+
+

Site Updates

+
+
+
    +
  • // Work is ongoing in fleshing out the content and bringing in new CommonJS 0.5 specs.
  • +
  • // Formatting has been cleaned up around the site and on the Modules 1.0 page. +
  • +
+
+
+

CommonJS Links

+ +
+
+
 
+
+
+
+ + + diff --git a/js/common/test-data/modules/commonjs/docs/contributors.html.markdown b/js/common/test-data/modules/commonjs/docs/contributors.html.markdown new file mode 100644 index 0000000000..b9d3a62dff --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/contributors.html.markdown @@ -0,0 +1,35 @@ +--- +layout: default +title: CommonJS Contributors +--- + +The CommonJS Contributors +========================= + +Creating the CommonJS APIs has been a volunteer effort, and the people below have contributed their time and energy to creating a consensus around these APIs. Without working through the details and making compromises, we would never have standardized anything or seen any implementations come into existence. + +The following people have contributed substantially to the work of creating the CommonJS APIs: + +* Ihab Awad +* Ash Berlin +* Aristid Breitkreuz +* Kevin Dangoor +* Daniel Friesen +* Wes Garland +* Kris Kowal +* Dean Landolt +* Peter Michaux +* George Moschovitis +* Michael O'Brien +* Tom Robinson +* Hannes Wallnoefer +* Mike Wilson +* Ondrej Zara +* Chris Zumbrunn +* Kris Zyp + +My apologies to any contributor whose name was omitted. With thousands of messages of discussion during 2009, there are many people who have come and pitched in to the project with their ideas. + +Additionally, thanks are due to all of the people who have been involved in building the implementations of the CommonJS APIs. Many of the people on the list above are implementers, but there are many other people involved in their projects and many other projects that are not represented here. + +Thanks to you all for making this project a success! diff --git a/js/common/test-data/modules/commonjs/docs/css/colorful.css b/js/common/test-data/modules/commonjs/docs/css/colorful.css new file mode 100644 index 0000000000..72750df39d --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/css/colorful.css @@ -0,0 +1,61 @@ +.codehilite .hll { background-color: #ffffcc } +.codehilite .c { color: #808080 } /* Comment */ +.codehilite .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +.codehilite .k { color: #008000; font-weight: bold } /* Keyword */ +.codehilite .o { color: #303030 } /* Operator */ +.codehilite .cm { color: #808080 } /* Comment.Multiline */ +.codehilite .cp { color: #507090 } /* Comment.Preproc */ +.codehilite .c1 { color: #808080 } /* Comment.Single */ +.codehilite .cs { color: #cc0000; font-weight: bold } /* Comment.Special */ +.codehilite .gd { color: #A00000 } /* Generic.Deleted */ +.codehilite .ge { font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #FF0000 } /* Generic.Error */ +.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #00A000 } /* Generic.Inserted */ +.codehilite .go { color: #808080 } /* Generic.Output */ +.codehilite .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.codehilite .gs { font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.codehilite .gt { color: #0040D0 } /* Generic.Traceback */ +.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.codehilite .kp { color: #003080; font-weight: bold } /* Keyword.Pseudo */ +.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.codehilite .kt { color: #303090; font-weight: bold } /* Keyword.Type */ +.codehilite .m { color: #6000E0; font-weight: bold } /* Literal.Number */ +.codehilite .s { background-color: #fff0f0 } /* Literal.String */ +.codehilite .na { color: #0000C0 } /* Name.Attribute */ +.codehilite .nb { color: #007020 } /* Name.Builtin */ +.codehilite .nc { color: #B00060; font-weight: bold } /* Name.Class */ +.codehilite .no { color: #003060; font-weight: bold } /* Name.Constant */ +.codehilite .nd { color: #505050; font-weight: bold } /* Name.Decorator */ +.codehilite .ni { color: #800000; font-weight: bold } /* Name.Entity */ +.codehilite .ne { color: #F00000; font-weight: bold } /* Name.Exception */ +.codehilite .nf { color: #0060B0; font-weight: bold } /* Name.Function */ +.codehilite .nl { color: #907000; font-weight: bold } /* Name.Label */ +.codehilite .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.codehilite .nt { color: #007000 } /* Name.Tag */ +.codehilite .nv { color: #906030 } /* Name.Variable */ +.codehilite .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.codehilite .w { color: #bbbbbb } /* Text.Whitespace */ +.codehilite .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */ +.codehilite .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */ +.codehilite .mi { color: #0000D0; font-weight: bold } /* Literal.Number.Integer */ +.codehilite .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */ +.codehilite .sb { background-color: #fff0f0 } /* Literal.String.Backtick */ +.codehilite .sc { color: #0040D0 } /* Literal.String.Char */ +.codehilite .sd { color: #D04020 } /* Literal.String.Doc */ +.codehilite .s2 { background-color: #fff0f0 } /* Literal.String.Double */ +.codehilite .se { color: #606060; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */ +.codehilite .sh { background-color: #fff0f0 } /* Literal.String.Heredoc */ +.codehilite .si { background-color: #e0e0e0 } /* Literal.String.Interpol */ +.codehilite .sx { color: #D02000; background-color: #fff0f0 } /* Literal.String.Other */ +.codehilite .sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */ +.codehilite .s1 { background-color: #fff0f0 } /* Literal.String.Single */ +.codehilite .ss { color: #A06000 } /* Literal.String.Symbol */ +.codehilite .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.codehilite .vc { color: #306090 } /* Name.Variable.Class */ +.codehilite .vg { color: #d07000; font-weight: bold } /* Name.Variable.Global */ +.codehilite .vi { color: #3030B0 } /* Name.Variable.Instance */ +.codehilite .il { color: #0000D0; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/js/common/test-data/modules/commonjs/docs/css/default.css b/js/common/test-data/modules/commonjs/docs/css/default.css new file mode 100644 index 0000000000..ef95359ffa --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/css/default.css @@ -0,0 +1,62 @@ +.codehilite .hll { background-color: #ffffcc } +.codehilite { background: #f8f8f8; } +.codehilite .c { color: #408080; font-style: italic } /* Comment */ +.codehilite .err { border: 1px solid #FF0000 } /* Error */ +.codehilite .k { color: #008000; font-weight: bold } /* Keyword */ +.codehilite .o { color: #666666 } /* Operator */ +.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */ +.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #A00000 } /* Generic.Deleted */ +.codehilite .ge { font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #FF0000 } /* Generic.Error */ +.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #00A000 } /* Generic.Inserted */ +.codehilite .go { color: #808080 } /* Generic.Output */ +.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.codehilite .gs { font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.codehilite .gt { color: #0040D0 } /* Generic.Traceback */ +.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.codehilite .kp { color: #008000 } /* Keyword.Pseudo */ +.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.codehilite .kt { color: #B00040 } /* Keyword.Type */ +.codehilite .m { color: #666666 } /* Literal.Number */ +.codehilite .s { color: #BA2121 } /* Literal.String */ +.codehilite .na { color: #7D9029 } /* Name.Attribute */ +.codehilite .nb { color: #008000 } /* Name.Builtin */ +.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.codehilite .no { color: #880000 } /* Name.Constant */ +.codehilite .nd { color: #AA22FF } /* Name.Decorator */ +.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.codehilite .nf { color: #0000FF } /* Name.Function */ +.codehilite .nl { color: #A0A000 } /* Name.Label */ +.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.codehilite .nv { color: #19177C } /* Name.Variable */ +.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.codehilite .w { color: #bbbbbb } /* Text.Whitespace */ +.codehilite .mf { color: #666666 } /* Literal.Number.Float */ +.codehilite .mh { color: #666666 } /* Literal.Number.Hex */ +.codehilite .mi { color: #666666 } /* Literal.Number.Integer */ +.codehilite .mo { color: #666666 } /* Literal.Number.Oct */ +.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ +.codehilite .sc { color: #BA2121 } /* Literal.String.Char */ +.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ +.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.codehilite .sx { color: #008000 } /* Literal.String.Other */ +.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */ +.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ +.codehilite .ss { color: #19177C } /* Literal.String.Symbol */ +.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.codehilite .vc { color: #19177C } /* Name.Variable.Class */ +.codehilite .vg { color: #19177C } /* Name.Variable.Global */ +.codehilite .vi { color: #19177C } /* Name.Variable.Instance */ +.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/js/common/test-data/modules/commonjs/docs/css/styles.css b/js/common/test-data/modules/commonjs/docs/css/styles.css new file mode 100644 index 0000000000..5941e66eb0 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/css/styles.css @@ -0,0 +1,209 @@ +@charset "UTF-8"; + +body { + background-color: #3c3c3c; + font-family: Helvetica, Arial, sans-serif; + margin: 0px; + padding: 0px; + font-size: 14px; + line-height: 18px; +} +.col_level { + font-size: 0px; + clear: both; + height: 1px; +} + + +/* PAGE HEADER */ + +.header_wrapper { + height: 107px; + background-image: url(../images/header_wrapper_bg.png); + background-repeat: repeat-x; +} +.header_bg { + width: 970px; + margin-right: auto; + margin-left: auto; + height: 107px; + background-image: url(../images/header_gradient.jpg); + background-repeat: no-repeat; + background-position: center; +} +.tagline { + float: left; + margin-left: 15px; + line-height: 107px; + font-size: 18px; + color: #9f9f9f; +} +img.logo { + float: left; + margin-top: 24px; + margin-left: 0px; +} +.nav_wrapper { + float: right; + height: 107px; +} +.nav_item { + float: right; + width: 125px; + color: #FFFFFF; + text-align: center; + padding-top: 60px; + height: 47px; + font-size: 22px; + font-weight: normal; +} +.nav_item a:link, .nav_item a:visited { + color: #FFFFFF; + text-decoration: none; +} +.nav_item a:hover { + color: #CCCCCC; +} +.nav1 { + background-image: url(../images/nav_js.png); + background-repeat: repeat-x; + background-position: bottom; +} +.nav2 { + background-image: url(../images/nav_commonjs.png); + background-repeat: repeat-x; + background-position: bottom; +} +.nav3 { + background-image: url(../images/nav_browsers.png); + background-repeat: repeat-x; + background-position: bottom; +} +.nav_div { + float: right; + background-image: url(../images/nav_div.png); + width: 1px; + background-position: bottom; + height: 107px; + background-repeat: no-repeat; +} + + + + +/* PAGE BODY */ + +.content_wrapper { + background-image: url(../images/content-wrapper_bg.png); + background-repeat: repeat-x; + background-color: #efefef; +} + +.content_bg { + width: 1000px; + margin-right: auto; + margin-left: auto; + background-image: url(../images/content_bg.png); + background-repeat: repeat-y; +} + +.content { + position: relative; + background-image: url(../images/banner_gray.jpg); + background-repeat: no-repeat; + background-position: center 11px; +} +.content-left { + width: 680px; + margin-left: 60px; + float: left; + margin-top: 60px; + padding-bottom: 20px; +} +.content-left h1 { + font-size: 28px; + color: #863e3e; + font-weight: normal; + margin-top: 0px; + margin-right: 0px; + margin-bottom: 6px; + margin-left: 0px; +} + + + + +/* NEWS */ + +.news_wrapper { + width: 219px; + right: 14px; + float: right; + margin-right: 27px; + margin-top: 70px; + font-size: 12px; + line-height: 13px; +} +.news-top { + background-image: url(../images/news_bg-top.png); + background-repeat: no-repeat; + height: 25px; + background-position: left top; + padding-left: 24px; + vertical-align: bottom; + padding-top: 20px; +} +.news_items { + background-image: url(../images/news_bg-btm.png); + background-repeat: no-repeat; + background-position: left bottom; + padding-left: 24px; + color: #9d9d9d; + padding-right: 12px; +} +.news_items ul { + list-style: none; + margin-left: 0; + padding-left: 1em; + text-indent: -.9em; + margin-top: 0px; +} +.news_items li { + margin-bottom: 8px; + margin-left: 8px; +} +.news_items a:link, .news_items a:visited { + color: #90d5ff; + text-decoration: none; +} +.news_items a:hover { + text-decoration: underline; +} +.news_wrapper h1 { + font-weight: normal; + font-size: 16px; + margin-bottom: 8px; + color: #636363; + margin-top: 0px; +} + + + + +/* PAGE FOOT */ + +.footer_wrapper { + font-size: 10px; + border-top-width: 10px; + border-top-style: solid; + border-top-color: #636363; + text-align: center; + padding-top: 10px; + padding-bottom: 10px; + color: #999999; +} +.footer_bg { + width: 970px; + margin-right: auto; + margin-left: auto; +} diff --git a/js/common/test-data/modules/commonjs/docs/history.html.markdown b/js/common/test-data/modules/commonjs/docs/history.html.markdown new file mode 100644 index 0000000000..dc4401ee16 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/history.html.markdown @@ -0,0 +1,12 @@ +--- +layout: default +title: CommonJS Project History +--- + +CommonJS Project History +======================== + +* January 2009: the group was formed as "ServerJS" following a blog post on Kevin Dangoor's Blue Sky on Mars +* March 2009: the dust had settled around "securable modules" as the module style for the group. This is CommonJS API 0.1 +* April 2009: CommonJS modules were shown off with several implementations at the first JSConf in Washington, DC. +* August 2009: The group name was formally changed to CommonJS to reflect the broader applicability of the APIs. diff --git a/js/common/test-data/modules/commonjs/docs/images/banner_blue.jpg b/js/common/test-data/modules/commonjs/docs/images/banner_blue.jpg new file mode 100644 index 0000000000000000000000000000000000000000..476bd2ea05426ab6e9928f051f71d1490163cb81 GIT binary patch literal 16604 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 literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/banner_gray.jpg b/js/common/test-data/modules/commonjs/docs/images/banner_gray.jpg new file mode 100644 index 0000000000000000000000000000000000000000..70c7c20739f19410556088ff4ecb87133e18458a GIT binary patch literal 13995 zcmd6Oc|4Tu_x~`fZHzUI83q$dDrM~3ooytUBqSwKjV)x!l5Iwo$}SaQY?&5oc1j^s z)Yx}f3fV%Ivi_!?=jmBK&v*I#^LzbnFYf)i&ih>Fyszt=``GT;9tNR~=o#pNSXeDB^U@p$3D~)uzW}m(!Mwt<-46-@!5|O_6as@nVQetw zF9!k!LvV1ivvaVsbD}tZZYWM9H;Nm{$;Zdf&&P)m78b^c{@PgJa5xtymkxb&zdhJ~0pdY`;=v_g79J2Q4-1%wWxJj!7z+r@@?&F4`rF3B3Wh*oaKz86e_m$Z z{BZ{bVgW-~z+hG;9taG~!hD|<%)`qE5tFll0>}B?#Ding4;H>WEMao~3T)&MUSPhJ z5~qD)A)^+~!|Vn8M>jwBJS+g~b{~k7*$yiYm&4m3#2i>5 z3i;vDT>2#C+Mp%ku6dYAUznfBL#R`11NGqw>qF2>+sP46P1m^?(*`3gen?jY1YxYD zvWDN`^;|J%#6;6|%K&=RE*{V_BFD&~PcW8=62Ce~d}+cmENV(Me_`V)Na0=nWr-jTn7d@T?gQXHeN6aMto%VK`lj|r4K+naflet49v8xu8CY)+|O+0f@0g6w8gM4n>);QID42iCqbyoPp^n1?wN8&%_)r(9s_- zJo9BT*6eC@0(-HQx^%42T?`i@edRA>_{&KC3)z@p{zd3CJBllwiG#uvUu9V>IJf>)MB~#_pW5xc_I1!Db#isoJs5@t@Gp0{&3@&sFg*6gIvAAms&&aIiPd86QXcX?M=_fYFb z2gP<_QT>6w>A{-H+xhdGCLFJ``JK4!#Wr{>-IvC;*k9`3QH^UD+>-IxG~v7@Krlgk z`wSk-LN})4Z@J%)_I&P~WOm1}7aL6C%op61 zF$VGxK%*$Vc8awcCeH;f5~W;@C=Kl>Y|%z-Dv{Z~i&|T|A#XGBI`GollfIM~ zOCjGdwNiyettmeUC9c8F(_Tx7yut=O{b&N!RUGFF+GE0nr1q>R9CvOU@F2?fGNN{( zh0V>P1U?^rBAjx~SUF%k_I0kK^?b1h8(cQZ)=-Gt=3imLS%BwRXoLT*eWtJ+Wk&BD z@2eaz-3CD@@7uXT71y3udtvYh`73u!`x-dz+fT+gZCZSwAN5p9nNm()lYzzAAG5oN zawA!ew566158jUH@>)}(yx~6HiF?&7DcPVuD;d^(8%GO@ieRevS9fXAy|~y%yle-M z*KrSnanVsR8Y)^pM}hkvhk&MN5g>6A7oYzEKM6WepO!q4kYds3^2EH5>PKEbE_Q{kyQg zUF9WI;rSL`5GCMtl)u38mr?8Lujz63b{FHid1Vi`x1C+|-ZeG}Ag9^$e)o?!%UXGH&qJy=qyZlVjqD`ri^&@6sf`mce_9dcX;EmWPyv24m zJ4$bhZ0?CU+UmgNirba1rk-UQyOnQ8WjAuZQ#q8_(G~$~SvaVHDGYSw9)KU;XyX`Z zzx+^+Po(iMhE09apBL#>=~dM5?B(;9xaL{|d`EmoLNK-H2NPBMni!aL&8w8pw=PSC zP;-n=6T6ffSJ~u!G|4%xChQiT51uQQ%;gWDxe`{EhzG9e8F1vLyKUxT0@z@)^Xt$k zAF{%g6*$M|rSS;p$j!!5J%iPPr*XCWAkpWgW875^e!f}fVEBk-;vrEn8fbUEyMncg znn(-0{2EGQ*tr{En%!>K6o3$OM)eSiLPmF{p>8|aoOk*aJcnO24rsw&__7bjzQ&@( z%RbDcT`!`L>JJ*`vgxM0zQSFuxE^RqQ9$qVc6BZ$J8J~v`Y#F-Y=Q@x_N;QxQyF+n zxhftFq~jNDBTGDGjr&s*K{x4!s0_0YR`02L$c)@R5#Ur@9{pVs#Us~$~ z5h9j|dk4?@G7ayAIxnJ5yA?;}R)bIun788MpXiffu(?NEV@{7*4c*V;31T_Si#TwD zgycmqO@j&Ww=U7mpLf{`&1<|1@gx!!3K|sp&T5~2FBRO1>ppLG$#2*7q5?Fy^+OU+ zwVb{UDyf(+c^R^Fl@#Nn^mC}-jej)sFDm>iC`jaae_oDj=a_OHh}McR|A$(b124!E zD|~Nq6cdmO3EaeE?>@hI*s_bIJp zpPBz$F+T1DXBQ-7nNLly7}wI3k4Et-GrDk7o4HasMVvEQg{<|$y6I}Snsz!#tR5ZK zhL3H7;*g===yqM#3T6uDZk?RL6$C&#wh%HJ4fi8&Auw_`VAgv6WT?*?t=495aK5{9 zbSxH%-aU!(&>tnH_qavTctN?erSiD0(&wG|cEX3xEvy?y48P{+U(YQW&3MKwu>jQe zV)>&zkb9AIcvl-G)6)FFTN^p5zJa!uaRu<%XcXu5_+p!VYK>#0xBap_ZIk5QQpmT| z%hA6LIstx&iOiP8)*_uFF7$X`%i@K?`G;}u>N!w*0q>Hm#A)HvfO|9z+>wAiFy+ud z$VusL-0e9dz|S?-o`6|!cUGzaddV(vN{6u!dV2LhlUH{ihaK%>NN^qX0GR2 zJ7^WH_noe}zJ2i7k*KzXP|=*NvYb^FY?QFwoQ39>ZEE4#h+`_Z7EuRuW$+Cv(fyWY zG=5C7@6$RtzS20Qv%Z1mt+4p>PUu2b3}}CX;$UM=S1?R<|9jO>;&+mQyQqxcRP$q` zIZ$%6*d65~u)9g>(xi(k6kps;)ZX9j{Jw*noJ5^QV0{25@r0aKNFRfeu#|%kZ}ZMz zt9wNvQgcZsbJKxKER&S%5-n8xWY8p?Oo3dZb+(X)7b(SL{%n$I3FLR6f9$Aq=c*B` z$;%@hYMvV;n|)6T(Zt%i&&PH63*ni=CH2WKct|Xo8JwTm?Vejq7h7~cAA;)$ENVzP z?*?11%6%vqcJ;%3{0ZQ9G38dY8hfGj;Q&2n)kr$yL8eX z>HaewK`Uf6|1&y5hXO3l-?7|d@MJACLYJ6NPoJWu%I+SAHec$|bRW>R(8%*dqdW~q zq{7Zr={BcX($pE{m8qLrKuwHGbkFTLptNVqR{Io3&o-zu^}alXni{yfN+x)}^XWP~ zC)pJnxknR%xuT1^y2^sQI=JddSpEbzj|yve)^^A>(dxr&lZ;;KFm96SXsx%KX8YV$ zlHZ+tN@y&9V4u_?Fn*J22q>iH<|AZ&T5y~CsVrz~!$e6!prsycX-1r&lWSM3W5= zhYDe9mAp=8$77nt1meuiy1IiId?zMZk=^!X4X=>{?q`R;R7%MguB4qdP~+dR*w1<6 z>LK0M(%sj;T(d5}0TT*QN$F? zK|(PX_eT+wTe-t$hxhy^xFSkHHhUp*xtP>v20+NydXJIL5L8z@K2Nh#Y;2JQ#;5*O zX~#B*$VJA2nD~CU-Y?4(D_#O@4efOVWOx1MD0tno;o`qN0U4X2w1n`~a)gJO(H_6Z z5xv3AU_f|o#ScP5AZd1jPC#{(eFsi3$Z^sirA?NZq1=ra58p><6j%oIb?q}a^gdJ- zvH4kiIY!b`Kz@Q6?xFnA@88_qv+koprgN0IMa|mB9o*ds==S=Vfbl95?WqsXHQ&;K zvWR$Necz*PaD}#=GAy#1Ef8<|bK_LUF!9yr&w}KE$=Ua?#<-q^DvZt=;%s2{O7tkn zXG^m-{?oD4w@PHf5D48~)?p~Vc_K(+_9Gt|cY@#mww4|r! z^QGnM86@qyeYkYYagdGy;3h<7vP)(!^ska*l_-eDURdiJi`sq`smw~A@3`0LEd+bq zI#q{vcmiF1NA!vVrF>oB(5BkGp-iyfB(II zv%pVz1dcDTjcukYB$=Z0$Js<{(fL zYC=>)($z_-)OY>YW3XGT%rueQQDa$fTf!$e!Xx7l$}i*?VeiA@*j}jI3h=q^X?ni! z8O$XyOlaFS=<)?`g|wvu{v@}V=Gm};aYAYhnSfv3^=_Yg4KJ0`KjtS1f<^6i+%!9t zW_NVI=N_#k@I#H4@W*3n$FD{u`^0QK?3os)++k_Umldrl0P-@cpYT1s6yQTB8T(kj zXn7Vccu++1IxCXrRbM~c%tD{*K`AhQ+CD`d)xyGAG8Wn4dd9OgWSpzp>vbccJl+oh&|Z7EIT=mQ<-> z+*JG3t9ZtBUHVJKK(zJYBiyo8SITtP%&5Xcq9-gV>MX1sbmgi*?^N9jlTjZtrG)_J6XcNxzd7RRo_7dLd%{Ay; zTKpcU;V=Y8r2ACm%gmm%z!NuVBz2uBO%k;>o*Co3cNS_)56 z6g%KW}d{|0ynHa z>h{_$uC)N$yqPb1Q6T=?8q8$YiqEE=H}DkW61rh)CGY zd6jj`D@W}PIvp?{YqWQDdA4WYnklZX@ztoMlvmx`ix|h9LRK%gE)lXiR@D4S&hSK) zt3ns9&AH{$@&FrwC6cD zd;9$Qg~{Rqx94)vs%<&*7}`vHZ5^^|qS<<{{QmB1mqkXjlHnwGa^?rcoy45i|dq>GE*H3hekDm+3i?P|@O;C2izuWwTN{V5)D|v$*nHx?ZczUjkMyw^54Py5Bxa}3~0zgqs${VTcQj6Mt zC-Wkf98)|s{e0W=5lSoge7TLRw;0&607ui|@j4h~DbzV`ao*|Xfa`;MNSA)~Cr7i@Y6$-4DReAI zl|rVB;#l}67_?+j;hT2$_97vqExOz*bCNG@Zczkp|2pJt+{K`aWPUC@D@cQ`G&}TY9&yj=kD27=+R?Xf6}SSPqlRUM!oj6Fdftv?I{)7!~7f_frbfwz98^nN=xLO z6AW5Oq`;*q>VZDi_9lQ-tAe{l7GnInWPj-C&$|byIgK+l#?HxH=VHnppE>K;oq+W_ zYk1jt^|IE4*2IZfcz=5(Ti+tj>~yTg(*WXURgJ!F5FN?RZT#w+HCoO3eLu8$N=qID zHrByh(cT*9RnXpB>7rTkeuw_qjZS!4&8WiCzyM7}aU1mZUg#6o8IpTA_aly8GVDGs zvvQ#o%E6{a`wxj#`h|h@>xVf63)mIYHvDDQXp}SF-s@KCfM#<778!QQCNiNgm%I)7 z1nOSMHl7R?c`!cq7Q86P9(2aK376s`_<2{^`C0EqnE9buQ4>QgAWP-BrnPrtsm|I& zR;&u`>N*Kq-r}FRaEfoa?@NJ-WJmO}lJYj_9+0)~L*GE6^-dm2?&HyL2Fb50Xp1QA zd98SiGp-Ng6ME{js5;Ov0bawkpRS*(E1tF9Bbv9$J$nSR7yEu2l(2L9P~&HpXUT3) zukf@kRE{k3i{&f;5^tTSXYUat0~_t1xYo>GP`~A@utikP9_aDvU&+)IF;E%VMNKUp zucnRvZctd1_u#$jEo7%_W(Ejb<*`+zAS&Ja5ON9SqFzw9fAC(GV0+;twMgn|md1+pA;qo+69v)DkjV52Zco8wQ4VtAM z=L6Zwe6iJX4ulAQ_BKkPA06gFc$R=F>Q}(u;#iR_+&qtW#71E!-!8APpuf0N9Y&_y zo_#n*C#c4Gw@gHMS?>lDl%A z-_2CR`#$?5vl4iIcNLZ5jblS&7rd&p3xdw>VVTI*#A6m6D-|oEvRmZkaW^(~4wAJ9|*ywn2*f2Ktrp;qf9>+SG8@_0uM@T%dK@*W^#D!W2HIJrB^k)woJE!2&rVcr9K)w|LjN>-CJFwBj~L?I2ha_7l$OW>yI|X( zm6iu@F;{B8HAiug{R|D(&gh6#U4y6uTom$>O|~?*ctI?W8)9Rc;6dcoZBSW~uJSm#(a{^p)TzesU!XNu;)f%qrR<=1mgQ zU-mV6{j6djO!3n4A%JMx#8bgO73k=fBWgaT(BcEtY9vGN+pY|WV(0x_z-8)PD zVJc%A3K*VQzh1`O!OtfcRX4!tHQ)eV9mn;%6 z!}AW^f+du+k-e7?hX#A%UCzB*Aw+x1+(NO5JTsO)nDADHn(de6$`7rN2R^@HAJb|G z62~*xnX0K;mW&)#Y#3K-i*zSSK2wrbbcskE?!{vEX|_xBb#p%sblo@%c`kZIJ@bhL zRz|m>ZMVy}h$T@|?5U;k`3ANDz45BYd0#3zT?*8Kq^YuB#IF(vBXOE@FJB}*(=XY* z!EiS!e5!U_SLSVIh>1d)7D;~TSXUj+F{x3Fp}d?O2qJm3q-Q@aZ}AyewfM3Y7OdAE zg;q&>#H~H?+2PHZ#{{vhyJL>QIcvnolDP@hNovz~Zl@w*!@(lnfEBr=4Gw2!yd*Pz zdt_1lo%b-WF~|eVj2M2mo2O?M)eb7$sa|pf@LMeKqp6|+N=47%Ft-zp0;|}=$O<(l zU-zdLQ`m|jwAHAU@cT^g?)HHMVMRydhVS;LxZX3|4R=L67%@@KHddpJL|Kb+j5o5~ zj=EJCdXBAp8)S}ATn6eT(&>Qx(W2_-=9T)Xd2aZv3x62yKc+91f{J@}fFh0C%aYe)!A@g-v z>}%0%QIW%2(zGrc(nU?>gQ*btZSKR|r%Ik)yByO)#jH#6rbemi{&zi>B%>7KpBAnV z7nPg>>ZYhS(a89UL&XhQkxsE?TPN;ojJuz(XJ*5huIOlgR)uCONo{3e2r?(5vCiO^ zS;e06fUU6B*gRlP7*LYmw6EoyRa*sw-f(cazw&;>f%RI#9%e5rP1QF=eG5|a0Dd_9 zQwbOPL*RiVMQfBUUfcDxyA>KRRLl(N9d`eN80slwRwVQ8431J16agT?3kYf8A#IAn zj3xkaz8T89ZrUS`&>(o>6s6`Bl*2$8ci1?Cqs+>eRv6WHf(AU#j~VEY8f&uTHe0se z;6|w4+nN}%H4+O~+6IyA;ooSBrP+5bUNYMKc(4;@!SMa+O&?j1P4vIg%W*l%OQpIh z^KAP@jL)Ae_4~R{jyBcMx4r`Ga}3NnF+`V%gw4PEcK4Llib&*D94_xv@MEIQ>N!r$ zWG(4~avdGZe=OS2)Am*8y=uD&d4ZsEMxZ=8T0pVoTa^1LSu#gN@fHr(I;3fAeF@h7 zu^g>d0D`+3;I{zSyaue1NH9Wy3zTJXNsO?kZAH`?odIo({zQo3hc z``&089vLL>swpp&l2Rukp%$uQ@^pEoBX;M+#&$FhfX)XeJorzw5#%<1&7s8SlCH8via-G+qg>u!_q1s&=SZ4h_!Kh zNYMBM`MJV}40|$bEVe-cND zL!w4KKXy&EpiVFoyA66Jle(pjply-Sr;V=VccoO|dOb0%9ZIQ~4zv&XIX@3s*Xm-C zftcvCPUb37K~1lNXFNu}0g;;rf5d(Ml-Go7V04nyG=n>Io}mjD4+)ePxttSW7nyV> zW+mJRi#cayxaIlM3a)272#0XLgq~?)PQRnOAmPd&S}aH) zKZC;pG}Z}mrCiU7qx_t;DD%2JsdBqZRj-fV9<5#i<^s#h#1avNVONh!bGsg7P=iqJ zQ{VEj3c+_Pk3QK3-Q9Wk^w0-8%xMw1)~E8ueACQ@pyCZLS0=gtJp!3*`V4ylcF3K}HreJAbv2sxA zZP%*{2-$pOh$`}?bH!=Kk#64BZv;q$cvp{8-+LQQc`kCy4#j610d(Q2Th~U<7^X|D z`sdm|oL*IoqpCk^oO!Oy0mh#bh<#=tLKi<#Q#^8rnsSL%tB=L_D@X;Ws_jMkZoKL& z;1?3ODR+MhEh#hIvCDSbNbf@^++He(4=wp&NZho%SSKUmPMO9Sc@tI;QnoIpP7cju zi)Z-u-l4u0?QHr4<8wK~Sx}%plR&YS$@A1Nk!EFAeeF_yVmG;1G58offUeBJ_Hp^= z9NQ+V{0XNooN_`-YqZ7`)pAt@5E`lPe_tUFw3m#HcGC~4RijZBmhE%e5y0bX7ptyi z5(W%u-gI@g#||o2fddZHy4ic%bQ8Vt#T29B&rQISz@Kj2y2JYBc;bmiNWE8>H7T0^%8Ct@SjOy?2OBFD&=cwkj~pTNH77ELV; z`{9NgsE-emm$N)xWw(XK?kI3umfn?oq3;XT=7CxHpz!0v-J&Gwy~uQ6Qvd1LqizH6 zJ&E1Tm#D{HLCW657pkUqBXY7|hDJFnLHKt%&FHv=XWd&VSGsqm5i7liYdB| z22P$kOx@eUGT0*4zUn`vulBsgAJi3t-Ohi+@m%Tr!j^kaC=T4v<={9r$<7)`2skTy4K|dROasyZe8h zB$*jaMK%h?Y$j`~%AbU%L}dn1TFBYi(4(f(LT_N=lv=T4q!WMg5+E)&MQOgU2W5ce ze#9Pg1W`{i2o1rNBs^k!dLuzVqQ{?PR?DOxhFq4(eOh|d_21`^P!xdSVbGSu`t70| zhsN@YhT;qS^R_{!NgkIEf4DV!H``WHJT5$inaERTc=!B0hoj;~i>c+(H|0I;_K=)k z4rHCOY(u|I@<-6MSRI4NEREUeC8FVzL7PT5BVy2Nva3H^~Yez(tD0aP5MSPR;op~&ohD#c@z+y*z*-Hj(3!NSdU%=uFfig zh55Z7h(6alp0#B~dxMS0xIw&*d9CSsRWls8f6?N#Tt%}~ZdUX#rJSMndrV#PDsGsA zC>47Z6Cf?$-Fj^`6oq+t+W5p0a9~n}*qoatLv>RW3JfCwBAXc-mo<-9`WFu_c9aAF2;lZyMlf zZ{D|OApVsPnCWb$0w+}>RhkpnPj)@4-v;f$br~V3Ry|s=EdsA&pTVt*aeY@E?-Cv) zVjlE!4+1N+$16Q8>4m~YgqDJO-O{oRjiv*=Jx)*dI-YfK^oT0I;mh&@A-0|zJuL>0 zt|+#bUzJF}e7a3gC+W%WxLh3VZEI;5twlAE$J=U0=3O9LwISfoP>%aTP{b}HSp)I( z%uM5aX{q6Z`(x~O5F)pFmv%MIs^LCIDGl3+rDsQz_Y0n#i0?QFb5?M;tdF&2c~O!> zVNnYaag9#EzVE-tCSjj=l#-A@5nck!zMv%BuIHuV(7i^!$R^ZfK}EY*{pQR30s;@E zsGr|(Ug$|RdHbI8Q!a>E8%ya|Jz*pX%pRqfZp3_SK^~W^{JEC>)ElhVtKTypN*#v69!Jh#UcQXPM$87W7Pv1YmY^8fg9Ksvdj-4<1Q)m1#y!Y!q&MU;NJDx+s-m=^u2_Sd#e?4b7cl$Y0yu% z+%=|ON-@~4N{dyR>^yo|uy4;;S1_}f%l7=UG9=k@L3eFp{c=RXvWLNnn#?aqW4C+7@p<9%hFE58Q3i*T+yir1F(FqTFq^Lf-%RS}cz`ig>-Afjo?m+NEA&cr{kZB} z{$V3BRp!_C{l9%@|M>}t$$OBWWX6L_j$=gu~JpL>pY`>^@mC zTv|C6v()-FEZ!Bn`w9nf()i@&r$Qt3| z#0Keba5@xPlB8MAMLzwx6KX9iyDl_x?6S14`c}B4ce0PWy<-JGkix8g`lBr9w`wTn8CwZ!J#)Zo+2m+2+-V&i2WYqi znvDl%3n<`D)gqYnL=-pLeH+$#fxlH!{88$2?i~t<{EwQWyA1ygQCdpw1 zamgsKbg+FcN!rocl=TghclKV!v3g^f6#2{A{)HcYFfv}pSc{^g>53eIhB!L~d9Km! zyM3^C5m^R!O1sU9$S%nJjJ$-QjF3PHhb=@8UdN1S?$IhxH$s~mzpf8i6&7ndh@ zvs`+AL{J;!^cQ9jCO`%WE*$Aj+6LhT{Lp7sqEK9h+Wx|=5asNKoF8#gtbh?Ko7@2; zmN`kgaX3R1MtwVIay0{L$P~B^pRlmEyZ5RC!pW|1c8&txYa6Uqbpv-txvQ8^Pr5?M zrSFqUzK&wa)OLoYP6~K-^22iwxFO&2)J`VR$*%T0d#?b{tmWS$=|2(yzvmSHJpC~` zg-qQ>LdLWTejB+Tr7FkdIar~=KgwGE;;MgDUNVZ4{EwjVN29z#LChApX8z_R9MZom z;YWGgPxJUOc?f;aU~34H;9r&II=76#vrNBtzy(32gLLhCK@^g1xX>H6##bcBxhNG{ zval(uQU-e{qZ7gyv^M3jpA0?^(+prT&Nm$5h1w!38z*Q$#TSV)993+CCKynuNef;l_{||!wH^lYd0{Wld iLo=mh0-{;|U+z}4eh2*j-R{h9|3mfv`Y(LD_x}Km$3LC` literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/banner_green.jpg b/js/common/test-data/modules/commonjs/docs/images/banner_green.jpg new file mode 100644 index 0000000000000000000000000000000000000000..55c28c3e9ae9e707aa9bf36cc31030e52d2c0ff5 GIT binary patch literal 13134 zcmc(F2RNKh_vo%&R_{c&VH433qPMV7A`yuYorLI?Wo>kVB_iq~5uGS0dhcb4EFyYu zvB3|~qC}6lEBV#$e&7Fp?{n{S@0`~>-kI4sXHJ%fj@SY`nFNFY$iQGQDVU6ul#GIm_(w%f zMn+CWO-V^bNl8sl{j<MK@7l?HUO4LHV8;8L_&WrKoSs`lnip(cv}8wCNAV> z2R#4?29khDLBv7=h7g+pB#a=2vtV(!CDR=gA2VrC?B$oG{4G~?`yaS{#%yd#kY$yr z>cP%I7=F%2LP7!}BKxf8qm_ySN+9p# zx>^D+Nc|G%-ilGU#-_6R?e~Y-I`AQnAX!o75P?5-ZngjuT|A@(1d?j2Z4Se8eZ9q^ zU|zzB7uM=i4ya)a<4c+49!2qvmep@M3IZ)qk2YzK zMHukIz^{yV^WB`oxf)Pi$&{4O0OFv%<^4pwaDJ!#59hDQ8qn}oGa!6Fh|#A}&+ znYa4xox_g9JP?z+ASAe{qi}&cJ?tOP6I4471!?GboBhC}@D|aDL)*E~U<`yAb6*X> zZ_r?m)skNKx2Dll&Vnc91V_SH(QceU7};kmBB+NoJYmqG+uV0)d(}>#mJLmT(tc=k zr^@QH-XXuyRdT1o;95R(e@mB2!OD&vCNI3Kq45NS z5i_tLa_#@w#6 z_qD1Apfc@YTT|W6z2@N)!03qAN{>{UvesVxZM(0&g}Wu|d*xq3B}5J`Wv|5@%PZ6G zPM>Lu7N}anDpjimt<}NkoUryDbdiDaepj3F8ILQkHqXhYLpQZsZcQiRZ;@cu_V?7} z-T|lN^OxaA1_p3j)pq{kZ`v(};%y6}y^&WbY+JrMb-eS_ljG|hFO8x_s@6nqZ}pqE z3N6%5B*m2gJP&(5xOS7>7FI7 zfYY$-?GB2jgm+yQESy-%Ix>JSpSb~BiX_QUXRT;Jry@Wzf;%F4Ap(pZay1-& zu(xWgheOs5*@d!vvgG7$cE@P*^AT68vOCQP`HR)8 z$d5I$LD?EN;1|b3N7~UIk6Mg!O$FoAIQn1kJWZ7H7>=H_Nm45BjixNe)$bafsjgCv z0fAi)^J}vb^zR{E_`?n!OFnQsUscWp@P8qJ?yrG=>(rdcVInf}E_btp|E>@vzPCMGsqdOf+LjyjWt(KfkYSdhQfW3;c9=V>WzXDQ^Vk%BTURHMZ2ag*}=_;r_ z;q72}dzfG5WpJlTJT`{fPW_qv6{+<+_ruKtKyhZX9dd%ApmiN0pYa+~&R1$*TNq)c z>c^~314~W2K6?YJKmjVj8mGuKZ*tJWmLN&;=iOu`op;+ss+knI0(fhL%@%~x%C*a^ zk{8i5JgI^kk!ja`yGnp40&}qKcboUQV`TERnNO`c5q&0g9+qp5%m$_(XrQCtCWYgM zv~zKG0#IJ5XO7+Rg;T6%OAY(``=WL-etC}LQVB{4k|~f`G4kzEwVtbodG9nCtFL6; z3{{lG9i3m`hYa1Dodxtl#aJI+vxIsuLQX5H(dxWQ8El7&!yj?AY3-m$3t$YaKX(Wp zo+sbn6Qklq>ZwSrKqY2U_&lMBn%$GR$9}08IZ@!Q!pZX)WBd|~0wOMZ>2??1d^`BY zV0&NM*fYrxO$Hl7P(v-KAy#HyHn!Q~aNG^cNDj`jlt56MW2PnSGU5i%$$Wr<0Sf^HkQM>i-XZSX!4i*V<0bMfK5!dyLf z-zOaDvepiJHy5`=welv<_@ubHwy7w;g$k#Tk+v!I6z{jp4|s|6YrbJn38xXBFxl;q zEkKnl_3s$U^_P3FG`%o3??xwHUWnx#D)jL>;1jJ!ZnR8X2?`vyY<9BS(Vk)(6Y-)& zyY^7y-uYpAqLMb}Eha2e837Q$Ml1}t_hIz)e3bB-^Ce#{sugsAh~?Ck<@rVZ4?N4C z=I)3>pk9Q6`>jyjtwHPS7P9EgSAGMulUJ@}tCTy@)b^!rtVEJF&b2>|bgHX%PBBgS zKFlS)h8JU=-iSn&b(sq+tKjwxEyYt&Vp|f zs}lhn#>*Z7Q(mOacO0u8*IRn!*X_wx$bduV+Q2=2cMz#UlCq@*Q>%R z=YgSU4_#$1!h#FU^_$hBJ3pBU*5Sh#Yo!zL(zoOREFaG(nEEy*F7z<4DVO=I1>d*v z*Z!&=L;XEewRC~C(Ni&^F;c-}ec7T2-$ZNwIn_>9=d>j(y9RcVW_3;nHEJtIVA4?Ji{TwV z>Hax0Z5aI$ruF4x3)Vmk6}nS}<*`NB->`n-+Nva>ZkJ@_{t^l2y}zVm{QT2mOJHz2 zNF6O{FC7OPw;YTpjopDo`s?p7=zYm*_wj8=UI%+Wx}K6KJRQ-sg5+&e!r$U8IcCnf z*tAkQ^)UOLin8_eG&@nDXm*ci@Pso4gJeH$wcw7dGqOe%kr8V@r1ne>A4k%;05iHe zCBjQ{6?~+(kvqYmoKI{BCxABIX@rEty!G_tO3?@7mE3U}I*#ZD1OL|{Huokbfub%s zDAYTXE3bh>19h>(o0?xeke)yW3MX%dj#j zevL4HF7@fRDryGI2yNZ6K{;CaIm)M$E0u>oZXxWH!I;&oQH)W$EG>-073=Z+5k5tF z&*a$2_GLya043gWY6`9A^DE8@Vnl%Cy@5cJOA#F81q? z4SFgpN5@&Ce@_#`fv0XA)%h#z56d;~)7>&Z&FBhTemFFgGT z-AlGX~$bO~h%l?MIY{R>co8*nec8w?31 z_Am1%+gPpy!!;$Xx=hrrsp5WwFXRQ%yV25xskow}&D{KMkYi%WVP}e6oI}FL?gzyO zrPAgt=p%chN~(}(la^y#2ja))C0;|)0z$OsFoboU3k_!2W2aIGc7C;us`Qeo7yYr^ zJL}gvs)QtWmtLoNak;88+fY0iI2RiK{M^>1YwgB1v{MSAxv%8xuF&wNH%Uwg#6<(p0weX4<$i$JmUxEZjvqTdru4 zl<4wT)mJ^MU={1-;ymzo@<5#c5Z98wq$C#kuDbWcB20g4i~kt^g7>ZQboK?2HYoNK zOzK2R`>nKMxD^#|)IK*q5)Ja`=^jLUofza;#;a_ixJGYzZE7}6PaYOJPuAbp79Fix zqYC^nGI|2IDf~ilX@PT+y`dbXr|O&Zja!4Vy*gRW!p!gbhH-FS%+skU!cbS zG3wt?h`&2Apd>4wc5PB{PUaeuCmnKl(ut&9RzV<)zXja{?HL_MEL!EP0^#0>>1`SaRqmGL&baJN^Y8lFymz}@Ljy{bd5Jp{Wbz5 z2o8-F!g+{iVM3VlC|J@J<0zy8FH32{C?rGZm5Gj--at<70xYNlTEH9zhyHg^i7b2l zWMsBI8qCFlZhbXs>>ORXcnQ_1D0O)LfM>65-C+vg++P1S_hoxT%CX_=ot>2Jt(vVB zJKx`eHp`W5+An{Lx&NEevr#@l#Kp3*%!R98x2FuJzkz|~T%{oS8<6#z zgsVeiP1A689Wd6sCr0}+fSrD`4IIy=Os`S+&?|^X|HIZ%ISb!pgWU1*n~UwCk)( z%xFpkyEFSH!32q7r8{P?NQlnOmQ$h)N2eZV-)K@<%W*6nshKCEXV>W!!?_=`^nAYO z4UW6b^wumy9eN4_QMsc{%q5LuJrGQ7&sSU%(Rr-9THq|Yro3d0)Nx zt8@}$Wmk^c`>jGkRUfef-yLUx$`7AC)GxK4ILZ%>vgxy8e<{!wM-D{DZa#EzH}$#j z+V#V9^;EA&L7iGf0IH)OftI+0&*xrWOZcj>9B8yEnR)`i{)kX=_n4JiFPkiIPheMS zzbFg34=u0PKi2iou^8DD4H4`0xUQa!Q zOx&pAVo&tgV9AVp+-!HkY?-T@tC{#ho!6q>NdDs&`juaY_3C$~I?g!uXE4myPIYBm z_${rmXeh=hiPfz){QV{=Uk>?y1FSX{n}%XWVt{Lsme49G7FNuDu-f5Zp68mMQfvC={^< zu;--pD%|=QlaWOpLGb%*(YreK1yxo!dKbTo$b3fI$r0o z@S5Z4kG=r)!WB;>MYC7;dx3f_-?_(ygX>H_wTlpB`<#cW)%qSg+6ya*uQ8XMJ2#AO zY7T9{S2sJYtGC`fEa>sv=kjfinQ{(W2N->A#V?O~v-B3pFks(migH2U!gZ(K@ClOq z3qVvXAa}5pq!A{vh!a4}IW?OBY+sD>aO*BvI)nwT;}X}qohgeSK=U#zNP+6o z=}do?dX2eO8u256riFcBPMI?bt}A1{mjZY`nJBx<6joS~Cemx3f>geZI|lx;-~=Fp z9a$M3qg+(TMs3;_4(lURh4Z?712N(Yl|Rsau>ob)jeG0v~BM3PCL35DH4am|{|YQ-?R3-kT*`B1D& z)fiGnv}9o119y?VWf+kz^N8%yo6`41c#S8-6AbYH6A*)T{4}r!FyR7~NxbYw#Bf;k z)fiSBD9Esy%ap`@FyT&R$aYgxVK?_Y+;OZ)+2TwXK>!mkUUCoxSH!1Xu02{dl<4~O zMd^LdrhveXQNIz4{J#XoiPTw+KCKvllptACm+K^3moS>D2OJXMC+f5GjdN3Kt?5SH z+WTjU?`!4ftFNjo*9D}me86Aa_Xx7LS#$q}SsWm%;r25K=sn;=P|rB8Ard)jU&dRF ziJz|ygQ5+Us{;5OFU~k$Ec&WHB<*ezAVMoDkZiZx%a2LWpLX$7YBT;Q+LrP`&FvWV3I zV6kxPQ12XO43_FTTr^*939H5k{t1ABbPCeP0$6Z`c{;{e05Qe&WrGE4}VH_|kXem#DW#+8sTgK3PTF4qs`%Z@N*_j^6a> zUk24)A5N&&x!QZbh+%vaFfN)_m_`RCe%v`M)jevyB132=+eUgEJsHFcsP?-N&&*u! za|%L!r|}o1f7G;LGTeTwnb?s4^rM$|j0DM^b578?zQetO!8Ek8C8; zSc~nCE}})w6}kL|%NTl$&JgNP(awaKA~|tJQ`|n~TZVGIrLQK@l{t0!4mQJx2vz@k zk8-_NByjBwLd}iU7il3->`0`SdY#C4HK~k@G744MjWF}VS=hb5Rkfz!B5mZhcLpm) z75$LM(Y}C4Ed_NaZWe1i>B~lF7w;y9kjUk~8PI67j*~T%m3b@Sc;C!k$vbq6*(ZocPF7t;z6srycUY+WlFv;yF5!Z( z-(5r@0%384X>V!Squ&tT>E}48b|*!TChwV7qOEK!=B=Yp=|WSB#RRvq?%Z2tEN3b| zin_RxxOsnhw_{uzoGeWK;>FmhT`Eqw1>F6QcF8CVBamDtkf=yuHTl6P3bNO>Uma!S zNOSx66J+KL-mZ=|gMgH&dN}Q{sYO^L1@lE9iXCya`XA0GP8yf?JZ9gaZ({*@|<;Wsl zwoC4QTt23*Dt_&vJ@UkM1z1$&1$zJ9F70E>4P;STZluNeqsB`p0y{x*P}<@*Oq<4! zg?ClEUuk?f_ZgM6w}kI~;w!;?yh=fuJY_=y{?ZAR&tjzVXgrIvmwj$gYSBuGeds}# zOlk3k9?qBD4K2-Wkjp1E5xWa9kjR1?!I;1p6Z|$u-X#D9*JUh!=t_GW<(GDjOw47m z%u~hv3n(yfOU=b@BasOlM+kkOR?wf#oe#PP;qTp_@UDZX0#f)|9O&V?yMnCIac*^s{x^NTFnFw)%X_CNYVSTHn>l^-3D zpk#0EtF>7Q37~|;4A#KGJqit19cU1k9116U=A7nUSeQeyPC7w~PQED3>YIU_9cd1| zg*p=cvcTZ!Ed6a}qOrH5|9vJv9^-ZVeCOi~%vmpQ%mr?h;%*m#&yn0Dpq{&-vjx_J zWzvpoz6CEKk^$^`NL$S=hj-mtQT()ZH9ZX@#0d%{pv~Qz08Cs1E0@hG(lHnX@%Bp?ae)gh88re ze*kkrgXfNePXLc)T-{#ym~h})r)?$peBum9@7=e`**jDJzFlBPPu=3@8o}Y6gv&%f zIUzng?q0j5|2{k7DS@?iaW%?=)4Z{;w$}lj&xnu+R5{k4OYO@>sTA!tzN$8F*#Tyr z0JyB}lSaJRQ3^}5gq&Ul z^T!LgDr+u~Vrv-srP)GwDqI!k0Gw{O7mqA-VY1|iO7WO&9QN?!Xn$&x+gvwVuqD%= z+kKEdDYaILt8HVPyXdS~Qd!nf@Lt4OVY>d7scG=|H=)~{!G=ibp33@ArRVh|YLz`D z^x~P{^>=$?JN0+2RIlx^ugMMC1Uim-i`XvWvv$@~ZuNf?A8;)fIhTo%bro9FgU;7Y zBK=l9%p|!2K{(Q=>Hez&?gB#Or&MEnZ?%Tt($Yrls-}Y4;sCt5Md&*9$<4`N zugt1T(Aab^jn`v;=~j8^X0{pBL}NFs1l#8h`9i4d<*|*8xS}ZE#UV=i{Hfd;>5RoI zR}Gm#Q!Y}ML_9id?iFPZVP#?+QPfy(egYWuOh>sK=Z|Se~V!oo9TRR5-zcY=bo60 zCxFN|W6SJbGBW21peut{gue3LjrNh2HXCiItt@Ng+H>v2;L(~B(-Ed6h{kirAE`Lp zsBVmG5+c@r$miu1Nik(>t&5*B#x zJna}%Idgw}bmU@Lwq<#_z4JxC$%9Zr>?oBS9tm@sE=6-r6}C4#pG%vMgqHnH zamhCBLf^z2b7?SAFxNzerh0uQCVBYQSj2bnE7!qACzX0b`M#3SeIr%UC>WQlyXft( z@PG=wO}zbN()Kl37irLLC~%PFRY^)pnFo!lw|+4DD7oRZb3I`^IS(C(tzCx+8C;c;0xD4Mj4~rE z)cgo}yHY2H3C^AL&(1^SS6%wC+pPSGWT@l(iu6MA`v)?kcszOVv7V>EmN4?mZfO=? zyvP3CJ$UcekWX*$2CCKkv|^p@uX??j*#9dnP;d$y$%_BjH`?5EIu_If@k za|COd+s+BBk{+va?#Lm*)yR9QPettuheH?fZFx{~Vko04=Z-8k#;6k^f}4(#tq+6KzR4&Uo_TJ$hCyJwmZH+w(T zP6uqTow~1YG`ME;L4?IXm+vedvJJJLQ^G ze_fj5@lk`vJr^NhR_v9>2=8EcS#JHpz^wKyc1U_Q|Bm6P2$McB!g9oGw)S=t8XrTW zCjqTz*NWmyC^68+`d*v$dF^NAvSM;{~1hClyM=FVL8g~C614dRm+84GI**qRY zwLLkPgzFGs-PoW*Zn?DbYkh4OsI&KKd5UyaH}i1K#iA{a)uhVT zH`Bq)o5Zh|72yg4V9I2YG27xhwH5n$Ovenu>VkJk^(DaWcc9|%qD8{GgjQaSC&$f1 z@5*VGrt^^;Q!KG#T~&|b4kPYOIlg<@p8N?ZWZHaw#f+ftF()qT+D^hW(`h{IZc9=< zw#v@9{kdOz$R1fZ!zV-2VXNULZ;>BRdAD?EtZR4up~>EhksoH>`SD09x#y#$W$ANf z2P6RHGJm-FxQm_RhCB6B&~c4kaU>`4s&u?`D!t`M^aQYad13@V?2qB=TfII9r7qac z;7bW#mMZHro<=lYZKCCo)hlSBo3=($@Z^_p_JKb&UE`7@lro&nX1f3_g@&D;S=6nP z;YQFu^ox;=g>mFF_!$c{QzeJ?6C>3%c9k&v4f3<34}wTZ-OU(K(KmF=Y<)tB1 z0BhvPVUe4Z5u;NyP-$(&un!LcjjY}YP;*$x8B&qxT z+%3jsRe^`;-iwFy36z}Nj3WSi{T5A6lXcwPY}pGT|IXKwkV`3`#t`@au$`l&G7zv$kQXS?uN8G} zTUwzGCDT9;OBBaGPnfiHijMkjLIyYzSzoFg9k-f-iy~^u1t{11BUyF+JpcSI6OgNp zDQGz_n}-})Ep&ELQ_|iG+R^byphe%L`bzZ~$>o5HO^ypKGA2&;3I>T zsl%s({}{%(=CLz2%i9$z%YKSEBUD9d?GnNt>v zYsVDYEso}sB?{~}H$?V={Knrv_(435>j$*kj~7O$ncBFo-j~$5g1c#ELeU8d&7-Wl zC5M9Trx9KHe~1XA50<8Kd2MOF!Kfka3o9UYL+d`r6(;E{*&OUOmTXZ`qc>@;)~2gF zAlOE$WlOm1WCvdgSrqnIP2sk&pUyQrS`4?(DK*Up4cyYWOMl;ztp_+42w8o0cjOxV z)mWx+lvCiKtY-d^A!|joF?G6;;gG6F&n1y7sgAeRc38`ieVvlA9Z#rPJh7A1a-ZU^ zbFgmmT<_>h7_~=7q(N1KE6?7KVlM3tLYSw{sr2<{B@3eKqiOMC0A+QV4o(p%%Fb^w zb$4jo3)v81Jb=ucyI~1Ki;tigu<-h-5lNEIk*TEq@JYA6S

$%sUVrT;~%_JIGBK z)dk?owab=AF_Kd(MI|d7bR;T*iRTxhKLf~uGC^7PIsZO{f^7?$)I1M_s=@Tg`OeW( ze^6Ol#%dNqRbaY;U`vv7eB2e`9s_*7me9l;eJC+9NZdW4#2DI5$x{yBydiYj_9x`9 zio#&}7JqMoF^)^MboYfAWL8cDGkOK*-{^Zm)(W$F#}UFVon>J0)|T-!rW9;nsLqGw z!`@^(y*UDugkbov=0gda%GQAn-@4@8`=POVs5o>VJxk#73V<~=-C6!eC%Cz40RuqP zMxGB0*t}*;*OnPQmud3V!222ddrgM_5(KJHL^a7_U=B7}c0k_dnuDkmSv=8y0>Uw6 z5_8gG^6sTB-40t~VN)uMjiJ>Nllbo1uJ{|^1>4I0j|;-g7167;?1{G?Z~=6ujWFfRH!h6_J8 zF!*|p8T0CzoZ_w9$(U~5*3BW7M}acT*npZP#rP%t#~G(P@4SRH;gBvlwt+7Nv^4sK}_cD7a! zm_3SfCD3bejFU)iQijo-E8@Nj7^{f3ivtSK05&)>L%*c1U;}A6BS8y6FYNel!-$yU zi0L^Q2I6Tf^d`5N$xjoqz`xRT{$(Y^6qwf29u|wl5b{h*_|JjR0w($(X6k=U%lUJX ze3H{x{-1e4r&9--yitc27-0TNsezG0{}mVg5>b3a(_{oZP@&;!6^vn~rsf0NFhifI zsgpojpowTrdPp}^&4vZ$5W*79hbp>rhxzISdd>47;xBC@9{!OhMdXKAPzW)zG1KBti~yBZ zGJ3H;Sw?dz53wN3uVMc$2>uiGskDB7xx{kyFM0h=DjEGBz5ju2#PzblWq&Eke>3#| Q!McofRQ`Vy_{sSH04hn&5&!@I literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/banner_home.jpg b/js/common/test-data/modules/commonjs/docs/images/banner_home.jpg new file mode 100644 index 0000000000000000000000000000000000000000..89f707eecae7283d4d8a4960652c9aac150b160b GIT binary patch literal 21665 zcmYhi1zgkL_dhf;WQ5?TF$Rp$p|pZ@w{(vj?Ue5BmJ$Rhkq|Nd z^Zow3f8YOQk6m8(-gEanbAw4vkHg+5EK3_*mq)bVj^O4N>XBCQc5Zc3Q7tJDr$1< zJ0&^w9U597EzKQ9MrLM4My`AJ?s4(`zk)+TOiV&bLPkPDMoC6NMoCSHE!4FCOhC&> zeFs~p8R;2-Kp+GCUvg$)PSNZ~v%&FqBqwQR zO(tm1_i<4NB#uKfjF|rj5G4n5_{-g@O($8~maGtRR*C2p%6WaE1KojW>_Dc8j56`a z7LV{>mXDH)*B9`&oCuy==+@1(fcP9JeQ-9OfbXV@lew@;-~9v7f;CD)SX?QB$Ew5kd|KT*w9Qt@SmHF(&bOGo6WoA{X8Lzc2xe3C>AH05PnANg| z{`kfa=^tf&>6P42XWL`?U+BhdJ*`R|&_Lqk$?+pwbX3m!<9wcH-Ut8c9a<&$7gWxA zfO~`TUe>lor{p9gd|aZh*@QqC>R(VEH2dYRNQVDUBw)m{1Ih2iXi^9Lp8f1pkjKvz#LX$S+z29edYpT4Qyz>0qT)cYH{? z$*%m>)ZZzQ11aUyk*R!t^&H2iJDR!NtsGi{^_-3e_NB*L@%;qE%O6bwmn|&YZWQPL z>YNshkt!;hz+Jp^qx)6BEu&m968ogy-HWxi2i152O#!HX+50l9TweJXy_wJ3vcyN- z-G*^~x?lO`wJoro4=Fq7U&iQ@{sEXw(oklVv+Cs%VKJm<7v5iGR(;TMG5P$j8I-RF zIQ?T7;M9n}TF5_~RgC$&PQ3Mo=J)?yIbb|$Ce2t_d>!b2NNxm!=gR_te^;5RDkH2k z!~?5!ulN;aA0;RJkLKJAZTgp!2md4K`>!J!ree`38TI79aVEFbI)6zObijh?om`ss z*JfEq23RXe{o5h*5{qNuUswlNSRb)?6TA*y^t)quwgiU!rFed=pLJyR8w=*)!OX9J zhO|^v{Oja-50>CRXB9NB%`*NS(paIB;wYzjw*&pbt`+P4T!OrK+m*?u+FL*{j>a5sL1Ku zY&>SbSZO*^I-*_P?|_vtKBY{7_E6OH!?c7`r~#B&|CS%;U`wK}LpO)&t_tNW#^~v} zLfjx#K=SVKKvMVX&jCKu5Vx0&PSN)dm~Ca2{u+cebOk&#)NMq+pGpL=No{InR?Rqx zlUPFiBM$ZdNo*!9v{AO$R)b_&Cd9{Rwv}0fNcu0=%Gen+Iwb!!kk)CSjy$5o!}hPB zMX{<$I?0n*D!@ul_(F~D@61FUUjGg)UYGmVmaIwni!4^-IK%&IF#L~3Bob(N|9Bv= z`@aUP3jU?B{9F_b{f7qpZ-d5v#?xx}4+7D^@_)<>t4}PFzebXN$X^7;iq`Hwt4TUR z{SVrl;p4y1?)*2$|1&_i8qMtA#peHK=I{S8b9fQftFS#UzWmPt61)%c{|TM02I*Ko z7Th3Q*5s}CN=M$|wY0d4H+Wiz)V{Lnyw%&&BXr)G+k4Sex{%x$z*4b#W2mQO|BFd5 zpy!;&Bn=|qB$6({Zh9X4;16Kg>zT(Nz|}KLrw%`xhA;As#>M5{at7}`6O41uF9(I& z_vbBx34S8nMj*LbY;rP%2`7bae*lMT>+OF43yZvKpQ1n)l6MLfWSyML=$2oFiZx17 zL}7#`to?2@hOS;w8<5~wqhL8!oAL#l$;;24b)udGl@XWaGQ`k;&_?e8#a<9c2;)eGsbVSDDcq7dZR~~AwaEnl^C|6cZ|cI1Ra}4ZE$jJy-V!oU`te|`yxnp zB`}yGVznEcYN50U#oxE0@p2#?SKdY-4->N2-S48b+3mm77 zGd^CNdj7{bIAU#$@CX@`>kb-Agpg%Y9fub|j<|#%tBqEr6dzPjg2z!me#76QpF%hS zo;6R-_6I-%j2$_G>{dE=!4X}Q2Qqx15n17nlG4I~#dLwhL-G@dyGAvO>5U*!PLHh^ zLZ@P(86~>Gj-rL?RTkr?djZe0&rooOncJ96h%eS~??PbD<)ML+6J8D<8>Vtz&d1`hCc5{}{ewIg*)I zCwWY^(ey~T4;?#Su1rFx zJChL#?kHeCG;po8%MpsTot`oHgnyAXo!-M|2@0e-__B!R2# z)Nxd||6bf0*Ya)ck%DK2lWj$T8%u-5PTch!kJsclh)Muq+$FzZ17qWG-+6c-+nkPQ zQg@e82&pfwaqK;Mdd$FceV>^)yv~`5t{YY+7M)xlsiKmCRrzyepoo;;G4&K>SCiwD zOZ9#;{c|T7(1ytBmz!PNhs}QQwNdqT5UoOjzb%|B9Eurd(SGx|pJo3grICwtdwWOaFvO#3!o3VfvqZ$HFngu9+bmLZ*Y$;^YWB|$CAh%JET;6qbQUug zQBgH6?k!C5FiI#Bx6x`)f#y>iFsV!7=+?TQRJL5W_~VT`1>2UcT|ZRE333fjZbM%E5`7|1bX|P80HCy$p`>uD$ws;DjAPV@k*6~NrAR(f=l>CzayE3RpQ1~ zVwXx|QfXBmgKe6PU$3N73Pf(&8kFP$k4dw-dR<~asl-+=0vRYmMJlR*7(-KVQ3bl$ zWZtOCC6f6jj|;qL+*BVis?sfwOq`DA12mb^spRnFy)zeAmpUfGtN(7CyYx$IGQP0n z$a8PrnZap3uEDv~h4szjLY2RbqC5d;vyll+Se16mIIfAQvS3M(QC}5Jm?^8NR#hV~KA|r(s$|b$JvS$y@c&w*eeF53jTz>$uM!o3{ zUtXmK<){tXOK@qP#(XEWw?SXOE`-9OWHp?6f6u+H9di{PA>kr&@s0B)Tg|>$%Qi>pTUIrDBKkDeNn5tk^QQyu-O5+B1+?W4I%PA*{4s~$`o%3rhZ)|dVlEm^{%KAa&s!j#4VEv$OU?K=o?2#pI?OX! zI;nxSd*y@ATkrdxt2Qk%nNtfY-*>A8+8kh^7ETKfcszKHc{0V7242mU$fdDuw`XO5 zS$;iS0Cn)M_j8ztXZ@gXN@Oi}|At7IQJp-pdr4h;JGHs*(`i~+D>YaOo5ieimBjy= zNRW7OXb6^Cw zgMZ_ybwn7-;p^OyZI*c;Iee*Ea5);Kph3~b6z*fDA?k0k2I5^FuLkRnj+<@k=sdku zXCi?nlFJ}0w^|*$aKXoO7~X-6K%JZ{Vz2t`r89pD7VF-zwE&?oVHSdk90c552$DO( zre($WjPcykIIK@9t7y*YLkq-WK!lZ#v{k5;iog9P_uB4Ft`E+;3&5MrSp_3Yt=_~| zDWN5#jlz9y9!JZg3!yKqE#i>YWF=k0iL=4?Y3Gps+Yb6;&4mf#5am6cVZXOD50 zLjJrhm-xUe#q^DKN86hxz9?l;LSJpfHYA5T$$r_o5Gmr#RQvSa$WS4XXcUJk@-BLN zdtc_VE%h1kO-FX~4rgxDlOTAE<15VB_PKR)osZ;+h?TE#AKCM?Bj^hAHqP07Y%rqH zpS05YyCh58`zKBd`viC&-|{5SaPdcF^*URxbQyMP1NH4!{Tw?|Ro!}SC^VfvGv-y7 z!b`!UWmZ;JvR|J#NQrbEv*zGET~FhA$nScTWmgNG$Os)2T@yE&+3GyPL7NKuw5O*_ zONVKw<3V0AmG}chz4E>k;!_<=w#*e~TCaAfQhQLwHurh4mqOiKFEExSEosZgZj5{J zY^+Fm>i3y6=4{!qHT5Y^Mi$k$`m*AXk_p3u0m6@i)`uOUR?RzFJA|WT?|B&vEli0% zqVH^Mkkf%bT=BEZYn8A9^gJboFpJ4#o1~5A9|l&+G`+)IP*i@#4Y5tjqFHA;*#;$o zm55<5?g<~J5*a^$X8P7Q8QJ||92A}{jw3c|MeP}9@nNHxVSDPH7B-p*|064Gl=Jx; z-C~CfyXVZsW6?#}IGyBtw0o*0|)__;q0%5|;E0S}}v(CzXjEi{fP7k=}pW-5T!%In} z8jUcdVlow+C})p;%@;mN^$}nzX$Spzb00k*$beaS1tdshGCyQE-O1J_fXqHQH1u1- zMHxE(K)YAfx|GiAnedMkReBqnfNiQ=GEA{qfMDz}_E8|9vdY?Io<5^0yL6sTCALbi z(!`WL=iZ05xOUdZ4Zk0Ui~cZHMSn@)mz&@BJ8tSmiv$~*2rSH&wKQ}j>Tw`F6Ni~e zpugss{VwyYYZ+rFf&)T?(oBZR(}|)v{UHN`l2e6Glo1NXAD@)1*|AjI^WA+PYS%Oy zJx7r@>H&v!6s6&dxHb(d)MlGIChgVwj0KL)ea>jPjwAFWI1(17MHYm^Q46WaI zxFOgPPXYItD;>w5lII?~|0ox9O+WOZA9gRCNc)L@`L8#aYOKSO3Fmk_Gvmi{N!h%1eA&4 zY5!zS8=|9E&9J3rKq9ydMY|jA6CUg6Rg@W|?^BGho|}@G%^;KoOSJ?eN}FWDOtr8P zz8b2O+DiA_Xw5J>^2L-Qqn|NkL92GmG^}qc;>xip&Yu;LZ(R-`*B8_kS-J|5yl<>(*!?Xu_#c5VV`h;<)H zdh}7F*%Lc_&Y<+nh2bVhx1*tA$JP{4x}}{SsZ;(G^Z1dQjgxp1*W#D!B*Ht@Io6Tq zM59}tz)5m&e1oSYdtl}H{A6IYIvO6hD+%yU^LZ++arXS}LODme8kA*MHfo>Yb-&!I zY2(U{`P?O0PP}ysD56!e-cl}{|A3N14!uO=FErmCcKuVhe~?^rQ?Ge^%wtX!WHX2A-dVsL0)Z0j*!m_C_cd?dVzc90mVe#1BTZ#eDRtQ zh_<|CF8?mKrDhA~7Bk<|S^rEehx>64>tq7`IPxNwAU}EX$5-?ds)i{m$piALU05XV zOn_|n96TVMk$3Li3FpUP(k+6YC{Uzk$ZagWQx|H98}qP^W63!7W_t)LmMHCb?RY8U z*?#P(ShUtF_9!K*nt0Fhi_kYvmiL1yvH7SKu((3`QRZ`B@)wtOZ_PWCe^{#!1?0~9 ztITz92x*6E(8dWh-?@|Urm!@R0@d!lTbhAKCUIZwYiv+!L*)FUY?qDf^3`udoyZ)E z-HyQC?0ZNSf@+dmy~v2YGb#UfLsdN42iT3?ajlemOT}1*iK&SMHhH7(aJXFci?xlX z)?U-U>ZPhIxEc8*V6YJ;&a@go1Xr^e)zwT%MKkrDeTOin zxun%`b662Wo}R3-_Xlu?YjkNN?5d^O_%c{zX1FFeRiyoW!cSw@5-+ z3cP{7dCPAv?I@6YizkeBTiU=T=mT{SNUfrFZ2a~n=4-=w`c(;1*;{T+N@rznF$mJ(Y$98$a^K!*j`I_ zH@8Rm^xh0oB(f#CdVMvgI#Bj5G2H}#pd6TjtaIeu2Vb_bCMSh)SP>23a4r#G(MPNB zbJc}!Ld#Tp`o7V-4-z_V`;7M?_My9qAAG5i*<3JYwzgd0)7RfJgtVJx$6ITkJ>GAq z+Zs7|+Z9@l1V6pYolqv}475%;eD|T|VgI=t8~bnE&Aa9Ro3-ZU9Nc$bWOEGT*B8dA z(wVH~$+jWuEE`B#CO^r(TKh%XwMWqiuF@A{rwBy3S0RF3e=H!fCE4Be_}P~;>+T+} zR53|~w*m!W`i5&(4Za@2;{{1QYn`v36E#|En_L`ORFzc~rm5R^6jeky8k=A%w1Z)m z5q9^AtwgZfR;DaElPbZY=`?i*?V<|9G&NJf80?dpiTW^)Up#LHW=SdzKRF--{A>9o z>sdDvexJ~nP*k&*NlLygO9eP?vXs5JsYm(gV0qL48r16!4X{8uc$@&0Czytj@*+rP z7eK%upHMTZ!{L1)uyp|*)MOFj!Z?l&cD9m^5rDN=A<_!aG4cq(<+rqB$oht^=d8q! zw2v(1MC|H2;?5d{wFhVsqv>uf!<&F#`=nV1 zH|_P-8&H4mBe`%ZHj1PB>3G_#=+e74y#c`O$D1US8+Dmzsv~fd?7Y-cOnxf=iO}nU zwSqks--`IiTCPsY1 zoSPSmws#J-m zF`&;?sX(v*#o9v^Nt@M556k|hOMmmDQqyd*INZM}UTKYNh>Q@u*gVAwPyk$1)fQJ# zCH%lt3ait|f2%h-^LkjF7XJS#TqI;5{$m4uYL#Hk=Po)Z3RId4!VbV%LUx7GyjlPd zpx-x8f5eXtj{H*NmgTuXLgv#vKhTK)pLknVo>~XH?kidA5BW|n)caV5tj-jSOo#Ev zNz3K>rtdEZXMMSsn*VV8rB)~D;X#L4uH>Zu#{Afdk|Y36ZFh7+a-%a_q@0#BMQ08N zhki00LNrAw{A)w-m0}X z-VVeoR!2hG6VN^K#m^7UcjAUqwA!3#Cd`tRZz&I;Yp=hBrmkYZg$2xfhdw8>r#wx3 z(iC&B4)sqVZF!~iv0jrr+hPCP@}(lN`wjHTMbaMt{bS*u*zZR2KioZe$?~v@i@Efs&e>`_boo2y#lUggF7MFB{#L~hUez(4RCbZ z+;doeMPL?3@qq5JB;)4hR>N~L@3L~KnkNwrO^>%CJjut2+KN4dFK(ANW?doTkLa75 zdf0xlZkB@&e5HLG!RxZqT2wV9yU14oT3mI0X&D;~aM>ci(2r?&EVLEAj~O`qmFkbmW+L<}v;K zm(jmP$i@rlFTC|DMio^TFDkiRQ9h1}WAXH#e!fyAuv{->>x(lt$uYxtUrhIt*WrnV zmZG?WYjhffNU85HpSZc@bGK)GQ$&$dCiU-1x;l&0;t06Rdfj;IEY;X0%j{-O$ET*Z zbozvRLgju4@J=Zl`(Dsd>Fib7BkmI;i{fKj;xzgsfHT2~qT>S)&Y1gH^J&doKJbM} ztT8cfF6ZGf4}dk`{1;g7_sy-U{<_>pAKVE5(XQbUNW8oEzipGbNzv8BowbyCC3 zv$AJSHq2Hh@so599ioqrHb~cEE1{T`ankG8OSSf46B3+YsiiQ+~q7(04n{PS<0NR?#&_!nW^{ZX#+RyNJN}y|rNpoZ2(N zS79Qufo3gp&&uSeZqp@Vj^d%t3GUPr+=Q*DIm=(4%4|G)YutB{-j)J54gQn7KDOeL z+Y12EGCY8}wCT)cj@DaH128tNPj+T(bNl=y&vHC+R(sm3Z0gvnxXh*L4(|&D7NMaO!lwN?SM_C_aeu91C24UC|kMuuH zb|AJVX99VRrR0dyjfp3k_+3D`*va*&&U;~N#a|h@iyk#?Ey0P z_-!_>b^rMIS{bbJtwK2-ckKfN-nU$>$7g{Obx=9$-jbP9Kr^E_ncpsD8L-CPo_tI| z_gw42=Mx+AjpWAdz}H2uv+}L4r`4ncVIe_5kMMANB6uD3^Un|W3?;uk)M5s}a`nK3 z1FZ!VUEFi2oF>FZ3$lB$*ey*q>1M}|hiL@;rF*C#>q9dR#~2BXQLZxx4#y{WP_f?Y z$1;a!y;6Oss10cyp)-2~y1nmGs;y3Sl-V((Qmss8DJ34Lv9})~G&8_V|byvN9O(=GpoF_~^fQ8OV(2_U;ohXf&I3<`&F>7s_J(0w4HlEdv z>dlW`-0^ecjE#$E4lhS*J7k@=W*}<#m zZ@MJ5-y6>IJ#K7|d|5(<$gn4kuM|=Ee%kd@$7P_#nkqMC46P6I{#Wb)7Hy+ae4a(; ze8mnY86Z)aFv3-!Y0b)7)3H76o3_s|*PC4E!fvTx5wK8?N+tE)YkUEf5S3IzAg4Be zh`K=1;~VRAknHYrRU8BWE=kr@aenLC9Cd)|fN*-jQ?0G2Sv=GC_((59aD`>Cp5$Q< ze-Ky?0}E;$;!wgew+F)(B@_3ORESrIZ3?p`!K%WtVFO3&YVJrDhdYsHdCin=o=Dt| zfav;`JxEF1J)zg`Jg~BCrG4!av9bN0O?88{)ed0u%DIMiCX`|UZ^cf6k+s`u+=Hp= z9QD1p6q#53H2tQdbmE8y}0N|qj^+U67Qg@$rKJq3RKXxA6db_TpErRVx7prlESV<@K&kI794ZRgME&4hx9G+D4 zq(j@_0q{N+aI&05$=2=|hjau#3>r^VUy&V8%BuqDzI8A4j}a)M+)ML!D6@EG6D?u0 zCU(`buwBrQa9--a-1Jgb4WjSX(jeXdo@2`O2PG7~jOF4UK}n~rf&cM4fwO@DI>vxH`k>VzYi zoDm4SSoCi#SZnP<3JMIiJV?|@sJ7C&|10~-3g9Mxl?wLX@B4gpbf8a7OKVTT6LPgi zh}U86u03xdHP+#M5frGWd}A{ZKg+(eocyrfEZ-savrl>lMZGUz!N1(2AZ>T%Ek>>U zt*lZ{o|YT(EKzdSzl^NdfAmLM1n$*VLkGapDwznbh!ap*+sv}xV)LxCC4Z=)0BY16 z=TYoznYMFxi{s}XfP6z4;6$nR(`WQCLCT;%vZCebs`KVDM`-bDo1I-Wl~R%Y4}wlM zCvTSnwY0S&q87)fQI_aZwzh(AsOW)+O;WqaOf>tHP5KLPbMP28nJ-#&p(c`(_f_9y zCFE?saxD6^sfn0n4^q8YXmM0sczV|c#P$+}toQ8Nc^l=_i^jY3zJpUH{(H5uR#QDe`1}en{N{ykGPc_0 zOJ{e28pIkp)S19|XG|5FZT>n|pC`7lySdlrIIk-|>lK5yrz2HNg0ld4Vkm%qn?s*F zk~ex<7Cp8oiH3ci#6Zl+YqVKqLDyPZg81oTf=}ZpmXLz_*|>FxP;2 z+k+%bRKny&a2{aduB@){Ou%Zsgt{JX*iWZ}9OgdZ2d%hVulPT#6tm?meMO)D#X9U@ zZ~`0w=THXt-@>6ppM@qkX$roKwx5;sw9 z=6DS%w({Av?Oij{9*OMrrmZ3gCbN)WYpRIcH*eUdFj@(;v=m}u;nu$$WE{E|chuZ= z--j8LC2rYuP8bI0Lh8?8+a!dVW_lHRB;@Pu^-J{4(i6*vy<^`tkS8@C34}<}u{z z1^=?)!J;wMy)Ded`P1bhkw=(GaJ6!o^|sPxG4_D5i3=7#0i`k2dCtdec z&ZmJYpS8H{{{Z?J0QGjQLaDHzZv5+U%v4)CPgj=n(9R3wr{JT5=p%7%2TZ)&4xh>e5!9t5`Vqaa9c&0PGH{=6w|!bKxrBG8B8)=GxKBlD+w zB+dSCH*0(kYs==sMe0TQjajRGpY^xkoXVS5mVr_N#p!O86dmy#1NG9Z4sj^9{0vt5 zH~G&a4i?U!S4BO)GN1UnGLiT(8a1FFv3-w>8MJv{-_%iWYu|Eh8_gstQuqkk7Hjy> z(>0s7GidpAJ^eaD;)#%mU7H^O?xSUMgu8QXj5-xL8qI?$Br?Rv^j(W4O?f6JYjG#L z=yRuP_*g&6*q=S#Z=8F~@bae3?OQf`x`&;Nc}GsgVSqe(RmSzH-TYA;TQH0>IzN-9Xx|;0IYQlq&MncQTx;uWJ|9CK z+$T8oRs|2l)dsGqg5`#-QMe#z$9zf3C|pv+4f^|QyuGWhQ_KEz;nERdrOl07_AecM zbUe$r+@5hn;f@4Y--wMRa~C|<=I^<;x8Z+Wi*odCB5&$uEy190%a3*?4-wWnw~7ym zFW7>UKsrLXHJz=(5D09CLlzUVa^xdY*-O`(V*Yl1w;3HH#Lo-NOW&GLq?k-L*W!_D zGOolfVgM};Qp!T`)|SfFmy??aDC-bg>Du1(rr*7V#Rd{6&~Ic7<^R!m%c|v@aDVgh zMTmeok%Rv@)r4BnNFsUr`~cb6M(27=MgN6M8^iqj`?YP3b09Vq|{~ud|*} zJmir~ZQMq<^OEBmT?$MxFM?tb)w_$vy#}pkhPJ|zpivLObK(ux$(Bpv>aPae_Us+T z-ll8nWO$3xf;j+R(gRxL%EB3}aGoa^s7$bynDN-!<9h8C{XVQD9&~0otKuWVTZvK*#0g{E z_eX}uE+Uz%ra&N&q*Uw~&y%r$`7WGmH&~<)w_U@~(R+O;7X`9%!QjjX9+5BwKbCy+ zxyGF{`-xxk%xmtz>ZKQ+YT)UPsvl9UrP2m74@&&zdC(Eve&TJW$Bf#uT&mV9+>txO zB0LjPd^Gwq29cfDxdYtj&e`MT`_tCx?cX+r`%>w%uT=5Cb6Ng%)`<=b>Y%e#Dsq4! z3fMh2MzW!7wRHcaR)h&guJ3hjyL6xuB;+s=?F(aZLKdater5R-rar{@?dn;EoofHM z6oNZDC7K6l6LzgKdy!LtYG&EK#vD%!S-g4f@yKsquGsA)5?R=5cdGS3gPz41?7E8| zg_&i3`~w}c)lQ%9^TxC+=Vj0yXl6qT*~w+KfK^*|*1NpSItZSySDV+~V=iw@-~D7C zGAAn?kL%}q`(*}%U4o4o$gb(jTT6w7@pwl$nGH`2DzFjLM%#{7$p;HTdD2dSDAIJ3X||96GCO&ekSFYk)(?i*O3Y1W4c$F=Dk(GaQ-^n?UU6Yb?IzyU1VT5$SOwPM3 z&bPv9`N#Zm>gj6%{W=(hq`zxm8pwzsCv+Sfhq&}l8uoueTz+PL}(1y}YEOgqgwRVf3 zWs|Mt{4{4+?O}yO__)k8Y+xfyu+We-jN!UAVokxmm7^C3cXfp_ZY}_5n-v4D4cgk0 zWx2!1Vw_rB_?xAIlgdTfB zub7+4(DNnn0^zwL9MS7x`zGS*@6&*vtw;rmggVCp;!3|ayBhtNALHx^+@N~(n$=}G z@rCx5p&s>PHem*X)|vg}uU|WK(i_In%V~8UWxnQx;%rXQkcV$8)!mBy#g%@}1sSCn z?IlwZ`B_y7sDb$i<;tI5fPU15KHY6^NEX;0L0UeHMY#2-#;JTuHC7`kNyyfzJ9WsH zZdte$L69|$jD<+mLh1)Xo#v!;%+FYy6nB5h;@5f49?Hw(Jtb@Ls^y`}_DnRiNjyw% z{H7c5&S9)|td|q1r!>U;lf`5dR!z1fC43LsC-%hS%NxruVh5cTdA|y>NhTKE-VqaV zh*^xe3-D4xd}cC31pU!E%D=BB2?eR|OSp#~k6PjWf*f%5(uq=FAbUaEtN*>xHb`ik zL3Y(J^|(k_agpJH^s2&*H2v{lN6#a~^XbCYm`S5|(8$)LCn;|{XRg$HpjHKJ*bBS; zQho0BMNZMhcfEcNpbp8@@-F97>)IlJwF~m%<1U7yWy^6RecCj6x;g zta$bgE_YLoQY$Z~t`5)XsX>LkuBL!ph!*OJM@>Lf)$QjT>L|v?Ze#fODJoBD2(?>s zrb_vVyIfal2XWV4^`r}m8WH&L7qmpZ2INJLzoD|OuXX@r2d5h0Y4t?ML6oXn%3=#r z8aru9IdZ8U1OTUrD~i$_Tgq8+Gn$K1mDMCwsC1whaXzEs=T9Z2l%=GUW<@womrU8X zVybM(fy%nIf;!@fIYwGUj=R}c4N5bfbCEnybComFcdJVGIvs`Z+@SxzLvd9 zM~)KJ{ZK!%%&YztUcIXuh+zLNSn}@1RLFF`q@|7`5tmhPu$8{eE366VsN-ooo11+3 zG;R5}%F8c>zqyCZVqYF#-(BqfsWsJlcKg28eew3~z;K;iolE%d#+}>6`^sLj(eX~A zhvQt-{)mgA?RrVt5IRNe$!xnD$ZqO)k@8kbst^2r#i4-k4G#ehw$wg1GgqTWLvD~M zv4=P@aRsvDK0e8dcn0eD?B~;`!jGxc*5+C6Q2&sMxZa1}(TgW%%!dV99h5hLAtk;BFM zXv3gffD9D~FIiQl7|(sD)r7r7mAecwXPx>4>@9VkbGr!q^3<`#9+VN7(}Iw zX7d-jfkkHav1&Qe>5GOaL@h@KPyX|4VNX4`0m7~uST<4e70uo!Zyi4;+Le=9L29=b zDAfEV<6E(ow%{hd!2Iua$Q;H8tLk$#*9_*;o(Q+HpmU?FU4(zRnw7Q@ol*oR0Q-s& zP{AQ}j-XZ(=$ZN4KS(uX_Xm)Z`lpORS$q&3pMt|$eVq!_$QYdH=oOAkxmHLSJmg=FKbz416bU@wOdd}?K?cS+KR zY%{Tt#lnx$2k*!EIm$z0CaYcOeOp0@jp4y~fTcpqyjO`EE7UXkj*WqQb%;*x_CAf3 zo|a6qwmoQ(fl|0N`aB6ORyubwP4->tcC6{iTb&rW)lt!`c>n5bmU_F$08@wgy1nQr zCKgtAVBqt(BuBP8Vp65O6*UQQUlpf^W){)Y<1$nMi_iwk)ejo)1DT(vjMzVq=nyBc zv9SiXZ5Qke<4=7OAJ}uEbF)>`(5ynbihOi^z(nmu@KbbeD!0olOI@gNtO+3{Ymp*g zcm5`K`)KZwb0U$!li50l4E46zRi9OV#;Xq2NopT0o*fXKTA90twH6$TfL-@|ipO4N z0V$M#;se(R1=D}9?Pi=mU8BS+geLnYPOndMDxeZko?ZtJ^x@{up=bP^aSZN@7hxYo0@{Fze!x>yz z3`H7(K{@PcT-~kF%Q-hs&Ej}F2|UyW(iEt2(jUsdRxU1yTn>M-?NrhfqGJ zojb0Put~^5!#l((W>2}&1vKpeKlv1MKae~yTWmE%2*jO?;G@AFUazj|QC9xG8_Deo z+ky-uiwloQvxBue!Wq3V;*Me{S$q4)0$fcWI+aY}nv>c!OE}pcmz#Qu{;A6R!{`cd zLqdD33U?sH7MWvY{XQf`tu7;X<)bR6hkg3Vc*;mu0&nMx$n#cL*`t~hmc&;ql^sNT zXonvrU^6(oj-&p~p6#W-C0Vb_VFvj;BSokUTzo;E`lY*<(`#MMS1?uKsDgBHuis@@ndQ=N#n=&O5-RcWrWV0eX0mNzZv)z*u@pRI85A& z+BQPUm+Dw%PSd$PFypc_6+uWHn2k(1o92$-T%-{&_k6l1Zmm=^!|Y5s|NLxCea-~L zaR>Iien_lTpxJP;w%u(bd?qlj6K;W3^8rGNRviB(7@4vng)B5D_R|LBgn_ z+b{#QGRYx>xk@O|v<@WjOIpdS3n_}`ne`~pLrXxcKjL{<@dxdieR8^;=<_zI@DFVq zh1}bE+O)i{Rkp{rCRjX=&PofYA~^oDn9%1lSWfRc~)J z%*Phekp@=-oD%q*+>4d5l9RQpS6})J`(dH6P&AA0p(9qJ`#@0{+S-7uwV;@{gS8}! zoeIPs(yKs5j`|jvWj}QL+*J{A|0o;V+)f@y;qs#3Rk$wbs->gEp!0O~tx)#Wd|S5r z>ZaasnS^n0$<;A+hP>oNV2*ZdPnHfCcTdM3As?Q9G9^{51g-O~eB6Fg$ur?IgWxXe z2!Q1|`Q1d^2-_iOSm*Cx?{D4_tbU8&a?ICyx)vAsCVL`8AIEau4NoW54FK<@-q3}Y zueEGzF%RV#2pAp4&HVwm5K0*5wT!iRAvA}od&EU$TFT1OdV6Rb-*vVTH0fTWbC=2D z!I#pux-kp#uVHx6dGAf!3Mvj<0xcnIo6(#0acB`K&Ka-HN+Qr3wX{w*x1!LKk;OJ5 zxdOX+>o4|;KcBy!t7MqLxs(B0cXVc?C?p8EKHh93P1(lutY z&AJ}(2Oyo`S;#-ga$)Nk%56M-QYPuKVdk_k;?CyJNR3$~T(Q$TP|?z{W<-p9%Nl1P zIU%6ipl?Y(g)!kdws0_LTjYpt>YF> zRM4cWo{#Xj(YBl_m{ic++U52Y3n;x;SxHOgluJsx>C_>4hD@B9$!%Xwnsl!^nlG3x zvc`2-sASu+ec9^DR{0AhNyEw@!C2J)SIu=sHMMQ)C<-bFQX@4K=?GG!h_q-xdT7!@ zQIR4=LqH@1V?)r;f)o)sp!6W16ai^Ukw}#yHHegmv;dJ}6!Go^^?1+w@!oiU?zm&@ zG1kmlbAR)j-&#AnW#%f0Q>|h3Iu*)xuls0!t|Q4!BA@l?*tMY)=n?rsA*)fd`AhIe$_IOZ8Ta(VxB;%w2v)EVV5qzBK!rFJ7X@5I88 z7h3l}8aImm0BQAnZ~?y$C&d7z82k@T92{7XzItJwcq(tAZr-l9Bj}CBtt)w>&mHTSq?c>}4H!?tsP4a=1BXe6zW>qoH(tzG7A2b7${SKDhqQ z;?X`^duMb1?38CN!y=r#+@qQc`I=?fcH$$llFu5--3yzeQO7+uX8wr zGCOnRCj-f5`lH$;77G=%Z}Ry$_~PVgW_7;!x&0L6L3za7JyzdSMFBz`c;>bNE*T>y zvMkKEygrDd3R4l^EtrLr7N`l8R1r37xzKL!+MHn z+@9Vkbxj5xV<%Zx_mHm>DKWBGq^N}v!#~+$ih2z-4kGaF(&YWpz>(Dg)zr1Oj?9BgFQ=OrC|x zfe24`=F8+pI8|sC+P}P;e_mN`*!g~tOlOR(r`ls?caj|{U|H@R6A#ynoso4s^Xfh} zxS=+0sp#9u8>@U-mt}W_BoM5uZ?tT2*4ZY&>0k9bZ;1h?f&;(}=Js}KZne%Q~SJ#@Rt)*>O6)URtkhx`+mbD(-QClQ2ezc}|!RTIC0Bfp6s({?bkmY$- zGp*1LZDf~}qEweJ^+8-_kMf4nmG)~a{u&#n{fHe|r;+C(_6lB>Qs;l5dNbvbXvd6( zY!2sZr2Cnn17#kmy#mA?A!O^wPjHFQfbf`E%|o8{+*KN~S!r+KWoM(>=2&)^lN}mW zr#TAd@?yOFa*7L&=t7E2|5{#XUXO$Fg^97>Z>BoIyx~Ja8`YWD1Z%UamsqsZN50yr zRz2t+%tQ0_y&N@)=4x^=>(>fNZ_94Gq^Q$~9eGqFIqWh_dE~FM>?4?FX5_tZ_gQ~$ z7!#UZQP04!^r^ODz^wI(AVNS6*}^ySxZ2}Vy|{64=i~Zak>>Z$vw6=mLH61z1YjyM z;U{31bVhC|Y`B1-#8R4|u&wT#eRW*1{Si1{j;GJvq~?HE4yFg06j{PySR^ZA%xrP8 zP78)nBV?HsEovN@=haUyia);3#(y^tYa~m`qyfo<4|Oj2^b6<~K<%?~Cjdvcr)|TJzQ@%z}?$scIxEuC;m&+EI zgjt5O`cx+2BW>057P+G+?l$}T9Mw=NB`AZ=`w4nz3wbeLr-keUbcF43kIPQ)pd+25 zhG$>L&)A;M^#9IR{$18{;v?sdTzwQ%ofiQm(l}n{ojbXE@3Q#F4wUzV)m!M@f~1zN zVt2#W*Q-K!y(za8h(jJ%+#72w_01AQUqS@So=&8l=Wwz)KT&?2EVOq-<~mApk5uM_ z$(dF0;V!l{PpzWGk6Cvs?oml%qA2nHP%O;6`>K*@IC{4G;!#dg`fL3ANUERoD}M*5;^Z5m6NLwtxfl$h5_ z_QWzuMA$c_$W)3bBhZVLDd%3z_B1@t>K#PYsYZn9fOf3yHp%&D=;5pa6s@FMFxn)b zRcI?90Hv&WKcIC5N?ALB>J?x|K1OSk$_lvC-JI3)>2C35z~6e%QPc?+?xk7;vjS}r zP~_t`Qb4d^4CfYT_0K>%fubObATL-M0r=dLE>l(}+i@?QzZa*c68*-pC!Md0@SsQH z&OofVRn^zK1>LZ;I|I?Ph99HnRP7{=#jj=|*KBO#$?jyn4rsm{u>cBO0Y&V}lzU9b zY0Dudd!7eMsPnsuq^8Ow=y6Omgn~xlS`5GvPzfL5I_)29MJ{n0+q76Hg^-IE42=$`bTbcUct^4 zVQXGMqb#>t(b%~~y_y>6coXGob;-)s%u0P3^g!LX@~)jSFe3xRep7t4>1kxbH{(i7 zEH%fMNhGYq)4Faa=ULC=xqk_dmns^B;bN0NSWF-_MRthCB??_%ZoMis)vFX3A*bd- z`)momO*0@u*g_@)bi{SxfhcDcwx5KCQFyH6)NWR1s3TlOw}{ou6~}z% zw{oX?=^u72_PJu$G(_-Wcg21=36eQPF-PeH=~N(WSb9$MFrpN%&J^%%I#<2Ta}Au^ zMCt{Wnh`)0c#?n;O4ny{xpf^zJOR|`hD<5~T3AsJH2cJse8t`T0gC!tkL%wKP3zPz zUZEgJ9GfR0!_wl~ZFDN!Utx=HlLQP%-D!$S2lPBJw@J>qRS=;6BqnS6Fe4|+S#TxP z)`tb93;eXe`1`#;+0i_`6|e~2o(vHKm;)l>NWasO06I5;&Wv6OvNT`;G=T9@K>BS> z{^*UO856Plv2@<+pBVXer|@3^bd6kQ$ojWc_kt_y6fkw<*RIkG)NOpFpOKXOZsqr~ z&)8%rs;ubAhH^|4Z=T%3Lu5m_x2-S_NyGS%V-IP_lshz2V#fZENohcBb7BTN-NKDB z*!R!0N7q`m1)ThXYT(q%wxOosb%mCif%Ge&{=jUkX;G(?c!A!lLckk&OJG@K0OtR6 z_|^OW8wXRf@bwH-&fgZe{BHvP`*c(Pb~x-=)If_ zi{T0``cF%EWjZpv5wcyHl(!+bp8#LN?aoy8_mQCX` zGpoN5+)zrkwHMpo8-EGg+&w@Iv@nq@~K{T=PdZy&ny@mmXd1kEpPz9Cox6S8SdDOv|gpN zw?<>}FPDPDJAf?4fyfNtD4O#d-IqT=dK%fTEr3)K*Wb^5OGW2Q)&D}~%Ke^54T?D& zJK|t|1SJ)Z9~?#9SSOlS&9a0QQqI42i=D?lYtMI@Ef?(46g*7v9{g)MW+4OQ_R!5? z+$Tg4crzDX*K|C8nn$OnD)wo80U{lnqE_!wrjAZ@EQk(#e#1~ZC-yatKj<;0R#+H9 znTZ~>Sutz?cXS52%NKSEmE;HJX8H%b3a?F4uhh3HRSUNeY^5lwB5I}N8{KT!reva@ zrQHF}kNL6#$yC>|S6&>SE4fr;fWK{{?1vaz)ht(LlSPdCwFpKggXrh!ob8AEA}%Zu zW2!tu-hyY>8%p29E2CAyLIX(5DyFIY6EW^Vu{uV(S@d7Ef)(Z-KwIbmzKO|DpKwRR^kGV}nEWDv@@M_ye@>``MX3CBz@I zM%7aYg-o~s*d7=<*i`^5rTC9|4}~Njk6SJoPz+bm{RP%O_;d9#R!&^Ih|w4Od9ZFO zL_tfCfpvcV&$VYnj+5AwU&CdX#U%^HY-6p_CtHYp!=BXsPDz5=gsI0+f!qPdjFX{D6>aS+DS z+=#%HC6K-ZIYfM$O&uCQfQF#y2WcG5nV7*Cm!UZlv3nUp0n1y!U~CQre3u(HlqsI_ z<9IIMB8FeUFRbAnx*ZI2@NFsHX(Wd3mo&UX>h2DjpIM>qf%1BY?a}{_ZU$WgtLA!c zebapv2fxI>iMsTvQ&a2M-Lu@Bk*MAA_v-yqH8UfYqe9fri7HO-5Vs`_NacVAfF z+IL+S4Qt#Twlwxu<)(8(i(Rbz6a1Jl$l%s%7uiAn&v8$5UD;g%?1MwoV34)-hH+)L zG%b5LSx0|lj7joIl6s2!_R%!@4W}pfqPFKTwxnWuKL`pX^?JY@mMiqG7+~MAG8qH=Fd@e}GJXfIg>&&QvyTj=2p` c2Ar{y=Hq>fA@R4AjAWn(uKgdjn?HvC1>mtlegFUf literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/banner_orange.jpg b/js/common/test-data/modules/commonjs/docs/images/banner_orange.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd95ae0fe3634f8ed3d6fdd1fe4256b5d12af077 GIT binary patch literal 14994 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 I%KhyB0?}Y-T>t<8 literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/content-wrapper_bg.png b/js/common/test-data/modules/commonjs/docs/images/content-wrapper_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..fc7451b0fbf55f673516e866c9620380c8750ee3 GIT binary patch literal 985 zcmZ`&e@GKy7`_rDWI~ZCCm2FV7Gc5>Y|RmdKbqk%OO$BU)OA=mfA7;aCl!sNA%uU3 za5Ly1!J$wDK{vNTU9H6p`az^@L!Dgec855)<{*3T=1L_0`tIKEeV^xfpZEP9*Jvs; zGjcO949iqsD656DAH(*|9@r0GH8Ncg4!pa(q5E>%t!||2)MKU1ZH@YTb*qll*Xni6 zeH~tX35KPa)McetdgmhFOULJnv#giYy}r3uIl6-UgPL^DgP*z2H!`c*l!>*YiRG(z zs!p)is#+%U-Y>}H7e60vnzT$Vd_Vxk$6Wy#itp z&g5A!S&5f)K#xL%i=4q}9~X3J_&VkTXB-yBh4F|1(LU2RQyujJ@~2i~*OzS(2DzRP z#^FFzgfj|VLtp&WaQ}-z9Ug8`8JflEwMM~w8w*qYcY}&1^w8oKLdrCaUkMUi8`_=8 ziepTB#a;m`p@CZ?D`BRzJtC+>qUU*GYW*~;4LT&RlM@o_ zM|$kI`)nE$T|3PTL@Cs1<$ar+)J9U=P|6_*l1h>QsW& zIE=VUZ1b-;7y^`yY#}T5Zj7}P#+*>RXor^(my@43Lw;JBTAlicegyp08bA=Y%z)y9 zu{`fK@~pHwP|WNOz%to+sfeYAc3NZkcwMx?ivP31u`6eSbKo=&DJemZ!Z+Hu6KB@ zYtt^*s9nIYhjGgm5lKeQ?I`MdhO`eV|VYyW*bQSIRkWIL(s)5 zkIQ!dUHsy?>z^t7KX%cCg6 z^X2;W>jkByQ)}z$!rEJH&Nok&0oq-sJ!{vir=J9^t@`e6T+MH5&-ZldwR4K?^P=Sh zviDn*RImMUqlgcvu-a^I&9?=6d*AGs6W(?>(V{4#vUY1!{r{B8EpD*pT3qJ6e0J7e1R&SwEy$euidS3mRdpm_~SBpNsulxM@nU6rRf|rSP zeZ}?BpycqO|L@gmkgFU13p}4z3>5K@86x!K=?u&a6Dz+T`}X|WAE3h-JYD@<);T3K F0RV0#R&@XX literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/explosion.jpg b/js/common/test-data/modules/commonjs/docs/images/explosion.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d85bccdfd5253e4c4f0bd0423331bd03a154d1e2 GIT binary patch literal 27839 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%0AmB`(= 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 A7ytkO literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/header_gradient.jpg b/js/common/test-data/modules/commonjs/docs/images/header_gradient.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3202c3802d81a9da4b011ee844bb0712bb84dad8 GIT binary patch literal 3178 zcmd5+e{5S<6+ZX*y_dvxlV|(Q`L!(mqht}#W|1oXNYms!36vPv~hY2B8o zDuk%3TKZm8X%-vQkp1BxrF|OFQV9)IwW9^GHQP+938`HZU~Q3Tn=(Nlg>-9CCbF9E zTqo|7f;1%l;M%_L_?~<2{mys3^NN>?*U3n1j&CNR5N*SUit`lu{I>>oKTCpCBI?A_ z->BN&wkQ2H+BSt1QT#m}CS6rkP1Q9`uhQ`gRO)(VAn5l8{QjU3l*0&C*BCX`!AQh3 zBaw$28yg>PE)P*rQL!etrp_?x8XgKg)KGSOQlmIUp-S5A`?XJmNC^pFNE8dSm4p!F z1I+Reichb=;;LZ?QiK9W*(E|@#rOTM{2=m#YF_&4lV1)!5L3KLK_B8mz7TcO?e8d# z*Xrjf8jJG0!L^cRpux@r?Y&wd>Sk(ejLd4vth!Sx)EZmty*{HA zu6Ca>a8JB2GONd)S_tmAr@%<--BX`g)D96}aMr>4At#OHsuzj`hqTJFIk7wk4Jyc|4a;+;+84UkKW*VYVVhYj|iRX={KB8S-_1th3JNnbGa?{V9z>b7C8>~tdAw7X>l@^H-JFo?SozLYlUFS z?+la)l2??cgwyV{tDHCzU{sEmfNi%cLnBDwMLjk;0i-ZTCn83Cx~c;%WH64jl56Kw zhMGbU2d<>x{$k~_{%K8E=|I-hlykWOq%^qX~@Z}N>*h-H`AU*4LE@pSzMzN z^#%V*Ucgs1U4?V8V|6iDN={Z|DP{3tjU0EFc(32-pI(y&W=vT#V4aw#MKgGQ-UF?{ zC`kQ4N8DOv={#t;&=QIOO{w0eg*4d!X&_ih){UftXu5RpLN4wkR4?wto$c7J=JCP7 zYMv`t7LtkAglUqnC`!6(X<7XxVW&l=AxqI%gG@qXqApelPsdB5gZa(EAUT$31+4tT z9pzQ!M2&d}vDjD^PO=RFDCZjP$g{1(D85PGFfRhAq z`b#8nrG=fro5y7+X4KI<>?e@TIJk}ZZ)tFTuz-f&>Eu@xS4b%Q4#3^=b|qC0imW(; z%5Ap+A#70?cuJ#zC`p>ruK@$D_h?rv8Z(zkLD@7f2^fA&^RQoJ{2CtK0H#&LOJD)a z8+iCt)ng#2OF~^HM6}?OTMIgJR$R@+f!HG5DxHGM311DRL19uRD#DcPLTQ*D+y?|+ zQeF#2h?dJ!ivHNl^&rr|OP+=M1$l{5Ikt;2uz=#&YrzX@0t9h`@NZ2gqPJ`ZgmB zJT@sdftb=MD7=)0Cywi0B?v)V-LDEk8IT1R1B&pHGUh&-(h- z!n%~&0FW`o9@8!0fINxnu@5JwOp2M*uW=Q)Q_$U-tOnEKnP9?8;^GnyG6WpR=c;L0 znY2O$tHHAb%Rsitn3`iW_LwSVQI_WL-=CW9LB7e_cE^G}YYwQ+A#0I)4PN%a?D@%{dzzAKA3&v5LXL^OJ|gfFs9_Z*8T&NlS z?ZThuj!bp+J@wXU=;pxD$>;XG+)axg_376hhnBmac;ocUDSr z1<%~X^wgl##FWaylc_d9MH@U_978H@y}9DZ%b>u+;@J0K>HlBi$E9Ti(o}uc`Ihs~ zU8^FpPK`+;U_r%}X-uqKBK_Bb7C3wiPSFgQ)4$ZA@zL@KE)k8oE+A9M{wPqY@zKR7 zph$pCly{>NP@6*|NEd|RikHjUg`$}C)cduo7A0uH^}OH4D#5_%z$BWtqvZn7?F^o- KelF{r5}E+^VpSUe literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/logo.png b/js/common/test-data/modules/commonjs/docs/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..90b43b4693c785e87c9ba927aa32ade5ba3b9d7e GIT binary patch literal 1543 zcmV+i2Kf1jP)P=GVG_O_9ux!#CkB;bIiv|w#($-R1)Ql zXrm9rn8@RaJ2A(20HK4u#t%<>Ca3U&&v{P}NsLJT`K7oX00^BNs0suWsvAO{N zYCjdfvj&xTtpu*x$kJ61bLv`^UzjS5xmr0sr@jnC=biMuC!|9EQ^$7PBQYrLMn6a< zhR-S0mU5iqBkzGsP87+KE9ByjOFh4 zH`j&I_DPrvZx@mjUN@Yh#~=*{O7I{&c@C7?e$qg`Zvoppl)emH=iYtq5Vq;vx~|qe zDM6%S=b~L{%2b}a_86!>F!;U%qH|~8I|h|VnLL(vA>*+<$RP?@@f^AysN@6&IrzQ= zrgK-{JA<5VRZJ3_7l}?r5WbTgs*FU5hkU9pkBLF{B|x3`c4Luo#>O$#dN`#Au?-Xj zQ-90jFY%gUGrHvuNrR>5fKgUr<{`gs`#I#k1g7)8pF3JwK8vLnv6jUjGtFztAke&U zp=2~RoI{U&WYBAcrRy18067v|?fXsT7H3pMnb#nRnr zH0i!Zb@Z;gnkKJbSlU+S(w9(legdRz1NM+hO)B&S-_z5Jv<}!&iv?T?vNi!b2m)LL zIL1gF0ecLB0GCXX+z}f+fFQu7!>vn$fZdE31OX7RV`W7EumTpX`l;Q#U%0YO4W$hVk%n3 z9W``$;eR@ z^UPt)jqQ&;$|1VgP@UF@6-!DIGwXGx4rg4Grih_ z7q4zZ_=3;YUTMb0wI5vp?P( t$BEr;_s4s@-GQnLB3otJv+#cb1^^+B`$K4Zp~3(F002ovPDHLkV1jK_*XjTO literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/nav_browsers.png b/js/common/test-data/modules/commonjs/docs/images/nav_browsers.png new file mode 100644 index 0000000000000000000000000000000000000000..a3e8bc0bff8aa587ca61a3d2992742a83f43800d GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^Wk4Ln!3HE7XDJv0DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MQc1=978H@y}9hj%b*~@?5L38q;~GYmCXm5#b-{v;8{Is z*?%cD2JH<@K*W8GC4n^zgbvPPSaX02h;$-^8$=@-frvGm39LwaLxL{@SP`q(8cwjH zH3ynZ8NrG~BQ_9Y*j@AUafZ#uK^6e@g3Y&G&mzH)e~-=hM=;lPpt~77UHx3vIVCg! E049o71^@s6 literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/nav_browsers_on.png b/js/common/test-data/modules/commonjs/docs/images/nav_browsers_on.png new file mode 100644 index 0000000000000000000000000000000000000000..30bf37cd2172437c75f7689b48afa35faf2d865f GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^Wk4Ln!3HE7XDJv0DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_cg42*`JE{-7;x8B@6$a%Ch^V^VvfMVDg08;d@5!;~)DZpHp6ua`$BXkJS{+L?6wVni?N zMg_4WNynac!kBG09C`AN8UW#ih>SJIx*U@iZoCjt6PIIsWLDCQqzoMsF)8mg$Fe|l zw|+fVcnmF5*R!e W^UHpiwci97!VI3SelF{r5}E)wdztb8 literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/nav_commonjs.png b/js/common/test-data/modules/commonjs/docs/images/nav_commonjs.png new file mode 100644 index 0000000000000000000000000000000000000000..9daddb62c4aa026aebdbad1c85f77c7fa2a27adb GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^Wk4Ln!3HE7XDJv0DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MXNkr978H@y}9Vf%b>u+VCZJhpDSr z1<%~X^wgl##FWaylc_cg42(>kE{-7;x8B@6y|&pwfHiQIe_e`$jLQRy6Ae7EY6W7~ z_8T`1XCy(O#jkWTWc6saX|iop5Ia&OS}m$Ab_8fl_qyYg>mMwQ*yFh- z$=A>a41s3ZuUHbXBY9%n8qKofP8&T`=h^*{SuO09a{nCA_)oKx*R)Hjf%S7IIqCpS dd>O;U!!V|6H_V+Po~-c75RC(IEGZ*O8W8tzdf@sv%mx=gNI5p0wY}nbXMr(#3*ru zeLB){wQc@^msKk3jrRQc^4MP3SXkMhM8eULCCSj3iPO!^fLn#_p;IISBOAlYEgYrg TlX`CgO=j?P^>bP0l+XkKwXZeV literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/nav_js.png b/js/common/test-data/modules/commonjs/docs/images/nav_js.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab2cbb60df5971689f33ced64f552b847204de5 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^Wk4Ln!3HE7XDJv0DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MUOpQ978H@y}9bh*^(gA8fe;BHiOAcVnb7+PlALthuek* z*<)FzKSb<1v4d(%_H6YYv${5io3PKyy7_>Jq z0TK5#7O2tZB7_^jiW*t7nZSy)HzfEHGVE9R&zX-)CBFUMlzX^_zisVr z!=Dwu{*>K#A9VEM<}2lMch*N2U%$im`t;|1sNrA-?Aqtsz{oJUUQ$q;U!?`;T?S8A KKbLh*2~7azD0CD6 literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/nav_js_on.png b/js/common/test-data/modules/commonjs/docs/images/nav_js_on.png new file mode 100644 index 0000000000000000000000000000000000000000..668c2adeeca9037cbc41e1d8e22e6728b7fc0a0f GIT binary patch literal 434 zcmeAS@N?(olHy`uVBq!ia0vp^Wk4Ln!3HE7XDJv0DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_cg42&V3E{-7;x8B_K^*S8D;QCOl@~5+aqks%Y6Z65w1<@B= zUviZM?qZF-WXvqfr5VvQ{k_A2DHjgf?%mEGl@XkMSFykCM!?3?SGyDg-Z%+5FT3H$ z)0lL7+uS1)G{1QOnY-6nivdN24OzN$m(J-@41P0Hg6ZhD+Iqbpe-iYJzJ8A%g7a}s& z9P4sSUbyi>#Gk!4o+@1vIV|D~<|dhjfoU0sH|PA5eGGjJfu<;2TX|z;M6#m}$i&wl zu5>ykf9yY!wMMfI0*_^_*)MrD;z!TXXT7FJ?SKZ{nDXr1)7-CT<^B23o`3xN`uAVA zi?idi=l{O^qo&Sg$BkEi=eA3#i5+Q*5a3R7)B(D0_Gi@t3_3@oA6bU^%K{^T!PC{x JWt~$(696r9zc2s* literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/news_bg-btm.png b/js/common/test-data/modules/commonjs/docs/images/news_bg-btm.png new file mode 100644 index 0000000000000000000000000000000000000000..14ccb2a6dee7ea6a5d82cb6cdd181035f42c5b79 GIT binary patch literal 2203 zcmeAS@N?(olHy`uVBq!ia0vp^w;33iTR7N&ERD@B|ACZbiEBhjaDG}zd16s2gJVj5 zQmTSyZen_BP-_d#Mo+YN^t1v3y9nC;Gx z#JrIah#PM(K(Rwk15g17Lll7(N&^*xaR;w}Gz1@E>)?gpB<3S*5DYeI)VLuMcB9ch zqSN|l^p8eAO$z^myQTQ*>?=(!TqzNWt}we0G9#xTDM!)lM7;9hl;&H;vu`LEZWE9O zik7x-pU8inZB`YJwf2(R9vU&qzGek!&DBT5)TE!xySeRPC$CTvcecus?#1R?ea$o? zl#j9{HJ`qe))oH;q`{wW%7oAGt?+Y_IG!C~<$XUR#n&g>^u pAYU9$>ur(AQ(maGEuN8$LFE38iB}#8Cjna<44$rjF6*2UngC{C2(kbG literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/images/news_bg-top.png b/js/common/test-data/modules/commonjs/docs/images/news_bg-top.png new file mode 100644 index 0000000000000000000000000000000000000000..3aeed16ca925bbcc38dfd1b6617819fd67ea3bf1 GIT binary patch literal 970 zcmV;*12z1KP)SxTi+82t?N|r^mPcXn3Y!wq}zxYu0f7+}vDrff~%Ybbfx`6bc1dSy^d#bA5f?q*5tk zkBxhvp>?CSy}hmGGn<>6E{wuICYu^;WMrgaGIgoC)lJ{s-4%Nyv$M0)aIQTM(&_Y7 z&7h%mnHJhaGnq_AtWWCK%+{Q2S~5CQ=}?mm3=D{MuDhA2v69JTu)n{rH`C!A9UTRg zO2yb?;~%l-1`Vytw6I#Oiq&+~t9_3jY6Cz!Wu$Xo zwOaLqAdu73)9CZU!omlP2GD^rQn&e=A66e69EdSSPEJnzsi~>l;NYN^j>hd)0zmsc zTeSPA&j)O>nX|JqzgR5(vXfr0Q~>QGP22p@u;rtipP$Rj%*;m-dCL+3bTHZW_V!$j z7#Yo`nr@POb&~*~LuQL#Gl{fXt>%x7jTLO)_L?OE=$zT4TrRh~2YGREA^Cj1$npSm zmMGbDyWbhEUa$Mp`PHh|8WO;`p1k`3T#n@x8kF&hBM2Jp1Z=Dq}gM@TjR zz-$2jrP&0t0noDnP(}j4{lRPiBpU!d8vy);+1QN)po|2dj06D6NPvGAk_~{K4WJ9k sNC0@GGLmEiAlU#&HUPLi*?tQ!0Gi3XDbsrI7ytkO07*qoM6N<$f{%yT-T(jq literal 0 HcmV?d00001 diff --git a/js/common/test-data/modules/commonjs/docs/impl/flusspferd.html.markdown b/js/common/test-data/modules/commonjs/docs/impl/flusspferd.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/impl/gpsee.html.markdown b/js/common/test-data/modules/commonjs/docs/impl/gpsee.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/impl/helma.html.markdown b/js/common/test-data/modules/commonjs/docs/impl/helma.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/impl/index.html.markdown b/js/common/test-data/modules/commonjs/docs/impl/index.html.markdown new file mode 100644 index 0000000000..45ce4e7476 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/impl/index.html.markdown @@ -0,0 +1,10 @@ +--- +layout: default +Title: Get CommonJS +--- + +Getting CommonJS +================ + +There are several implementations of the CommonJS standard, and you can choose the one that fits what you're trying to do. + diff --git a/js/common/test-data/modules/commonjs/docs/impl/narwhal.html.markdown b/js/common/test-data/modules/commonjs/docs/impl/narwhal.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/impl/persevere.html.markdown b/js/common/test-data/modules/commonjs/docs/impl/persevere.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/impl/v8cgi.html.markdown b/js/common/test-data/modules/commonjs/docs/impl/v8cgi.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/index.html.markdown b/js/common/test-data/modules/commonjs/docs/index.html.markdown new file mode 100644 index 0000000000..301b785eca --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/index.html.markdown @@ -0,0 +1,45 @@ +--- +layout: default +title: CommonJS API +--- + +CommonJS +======== + +JavaScript is a powerful object oriented language with some of the fastest dynamic language interpreters around. The official JavaScript specification defines APIs for some objects that are useful for building browser-based applications. However, the spec does not define a standard library that is useful for building a broader range of applications. + +The CommonJS API will fill that gap by defining APIs that handle many common application needs, ultimately providing a standard library as rich as those of Python, Ruby and Java. The intention is that an application developer will be able to write an application using the CommonJS APIs and then run that application across different JavaScript interpreters and host environments. With CommonJS-compliant systems, you can use JavaScript to write: + +* Server-side JavaScript applications +* Command line tools +* Desktop GUI-based applications +* Hybrid applications (Titanium, Adobe AIR) + +Read an [additional introduction by Kris Kowal at Ars Technica](http://arstechnica.com/web/news/2009/12/commonjs-effort-sets-javascript-on-path-for-world-domination.ars). + +Current version: [0.1](specs/0.1.html) +In development: [0.5](specs/0.5.html) + +Implementations +--------------- + + + + + + + + + + + + + + +
ProjectAPI VersionInterpreter
Narwhal0.1+Rhino, Mozilla
v8cgi0.1+v8
Helma0.1+Rhino
Persevere0.1+Rhino
GPSEE0.1+SpiderMonkey
Flusspferd0.1+SpiderMonkey
MonkeyScript0.0Rhino
+ +More information about CommonJS +------------------------------- + +* [Group Process](process.html) +* [Project History](history.html) diff --git a/js/common/test-data/modules/commonjs/docs/interp/jsc.html.markdown b/js/common/test-data/modules/commonjs/docs/interp/jsc.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/interp/mozilla.html.markdown b/js/common/test-data/modules/commonjs/docs/interp/mozilla.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/interp/rhino.html.markdown b/js/common/test-data/modules/commonjs/docs/interp/rhino.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/interp/spidermonkey.html.markdown b/js/common/test-data/modules/commonjs/docs/interp/spidermonkey.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/interp/v8.html.markdown b/js/common/test-data/modules/commonjs/docs/interp/v8.html.markdown new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/docs/license.html.markdown b/js/common/test-data/modules/commonjs/docs/license.html.markdown new file mode 100644 index 0000000000..8c42f773fa --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/license.html.markdown @@ -0,0 +1,32 @@ +--- +layout: default +title: License +--- + +CommonJS Documentation and Code License +======================================= + +The output of the CommonJS group is protected under copyright laws, but is intended for the good of the JavaScript development community. CommonJS related projects are licensed under whatever terms the author(s) wish to apply, but the CommonJS specifications and test suites are all licensed under the MIT-style license presented below. + +Copyright 2009 Kevin Dangoor and many
CommonJS contributors + +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/js/common/test-data/modules/commonjs/docs/process.html.markdown b/js/common/test-data/modules/commonjs/docs/process.html.markdown new file mode 100644 index 0000000000..e7bfef0860 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/process.html.markdown @@ -0,0 +1,34 @@ +--- +layout: default +title: CommonJS Process +--- + +CommonJS Process +================ + +The CommonJS group has, to date, operated in an informal manner. Our goal is to make meaningful progress toward these goals: + +1. Design reasonable APIs for common application needs +2. Document those designs +3. Implement those designs in different interpreters and environments + +The process followed through the development of CommonJS 0.5 has been: + +1. Discussion of an API area is started on the mailing list +2. A page is created [on the wiki][wiki] to collect proposals and prior art +3. Further discussion and iteration on the proposals +4. A rough consensus is reached +5. The proposal graduates from the wiki to this website + +So far, achieving rough consensus among the group has been a successful route to meeting these goals. Everyone involved has interoperability on their mind and interop necessarily involves compromise and minimal [bikeshedding][]. + +As applications built upon the CommonJS APIs start appearing, we will likely need more process to handle changes to the API. + +Further reading +--------------- + +For an interesting take on API design from a highly regarded master, take a look at [this tech talk by Josh Bloch][bloch]. + +[wiki]: http://wiki.commonjs.org/ "CommonJS Wiki" +[bikeshedding]: http://en.wikipedia.org/wiki/Parkinson%27s_Law_of_Triviality "Parkinson's Law of Triviality" +[bloch]: http://www.youtube.com/watch?v=aAb7hSCtvGw "Josh Bloch on API design" \ No newline at end of file diff --git a/js/common/test-data/modules/commonjs/docs/specs/0.1.html.markdown b/js/common/test-data/modules/commonjs/docs/specs/0.1.html.markdown new file mode 100644 index 0000000000..b93e596092 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/specs/0.1.html.markdown @@ -0,0 +1,13 @@ +--- +layout: default +title: CommonJS API 0.1 +--- + +CommonJS API 0.1 +================ + +As an initial step to allowing code re-use between JavaScript interpreters and libraries, we have defined a common module format: + +* [Modules 1.0](modules/1.0.html) + +This format has gained broad acceptance in the community and had several implementations which were demonstrated at JSConf 2009 in Washington DC. diff --git a/js/common/test-data/modules/commonjs/docs/specs/0.5.html.markdown b/js/common/test-data/modules/commonjs/docs/specs/0.5.html.markdown new file mode 100644 index 0000000000..c492146246 --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/specs/0.5.html.markdown @@ -0,0 +1,21 @@ +--- +layout: default +title: CommonJS API 0.5 +--- + +CommonJS API 0.5 +================ + +CommonJS 0.5 is currently being developed. It will enable a much broader range of applications to be developed an run seamlessly in different environments. + +Here are the current specifications and discussions for 0.5: + +* [Modules 1.0](modules/1.0.html) +* [Binary Data Type](http://wiki.commonjs.org/wiki/Binary) +* [Encodings](http://wiki.commonjs.org/wiki/Encodings) +* [I/O Streams](http://wiki.commonjs.org/wiki/IO) +* [Filesystem](http://wiki.commonjs.org/wiki/Filesystem) +* [System interface](http://wiki.commonjs.org/wiki/System) +* [Unit Testing](http://wiki.commonjs.org/wiki/Unit_Testing) +* [Sockets](http://wiki.commonjs.org/wiki/Sockets) + diff --git a/js/common/test-data/modules/commonjs/docs/specs/modules/1.0.html.markdown b/js/common/test-data/modules/commonjs/docs/specs/modules/1.0.html.markdown new file mode 100644 index 0000000000..277de3bd0f --- /dev/null +++ b/js/common/test-data/modules/commonjs/docs/specs/modules/1.0.html.markdown @@ -0,0 +1,74 @@ +--- +layout: default +title: CommonJS Modules 1.0 +--- + +CommonJS Modules +================ + +This specification addresses how modules should be written in order to be interoperable among a class of module systems that can be both client and server side, secure or insecure, implemented today or supported by future systems with syntax extensions. These modules are offered privacy of their top scope, facility for importing singleton objects from other modules, and exporting their own API. By implication, this specification defines the minimum features that a module system must provide in order to support interoperable modules. + +Contract +-------- + +### Module Context ### + +1. In a module, there is a free variable "require", that is a function. + 1. The "require" function accepts a module identifier. + 2. "require" returns the exported API of the foreign module. + 3. If there is a dependency cycle, the foreign module may not have finished executing at the time it is required by one of its transitive dependencies; in this case, the object returned by "require" must contain at least the exports that the foreign module has prepared before the call to require that led to the current module's execution. + 4. If the requested module cannot be returned, "require" must throw an error. +2. In a module, there is a free variable called "exports", that is an object that the module may add its API to as it executes. +3. modules must use the "exports" object as the only means of exporting. + +### Module Identifiers ### + +1. A module identifier is a String of "terms" delimited by forward slashes. +2. A term must be a camelCase identifier, ".", or "..". +3. Module identifiers may not have file-name extensions like ".js". +4. Module identifiers may be "relative" or "top-level". A module identifier is "relative" if the first term is "." or "..". +5. Top-level identifiers are resolved off the conceptual module name space root. +6. Relative identifiers are resolved relative to the identifier of the module in which "require" is written and called. + +### Unspecified ### + +This specification leaves the following important points of interoperability unspecified: + +1. Whether modules are stored with a database, file system, or factory functions, or are interchangeable with link libraries. +2. Whether a PATH is supported by the module loader for resolving module identifiers. + +Sample Code +----------- + +*math.js:* + + :::js + exports.add = function() { + var sum = arguments[0]; + for (var i=1; i < arguments.length; i++) { + sum += arguments[i]; + } + return sum; + }; + +*increment.js:* + + :::js + var add = require('math').add; + + exports.increment = function(val) { + return add(val, 1); + }; + +*program.js:* + + :::js + var inc = require('increment').increment; + var a = 1; + inc(a); // 2 + +Related Documents +----------------- + +* Proposal to ECMA TC39: [Module System for ES-Harmony](http://docs.google.com/Doc?id=dfgxb7gk_34gpk37z9v&hl=en) +* Presentation to ECMA TC39: [Modules](http://docs.google.com/Presentation?docid=dcd8d5dk_0cs639jg8&hl=en) diff --git a/js/common/test-data/modules/commonjs/pavement.py b/js/common/test-data/modules/commonjs/pavement.py new file mode 100644 index 0000000000..83b45ef495 --- /dev/null +++ b/js/common/test-data/modules/commonjs/pavement.py @@ -0,0 +1,34 @@ +import sys + +from paver.easy import * +import paver.virtual + +options( + virtualenv=Bunch( + packages_to_install=['pip'], + paver_command_line="initial" + ) +) + +@task +def initial(): + """Initial setup help.""" + venv_command = "Scripts/activate.bat" if sys.platform == 'win32' \ + else "source bin/activate" + + print """This is the source for the CommonJS website. + +You can build the website, by running these two commands (the +result will be in _site): + +%s +paver build +""" % (venv_command) + +@task +def build(options): + """Builds the documentation.""" + if not path("src/growl").exists(): + sh("pip install -r requirements.txt") + sh("growl.py . ../_site", cwd="docs") + \ No newline at end of file diff --git a/js/common/test-data/modules/commonjs/requirements.txt b/js/common/test-data/modules/commonjs/requirements.txt new file mode 100644 index 0000000000..277c859580 --- /dev/null +++ b/js/common/test-data/modules/commonjs/requirements.txt @@ -0,0 +1,4 @@ +-e git://github.com/dangoor/growl.git#egg=growl +PyYAML +Jinja2 +Markdown \ No newline at end of file diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/b.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/b.js new file mode 100644 index 0000000000..da5bf4fd18 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/b.js @@ -0,0 +1 @@ +exports.foo = function() {}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/program.js new file mode 100644 index 0000000000..7980ecf143 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/program.js @@ -0,0 +1,5 @@ +var test = require('test'); +var a = require('submodule/a'); +var b = require('b'); +test.assert(a.foo().foo === b.foo, 'require works with absolute identifiers'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/submodule/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/submodule/a.js new file mode 100644 index 0000000000..bc138b87da --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/submodule/a.js @@ -0,0 +1,3 @@ +exports.foo = function () { + return require('b'); +}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/absolute/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/a.js new file mode 100644 index 0000000000..e0188fa08c --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/a.js @@ -0,0 +1,4 @@ +exports.a = function () { + return b; +}; +var b = require('b'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/b.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/b.js new file mode 100644 index 0000000000..873a305776 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/b.js @@ -0,0 +1,4 @@ +var a = require('a'); +exports.b = function () { + return a; +}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/program.js new file mode 100644 index 0000000000..2ee4758dbe --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/program.js @@ -0,0 +1,10 @@ +var test = require('test'); +var a = require('a'); +var b = require('b'); + +test.assert(a.a, 'a exists'); +test.assert(b.b, 'b exists') +test.assert(a.a().b === b.b, 'a gets b'); +test.assert(b.b().a === a.a, 'b gets a'); + +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/cyclic/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/program.js new file mode 100644 index 0000000000..7c0e50b0b1 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/program.js @@ -0,0 +1,3 @@ +var test = require('test'); +require('submodule/a'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/a.js new file mode 100644 index 0000000000..215ea1d9a7 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/a.js @@ -0,0 +1,9 @@ +var test = require('test'); +var pass = false; +var test = require('test'); +try { + require('a'); +} catch (exception) { + pass = true; +} +test.assert(pass, 'require does not fall back to relative modules when absolutes are not available.') diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/b.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/b.js new file mode 100644 index 0000000000..139597f9cb --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/submodule/b.js @@ -0,0 +1,2 @@ + + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/determinism/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/a.js new file mode 100644 index 0000000000..99c929e44f --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/a.js @@ -0,0 +1,3 @@ +exports.program = function () { + return require('program'); +}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/program.js new file mode 100644 index 0000000000..e82bd6db2c --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/program.js @@ -0,0 +1,4 @@ +var test = require('test'); +var a = require('a'); +test.assert(a.program() === exports, 'exact exports'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/exactExports/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/hasOwnProperty.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/hasOwnProperty.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/program.js new file mode 100644 index 0000000000..1653f1b863 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/program.js @@ -0,0 +1,4 @@ +var hasOwnProperty = require('hasOwnProperty'); +var toString = require('toString'); +var test = require('test'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/toString.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/hasOwnProperty/toString.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/method/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/method/a.js new file mode 100644 index 0000000000..69c48af67a --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/method/a.js @@ -0,0 +1,12 @@ +exports.foo = function () { + return this; +}; +exports.set = function (x) { + this.x = x; +}; +exports.get = function () { + return this.x; +}; +exports.getClosed = function () { + return exports.x; +}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/method/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/method/program.js new file mode 100644 index 0000000000..192811c5a7 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/method/program.js @@ -0,0 +1,8 @@ +var test = require('test'); +var a = require('a'); +var foo = a.foo; +test.assert(a.foo() == a, 'calling a module member'); +test.assert(foo() == (function (){return this})(), 'members not implicitly bound'); +a.set(10); +test.assert(a.get() == 10, 'get and set') +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/method/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/method/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/method/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/missing/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/missing/program.js new file mode 100644 index 0000000000..c6b03aa28f --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/missing/program.js @@ -0,0 +1,8 @@ +var test = require('test'); +try { + require('bogus'); + test.print('FAIL require throws error when module missing', 'fail'); +} catch (exception) { + test.print('PASS require throws error when module missing', 'pass'); +} +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/missing/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/missing/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/missing/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/a.js new file mode 100644 index 0000000000..a949e1dcf5 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/a.js @@ -0,0 +1 @@ +require('program').monkey = 10; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/program.js new file mode 100644 index 0000000000..42d67112ee --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/program.js @@ -0,0 +1,4 @@ +var a = require('a'); +var test = require('test'); +test.assert(exports.monkey == 10, 'monkeys permitted'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/monkeys/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/a/b/c/d.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/a/b/c/d.js new file mode 100644 index 0000000000..69fd282283 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/a/b/c/d.js @@ -0,0 +1,3 @@ +exports.foo = function () { + return 1; +}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/program.js new file mode 100644 index 0000000000..c014b57277 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/program.js @@ -0,0 +1,3 @@ +var test = require('test'); +test.assert(require('a/b/c/d').foo() == 1, 'nested module identifier'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/nested/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/program.js new file mode 100644 index 0000000000..b3e4b6ed7c --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/program.js @@ -0,0 +1,5 @@ +var test = require('test'); +var a = require('submodule/a'); +var b = require('submodule/b'); +test.assert(a.foo == b.foo, 'a and b share foo through a relative require'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/a.js new file mode 100644 index 0000000000..42e4ca0864 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/a.js @@ -0,0 +1 @@ +exports.foo = require('./b').foo; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/b.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/b.js new file mode 100644 index 0000000000..9042c16b5a --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/submodule/b.js @@ -0,0 +1,2 @@ +exports.foo = function () { +}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/relative/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/a.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/a.js new file mode 100644 index 0000000000..4df7bb8d26 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/a.js @@ -0,0 +1 @@ +exports.foo = require('b').foo; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/b.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/b.js new file mode 100644 index 0000000000..30ea70dd17 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/b.js @@ -0,0 +1 @@ +exports.foo = require('c').foo; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/c.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/c.js new file mode 100644 index 0000000000..69fd282283 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/c.js @@ -0,0 +1,3 @@ +exports.foo = function () { + return 1; +}; diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/program.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/program.js new file mode 100644 index 0000000000..98bb996445 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/program.js @@ -0,0 +1,3 @@ +var test = require('test'); +test.assert(require('a').foo() == 1, 'transitive'); +test.print('DONE', 'info'); diff --git a/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/test.js b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/test.js new file mode 100644 index 0000000000..5d0984eec8 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/modules/1.0/transitive/test.js @@ -0,0 +1,15 @@ + +exports.print = typeof print !== "undefined" ? print : function () { + var system = require("system"); + var stdio = system.stdio; + stdio.print.apply(stdio, arguments); +}; + +exports.assert = function (guard, message) { + if (guard) { + exports.print('PASS ' + message, 'pass'); + } else { + exports.print('FAIL ' + message, 'fail'); + } +}; + diff --git a/js/common/test-data/modules/commonjs/tests/unit-testing/1.0/program.js b/js/common/test-data/modules/commonjs/tests/unit-testing/1.0/program.js new file mode 100644 index 0000000000..14ae2b9342 --- /dev/null +++ b/js/common/test-data/modules/commonjs/tests/unit-testing/1.0/program.js @@ -0,0 +1,162 @@ +// From Node.js test/mjsunit/test-assert.js +// Felix Geisendörfer (felixge), backported from NodeJS +// Karl Guertin (greyrest), backported from NodeJS +// Kris Kowal (kriskowal), conversion to CommonJS + +// strangely meta, no? + +var assert = require('assert'); + +function makeBlock(f) { + var args = Array.prototype.slice.call(arguments,1); + return function(){ + return f.apply(this, args); + } +} + +exports['test AssertionError instanceof Error'] = function () { + assert.ok(new assert.AssertionError({}) instanceof Error); +}; + +exports['test ok false'] = function () { + assert['throws'](makeBlock(assert.ok, false), assert.AssertionError); +}; + +exports['test ok(true)'] = makeBlock(assert.ok, true); +exports['test ok("test")'] = makeBlock(assert.ok, "test"); +exports['test equal true false'] = function () { + assert['throws'](makeBlock(assert.equal, true, false), assert.AssertionError, 'equal'); +}; + +exports['test equal null null'] = makeBlock(assert.equal, null, null); +exports['test equal undefined undefined'] = makeBlock(assert.equal, undefined, undefined); +exports['test equal null undefined'] = makeBlock(assert.equal, null, undefined); +exports['test equal 2 "2"'] = makeBlock(assert.equal, 2, "2"); +exports['test equal "2" 2'] = makeBlock(assert.equal, "2", 2); +exports['test equal true true'] = makeBlock(assert.equal, true, true); +exports['test notEqual true false'] = makeBlock(assert.notEqual, true, false); +exports['test notEqual true true'] = function () { + assert['throws'](makeBlock(assert.notEqual, true, true), assert.AssertionError, 'notEqual'); +}; +exports['test strictEqual 2 "2"'] = function () { + assert['throws'](makeBlock(assert.strictEqual, 2, "2"), assert.AssertionError, 'strictEqual'); +}; +exports['test strictEqual null undefined'] = function () { + assert['throws'](makeBlock(assert.strictEqual, null, undefined), assert.AssertionError, 'strictEqual'); +}; +exports['test notStrictEqual 2 "2"'] = makeBlock(assert.notStrictEqual, 2, "2"); + +//deepEquals + +//7.2 +exports['test 7.2 deepEqual date'] = makeBlock(assert.deepEqual, new Date(2000,3,14), new Date(2000,3,14)); +exports['test 7.2 deepEqual date negative'] = function () { + assert['throws'](makeBlock(assert.deepEqual, new Date(), new Date(2000,3,14)), assert.AssertionError, 'deepEqual date'); +}; + +//7.3 +exports['test 7.3 deepEqual 4 "4"'] = makeBlock(assert.deepEqual, 4, "4"); +exports['test 7.3 deepEqual "4" 4'] = makeBlock(assert.deepEqual, "4", 4); +exports['test 7.3 deepEqual true 1'] = makeBlock(assert.deepEqual, true, 1); +exports['test 7.3 deepEqual 4 "5"'] = function () { + assert['throws'](makeBlock(assert.deepEqual, 4, "5")); +}; + +//7.4 +// having the same number of owned properties && the same set of keys +exports['test 7.4 deepEqual {a:4} {a:4}'] = makeBlock(assert.deepEqual, {a:4}, {a:4}); +exports['test 7.4 deepEqual {a:4,b:"2"} {a:4,b:"2"}'] = makeBlock(assert.deepEqual, {a:4,b:"2"}, {a:4,b:"2"}); +exports['test 7.4 deepEqual [4] ["4"]'] = makeBlock(assert.deepEqual, [4], ["4"]); +exports['test 7.4 deepEqual {a:4} {a:4,b:true}'] = function () { + assert['throws'](makeBlock(assert.deepEqual, {a:4}, {a:4,b:true}), assert.AssertionError); +}; + +exports['test deepEqual ["a"], {0:"a"}'] = makeBlock(assert.deepEqual, ["a"], {0:"a"}); +//(although not necessarily the same order), +exports['test deepEqual {a:4,b:"1"} {b:"1",a:4}'] = makeBlock(assert.deepEqual, {a:4,b:"1"}, {b:"1",a:4}); + +exports['test deepEqual arrays with non-numeric properties'] = function () { + var a1 = [1,2,3]; + var a2 = [1,2,3]; + a1.a = "test"; + a1.b = true; + a2.b = true; + a2.a = "test" + assert['throws'](makeBlock(assert.deepEqual, Object.keys(a1), Object.keys(a2)), assert.AssertionError); + makeBlock(assert.deepEqual, a1, a2); +}; + +exports['test deepEqual identical prototype'] = function () { + // having an identical prototype property + var nbRoot = { + toString: function(){return this.first+' '+this.last;} + } + var nameBuilder = function(first,last){ + this.first = first; + this.last = last; + return this; + } + nameBuilder.prototype = nbRoot; + var nameBuilder2 = function(first,last){ + this.first = first; + this.last = last; + return this; + } + nameBuilder2.prototype = nbRoot; + var nb1 = new nameBuilder('Ryan', 'Dahl'); + var nb2 = new nameBuilder2('Ryan','Dahl'); + + assert.deepEqual(nb1, nb2); + + nameBuilder2.prototype = Object; + nb2 = new nameBuilder2('Ryan','Dahl'); + assert['throws'](makeBlock(assert.deepEqual, nb1, nb2), assert.AssertionError); + +}; + +exports['test deepEqual "a" {}'] = function () { + assert['throws'](makeBlock(assert.deepEqual, 'a', {}), assert.AssertionError); +}; + +exports['test deepEqual "" ""'] = function () { + assert.deepEqual("", ""); +}; + +exports['test deepEqual "" [""]'] = function () { + assert['throws'](makeBlock(assert.deepEqual, '', ['']), assert.AssertionError); +}; + +exports['test deepEqual [""] [""]'] = function () { + assert.deepEqual([""], [""]); +}; + +exports['test throw AssertionError'] = function () { + + //Testing the throwing + function thrower(errorConstructor){ + throw new errorConstructor('test'); + } + var aethrow = makeBlock(thrower, assert.AssertionError); + var aethrow = makeBlock(thrower, assert.AssertionError); + //the basic calls work + assert['throws'](makeBlock(thrower, assert.AssertionError), assert.AssertionError, 'message'); + assert['throws'](makeBlock(thrower, assert.AssertionError), assert.AssertionError); + assert['throws'](makeBlock(thrower, assert.AssertionError)); + //if not passing an error, catch all. + assert['throws'](makeBlock(thrower, TypeError)); + //when passing a type, only catch errors of the appropriate type + var threw = false; + try { + assert['throws'](makeBlock(thrower, TypeError), assert.AssertionError); + } catch (e) { + threw = true; + assert.ok(e instanceof TypeError, 'type'); + } + assert.ok(threw, 'assert.throws with an explicit error is eating extra errors', assert.AssertionError); + threw = false; + +}; + +if (module == require.main) + require("test").run(exports); + diff --git a/js/common/test-data/modules/node_modules/TestA/index.js b/js/common/test-data/modules/node_modules/TestA/index.js new file mode 100644 index 0000000000..19a088badc --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestA/index.js @@ -0,0 +1,5 @@ +exports.version = "A 1.0.0"; +exports.x = require("./x"); +exports.B = require("TestB"); +exports.C = require("TestC"); +exports.D = require("TestD"); diff --git a/js/common/test-data/modules/node_modules/TestA/node_modules/TestB/index.js b/js/common/test-data/modules/node_modules/TestA/node_modules/TestB/index.js new file mode 100644 index 0000000000..7ec079f710 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestA/node_modules/TestB/index.js @@ -0,0 +1 @@ +exports.version = "B 2.0.0"; diff --git a/js/common/test-data/modules/node_modules/TestA/node_modules/TestB/package.json b/js/common/test-data/modules/node_modules/TestA/node_modules/TestB/package.json new file mode 100644 index 0000000000..447071a2a9 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestA/node_modules/TestB/package.json @@ -0,0 +1,6 @@ +{ + "name": "B", + "description": "B", + "main": "index", + "version": "2.0.0" +} diff --git a/js/common/test-data/modules/node_modules/TestA/node_modules/TestC/index.js b/js/common/test-data/modules/node_modules/TestA/node_modules/TestC/index.js new file mode 100644 index 0000000000..303ee38433 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestA/node_modules/TestC/index.js @@ -0,0 +1,2 @@ +exports.version = "C 1.0.0"; +exports.B = require("TestB"); diff --git a/js/common/test-data/modules/node_modules/TestA/node_modules/TestC/package.json b/js/common/test-data/modules/node_modules/TestA/node_modules/TestC/package.json new file mode 100644 index 0000000000..b03bb8c694 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestA/node_modules/TestC/package.json @@ -0,0 +1,6 @@ +{ + "name": "C", + "description": "C", + "main": "index", + "version": "1.0.0" +} diff --git a/js/common/test-data/modules/node_modules/TestA/package.json b/js/common/test-data/modules/node_modules/TestA/package.json new file mode 100644 index 0000000000..4d781bfde6 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestA/package.json @@ -0,0 +1,6 @@ +{ + "name": "A", + "description": "A", + "main": "index", + "version": "1.0.0" +} diff --git a/js/common/test-data/modules/node_modules/TestA/x.js b/js/common/test-data/modules/node_modules/TestA/x.js new file mode 100644 index 0000000000..6847468a84 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestA/x.js @@ -0,0 +1 @@ +exports.version = "x 1.0.0"; diff --git a/js/common/test-data/modules/node_modules/TestB/index.js b/js/common/test-data/modules/node_modules/TestB/index.js new file mode 100644 index 0000000000..613ef085a3 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestB/index.js @@ -0,0 +1 @@ +exports.version = "B 1.0.0"; diff --git a/js/common/test-data/modules/node_modules/TestB/package.json b/js/common/test-data/modules/node_modules/TestB/package.json new file mode 100644 index 0000000000..c71c4e3d7c --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestB/package.json @@ -0,0 +1,6 @@ +{ + "name": "B", + "description": "B", + "main": "index", + "version": "1.0.0" +} diff --git a/js/common/test-data/modules/node_modules/TestD/index.js b/js/common/test-data/modules/node_modules/TestD/index.js new file mode 100644 index 0000000000..33b2d22cf4 --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestD/index.js @@ -0,0 +1 @@ +exports.version = "D 1.0.0"; diff --git a/js/common/test-data/modules/node_modules/TestD/package.json b/js/common/test-data/modules/node_modules/TestD/package.json new file mode 100644 index 0000000000..5e1206560e --- /dev/null +++ b/js/common/test-data/modules/node_modules/TestD/package.json @@ -0,0 +1,6 @@ +{ + "name": "D", + "description": "D", + "main": "index", + "version": "1.0.0" +} diff --git a/js/common/tests/shell-require.js b/js/common/tests/shell-require.js new file mode 100644 index 0000000000..bbf503b200 --- /dev/null +++ b/js/common/tests/shell-require.js @@ -0,0 +1,151 @@ +/*jslint indent: 2, nomen: true, maxlen: 80 */ +/*global require, assertEqual, assertTrue */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test the module and package require +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2010-2012 triagens GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Jan Steemann +/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var jsunity = require("jsunity"); + +// ----------------------------------------------------------------------------- +// --SECTION-- require package suite +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test suite +//////////////////////////////////////////////////////////////////////////////// + +function RequirePackageSuite () { + + return { + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test package loading +//////////////////////////////////////////////////////////////////////////////// + + testPackage : function () { + var m = require("TestA"); + + assertEqual(m.version, "A 1.0.0"); + assertEqual(m.x.version, "x 1.0.0"); + assertEqual(m.B.version, "B 2.0.0"); + assertEqual(m.C.version, "C 1.0.0"); + assertEqual(m.C.B.version, "B 2.0.0"); + assertEqual(m.D.version, "D 1.0.0"); + + assertEqual(m.B, m.C.B); + + var n = require("TestB"); + + assertEqual(n.version, "B 1.0.0"); + assertNotEqual(n, m.B); + } + + }; +} + +// ----------------------------------------------------------------------------- +// --SECTION-- require module suite +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test suite +//////////////////////////////////////////////////////////////////////////////// + +function RequireModuleSuite () { + var internal = require("internal"); + var console = require("console"); + var modulePath = internal.MODULES_PATH; + var first = modulePath[0]; + + function appendModulePath (testPath) { + internal.MODULES_PATH = modulePath.concat([ first + "/../../common/test-data/modules/commonjs/tests/modules/1.0/" + testPath ]); + module.root.unloadAll(); + + var test = internal.GlobalPackage.defineSystemModule("/test"); + + test.exports.print = internal.print; + + test.exports.assert = function (guard, message) { + console.log("running test %s", message); + assertEqual(guard !== false, true); + }; + } + + return { + +//////////////////////////////////////////////////////////////////////////////// +/// @brief tear down +//////////////////////////////////////////////////////////////////////////////// + + tearDown : function () { + internal.MODULES_PATH = modulePath; + module.root.unloadAll(); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test module loading +//////////////////////////////////////////////////////////////////////////////// + + testRequireCommonJS : function () { + var i; + var tests = [ + "absolute", "cyclic", "determinism", "exactExports", "hasOwnProperty", + "method", "missing", "monkeys", "nested", "relative", "transitive" ]; + + for (i = 0; i < tests.length; i++) { + var name = tests[i]; + + console.log("running CommonJS test '%s'", name); + appendModulePath(name); + require("program"); + } + } + + }; +} + +// ----------------------------------------------------------------------------- +// --SECTION-- main +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes the test suite +//////////////////////////////////////////////////////////////////////////////// + +jsunity.run(RequirePackageSuite); +jsunity.run(RequireModuleSuite); + +return jsunity.done(); + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}" +// End: