systemjs/dist/system.js
2014-05-05 15:56:44 -07:00

1623 lines
50 KiB
JavaScript

/*
* SystemJS
*
* Copyright (c) 2013 Guy Bedford
* MIT License
*/
(function(__$global) {
// indexOf polyfill for IE
var indexOf = Array.prototype.indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++)
if (this[i] === item)
return i;
return -1;
}
__$global.upgradeSystemLoader = function() {
__$global.upgradeSystemLoader = undefined;/*
* SystemJS Core
* Code should be vaguely readable
*
*/
function core(loader) {
(function() {
/*
__useDefault
When a module object looks like:
Module({
__useDefault: true,
default: 'some-module'
})
Then importing that module provides the 'some-module'
result directly instead of the full module.
Useful for eg module.exports = function() {}
*/
var loaderImport = loader['import'];
loader['import'] = function(name, options) {
return loaderImport.call(this, name, options).then(function(module) {
return module.__useDefault ? module['default'] : module;
});
}
// support the empty module, as a concept
loader.set('@empty', Module({}));
/*
Config
Extends config merging one deep only
loader.config({
some: 'random',
config: 'here',
deep: {
config: { too: 'too' }
}
});
<=>
loader.some = 'random';
loader.config = 'here'
loader.deep = loader.deep || {};
loader.deep.config = { too: 'too' };
*/
loader.config = function(cfg) {
for (var c in cfg) {
var v = cfg[c];
if (typeof v == 'object') {
this[c] = this[c] || {};
for (var p in v)
this[c][p] = v[p];
}
else
this[c] = v;
}
}
// override locate to allow baseURL to be document-relative
var baseURI;
if (typeof window == 'undefined') {
baseURI = __dirname + '/';
}
else {
baseURI = document.baseURI;
if (!baseURI) {
var bases = document.getElementsByTagName('base');
baseURI = bases[0] && bases[0].href || window.location.href;
}
}
var loaderLocate = loader.locate;
var normalizedBaseURL;
loader.locate = function(load) {
if (this.baseURL != normalizedBaseURL) {
normalizedBaseURL = toAbsoluteURL(baseURI, this.baseURL);
if (normalizedBaseURL.substr(normalizedBaseURL.length - 1, 1) != '/')
normalizedBaseURL += '/';
this.baseURL = normalizedBaseURL;
}
return Promise.resolve(loaderLocate.call(this, load));
}
// Traceur conveniences
var aliasRegEx = /^\s*export\s*\*\s*from\s*(?:'([^']+)'|"([^"]+)")/;
var es6RegEx = /(?:^\s*|[}{\(\);,\n]\s*)(import\s+['"]|(import|module)\s+[^"'\(\)\n;]+\s+from\s+['"]|export\s+(\*|\{|default|function|var|const|let|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*))/;
var loaderTranslate = loader.translate;
loader.translate = function(load) {
var loader = this;
loader.__exec = exec;
// support ES6 alias modules ("export * from 'module';") without needing Traceur
var match;
if (!loader.global.traceur && (load.metadata.format == 'es6' || !load.metadata.format) && (match = load.source.match(aliasRegEx))) {
var depName = match[1] || match[2];
load.metadata.deps = [depName];
load.metadata.execute = function(require) {
return require(depName);
}
}
// detect ES6
if (load.metadata.format == 'es6' || !load.metadata.format && load.source.match(es6RegEx)) {
console.log('load traceur');
load.metadata.format = 'es6';
// dynamically load Traceur for ES6 if necessary
if (!loader.global.traceur)
return loader['import']('@traceur').then(function() {
return loaderTranslate.call(loader, load);
});
}
return loaderTranslate.call(loader, load);
}
// always load Traceur as a global
var loaderInstantiate = loader.instantiate;
loader.instantiate = function(load) {
var loader = this;
if (load.name == '@traceur') {
loader.__exec(load);
return {
deps: [],
execute: function() {}
};
}
return loaderInstantiate.call(loader, load);
}
// define exec for easy evaluation of a load record (load.name, load.source, load.address)
// main feature is source maps support handling
var curSystem
function exec(load) {
if (load.name == '@traceur')
curSystem = System;
// support sourceMappingURL (efficiently)
var sourceMappingURL;
var lastLineIndex = load.source.lastIndexOf('\n');
if (lastLineIndex != -1) {
if (load.source.substr(lastLineIndex + 1, 21) == '//# sourceMappingURL=')
sourceMappingURL = toAbsoluteURL(load.address, load.source.substr(lastLineIndex + 22));
}
__eval(load.source, this.global, load.address, sourceMappingURL);
// traceur overwrites System - write it back
if (load.name == '@traceur') {
this.global.traceurSystem = this.global.System;
this.global.System = curSystem;
}
}
loader.__exec = exec;
// Absolute URL parsing, from https://gist.github.com/Yaffle/1088850
function parseURI(url) {
var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
// authority = '//' + user + ':' + pass '@' + hostname + ':' port
return (m ? {
href : m[0] || '',
protocol : m[1] || '',
authority: m[2] || '',
host : m[3] || '',
hostname : m[4] || '',
port : m[5] || '',
pathname : m[6] || '',
search : m[7] || '',
hash : m[8] || ''
} : null);
}
function toAbsoluteURL(base, href) {
function removeDotSegments(input) {
var output = [];
input.replace(/^(\.\.?(\/|$))+/, '')
.replace(/\/(\.(\/|$))+/g, '/')
.replace(/\/\.\.$/, '/../')
.replace(/\/?[^\/]*/g, function (p) {
if (p === '/..')
output.pop();
else
output.push(p);
});
return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
}
href = parseURI(href || '');
base = parseURI(base || '');
return !href || !base ? null : (href.protocol || base.protocol) +
(href.protocol || href.authority ? href.authority : base.authority) +
removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
(href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
href.hash;
}
})();
function __eval(__source, __global, __address, __sourceMap) {
try {
__source = 'with(__global) { (function() { ' + __source + ' \n }).call(__global); }'
+ '\n//# sourceURL=' + __address
+ (__sourceMap ? '\n//# sourceMappingURL=' + __sourceMap : '');
eval(__source);
}
catch(e) {
if (e.name == 'SyntaxError')
e.message = 'Evaluating ' + __address + '\n\t' + e.message;
throw e;
}
}
}
/*
* Meta Extension
*
* Sets default metadata on a load record (load.metadata) from
* loader.meta[moduleName].
* Also provides an inline meta syntax for module meta in source.
*
* Eg:
*
* loader.meta['my/module'] = { some: 'meta' };
*
* load.metadata.some = 'meta' will now be set on the load record.
*
* The same meta could be set with a my/module.js file containing:
*
* my/module.js
* "some meta";
* "another meta";
* console.log('this is my/module');
*
* The benefit of inline meta is that coniguration doesn't need
* to be known in advanced, which is useful for modularising
* configuration and avoiding the need for configuration injection.
*
*
* Example
* -------
*
* The simplest meta example is setting the module format:
*
* System.meta['my/module'] = { format: 'amd' };
*
* or inside 'my/module.js':
*
* "format amd";
* define(...);
*
*/
function meta(loader) {
var metaRegEx = /^(\s*\/\*.*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)+/;
var metaPartRegEx = /\/\*.*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^']+'\s*;?/g;
loader.meta = {};
function setConfigMeta(loader, load) {
var meta = loader.meta && loader.meta[load.name];
if (meta) {
for (var p in meta)
load.metadata[p] = load.metadata[p] || meta[p];
}
}
var loaderLocate = loader.locate;
loader.locate = function(load) {
setConfigMeta(this, load);
return loaderLocate.call(this, load);
}
var loaderTranslate = loader.translate;
loader.translate = function(load) {
setConfigMeta(this, load);
// detect any meta header syntax
var meta = load.source.match(metaRegEx);
if (meta) {
var metaParts = meta[0].match(metaPartRegEx);
for (var i = 0; i < metaParts.length; i++) {
var len = metaParts[i].length;
var firstChar = metaParts[i].substr(0, 1);
if (metaParts[i].substr(len - 1, 1) == ';')
len--;
if (firstChar != '"' && firstChar != "'")
continue;
var metaString = metaParts[i].substr(1, metaParts[i].length - 3);
var metaName = metaString.substr(0, metaString.indexOf(' '));
if (metaName) {
var metaValue = metaString.substr(metaName.length + 1, metaString.length - metaName.length - 1);
if (load.metadata[metaName] instanceof Array)
load.metadata[metaName].push(metaValue);
else
load.metadata[metaName] = load.metadata[metaName] || metaValue;
}
}
}
return loaderTranslate.call(this, load);
}
}/*
* Instantiate registry extension
*
* Supports Traceur System.register 'instantiate' output for loading ES6 as ES5.
*
* - Creates the loader.register function
* - Also supports metadata.format = 'register' in instantiate for anonymous register modules
* - Also supports metadata.deps, metadata.execute and metadata.executingRequire
* for handling dynamic modules alongside register-transformed ES6 modules
*
* Works as a standalone extension provided there is a
* loader.__exec(load) like the one set in SystemJS core
*
*/
function register(loader) {
if (typeof indexOf == 'undefined')
indexOf = Array.prototype.indexOf;
if (!loader.__exec)
throw "loader.__exec(load) needs to be provided for loader.register. See SystemJS core for an implementation example.";
function dedupe(deps) {
var newDeps = [];
for (var i = 0; i < deps.length; i++)
if (indexOf.call(newDeps, deps[i]) == -1)
newDeps.push(deps[i])
return newDeps;
}
// Registry side table
// Registry Entry Contains:
// - deps
// - declare for register modules
// - execute for dynamic modules, also after declare for register modules
// - declarative boolean indicating which of the above
// - normalizedDeps derived from deps, created in instantiate
// - depMap array derived from deps, populated gradually in link
// - groupIndex used by group linking algorithm
// - module a raw module exports object with no wrapper
// - evaluated indiciating whether evaluation has happend for declarative modules
// After linked and evaluated, entries are removed
var lastRegister;
function register(name, deps, declare) {
if (declare.length == 0)
throw 'Invalid System.register form. Ensure setting --modules=instantiate if using Traceur.';
if (!loader.defined)
loader.defined = {};
if (typeof name != 'string') {
declare = deps;
deps = name;
name = null;
}
lastRegister = {
deps: deps,
declare: declare,
declarative: true
};
if (name)
loader.defined[name] = lastRegister;
}
loader.defined = loader.defined || {};
loader.register = register;
function buildGroups(entry, loader, groups) {
groups[entry.groupIndex] = groups[entry.groupIndex] || [];
if (indexOf.call(groups[entry.groupIndex], entry) != -1)
return;
groups[entry.groupIndex].push(entry);
for (var i = 0; i < entry.normalizedDeps.length; i++) {
var depName = entry.normalizedDeps[i];
var depEntry = loader.defined[depName];
// not in the registry means already linked / ES6
if (!depEntry)
continue;
// now we know the entry is in our unlinked linkage group
var depGroupIndex = entry.groupIndex + (depEntry.declarative != entry.declarative);
if (depEntry.groupIndex === undefined) {
depEntry.groupIndex = depGroupIndex;
}
else if (depEntry.groupIndex != depGroupIndex) {
throw new TypeError('System.register mixed dependency cycle');
}
buildGroups(entry, loader, groups);
}
}
function link(name, loader) {
var startEntry = loader.defined[name];
startEntry.groupIndex = 0;
var groups = [];
buildGroups(startEntry, loader, groups);
var curGroupDeclarative = startEntry.declarative == groups.length % 2;
for (var i = groups.length - 1; i >= 0; i--) {
var group = groups[i];
for (var j = 0; j < group.length; j++) {
var entry = group[j];
// link each group
if (curGroupDeclarative)
linkDeclarativeModule(entry, loader);
else
linkDynamicModule(entry, loader);
}
curGroupDeclarative = !curGroupDeclarative;
}
}
function linkDeclarativeModule(entry, loader) {
// only link if already not already started linking (stops at circular)
if (entry.module)
return;
// declare the module with an empty depMap
var depMap = [];
var declaration = load.declare.call(loader.global, depMap);
entry.module = declaration.exports;
entry.exportStar = declaration.exportStar;
entry.execute = declaration.execute;
var module = entry.module;
// now link all the module dependencies
// amending the depMap as we go
for (var i = 0; i < entry.normalizedDeps.length; i++) {
var depName = entry.normalizedDeps[i];
var depEntry = loader.defined[depName];
// part of another linking group - use loader.get
if (!depEntry) {
depModule = loader.get(depName);
}
// if dependency already linked, use that
else if (depEntry.module) {
depModule = depEntry.module;
}
// otherwise we need to link the dependency
else {
linkDeclarativeModule(depEntry, loader);
depModule = depEntry.module;
}
if (entry.exportStar && indexOf.call(entry.exportStar, entry.normalizedDeps[i]) != -1) {
// we are exporting * from this dependency
(function(depModule) {
for (var p in depModule) (function(p) {
// if the property is already defined throw?
Object.defineProperty(module, p, {
enumerable: true,
get: function() {
return depModule[p];
},
set: function(value) {
depModule[p] = value;
}
});
})(p);
})(depModule);
}
depMap[i] = depModule;
}
}
// An analog to loader.get covering execution of all three layers (real declarative, simulated declarative, simulated dynamic)
function getModule(name, loader) {
var entry = loader.defined[name];
if (!entry)
return loader.get(name);
if (entry.declarative)
ensureEvaluated(name, [], loader);
else if (!entry.evaluated)
linkDynamicModule(entry, loader);
return entry.module;
}
function linkDynamicModule(entry, loader) {
if (entry.module)
return;
entry.module = {};
// AMD requires execute the tree first
if (!entry.executingRequire) {
for (var i = 0; i < entry.normalizedDeps.length; i++) {
var depName = entry.normalizedDeps[i];
var depEntry = loader.defined[depName];
linkDynamicModule(depEntry, loader);
}
}
// now execute
try {
entry.evaluated = true;
var output = entry.execute(function(name) {
for (var i = 0; i < entry.deps.length; i++) {
if (entry.deps[i] != name)
continue;
return getModule(entry.normalizedDeps[i], loader);
}
}, entry.module, name);
}
catch(e) {
throw e;
}
if (output)
entry.module = output;
}
// given a module, and the list of modules for this current branch,
// ensure that each of the dependencies of this module is evaluated
// (unless one is a circular dependency already in the list of seen
// modules, in which case we execute it)
// then evaluate the module itself
// depth-first left to right execution to match ES6 modules
function ensureEvaluated(moduleName, seen, loader) {
var entry = loader.defined[moduleName];
// if already seen, that means it's an already-evaluated non circular dependency
if (!entry.declarative || entry.evaluated || indexOf.call(seen, moduleName) != -1)
return;
seen.push(moduleName);
for (var i = 0; i < entry.normalizedDeps.length; i++) {
var depName = entry.normalizedDeps[i];
// circular -> execute now if not already executed
if (indexOf.call(seen, depName) != -1) {
var depEntry = loader.defined[depName];
if (depEntry && !depEntry.evaluated) {
depEntry.execute.call(loader.global);
delete depEntry.execute;
}
}
// in turn ensure dependencies are evaluated
else
ensureEvaluated(depName, seen);
}
// we've evaluated all dependencies so evaluate this module now
entry.execute.call(loader.global);
entry.evaluated = true;
}
var registerRegEx = /System\.register/;
var loaderTranslate = loader.translate;
loader.translate = function(load) {
loader.register = register;
load.metadata.deps = load.metadata.deps || [];
// run detection for register format here
if (load.metadata.format == 'register' || !load.metadata.format && load.source.match(registerRegEx))
load.metadata.format = 'register';
return loaderTranslate.call(this, load);
}
var loaderInstantiate = loader.instantiate;
loader.instantiate = function(load) {
var loader = this;
var entry;
if (loader.defined[load.name])
loader.defined[load.name] = entry = loader.defined[load.name];
else if (load.metadata.execute) {
loader.defined[load.name] = entry = {
deps: load.metadata.deps || [],
execute: load.metadata.execute,
executingRequire: load.metadata.executingRequire // NodeJS-style requires or not
};
}
else if (load.metadata.format == 'register') {
lastRegister = null;
loader.__exec(load);
// for a bundle, take the last defined module
// in the bundle to be the bundle itself
if (lastRegister)
loader.defined[load.name] = entry = lastRegister;
}
if (!entry)
return loaderInstantiate.call(this, load);
entry.deps = dedupe(entry.deps);
// first, normalize all dependencies
var normalizePromises = [];
for (var i = 0; i < entry.deps.length; i++)
normalizePromises.push(Promise.resolve(loader.normalize(entry.deps[i], load.name)));
return Promise.all(normalizePromises).then(function(normalizedDeps) {
entry.normalizedDeps = normalizedDeps;
// create the empty dep map - this is our key deferred dependency binding object passed into declare
entry.depMap = [];
return {
deps: entry.deps,
execute: function() {
// recursively ensure that the module and all its
// dependencies are linked (with dependency group handling)
link(load.name, loader);
// now handle dependency execution in correct order
ensureEvaluated(load.name, [], loader);
// remove from the registry
delete loader.defined[load.name];
var module = Module(entry.module);
// if the entry is an alias, set the alias too
for (var name in loader.defined) {
if (loader.defined[name].execute != entry.execute)
continue;
if (!loader.has(name))
loader.set(name, module);
}
// return the defined module object
return module;
}
};
});
}
}
/*
SystemJS Global Format
Supports
metadata.deps
metadata.init
metadata.exports
Also detects writes to the global object avoiding global collisions.
See the SystemJS readme global support section for further information.
*/
function global(loader) {
var loaderInstantiate = loader.instantiate;
loader.instantiate = function(load) {
var loader = this;
// global is a fallback module format
if (load.metadata.format == 'global' || !load.metadata.format) {
load.metadata.deps = load.metadata.deps || [];
var deps = load.metadata.deps;
var moduleGlobals = loader.moduleGlobals = loader.moduleGlobals || {};
var globalExport = load.metadata.exports;
var init = load.metadata.init;
load.metadata.execute = function(require, exports, moduleName) {
var hasOwnProperty = loader.global.hasOwnProperty;
// first, we add all the dependency modules to the global
for (var i = 0; i < deps.length; i++) {
var moduleGlobal = moduleGlobals[deps[i]];
if (moduleGlobal)
for (var m in moduleGlobal)
loader.global[m] = moduleGlobal[m];
}
// now store a complete copy of the global object
// in order to detect changes
var globalObj = {};
for (var g in loader.global)
if (!hasOwnProperty || loader.global.hasOwnProperty(g))
globalObj[g] = loader.global[g];
if (globalExport)
load.source += '\nthis["' + globalExport + '"] = ' + globalExport;
loader.__exec(load);
// check for global changes, creating the globalObject for the module
// if many globals, then a module object for those is created
// if one global, then that is the module directly
var singleGlobal;
if (globalExport) {
var firstPart = globalExport.split('.')[0];
singleGlobal = eval.call(loader.global, globalExport);
exports[firstPart] = loader.global[firstPart];
}
else {
for (var g in loader.global) {
if (!hasOwnProperty && (g == 'sessionStorage' || g == 'localStorage' || g == 'clipboardData' || g == 'frames'))
continue;
if ((!hasOwnProperty || loader.global.hasOwnProperty(g)) && g != loader.global && globalObj[g] != loader.global[g]) {
exports[g] = loader.global[g];
if (singleGlobal) {
if (singleGlobal !== loader.global[g])
singleGlobal = false;
}
else if (singleGlobal !== false)
singleGlobal = loader.global[g];
}
}
}
moduleGlobals[load.name] = exports;
var module = singleGlobal ? singleGlobal : exports;
return { __useDefault: true, 'default': module };
}
}
return loaderInstantiate.call(loader, load);
}
}/*
SystemJS CommonJS Format
*/
function cjs(loader) {
// CJS Module Format
// require('...') || exports[''] = ... || exports.asd = ... || module.exports = ...
var cjsExportsRegEx = /(?:^\s*|[}{\(\);,\n=:\?\&]\s*|module\.)(exports\s*\[\s*('[^']+'|"[^"]+")\s*\]|\exports\s*\.\s*[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*|exports\s*\=)/;
var cjsRequireRegEx = /(?:^\s*|[}{\(\);,\n=:\?\&]\s*)require\s*\(\s*("([^"]+)"|'([^']+)')\s*\)/g;
var commentRegEx = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;
function getCJSDeps(source) {
cjsExportsRegEx.lastIndex = 0;
cjsRequireRegEx.lastIndex = 0;
var deps = [];
// remove comments from the source first
var source = source.replace(commentRegEx, '');
var match;
while (match = cjsRequireRegEx.exec(source))
deps.push(match[2] || match[3]);
return deps;
}
var loaderTranslate = loader.translate;
loader.translate = function(load) {
load.metadata.getCJSDeps = getCJSDeps;
return loaderTranslate.call(this, load);
}
var noop = function() {}
var nodeProcess = {
nextTick: function(f) {
setTimeout(f, 7);
},
browser: typeof window != 'undefined',
env: {},
argv: [],
on: noop,
once: noop,
off: noop,
emit: noop,
cwd: function() { return '/' }
};
loader.set('@@nodeProcess', Module(nodeProcess));
var loaderInstantiate = loader.instantiate;
loader.instantiate = function(load) {
if (!load.metadata.format) {
cjsExportsRegEx.lastIndex = 0;
cjsRequireRegEx.lastIndex = 0;
if (cjsRequireRegEx.exec(load.source) || cjsExportsRegEx.exec(load.source))
load.metadata.format = 'cjs';
}
if (load.metadata.format == 'cjs') {
load.metadata.deps = load.metadata.deps ? load.metadata.deps.concat(getCJSDeps(load.source)) : load.metadata.deps;
load.metadata.execute = function(require, exports, moduleName) {
var dirname = load.address.split('/');
dirname.pop();
dirname = dirname.join('/');
var globals = loader.global._g = {
global: loader.global,
exports: exports,
module: { exports: exports },
process: nodeProcess,
require: function(name) {
var module = require(name);
if (module.__useDefault) {
module = module['default'];
}
else if (!module.__esModule) {
// compatibility -> ES6 modules must have a __esModule flag
// we clone the module object to handle this
var moduleClone = { __esModule: true };
for (var p in module)
moduleClone[p] = module[p];
module = moduleClone;
}
return module;
},
__filename: load.address,
__dirname: dirname
};
var glString = '';
for (var _g in globals)
glString += 'var ' + _g + ' = _g.' + _g + ';';
load.source = glString + load.source;
loader.__exec(load);
loader.global._g = undefined;
var output = globals.module.exports;
if (output && output.__esModule)
return output;
else if (output !== undefined)
return { __useDefault: true, 'default': output };
}
}
return loaderInstantiate.call(this, load);
};
}/*
SystemJS AMD Format
Provides the AMD module format definition at System.format.amd
as well as a RequireJS-style require on System.require
*/
function amd(loader) {
// AMD Module Format Detection RegEx
// define([.., .., ..], ...)
// define(varName); || define(function(require, exports) {}); || define({})
var amdRegEx = /(?:^\s*|[}{\(\);,\n\?\&]\s*)define\s*\(\s*("[^"]+"\s*,\s*|'[^']+'\s*,\s*)?(\[(\s*("[^"]+"|'[^']+')\s*,)*(\s*("[^"]+"|'[^']+')\s*)?\]|function\s*|{|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*\))/;
/*
AMD-compatible require
To copy RequireJS, set window.require = window.requirejs = loader.require
*/
function require(names, callback, errback, referer) {
// 'this' is bound to the loader
var loader = this;
// in amd, first arg can be a config object... we just ignore
if (typeof names == 'object' && !(names instanceof Array))
return require.apply(null, Array.prototype.splice.call(arguments, 1, arguments.length - 1));
// amd require
if (names instanceof Array)
Promise.all(names.map(function(name) {
return loader['import'](name, referer);
})).then(function(modules) {
callback.apply(null, modules);
}, errback);
// commonjs require
else if (typeof names == 'string') {
var module = loader.get(names);
return module.__useDefault ? module['default'] : module;
}
else
throw 'Invalid require';
};
loader.require = require;
function makeRequire(parentName, staticRequire, loader) {
return function(names, callback, errback) {
if (typeof names == 'string')
return staticRequire(names);
return require.call(loader, names, callback, errback, { name: parentName });
}
}
var lastDefine;
function createDefine(loader, getCJSDeps) {
if (loader.global.define && loader.global.define.loader == loader)
return;
loader.global.define = function(name, deps, factory) {
if (typeof name != 'string') {
factory = deps;
deps = name;
name = null;
}
if (!(deps instanceof Array)) {
factory = deps;
// CommonJS AMD form
if (!getCJSDeps)
throw "AMD extension needs CJS extension for AMD CJS support";
deps = ['require', 'exports', 'module'].concat(getCJSDeps(factory.toString()));
}
if (typeof factory != 'function')
factory = (function(factory) {
return function() { return factory; }
})(factory);
// a module file can only define one anonymous module
if (!name && lastDefine)
throw "Multiple defines for anonymous module";
// remove system dependencies
var requireIndex, exportsIndex, moduleIndex
if ((requireIndex = indexOf.call(deps, 'require')) != -1)
deps.splice(requireIndex, 1);
if ((exportsIndex = indexOf.call(deps, 'exports')) != -1)
deps.splice(exportsIndex, 1);
if ((moduleIndex = indexOf.call(deps, 'module')) != -1)
deps.splice(moduleIndex, 1);
lastDefine = {
deps: deps,
execute: function(require, exports, moduleName) {
var depValues = [];
for (var i = 0; i < deps.length; i++) {
var module = require(deps[i]);
if (module.__useDefault) {
module = module['default'];
}
else if (!module.__esModule) {
// compatibility -> ES6 modules must have a __esModule flag
// we clone the module object to handle this
var moduleClone = { __esModule: true };
for (var p in module)
moduleClone[p] = module[p];
module = moduleClone;
}
depValues.push(module);
}
var module;
// add back in system dependencies
if (moduleIndex != -1)
depValues.splice(moduleIndex, 0, exports, module = { id: moduleName, uri: loader.baseURL + moduleName, config: function() { return {}; }, exports: exports });
if (exportsIndex != -1)
depValues.splice(exportsIndex, 0, exports);
if (requireIndex != -1)
depValues.splice(requireIndex, 0, makeRequire(moduleName, require, loader));
var output = factory.apply(loader.global, depValues);
output = output || module && module.exports;
if (output && output.__esModule)
return output;
else if (output !== undefined)
return { __useDefault: true, 'default': output };
}
};
// attaches to loader.defined as dynamic
if (name)
loader.defined[name] = lastDefine;
};
loader.global.define.amd = {};
loader.global.define.loader = loader;
}
var loaderInstantiate = loader.instantiate;
loader.instantiate = function(load) {
var loader = this;
if (load.metadata.format == 'amd' || !load.metadata.format && load.source.match(amdRegEx)) {
load.metadata.format = 'amd';
createDefine(loader, load.metadata.getCJSDeps);
lastDefine = null;
// ensure no NodeJS environment detection
loader.global.module = undefined;
loader.global.exports = undefined;
loader.__exec(load);
if (!lastDefine)
throw "AMD module " + load.name + " did not define";
load.metadata.deps = load.metadata.deps ? load.metadata.deps.concat(lastDefine.deps) : lastDefine.deps;
load.metadata.execute = lastDefine.execute;
}
return loaderInstantiate.call(loader, load);
}
}/*
SystemJS map support
Provides map configuration through
System.map['jquery'] = 'some/module/map'
As well as contextual map config through
System.map['bootstrap'] = {
jquery: 'some/module/map2'
}
Note that this applies for subpaths, just like RequireJS
jquery -> 'some/module/map'
jquery/path -> 'some/module/map/path'
bootstrap -> 'bootstrap'
Inside any module name of the form 'bootstrap' or 'bootstrap/*'
jquery -> 'some/module/map2'
jquery/p -> 'some/module/map2/p'
Maps are carefully applied from most specific contextual map, to least specific global map
*/
function map(loader) {
loader.map = loader.map || {};
// return the number of prefix parts (separated by '/') matching the name
// eg prefixMatchLength('jquery/some/thing', 'jquery') -> 1
function prefixMatchLength(name, prefix) {
var prefixParts = prefix.split('/');
var nameParts = name.split('/');
if (prefixParts.length > nameParts.length)
return 0;
for (var i = 0; i < prefixParts.length; i++)
if (nameParts[i] != prefixParts[i])
return 0;
return prefixParts.length;
}
// given a relative-resolved module name and normalized parent name,
// apply the map configuration
function applyMap(name, parentName, loader) {
var curMatch, curMatchLength = 0;
var curParent, curParentMatchLength = 0;
var subPath;
var nameParts;
// first find most specific contextual match
if (parentName) {
for (var p in loader.map) {
var curMap = loader.map[p];
if (typeof curMap != 'object')
continue;
// most specific parent match wins first
if (prefixMatchLength(parentName, p) <= curParentMatchLength)
continue;
for (var q in curMap) {
// most specific name match wins
if (prefixMatchLength(name, q) <= curMatchLength)
continue;
curMatch = q;
curMatchLength = q.split('/').length;
curParent = p;
curParentMatchLength = p.split('/').length;
}
}
}
// if we found a contextual match, apply it now
if (curMatch) {
nameParts = name.split('/');
subPath = nameParts.splice(curMatchLength, nameParts.length - curMatchLength).join('/');
name = loader.map[curParent][curMatch] + (subPath ? '/' + subPath : '');
curMatchLength = 0;
}
// now do the global map
for (var p in loader.map) {
var curMap = loader.map[p];
if (typeof curMap != 'string')
continue;
if (prefixMatchLength(name, p) <= curMatchLength)
continue;
curMatch = p;
curMatchLength = p.split('/').length;
}
// return a match if any
if (!curMatchLength)
return name;
nameParts = name.split('/');
subPath = nameParts.splice(curMatchLength, nameParts.length - curMatchLength).join('/');
return loader.map[curMatch] + (subPath ? '/' + subPath : '');
}
var loaderNormalize = loader.normalize;
loader.normalize = function(name, parentName, parentAddress) {
var loader = this;
if (!loader.map)
loader.map = {};
return Promise.resolve(loaderNormalize.call(loader, name, parentName, parentAddress))
.then(function(name) {
return applyMap(name, parentName, loader);
});
}
}
/*
SystemJS Plugin Support
Supports plugin syntax with "!"
The plugin name is loaded as a module itself, and can override standard loader hooks
for the plugin resource. See the plugin section of the systemjs readme.
*/
function plugins(loader) {
if (typeof indexOf == 'undefined')
indexOf = Array.prototype.indexOf;
var loaderNormalize = loader.normalize;
loader.normalize = function(name, parentName, parentAddress) {
var loader = this;
// if parent is a plugin, normalize against the parent plugin argument only
var parentPluginIndex;
if (parentName && (parentPluginIndex = parentName.indexOf('!')) != -1)
parentName = parentName.substr(0, parentPluginIndex);
return Promise.resolve(loaderNormalize.call(loader, name, parentName, parentAddress))
.then(function(name) {
// if this is a plugin, normalize the plugin name and the argument
var pluginIndex = name.lastIndexOf('!');
if (pluginIndex != -1) {
var argumentName = name.substr(0, pluginIndex);
// plugin name is part after "!" or the extension itself
var pluginName = name.substr(pluginIndex + 1) || argumentName.substr(argumentName.lastIndexOf('.') + 1);
// normalize the plugin name relative to the same parent
return new Promise(function(resolve) {
resolve(loader.normalize(pluginName, parentName, parentAddress));
})
// normalize the plugin argument
.then(function(_pluginName) {
pluginName = _pluginName;
return loader.normalize(argumentName, parentName, parentAddress);
})
.then(function(argumentName) {
return argumentName + '!' + pluginName;
});
}
// standard normalization
return name;
});
}
var loaderLocate = loader.locate;
loader.locate = function(load) {
var loader = this;
var name = load.name;
// plugin
var pluginIndex = name.lastIndexOf('!');
if (pluginIndex != -1) {
var pluginName = name.substr(pluginIndex + 1);
// the name to locate is the plugin argument only
load.name = name.substr(0, pluginIndex);
var pluginLoader = loader.pluginLoader || loader;
// load the plugin module
return pluginLoader.load(pluginName)
.then(function() {
var plugin = pluginLoader.get(pluginName);
plugin = plugin['default'] || plugin;
// store the plugin module itself on the metadata
load.metadata.plugin = plugin;
load.metadata.pluginName = pluginName;
load.metadata.pluginArgument = load.name;
// run plugin locate if given
if (plugin.locate)
return plugin.locate.call(loader, load);
// otherwise use standard locate without '.js' extension adding
else
return new Promise(function(resolve) {
resolve(loader.locate(load));
})
.then(function(address) {
return address.substr(0, address.length - 3);
});
});
}
return loaderLocate.call(this, load);
}
var loaderFetch = loader.fetch;
loader.fetch = function(load) {
if (load.metadata.plugin && load.metadata.plugin.fetch)
return load.metadata.plugin.fetch.call(this, load, function(load) {
return loaderFetch.call(this, load);
});
else
return loaderFetch.call(this, load);
}
var loaderTranslate = loader.translate;
loader.translate = function(load) {
if (load.metadata.plugin && load.metadata.plugin.translate)
return load.metadata.plugin.translate.call(this, load, function(load) {
return loaderTranslate.call(this, load);
});
else
return loaderTranslate.call(this, load);
}
var loaderInstantiate = loader.instantiate;
loader.instantiate = function(load) {
if (load.metadata.plugin && load.metadata.plugin.instantiate)
return load.metadata.plugin.instantiate.call(this, load, function(load) {
return loaderInstantiate.call(this, load);
});
else
return loaderInstantiate.call(this, load);
}
}/*
System bundles
Allows a bundle module to be specified which will be dynamically
loaded before trying to load a given module.
For example:
System.bundles['mybundle'] = ['jquery', 'bootstrap/js/bootstrap']
Will result in a load to "mybundle" whenever a load to "jquery"
or "bootstrap/js/bootstrap" is made.
In this way, the bundle becomes the request that provides the module
*/
function bundles(loader) {
if (typeof indexOf == 'undefined')
indexOf = Array.prototype.indexOf;
// bundles support (just like RequireJS)
// bundle name is module name of bundle itself
// bundle is array of modules defined by the bundle
// when a module in the bundle is requested, the bundle is loaded instead
// of the form System.bundles['mybundle'] = ['jquery', 'bootstrap/js/bootstrap']
loader.bundles = loader.bundles || {};
var loaderFetch = loader.fetch;
loader.fetch = function(load) {
if (!loader.bundles)
loader.bundles = {};
// if this module is in a bundle, load the bundle first then
for (var b in loader.bundles) {
if (indexOf.call(loader.bundles[b], load.name) == -1)
continue;
// we do manual normalization in case the bundle is mapped
// this is so we can still know the normalized name is a bundle
return Promise.resolve(loader.normalize(b))
.then(function(normalized) {
loader.bundles[normalized] = loader.bundles[normalized] || loader.bundles[b];
return loader.load(normalized);
})
.then(function() {
return '';
});
}
return loaderFetch.apply(this, arguments);
}
}/*
SystemJS Semver Version Addon
1. Uses Semver convention for major and minor forms
Supports requesting a module from a package that contains a version suffix
with the following semver ranges:
module - any version
module@1 - major version 1, any minor (not prerelease)
module@1.2 - minor version 1.2, any patch (not prerelease)
module@1.2.3 - exact version
It is assumed that these modules are provided by the server / file system.
First checks the already-requested packages to see if there are any packages
that would match the same package and version range.
This provides a greedy algorithm as a simple fix for sharing version-managed
dependencies as much as possible, which can later be optimized through version
hint configuration created out of deeper version tree analysis.
2. Semver-compatibility syntax (caret operator - ^)
Compatible version request support is then also provided for:
module@^1.2.3 - module@1, >=1.2.3
module@^1.2 - module@1, >=1.2.0
module@^1 - module@1
module@^0.5.3 - module@0.5, >= 0.5.3
module@^0.0.1 - module@0.0.1
The ^ symbol is always normalized out to a normal version request.
This provides comprehensive semver compatibility.
3. System.versions version hints and version report
Note this addon should be provided after all other normalize overrides.
The full list of versions can be found at System.versions providing an insight
into any possible version forks.
It is also possible to create version solution hints on the System global:
System.versions = {
jquery: ['1.9.2', '2.0.3'],
bootstrap: '3.0.1'
};
Versions can be an array or string for a single version.
When a matching semver request is made (jquery@1.9, jquery@1, bootstrap@3)
they will be converted to the latest version match contained here, if present.
Prereleases in this versions list are also allowed to satisfy ranges when present.
*/
function versions(loader) {
if (typeof indexOf == 'undefined')
indexOf = Array.prototype.indexOf;
// match x, x.y, x.y.z, x.y.z-prerelease.1
var semverRegEx = /^(\d+)(?:\.(\d+)(?:\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?)?)?$/;
var semverCompare = function(v1, v2) {
var v1Parts = v1.split('.');
var v2Parts = v2.split('.');
var prereleaseIndex;
if (v1Parts[2] && (prereleaseIndex = indexOf.call(v1Parts[2], '-')) != -1)
v1Parts.splice(2, 1, v1Parts[2].substr(0, prereleaseIndex), v1Parts[2].substr(prereleaseIndex + 1));
if (v2Parts[2] && (prereleaseIndex = indexOf.call(v2Parts[2], '-')) != -1)
v2Parts.splice(2, 1, v2Parts[2].substr(0, prereleaseIndex), v2Parts[2].substr(prereleaseIndex + 1));
for (var i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
if (!v1Parts[i])
return 1;
else if (!v2Parts[i])
return -1;
if (v1Parts[i] != v2Parts[i])
return parseInt(v1Parts[i]) > parseInt(v2Parts[i]) ? 1 : -1;
}
return 0;
}
loader.versions = loader.versions || {};
var loaderNormalize = loader.normalize;
loader.normalize = function(name, parentName, parentAddress) {
if (!loader.versions)
loader.versions = {};
var packageVersions = this.versions;
// run all other normalizers first
return Promise.resolve(loaderNormalize.call(this, name, parentName, parentAddress)).then(function(normalized) {
var version, semverMatch, nextChar, versions;
var index = normalized.indexOf('@');
// see if this module corresponds to a package already in our versioned packages list
// no version specified - check against the list (given we don't know the package name)
if (index == -1) {
for (var p in packageVersions) {
versions = packageVersions[p];
if (normalized.substr(0, p.length) != p)
continue;
nextChar = normalized.substr(p.length, 1);
if (nextChar && nextChar != '/')
continue;
// match -> take latest version
return p + '@' + (typeof versions == 'string' ? versions : versions[versions.length - 1]) + normalized.substr(p.length);
}
return normalized;
}
// get the version info
version = normalized.substr(index + 1).split('/')[0];
var versionLength = version.length;
var minVersion;
if (version.substr(0, 1) == '^') {
version = version.substr(1);
minVersion = true;
}
semverMatch = version.match(semverRegEx);
// if not a semver, we cant help
if (!semverMatch)
return normalized;
// translate '^' in range to simpler range form
if (minVersion) {
// ^0 -> 0
// ^1 -> 1
if (!semverMatch[2])
minVersion = false;
if (!semverMatch[3]) {
// ^1.1 -> ^1.1.0
if (semverMatch[2] > 0)
semverMatch[3] = '0';
// ^0.1 -> 0.1
// ^0.0 -> 0.0
else
minVersion = false;
}
}
if (minVersion) {
// >= 1.0.0
if (semverMatch[1] > 0) {
if (!semverMatch[2])
version = semverMatch[1] + '.0.0';
if (!semverMatch[3])
version = semverMatch[1] + '.0';
minVersion = version;
semverMatch = [semverMatch[1]];
}
// >= 0.1.0
else if (semverMatch[2] > 0) {
minVersion = version;
semverMatch = [0, semverMatch[2]];
}
// >= 0.0.0
else {
// NB compatible with prerelease is just prelease itself?
minVersion = false;
semverMatch = [0, 0, semverMatch[3]];
}
version = semverMatch.join('.');
}
var packageName = normalized.substr(0, index);
versions = packageVersions[packageName] || [];
if (typeof versions == 'string')
versions = [versions];
// look for a version match
// if an exact semver, theres nothing to match, just record it
if (!semverMatch[3] || minVersion)
for (var i = versions.length - 1; i >= 0; i--) {
var curVersion = versions[i];
// if I have requested x.y, find an x.y.z-b
// if I have requested x, find any x.y / x.y.z-b
if (curVersion.substr(0, version.length) == version && curVersion.substr(version.length, 1).match(/^[\.\-]?$/)) {
// if a minimum version, then check too
if (!minVersion || minVersion && semverCompare(curVersion, minVersion) != -1)
return packageName + '@' + curVersion + normalized.substr(packageName.length + versionLength + 1);
}
}
// no match
// record the package and semver for reuse since we're now asking the server
// x.y and x versions will now be latest by default, so they are useful in the version list
if (indexOf.call(versions, version) == -1) {
versions.push(version);
versions.sort(semverCompare);
normalized = packageName + '@' + version + normalized.substr(packageName.length + versionLength + 1);
// if this is an x.y.z, remove any x.y, x
// if this is an x.y, remove any x
if (semverMatch[3] && (index = indexOf.call(versions, semverMatch[1] + '.' + semverMatch[2])) != -1)
versions.splice(index, 1);
if (semverMatch[2] && (index = indexOf.call(versions, semverMatch[1])) != -1)
versions.splice(index, 1);
packageVersions[packageName] = versions.length == 1 ? versions[0] : versions;
}
return normalized;
});
}
}
core(System);
meta(System);
register(System);
global(System);
cjs(System);
amd(System);
map(System);
plugins(System);
bundles(System);
versions(System);
System.baseURL = __$curScript.getAttribute('data-baseurl') || System.baseURL;
var configPath = __$curScript.getAttribute('data-config');
if (configPath === '')
configPath = System.baseURL + 'config.json';
var main = __$curScript.getAttribute('data-main');
(!configPath ? Promise.resolve() :
Promise.resolve(System.fetch.call(System, { address: configPath, metadata: {} }))
.then(JSON.parse)
.then(System.config)
).then(function() {
if (main)
return System['import'](main);
})
['catch'](function(e) {
setTimeout(function() {
throw e;
})
});
};
var __$curScript;
(function(global) {
if (typeof window != 'undefined') {
var scripts = document.getElementsByTagName('script');
__$curScript = scripts[scripts.length - 1];
if (!global.System || global.System.registerModule) {
// determine the current script path as the base path
var curPath = __$curScript.src;
var basePath = curPath.substr(0, curPath.lastIndexOf('/') + 1);
document.write(
'<' + 'script type="text/javascript" src="' + basePath + 'es6-module-loader.js" data-init="upgradeSystemLoader">' + '<' + '/script>'
);
}
else {
global.upgradeSystemLoader();
}
}
else {
var es6ModuleLoader = require('es6-module-loader');
global.System = es6ModuleLoader.System;
global.Loader = es6ModuleLoader.Loader;
global.Module = es6ModuleLoader.Module;
module.exports = global.System;
global.upgradeSystemLoader();
}
})(__$global);
})(typeof window != 'undefined' ? window : global);