Commit 3fb7134e by Andy Armstrong Committed by GitHub

Merge pull request #14020 from edx/andya/update-gemnasium-libraries

Clean up npm-installed packages
parents fa705d83 746e3100
/* globals _, requirejs */
/* eslint-disable quote-props */
(function(require, define) {
'use strict';
......
/* globals requirejs, requireSerial */
/* eslint-disable quote-props */
(function(requirejs, requireSerial) {
'use strict';
......@@ -48,8 +49,8 @@
'xblock': 'common/js/xblock',
'utility': 'xmodule_js/common_static/js/src/utility',
'accessibility': 'xmodule_js/common_static/js/src/accessibility_tools',
'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0',
'squire': 'xmodule_js/common_static/js/vendor/Squire',
'sinon': 'common/js/vendor/sinon',
'squire': 'common/js/vendor/Squire',
'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff',
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
'domReady': 'xmodule_js/common_static/js/vendor/domReady',
......@@ -289,6 +290,6 @@
];
requireSerial(specHelpers.concat(testFiles), function() {
return window.__karma__.start();
return window.__karma__.start(); // eslint-disable-line no-underscore-dangle
});
}).call(this, requirejs, requireSerial);
/* globals requirejs, requireSerial */
/* eslint-disable quote-props */
(function(requirejs, requireSerial) {
'use strict';
......@@ -43,8 +44,8 @@
'xblock/cms.runtime.v1': 'cms/js/xblock/cms.runtime.v1',
'xblock': 'common/js/xblock',
'utility': 'xmodule_js/common_static/js/src/utility',
'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0',
'squire': 'xmodule_js/common_static/js/vendor/Squire',
'sinon': 'common/js/vendor/sinon',
'squire': 'common/js/vendor/Squire',
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
'domReady': 'xmodule_js/common_static/js/vendor/domReady',
'URI': 'xmodule_js/common_static/js/vendor/URI.min',
......@@ -206,6 +207,6 @@
];
requireSerial(specHelpers.concat(testFiles), function() {
return window.__karma__.start();
return window.__karma__.start(); // eslint-disable-line no-underscore-dangle
});
}).call(this, requirejs, requireSerial);
......@@ -60,7 +60,7 @@ from openedx.core.djangolib.js_utils import (
window.baseUrl = "${settings.STATIC_URL | n, js_escaped_string}";
var require = {baseUrl: window.baseUrl};
</script>
<script type="text/javascript" src="${static.url("js/vendor/requirejs/require.js")}"></script>
<script type="text/javascript" src="${static.url("common/js/vendor/require.js")}"></script>
<script type="text/javascript" src="${static.url("cms/js/require-config.js")}"></script>
<!-- view -->
......
......@@ -31,7 +31,7 @@ var options = {
{pattern: 'common_static/js/vendor/jquery-ui.min.js', included: true},
{pattern: 'common_static/js/vendor/jquery.ui.draggable.js', included: true},
{pattern: 'common_static/js/vendor/json2.js', included: true},
{pattern: 'common_static/js/vendor/moment-with-locales.js', included: true},
{pattern: 'common_static/common/js/vendor/moment-with-locales.js', included: true},
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', included: true},
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js', included: true},
{pattern: 'common_static/js/src/accessibility_tools.js', included: true},
......@@ -46,7 +46,7 @@ var options = {
{pattern: 'common_static/js/vendor/jasmine-imagediff.js', included: true},
{pattern: 'common_static/common/js/spec_helpers/jasmine-waituntil.js', included: true},
{pattern: 'common_static/common/js/spec_helpers/jasmine-extensions.js', included: true},
{pattern: 'common_static/js/vendor/sinon-1.17.0.js', included: true},
{pattern: 'common_static/common/js/vendor/sinon.js', included: true},
// Load the edX global namespace before RequireJS is installed
{pattern: 'common_static/edx-ui-toolkit/js/utils/global-loader.js', included: true},
......@@ -54,7 +54,7 @@ var options = {
{pattern: 'common_static/edx-ui-toolkit/js/utils/html-utils.js', included: true},
// Load RequireJS and move it into the RequireJS namespace
{pattern: 'common_static/js/vendor/requirejs/require.js', included: true},
{pattern: 'common_static/common/js/vendor/require.js', included: true},
{pattern: 'RequireJS-namespace-undefine.js', included: true},
{pattern: 'spec/main_requirejs.js', included: true}
],
......
......@@ -34,7 +34,7 @@
requirejs.config({
baseUrl: '/base/',
paths: {
moment: 'common_static/js/vendor/moment-with-locales',
moment: 'common_static/common/js/vendor/moment-with-locales',
'draggabilly': 'common_static/js/vendor/draggabilly',
'edx-ui-toolkit': 'common_static/edx-ui-toolkit'
},
......
(function(requirejs, define) {
/* globals _, requirejs */
/* eslint-disable quote-props */
(function(requirejs) {
'use strict';
var testFiles, i, specHelpers;
requirejs.config({
baseUrl: '/base/',
paths: {
......@@ -24,7 +29,7 @@
'jquery.immediateDescendents': 'coffee/src/jquery.immediateDescendents',
'jquery.simulate': 'js/vendor/jquery.simulate',
'jquery.url': 'js/vendor/url.min',
'sinon': 'js/vendor/sinon-1.17.0',
'sinon': 'common/js/vendor/sinon',
'text': 'js/vendor/requirejs/text',
'underscore': 'common/js/vendor/underscore',
'underscore.string': 'common/js/vendor/underscore.string',
......@@ -152,7 +157,7 @@
}
});
var testFiles = [
testFiles = [
'common/js/spec/components/tabbed_view_spec.js',
'common/js/spec/components/feedback_spec.js',
'common/js/spec/components/list_spec.js',
......@@ -164,11 +169,11 @@
'common/js/spec/utils/edx.utils.validate_spec.js'
];
for (var i = 0; i < testFiles.length; i++) {
for (i = 0; i < testFiles.length; i++) {
testFiles[i] = '/base/' + testFiles[i];
}
var specHelpers = [
specHelpers = [
'common/js/spec_helpers/jasmine-extensions',
'common/js/spec_helpers/jasmine-stealth',
'common/js/spec_helpers/jasmine-waituntil'
......@@ -178,6 +183,6 @@
// spec files one by one, otherwise some end up getting nested under others.
window.requireSerial(specHelpers.concat(testFiles), function() {
// start test run, once Require.js is done
window.__karma__.start();
window.__karma__.start(); // eslint-disable-line no-underscore-dangle
});
}).call(this, requirejs, define);
define(function() {
/**
* Utility Functions
*/
var toString = Object.prototype.toString;
var isArray = function(arr) {
return toString.call(arr) === '[object Array]';
};
var indexOf = function(arr, search) {
for (var i = 0, length = arr.length; i < length; i++) {
if (arr[i] === search) {
return i;
}
}
return -1;
};
var each = function(obj, iterator, context) {
var breaker = {};
if (obj === null) {
return;
}
if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker){
return;
}
}
} else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) {
return;
}
}
}
}
};
/**
* Require.js Abstractions
*/
var getContext = function(id) {
return requirejs.s.contexts[id];
};
var undef = function(context, module) {
if (context.undef) {
return context.undef(module);
}
return context.require.undef(module);
};
/**
* Create a context name incrementor.
*/
var idCounter = 0;
var uniqueId = function(prefix) {
var id = idCounter++;
return 'context' + id;
};
var Squire = function() {
this.mocks = {};
this._store = [];
this.requiredCallbacks = [];
this.configure.apply(this, arguments);
};
/**
* Hook to call when the require function is called.
*/
Squire.prototype.onRequired = function(cb) {
this.requiredCallbacks.push(cb);
};
/**
* Configuration of Squire.js, called from constructor or manually takes the
* name of a require.js context to configure it.
*/
Squire.prototype.configure = function(context) {
var configuration = {};
var property;
this.id = uniqueId();
// Default the context
if (typeof context === 'undefined') {
context = '_'; // Default require.js context
}
context = getContext(context);
if ( ! context) {
throw new Error('This context has not been created!');
}
each(context.config, function(property, key) {
if (key !== 'deps') {
configuration[key] = property;
}
});
configuration.context = this.id;
this.load = requirejs.config(configuration);
};
Squire.prototype.mock = function(path, mock) {
var alias;
if (typeof path === 'object') {
each(path, function(alias, key) {
this.mock(key, alias);
}, this);
} else {
this.mocks[path] = mock;
}
return this;
};
Squire.prototype.store = function(path) {
if (path && typeof path === 'string') {
this._store.push(path);
} else if(path && isArray(path)) {
each(path, function(pathToStore) {
this.store(pathToStore);
}, this);
}
return this;
};
Squire.prototype.require = function(dependencies, callback, errback) {
var magicModuleName = 'mocks';
var self = this;
var path, magicModuleLocation;
magicModuleLocation = indexOf(dependencies, magicModuleName);
if (magicModuleLocation !== -1) {
dependencies.splice(magicModuleLocation, 1);
}
each(this.mocks, function(mock, path) {
define(path, mock);
});
this.load(dependencies, function() {
var store = {};
var args = Array.prototype.slice.call(arguments);
var dependency;
if (magicModuleLocation !== -1) {
each(self._store, function(dependency) {
store[dependency] = getContext(self.id).defined[dependency];
});
args.splice(magicModuleLocation, 0, {
mocks: self.mocks,
store: store
});
}
callback.apply(null, args);
each(self.requiredCallbacks, function(cb) {
cb.call(null, dependencies, args);
});
}, errback);
};
Squire.prototype.clean = function(mock) {
var path;
if (mock && typeof mock === 'string') {
undef(getContext(this.id), mock);
delete this.mocks[mock];
} else if(mock && isArray(mock)) {
each(mock, function(mockToClean) {
this.clean(mockToClean);
}, this);
} else {
each(this.mocks, function(mock, path){
this.clean(path);
}, this);
}
return this;
};
Squire.prototype.remove = function() {
var path, context = getContext(this.id);
if(!context) { return; }
each(context.defined, function(dependency, path) {
undef(context, path);
}, this);
delete requirejs.s.contexts[this.id];
};
Squire.prototype.run = function(deps, callback) {
var self = this;
var run = function(done) {
self.require(deps, function() {
callback.apply(null, arguments);
done();
});
};
run.toString = function() {
return callback.toString();
};
return run;
};
/**
* Utilities
*/
Squire.Helpers = {};
Squire.Helpers.returns = function(what) {
return function() {
return what;
};
};
Squire.Helpers.constructs = function(what) {
return function() {
return function() {
return what;
};
};
};
return Squire;
});
define(function(){var a=Object.prototype.toString,b=function(b){return"[object Array]"===a.call(b)},c=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},d=function(a,b,c){var d={};if(null!==a)if(Array.prototype.forEach&&a.forEach===Array.prototype.forEach)a.forEach(b,c);else if(a.length===+a.length){for(var e=0,f=a.length;f>e;e++)if(b.call(c,a[e],e,a)===d)return}else for(var g in a)if(a.hasOwnProperty(g)&&b.call(c,a[g],g,a)===d)return},e=function(a){return requirejs.s.contexts[a]},f=function(a,b){return a.undef?a.undef(b):a.require.undef(b)},g=0,h=function(){var b=g++;return"context"+b},i=function(){this.mocks={},this._store=[],this.requiredCallbacks=[],this.configure.apply(this,arguments)};return i.prototype.onRequired=function(a){this.requiredCallbacks.push(a)},i.prototype.configure=function(a){var b={};if(this.id=h(),"undefined"==typeof a&&(a="_"),a=e(a),!a)throw new Error("This context has not been created!");d(a.config,function(a,c){"deps"!==c&&(b[c]=a)}),b.context=this.id,this.load=requirejs.config(b)},i.prototype.mock=function(a,b){return"object"==typeof a?d(a,function(a,b){this.mock(b,a)},this):this.mocks[a]=b,this},i.prototype.store=function(a){return a&&"string"==typeof a?this._store.push(a):a&&b(a)&&d(a,function(a){this.store(a)},this),this},i.prototype.require=function(a,b,f){var j,g="mocks",h=this;j=c(a,g),-1!==j&&a.splice(j,1),d(this.mocks,function(a,b){define(b,a)}),this.load(a,function(){var c={},f=Array.prototype.slice.call(arguments);-1!==j&&(d(h._store,function(a){c[a]=e(h.id).defined[a]}),f.splice(j,0,{mocks:h.mocks,store:c})),b.apply(null,f),d(h.requiredCallbacks,function(b){b.call(null,a,f)})},f)},i.prototype.clean=function(a){return a&&"string"==typeof a?(f(e(this.id),a),delete this.mocks[a]):a&&b(a)?d(a,function(a){this.clean(a)},this):d(this.mocks,function(a,b){this.clean(b)},this),this},i.prototype.remove=function(){var b=e(this.id);b&&(d(e(this.id).defined,function(a,c){f(b,c)},this),delete requirejs.s.contexts[this.id])},i.prototype.run=function(a,b){var c=this,d=function(d){c.require(a,function(){b.apply(null,arguments),d()})};return d.toString=function(){return b.toString()},d},i.Helpers={},i.Helpers.returns=function(a){return function(){return a}},i.Helpers.constructs=function(a){return function(){return function(){return a}}},i});
This source diff could not be displayed because it is too large. You can view the blob instead.
../../../../../node_modules/requirejs/require.js
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1275,7 +1275,7 @@ base_vendor_js = [
'edx-ui-toolkit/js/utils/html-utils.js',
# Finally load RequireJS and dependent vendor libraries
'js/vendor/requirejs/require.js',
'common/js/vendor/require.js',
'js/RequireJS-namespace-undefine.js',
'js/vendor/URI.min.js',
'common/js/vendor/backbone.js'
......@@ -1690,7 +1690,7 @@ REQUIRE_BASE_URL = "./"
REQUIRE_BUILD_PROFILE = "lms/js/build.js"
# The name of the require.js script used by your project, relative to REQUIRE_BASE_URL.
REQUIRE_JS = "js/vendor/requirejs/require.js"
REQUIRE_JS = "common/js/vendor/require.js"
# A dictionary of standalone modules to build with almond.js.
REQUIRE_STANDALONE_MODULES = {}
......
......@@ -13,7 +13,7 @@ var options = {
// Avoid adding files to this list. Use RequireJS.
libraryFilesToInclude: [
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: true},
{pattern: 'common/js/vendor/require.js', included: true},
{pattern: 'js/RequireJS-namespace-undefine.js', included: true},
{pattern: 'common/js/vendor/jquery.js', included: true},
......@@ -22,8 +22,6 @@ var options = {
{pattern: 'xmodule_js/common_static/js/vendor/slick.core.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/slick.grid.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: true},
{pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: true},
{pattern: 'common/js/vendor/jquery.js', included: true},
{pattern: 'common/js/vendor/jquery-migrate.js', included: true},
......
/* globals _, requirejs */
/* eslint-disable quote-props */
(function(require, define) {
'use strict';
var defineDependency;
// We do not wish to bundle common libraries (that may also be used by non-RequireJS code on the page
// into the optimized files. Therefore load these libraries through script tags and explicitly define them.
// Note that when the optimizer executes this code, window will not be defined.
if (window) {
var defineDependency = function(globalName, name, noShim) {
var getGlobalValue = function(name) {
var globalNamePath = name.split('.'),
defineDependency = function(globalName, name, noShim) {
var getGlobalValue = function() {
var globalNamePath = globalName.split('.'),
result = window,
i;
for (i = 0; i < globalNamePath.length; i++) {
......@@ -15,16 +20,14 @@
}
return result;
},
globalValue = getGlobalValue(globalName);
globalValue = getGlobalValue();
if (globalValue) {
if (noShim) {
define(name, {});
}
else {
} else {
define(name, [], function() { return globalValue; });
}
}
else {
} else {
console.error('Expected library to be included on page, but not found on window object: ' + name);
}
};
......
/* globals requirejs, requireSerial, MathJax */
/* eslint-disable quote-props */
(function(requirejs) {
'use strict';
var i, specHelpers, testFiles;
// TODO: how can we share the vast majority of this config that is in common with CMS?
requirejs.config({
baseUrl: '/base/',
......@@ -24,7 +29,7 @@
'jquery.cookie': 'xmodule_js/common_static/js/vendor/jquery.cookie',
'jquery.qtip': 'xmodule_js/common_static/js/vendor/jquery.qtip.min',
'jquery.fileupload': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload',
'jquery.iframe-transport': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport',
'jquery.iframe-transport': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport', // eslint-disable-line max-len
'jquery.inputnumber': 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill',
'jquery.immediateDescendents': 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents',
'jquery.simulate': 'xmodule_js/common_static/js/vendor/jquery.simulate',
......@@ -47,8 +52,8 @@
'xmodule': 'xmodule_js/src/xmodule',
'utility': 'xmodule_js/common_static/js/src/utility',
'accessibility': 'xmodule_js/common_static/js/src/accessibility_tools',
'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0',
'squire': 'xmodule_js/common_static/js/vendor/Squire',
'sinon': 'common/js/vendor/sinon',
'squire': 'common/js/vendor/Squire',
'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff',
'domReady': 'xmodule_js/common_static/js/vendor/domReady',
mathjax: '//cdn.mathjax.org/mathjax/2.7-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len
......@@ -672,7 +677,7 @@
}
});
var testFiles = [
testFiles = [
'discussion/js/spec/discussion_board_factory_spec.js',
'discussion/js/spec/discussion_profile_page_factory_spec.js',
'discussion/js/spec/discussion_board_view_spec.js',
......@@ -804,11 +809,11 @@
'teams/js/spec/views/topics_spec.js'
];
for (var i = 0; i < testFiles.length; i++) {
for (i = 0; i < testFiles.length; i++) {
testFiles[i] = '/base/' + testFiles[i];
}
var specHelpers = [
specHelpers = [
'common/js/spec_helpers/jasmine-extensions',
'common/js/spec_helpers/jasmine-stealth',
'common/js/spec_helpers/jasmine-waituntil'
......@@ -818,6 +823,6 @@
// spec files one by one, otherwise some end up getting nested under others.
window.requireSerial(specHelpers.concat(testFiles), function() {
// start test run, once Require.js is done
window.__karma__.start();
window.__karma__.start(); // eslint-disable-line no-underscore-dangle
});
}).call(this, requirejs);
......@@ -34,7 +34,7 @@
requirejs.config({
baseUrl: '/base/',
paths: {
moment: 'xmodule_js/common_static/js/vendor/moment-with-locales',
moment: 'xmodule_js/common_static/common/js/vendor/moment-with-locales',
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
'edx-ui-toolkit': 'edx-ui-toolkit'
},
......
......@@ -11,7 +11,7 @@
"jquery-migrate": "^1.4.1",
"jquery.scrollto": "~2.1.2",
"picturefill": "~3.0.2",
"requirejs": "~2.1.22",
"requirejs": "~2.3.2",
"uglify-js": "2.7.0",
"underscore": "~1.8.3",
"underscore.string": "~3.3.4"
......@@ -34,6 +34,7 @@
"karma-spec-reporter": "^0.0.20",
"pa11y": "4.0.1",
"pa11y-reporter-json-oldnode": "1.0.0",
"plato": "1.2.2"
"plato": "1.2.2",
"squirejs": "^0.1.0"
}
}
......@@ -8,6 +8,7 @@ from functools import wraps
from threading import Timer
import argparse
import glob
import os
import traceback
from paver import tasks
......@@ -46,17 +47,25 @@ COMMON_LOOKUP_PATHS = [
# A list of NPM installed libraries that should be copied into the common
# static directory.
NPM_INSTALLED_LIBRARIES = [
'jquery/dist/jquery.js',
'jquery-migrate/dist/jquery-migrate.js',
'jquery.scrollto/jquery.scrollTo.js',
'underscore/underscore.js',
'underscore.string/dist/underscore.string.js',
'picturefill/dist/picturefill.js',
'backbone-validation/dist/backbone-validation-min.js',
'backbone/backbone.js',
'edx-ui-toolkit/node_modules/backbone.paginator/lib/backbone.paginator.js',
'backbone-validation/dist/backbone-validation-min.js',
'edx-ui-toolkit/node_modules/moment-timezone/builds/moment-timezone-with-data.js',
'edx-ui-toolkit/node_modules/moment/min/moment-with-locales.js',
'jquery-migrate/dist/jquery-migrate.js',
'jquery.scrollto/jquery.scrollTo.js',
'jquery/dist/jquery.js',
'picturefill/dist/picturefill.js',
'requirejs/require.js',
'underscore.string/dist/underscore.string.js',
'underscore/underscore.js',
]
# A list of NPM installed developer libraries that should be copied into the common
# static directory only in development mode.
NPM_INSTALLED_DEVELOPER_LIBRARIES = [
'edx-ui-toolkit/node_modules/sinon/pkg/sinon.js',
'squirejs/src/Squire.js',
]
# Directory to install static vendor files
......@@ -597,6 +606,19 @@ def process_npm_assets():
"""
Process vendor libraries installed via NPM.
"""
def copy_vendor_library(library, skip_if_missing=False):
"""
Copies a vendor library to the shared vendor directory.
"""
library_path = 'node_modules/{library}'.format(library=library)
if os.path.exists(library_path):
sh('/bin/cp -rf {library_path} {vendor_dir}'.format(
library_path=library_path,
vendor_dir=NPM_VENDOR_DIRECTORY,
))
elif not skip_if_missing:
raise Exception('Missing vendor file {library_path}'.format(library_path=library_path))
# Skip processing of the libraries if this is just a dry run
if tasks.environment.dry_run:
tasks.environment.info("install npm_assets")
......@@ -606,11 +628,14 @@ def process_npm_assets():
NPM_VENDOR_DIRECTORY.mkdir_p()
# Copy each file to the vendor directory, overwriting any existing file.
print("Copying vendor files into static directory")
for library in NPM_INSTALLED_LIBRARIES:
sh('/bin/cp -rf node_modules/{library} {vendor_dir}'.format(
library=library,
vendor_dir=NPM_VENDOR_DIRECTORY,
))
copy_vendor_library(library)
# Copy over each developer library too if they have been installed
print("Copying developer vendor files into static directory")
for library in NPM_INSTALLED_DEVELOPER_LIBRARIES:
copy_vendor_library(library, skip_if_missing=True)
def process_xmodule_assets():
......
......@@ -3,8 +3,6 @@
"version": "0.0.1",
"dependencies": {
"annotator": "1.2.6",
"backbone": "1.0.0",
"backbone.paginator": "0.8.1",
"backbone-relational": "0.9.0",
"codemirror": "3.21.0",
"date": "1.0",
......@@ -12,18 +10,12 @@
"draggabilly": "1.2.4",
"jquery-form": "3.18.0",
"jquery-watch": "2.0",
"moment": "2.10.6",
"mustache": "0.5.1",
"rangeslider": "1.0",
"requirejs-text": "2.0.14",
"slickgrid": "2.1",
"timeago": "0.11.4",
"tinymce": "4.0.20",
"urijs": "1.11.2",
"url": "1.8.4"
},
"devDependencies": {
"sinon": "1.17.0",
"squire": "1.0.0"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment