summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-02-06 11:34:26 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-02-12 12:38:31 +0200
commitcbd09bd37c87539889f6be688276a84bc57e5bf5 (patch)
treed116b74b81a9aebf1979a811cb910f069ce955db
parent62c559013516b74d59ef54ea316f8dc35ef2f477 (diff)
downloadaconf-cbd09bd37c87539889f6be688276a84bc57e5bf5.tar.bz2
aconf-cbd09bd37c87539889f6be688276a84bc57e5bf5.tar.xz
web client: use RequireJS for dependency management
-rw-r--r--web/client.html11
-rw-r--r--web/client.js2558
-rw-r--r--web/lib/require.js36
3 files changed, 1328 insertions, 1277 deletions
diff --git a/web/client.html b/web/client.html
index da812f3..7cce3ca 100644
--- a/web/client.html
+++ b/web/client.html
@@ -9,15 +9,8 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="client.css"></link>
- <script type="text/javascript" src="lib/underscore.js"></script>
- <script type="text/javascript" src="lib/jquery.js"></script>
- <script type="text/javascript" src="lib/jquery-bbq.js"></script>
- <script type="text/javascript" src="lib/jquery-blockui.js"></script>
- <script type="text/javascript" src="lib/jquery-ui/core.js"></script>
- <script type="text/javascript" src="lib/jquery-ui/widget.js"></script>
- <script type="text/javascript" src="lib/jquery-ui/mouse.js"></script>
- <script type="text/javascript" src="lib/jquery-ui/sortable.js"></script>
- <script type="text/javascript" src="client.js"></script>
+ <script type="text/javascript" data-main="client.js" src="lib/require.js">
+ </script>
</head>
<body>
<div id="status">
diff --git a/web/client.js b/web/client.js
index f4fd89d..25cf988 100644
--- a/web/client.js
+++ b/web/client.js
@@ -3,1494 +3,1516 @@
* See LICENSE file for license details
*/
-$(function() {
- $("#login").submit(function() {
-
- var statusBar = (function() {
- function set(status, msg, mode) {
- $("#status").prop("class", status);
- $("#status p").text(msg);
- $("#logout").prop("class", mode ? "hidden" : null);
- $("#status div").prop("class", mode == "txn" ? null : "hidden");
- $("#commit").prop("disabled", status == "invalid");
- }
-
- function setError(msg, mode) { set("invalid", msg, mode); };
-
- return {
- reset: function() { set(null, ""); },
- setError: setError,
- validationReady: function(txnValid) {
- if (txnValid)
- set("changed", "You have uncommitted changes", "txn");
- else setError("Some values need checking", "txn");
- }
- }
- })();
-
- $.ajax("/login", {
- type: "POST",
- data: JSON.stringify({
- username: $("#username").val(), password: $("#password").val()
- })
- }).done(function(data, status, xhr) {
-
- function split(path) {
- var res = [];
- while (path && path != "/") {
- var comp = path.match(/^\/([^\\\/]|\\.)+/)[0];
- res.push(comp.substring(1));
- path = path.substring(comp.length);
- }
- return res;
- }
-
- function escape(name) {
- if (!_.isString(name)) return String(name);
- name = name.replace(/([\\\/])/g, "\\$1");
- if (isNaN(Number(name))) return name;
- return "\\" + name;
- }
-
- function join() {
- var arg = _.toArray(arguments);
- if (arg.length == 1) return arg[0];
-
- var path = arg.shift();
- var name = arg.shift();
-
- arg.unshift((path == "/" ? "" : path) + "/" + escape(name));
-
- return join.apply(undefined, arg);
- }
-
- function isSubordinate(p1, p2, real) {
- p1 = split(p1);
- p2 = split(p2);
- if (real && p1.length <= p2.length) return false;
- for (var i = 0; i < p2.length; i++)
- if (p1[i] != p2[i]) return false;
- return true;
- }
-
- function isList(meta) {
- return _.contains(["list", "set"], meta.type);
- }
-
- function isCollection(meta) {
- return meta.type == "collection" || isList(meta);
- }
-
- function isTreeNode(meta) {
- return meta.type == "model" || isCollection(meta);
- }
-
-
- var txnMgr = (function(token, saveRequired) {
- var txn, changed, invalid;
-
- function reset() {
- txn = null;
- changed = {};
- invalid = {};
+requirejs.config({
+ baseUrl: "lib",
+ shim: {
+ underscore: {exports: "_"},
+ "jquery-bbq": {deps: ["jquery"]},
+ "jquery-blockui": {deps: ["jquery"]},
+ "jquery-ui/core": {deps: ["jquery"]},
+ "jquery-ui/mouse": {deps: ["jquery-ui/widget"]},
+ "jquery-ui/sortable": {deps: ["jquery-ui/core", "jquery-ui/mouse"]},
+ "jquery-ui/widget": {deps: ["jquery"]},
+ }
+});
+
+require(
+ [
+ "jquery",
+ "underscore",
+ "jquery-bbq",
+ "jquery-blockui",
+ "jquery-ui/sortable"
+ ],
+ function($, _) {
+ $("#login").submit(function() {
+
+ var statusBar = (function() {
+ function set(status, msg, mode) {
+ $("#status").prop("class", status);
+ $("#status p").text(msg);
+ $("#logout").prop("class", mode ? "hidden" : null);
+ $("#status div").prop("class", mode == "txn" ? null : "hidden");
+ $("#commit").prop("disabled", status == "invalid");
}
- reset();
- function isValid() { return !(_.size(invalid)); }
+ function setError(msg, mode) { set("invalid", msg, mode); };
- function request(url, options) {
- options = options || {};
- options.headers = {"X-ACF-Auth-Token": token};
- if (txn) options.headers["X-ACF-Transaction-ID"] = txn;
- if (options.data != undefined)
- options.data = JSON.stringify(options.data);
- return $.ajax(url, options);
+ return {
+ reset: function() { set(null, ""); },
+ setError: setError,
+ validationReady: function(txnValid) {
+ if (txnValid)
+ set("changed", "You have uncommitted changes", "txn");
+ else setError("Some values need checking", "txn");
+ }
}
+ })();
- function abort() {
- request("/transaction", {type: "DELETE"});
- reset();
+ $.ajax("/login", {
+ type: "POST",
+ data: JSON.stringify({
+ username: $("#username").val(), password: $("#password").val()
+ })
+ }).done(function(data, status, xhr) {
+
+ function split(path) {
+ var res = [];
+ while (path && path != "/") {
+ var comp = path.match(/^\/([^\\\/]|\\.)+/)[0];
+ res.push(comp.substring(1));
+ path = path.substring(comp.length);
+ }
+ return res;
}
-
- function objRequest(path, options) {
- return request("/config" + path, options);
+
+ function escape(name) {
+ if (!_.isString(name)) return String(name);
+ name = name.replace(/([\\\/])/g, "\\$1");
+ if (isNaN(Number(name))) return name;
+ return "\\" + name;
}
- function exclusive(task) {
- $.blockUI();
+ function join() {
+ var arg = _.toArray(arguments);
+ if (arg.length == 1) return arg[0];
- var def = $.Deferred();
- function resolve(txnValid) { def.resolve(txnValid); }
- function reject() { def.reject(); }
+ var path = arg.shift();
+ var name = arg.shift();
- var tasks = _.filter(
- _.pluck(_.values(invalid), 1), function(d) {
- return d && d.state() == "pending";
- }
- );
+ arg.unshift((path == "/" ? "" : path) + "/" + escape(name));
- if (tasks.length)
- tasks[0].always(function() {
- exclusive(task).done(resolve).fail(reject);
- });
- else task().always($.unblockUI).done(resolve).fail(reject);
-
- return def;
+ return join.apply(undefined, arg);
+ }
+
+ function isSubordinate(p1, p2, real) {
+ p1 = split(p1);
+ p2 = split(p2);
+ if (real && p1.length <= p2.length) return false;
+ for (var i = 0; i < p2.length; i++)
+ if (p1[i] != p2[i]) return false;
+ return true;
+ }
+
+ function isList(meta) {
+ return _.contains(["list", "set"], meta.type);
+ }
+
+ function isCollection(meta) {
+ return meta.type == "collection" || isList(meta);
+ }
+
+ function isTreeNode(meta) {
+ return meta.type == "model" || isCollection(meta);
}
+
- function query(path) {
- var def = $.Deferred();
+ var txnMgr = (function(token, saveRequired) {
+ var txn, changed, invalid;
+
+ function reset() {
+ txn = null;
+ changed = {};
+ invalid = {};
+ }
+ reset();
- objRequest(path).done(function(data) {
- if (isTreeNode(data.meta) && !_.size(data.data))
- data.data = isList(data.meta) ? [] : {};
+ function isValid() { return !(_.size(invalid)); }
- function index(name) {
- return _.isArray(data.data) ? name - 1 : name;
- }
+ function request(url, options) {
+ options = options || {};
+ options.headers = {"X-ACF-Auth-Token": token};
+ if (txn) options.headers["X-ACF-Transaction-ID"] = txn;
+ if (options.data != undefined)
+ options.data = JSON.stringify(options.data);
+ return $.ajax(url, options);
+ }
+
+ function abort() {
+ request("/transaction", {type: "DELETE"});
+ reset();
+ }
+
+ function objRequest(path, options) {
+ return request("/config" + path, options);
+ }
- data.get = function(name, valid) {
- var p = join(path, name);
- if (!valid && p in invalid) return invalid[p][0];
+ function exclusive(task) {
+ $.blockUI();
- if (data.meta.type == "set") {
- return _.contains(
- data.data, name
- ) ? name : null;
- }
+ var def = $.Deferred();
+ function resolve(txnValid) { def.resolve(txnValid); }
+ function reject() { def.reject(); }
- return data.data[index(name)];
- };
-
- data.metaRequest = function(name) {
- return request("/meta" + join(path, name));
- };
-
- data.match = function(filter) {
- if (!filter) return true;
- return _.every(_.map(filter, function(values, key) {
- return _.contains(values, data.data[key]);
- }));
- };
-
- data.status = function(name) {
- var p = name ? join(path, name) : path;
- function scan(objs) {
- return _.size(_.filter(
- _.keys(objs), function(obj) {
- return isSubordinate(obj, p);
- }
- ));
+ var tasks = _.filter(
+ _.pluck(_.values(invalid), 1), function(d) {
+ return d && d.state() == "pending";
}
+ );
+
+ if (tasks.length)
+ tasks[0].always(function() {
+ exclusive(task).done(resolve).fail(reject);
+ });
+ else task().always($.unblockUI).done(resolve).fail(reject);
+
+ return def;
+ }
+
+ function query(path) {
+ var def = $.Deferred();
- if (scan(invalid)) return "invalid";
- if (scan(changed)) return "changed";
- return null;
- };
-
- data.validate = function() {
- var valid = true;
- if (data.meta.required) {
- valid = _.size(data.data);
- if (valid) delete invalid[path];
- else invalid[path] = [path];
+ objRequest(path).done(function(data) {
+ if (isTreeNode(data.meta) && !_.size(data.data))
+ data.data = isList(data.meta) ? [] : {};
+
+ function index(name) {
+ return _.isArray(data.data) ? name - 1 : name;
}
- return valid && isValid();
- };
- data.set = function(name, newValue) {
- var def = $.Deferred();
- function reject(xhr) { def.reject(xhr); }
+ data.get = function(name, valid) {
+ var p = join(path, name);
+ if (!valid && p in invalid) return invalid[p][0];
- var mpath = join(path, name);
+ if (data.meta.type == "set") {
+ return _.contains(
+ data.data, name
+ ) ? name : null;
+ }
- var value = data.get(name, true);
- if (value == undefined) value = null;
+ return data.data[index(name)];
+ };
+
+ data.metaRequest = function(name) {
+ return request("/meta" + join(path, name));
+ };
+
+ data.match = function(filter) {
+ if (!filter) return true;
+ return _.every(_.map(filter, function(values, key) {
+ return _.contains(values, data.data[key]);
+ }));
+ };
+
+ data.status = function(name) {
+ var p = name ? join(path, name) : path;
+ function scan(objs) {
+ return _.size(_.filter(
+ _.keys(objs), function(obj) {
+ return isSubordinate(obj, p);
+ }
+ ));
+ }
- var tn = _.isObject(newValue);
- var npv = tn ? mpath : newValue;
+ if (scan(invalid)) return "invalid";
+ if (scan(changed)) return "changed";
+ return null;
+ };
+
+ data.validate = function() {
+ var valid = true;
+ if (data.meta.required) {
+ valid = _.size(data.data);
+ if (valid) delete invalid[path];
+ else invalid[path] = [path];
+ }
+ return valid && isValid();
+ };
- function ignore(path) {
- _.each(_.keys(invalid), function(p) {
- if (isSubordinate(p, path))
- delete invalid[p];
- });
- }
+ data.set = function(name, newValue) {
+ var def = $.Deferred();
+ function reject(xhr) { def.reject(xhr); }
- function resolve() {
- if (mpath in invalid &&
- invalid[mpath][1] == def) {
-
- var del = invalid[mpath][0] == null;
+ var mpath = join(path, name);
+
+ var value = data.get(name, true);
+ if (value == undefined) value = null;
- delete invalid[mpath];
- if (del) ignore(mpath);
+ var tn = _.isObject(newValue);
+ var npv = tn ? mpath : newValue;
+
+ function ignore(path) {
+ _.each(_.keys(invalid), function(p) {
+ if (isSubordinate(p, path))
+ delete invalid[p];
+ });
}
-
- def.resolve(isValid());
- }
- function validate() {
- var del = newValue == null;
- var set = data.meta.type == "set";
+ function resolve() {
+ if (mpath in invalid &&
+ invalid[mpath][1] == def) {
+
+ var del = invalid[mpath][0] == null;
- var options;
- if (!del)
- options = {
- type: set ? "POST" : "PUT",
- data: newValue
- };
- else if (data.get(name, true) != null)
- options = {type: "DELETE"};
-
- if (!options) {
- if (data.meta.type == "model" &&
- _.findWhere(
- data.meta.fields, {name: name}
- ).required)
- def.reject("Required value not set");
- else resolve();
- return;
+ delete invalid[mpath];
+ if (del) ignore(mpath);
+ }
+
+ def.resolve(isValid());
}
-
- objRequest(
- set && !del ? path : mpath, options
- ).done(function() {
- if (!(mpath in changed))
- changed[mpath] = value;
- if (!tn && newValue == changed[mpath])
- delete changed[mpath];
+
+ function validate() {
+ var del = newValue == null;
+ var set = data.meta.type == "set";
+
+ var options;
+ if (!del)
+ options = {
+ type: set ? "POST" : "PUT",
+ data: newValue
+ };
+ else if (data.get(name, true) != null)
+ options = {type: "DELETE"};
+
+ if (!options) {
+ if (data.meta.type == "model" &&
+ _.findWhere(
+ data.meta.fields, {name: name}
+ ).required)
+ def.reject("Required value not set");
+ else resolve();
+ return;
+ }
- if (npv == null)
- _.each(
- _.keys(changed),
- function(p) {
- if (isSubordinate(p, mpath, true))
- delete changed[p];
- }
- );
+ objRequest(
+ set && !del ? path : mpath, options
+ ).done(function() {
+ if (!(mpath in changed))
+ changed[mpath] = value;
+ if (!tn && newValue == changed[mpath])
+ delete changed[mpath];
+
+ if (npv == null)
+ _.each(
+ _.keys(changed),
+ function(p) {
+ if (isSubordinate(p, mpath, true))
+ delete changed[p];
+ }
+ );
+
+ if (data.meta.type == "list" && del)
+ data.data.splice(name - 1, 1);
+ else if (!set) data.data[index(name)] = npv;
+ else if (del)
+ data.data.splice(
+ data.data.indexOf(name), 1
+ );
+ else data.data.push(name);
+
+ data.validate();
+
+ if (data.meta.type == "model")
+ _.each(
+ data.meta.fields, function(field) {
+ if (field.condition &&
+ field.condition[name] &&
+ !_.contains(
+ field.condition[name],
+ newValue
+ ))
+ ignore(
+ join(path, field.name)
+ );
+ }
+ );
+
+ if (tn && !set)
+ query(mpath).done(function(data) {
+
+ if (mpath in invalid) {
+ if (data.meta.type == "model")
+ _.each(
+ data.meta.fields,
+ function(field) {
+ var mmpath = join(
+ mpath,
+ field.name
+ );
+ if (field.required &&
+ data.match(
+ field.condition
+ ) &&
+ !(mmpath in invalid) &&
+ (isCollection(
+ field
+ ) || data.get(
+ field.name
+ ) == null)) {
+ invalid[
+ mmpath
+ ] = [
+ null
+ ];
+ }
+ });
+
+ else if (isCollection(data.meta) &&
+ data.meta.required)
+ invalid[mpath] = [mpath];
+ }
+
+ resolve();
+ }).fail(reject);
+
+ else resolve();
+
+ }).fail(reject);
+ }
+
+ var prevTask;
+ if (mpath in invalid) prevTask = invalid[mpath][1];
- if (data.meta.type == "list" && del)
- data.data.splice(name - 1, 1);
- else if (!set) data.data[index(name)] = npv;
- else if (del)
- data.data.splice(
- data.data.indexOf(name), 1
- );
- else data.data.push(name);
+ invalid[mpath] = [npv, def];
- data.validate();
+ if (prevTask) prevTask.always(validate);
+ else validate();
- if (data.meta.type == "model")
+ return def;
+ };
+
+ data.add = function(name) {
+ return data.set(name, name);
+ };
+
+ function adjustListIndex(oldIndex, newIndex) {
+ var opath = join(path, oldIndex);
+ var npath = join(path, newIndex);
+ _.each(
+ [changed, invalid],
+ function(map) {
_.each(
- data.meta.fields, function(field) {
- if (field.condition &&
- field.condition[name] &&
- !_.contains(
- field.condition[name],
- newValue
- ))
- ignore(
- join(path, field.name)
- );
- }
- );
-
- if (tn && !set)
- query(mpath).done(function(data) {
-
- if (mpath in invalid) {
- if (data.meta.type == "model")
- _.each(
- data.meta.fields,
- function(field) {
- var mmpath = join(
- mpath,
- field.name
- );
- if (field.required &&
- data.match(
- field.condition
- ) &&
- !(mmpath in invalid) &&
- (isCollection(
- field
- ) || data.get(
- field.name
- ) == null)) {
- invalid[
- mmpath
- ] = [
- null
- ];
- }
- });
-
- else if (isCollection(data.meta) &&
- data.meta.required)
- invalid[mpath] = [mpath];
- }
+ _.keys(map),
+ function(p) {
+ if (isSubordinate(
+ p, opath
+ )) {
+ map[npath +
+ p.substring(
+ opath.length
+ )] = map[p];
+ delete map[p];
+ }
+ });
+ }
+ );
+ }
- resolve();
- }).fail(reject);
-
- else resolve();
-
- }).fail(reject);
+ function adjustListIndices(start, end) {
+ var offset = start < end ? 1 : -1;
+ for (var i = start; i != end; i += offset)
+ adjustListIndex(i + offset, i);
}
- var prevTask;
- if (mpath in invalid) prevTask = invalid[mpath][1];
+ function _delete(name) {
+ var def = $.Deferred();
+ var length = data.data.length;
- invalid[mpath] = [npv, def];
+ data.set(name, null).done(function(txnValid) {
+ if (isTreeNode(data.meta) &&
+ data.meta.type != "set") {
- if (prevTask) prevTask.always(validate);
- else validate();
+ delete changed[join(path, name)];
+ changed[path] = path;
- return def;
- };
-
- data.add = function(name) {
- return data.set(name, name);
- };
-
- function adjustListIndex(oldIndex, newIndex) {
- var opath = join(path, oldIndex);
- var npath = join(path, newIndex);
- _.each(
- [changed, invalid],
- function(map) {
- _.each(
- _.keys(map),
- function(p) {
- if (isSubordinate(
- p, opath
- )) {
- map[npath +
- p.substring(
- opath.length
- )] = map[p];
- delete map[p];
- }
- });
- }
- );
- }
+ if (data.meta.type == "list")
+ adjustListIndices(name, length);
+ }
+ def.resolve(txnValid);
- function adjustListIndices(start, end) {
- var offset = start < end ? 1 : -1;
- for (var i = start; i != end; i += offset)
- adjustListIndex(i + offset, i);
- }
+ }).fail(function() { def.reject(); });
- function _delete(name) {
- var def = $.Deferred();
- var length = data.data.length;
+ return def;
+ }
- data.set(name, null).done(function(txnValid) {
- if (isTreeNode(data.meta) &&
- data.meta.type != "set") {
+ data.delete = function(name) {
+ return exclusive(function() {
+ return _delete(name);
+ });
+ };
- delete changed[join(path, name)];
- changed[path] = path;
+ data.move = function(oldIndex, newIndex) {
+ if (oldIndex == newIndex)
+ return $.Deferred().resolve(isValid());
- if (data.meta.type == "list")
- adjustListIndices(name, length);
- }
- def.resolve(txnValid);
+ var value = data.get(oldIndex);
+ var length = data.data.length;
- }).fail(function() { def.reject(); });
+ return exclusive(function() {
+ var def = $.Deferred();
+ function reject() { def.reject(); }
- return def;
- }
+ if (oldIndex > newIndex) oldIndex++;
+ else newIndex++;
- data.delete = function(name) {
- return exclusive(function() {
- return _delete(name);
- });
- };
+ objRequest(path, {type: "POST", data: {
+ index: newIndex,
+ data: isTreeNode(data.meta.members) ?
+ join(path, oldIndex) : value
+ }}).done(function() {
- data.move = function(oldIndex, newIndex) {
- if (oldIndex == newIndex)
- return $.Deferred().resolve(isValid());
+ data.data.splice(newIndex - 1, 0, value);
- var value = data.get(oldIndex);
- var length = data.data.length;
+ adjustListIndices(length + 1, newIndex);
+ adjustListIndex(oldIndex, newIndex);
- return exclusive(function() {
- var def = $.Deferred();
- function reject() { def.reject(); }
+ data.delete(oldIndex)
+ .done(function(txnValid) {
+ def.resolve(txnValid);
+ })
+ .fail(reject);
- if (oldIndex > newIndex) oldIndex++;
- else newIndex++;
+ }).fail(reject);
- objRequest(path, {type: "POST", data: {
- index: newIndex,
- data: isTreeNode(data.meta.members) ?
- join(path, oldIndex) : value
- }}).done(function() {
+ return def;
+ });
+ };
- data.data.splice(newIndex - 1, 0, value);
+ data.invoke = function(name) {
+ return objRequest(join(path, name), {type: "POST"});
+ };
- adjustListIndices(length + 1, newIndex);
- adjustListIndex(oldIndex, newIndex);
+ def.resolve(data);
+ }).fail(function() { def.reject(); });
+
+ return def;
+ }
- data.delete(oldIndex)
- .done(function(txnValid) {
- def.resolve(txnValid);
- })
- .fail(reject);
+ return {
+ start: function() {
+ var def = $.Deferred();
+ if (txn && isValid() && !(_.size(changed))) abort();
- }).fail(reject);
+ if (txn)
+ def.resolve();
- return def;
- });
- };
+ else request("/transaction", {type: "POST"})
+ .done(function(data, status, xhr) {
+ txn = xhr.getResponseHeader(
+ "X-ACF-Transaction-ID"
+ );
+ def.resolve();
+ })
+ .fail(function() { def.reject(); });
- data.invoke = function(name) {
- return objRequest(join(path, name), {type: "POST"});
- };
+ return def;
+ },
- def.resolve(data);
- }).fail(function() { def.reject(); });
-
- return def;
- }
+ commit: function() {
+ var def = $.Deferred();
+ function reject(xhr) { def.reject(xhr); }
+ request(
+ "/transaction", {type: "PUT"}
+ ).done(function() {
+ reset();
+ if (saveRequired)
+ request(
+ "/save", {type: "POST"}
+ ).done(function() {
+ def.resolve();
+ }).fail(reject);
+ else def.resolve();
+ }).fail(reject);
+ return def;
+ },
- return {
- start: function() {
- var def = $.Deferred();
- if (txn && isValid() && !(_.size(changed))) abort();
+ abort: abort,
- if (txn)
- def.resolve();
+ query: query,
- else request("/transaction", {type: "POST"})
- .done(function(data, status, xhr) {
- txn = xhr.getResponseHeader(
- "X-ACF-Transaction-ID"
- );
- def.resolve();
- })
- .fail(function() { def.reject(); });
+ logout: function() {
+ return request("/login", {type: "DELETE"});
+ }
+ };
+ })(
+ xhr.getResponseHeader("X-ACF-Auth-Token"),
+ xhr.getResponseHeader("X-ACF-Save-Required") == "1"
+ );
+
- return def;
- },
- commit: function() {
- var def = $.Deferred();
- function reject(xhr) { def.reject(xhr); }
- request(
- "/transaction", {type: "PUT"}
- ).done(function() {
- reset();
- if (saveRequired)
- request(
- "/save", {type: "POST"}
- ).done(function() {
- def.resolve();
- }).fail(reject);
- else def.resolve();
- }).fail(reject);
- return def;
- },
+ function formatError(msg, xhr) {
+ msg += " " + xhr.statusCode().status;
+ if (xhr.responseText) msg += ': ' + xhr.responseText;
+ return msg;
+ }
- abort: abort,
- query: query,
+ function href() {
+ return $("<a>").attr({href: "javascript:void(0);"});
+ }
- logout: function() {
- return request("/login", {type: "DELETE"});
+ function objectRef(value, el) {
+ el = el || href();
+ if (value) {
+ el.click(function() {
+ $.bbq.pushState("#" + value);
+ }).text("Show");
}
+ return el;
};
- })(
- xhr.getResponseHeader("X-ACF-Auth-Token"),
- xhr.getResponseHeader("X-ACF-Save-Required") == "1"
- );
-
-
-
- function formatError(msg, xhr) {
- msg += " " + xhr.statusCode().status;
- if (xhr.responseText) msg += ': ' + xhr.responseText;
- return msg;
- }
-
-
- function href() {
- return $("<a>").attr({href: "javascript:void(0);"});
- }
-
- function objectRef(value, el) {
- el = el || href();
- if (value) {
- el.click(function() {
- $.bbq.pushState("#" + value);
- }).text("Show");
+
+ function makeRow(el) {
+ if (el.is("td")) return $("<tr>").html(el);
+ return el;
}
- return el;
- };
- function makeRow(el) {
- if (el.is("td")) return $("<tr>").html(el);
- return el;
- }
+ function setStatus(el, status) { el.prop("class", status); }
+
- function setStatus(el, status) { el.prop("class", status); }
+ var Widget = {
+ extend: function(spec) {
+ var res = Object.create(this);
+ for (key in spec) res[key] = spec[key];
+ res.base = this;
+ return res;
+ },
+ super: function() {
+ var args = _.toArray(arguments);
+ var cls = args.shift();
+ var key = args.shift();
+ return cls.base[key].apply(this, args);
+ },
- var Widget = {
- extend: function(spec) {
- var res = Object.create(this);
- for (key in spec) res[key] = spec[key];
- res.base = this;
- return res;
- },
+ new: function(data, name, meta, level, editable, removable) {
+ return Object.create(this).init(
+ data, name, meta, level, editable, removable
+ );
+ },
- super: function() {
- var args = _.toArray(arguments);
- var cls = args.shift();
- var key = args.shift();
- return cls.base[key].apply(this, args);
- },
+ init: function(data, name, meta, level, editable, removable) {
+ this.data = data;
+ this.name = name;
+ this.meta = meta;
+ this.level = level;
- new: function(data, name, meta, level, editable, removable) {
- return Object.create(this).init(
- data, name, meta, level, editable, removable
- );
- },
-
- init: function(data, name, meta, level, editable, removable) {
- this.data = data;
- this.name = name;
- this.meta = meta;
- this.level = level;
-
- var value = data.get(name);
- var status = data.status(name);
-
- if (!editable || !meta.editable) {
- var el = this.staticRender(value, meta);
- if (el) {
- setStatus(el, status);
- return el;
+ var value = data.get(name);
+ var status = data.status(name);
+
+ if (!editable || !meta.editable) {
+ var el = this.staticRender(value, meta);
+ if (el) {
+ setStatus(el, status);
+ return el;
+ }
}
- }
- this.makeEl();
- this.dynamic = meta.dynamic;
+ this.makeEl();
+ this.dynamic = meta.dynamic;
- var self = this;
+ var self = this;
- var request;
- function handleRequest(req) {
- request = req;
- req.done(function(value, meta) {
- if (req != request) return;
- self.render(value, meta);
- self.setStatus(status);
- });
- }
+ var request;
+ function handleRequest(req) {
+ request = req;
+ req.done(function(value, meta) {
+ if (req != request) return;
+ self.render(value, meta);
+ self.setStatus(status);
+ });
+ }
- this.wrapped = this.wrap();
- this.visible = true;
+ this.wrapped = this.wrap();
+ this.visible = true;
+
+ if (removable) {
+ var link = href().click(function() {
+ data.delete(name).done(function(txnValid) {
+ $("#content").trigger("reload", [txnValid]);
+ })
+ }).text("Delete");
+ this.wrapped = makeRow(this.wrapped);
+ if (this.wrapped.is("tr")) link = $("<td>").html(link);
+ this.wrapped.append(link);
+ }
- if (removable) {
- var link = href().click(function() {
- data.delete(name).done(function(txnValid) {
- $("#content").trigger("reload", [txnValid]);
- })
- }).text("Delete");
- this.wrapped = makeRow(this.wrapped);
- if (this.wrapped.is("tr")) link = $("<td>").html(link);
- this.wrapped.append(link);
- }
+ handleRequest(this.requestData(value, meta));
- handleRequest(this.requestData(value, meta));
+ function validate() {
+ request.done(function(value) {
+ self.validate(value);
+ });
+ }
- function validate() {
- request.done(function(value) {
- self.validate(value);
+ this.wrapped.on("start", function(event) {
+ if (data.status(name) == "invalid") validate();
+ else self.setVisible();
+ event.stopPropagation();
});
- }
- this.wrapped.on("start", function(event) {
- if (data.status(name) == "invalid") validate();
- else self.setVisible();
- event.stopPropagation();
- });
+ this.wrapped.on("updated", function(event, field) {
+ if (self.dynamic) handleRequest(self.refreshData());
+ if (!field ||
+ self.dynamic ||
+ (meta.condition && field in meta.condition))
+ validate();
+ event.stopPropagation();
+ });
- this.wrapped.on("updated", function(event, field) {
- if (self.dynamic) handleRequest(self.refreshData());
- if (!field ||
- self.dynamic ||
- (meta.condition && field in meta.condition))
- validate();
- event.stopPropagation();
- });
+ return this.wrapped;
+ },
- return this.wrapped;
- },
+ makeEl: function() { this.el = this.createEl(); },
- makeEl: function() { this.el = this.createEl(); },
+ requestData: function(value, meta) {
+ return $.Deferred().resolve(value, meta);
+ },
- requestData: function(value, meta) {
- return $.Deferred().resolve(value, meta);
- },
+ refreshData: function() {
+ var def = $.Deferred();
+ var self = this;
+ this.data.metaRequest(this.name).done(function(data) {
+ def.resolve(self.get(), data);
+ });
+ return def;
+ },
- refreshData: function() {
- var def = $.Deferred();
- var self = this;
- this.data.metaRequest(this.name).done(function(data) {
- def.resolve(self.get(), data);
- });
- return def;
- },
+ wrap: function() { return this.el; },
- wrap: function() { return this.el; },
+ showStatus: true,
- showStatus: true,
+ setStatus: function(status) {
+ if (this.el && this.showStatus)
+ setStatus(this.statusEl(), status);
+ },
- setStatus: function(status) {
- if (this.el && this.showStatus)
- setStatus(this.statusEl(), status);
- },
+ statusEl: function() { return this.el; },
- statusEl: function() { return this.el; },
+ setVisible: function() {
+ this.visible = this.data.match(this.meta.condition);
+ if (this.wrapped)
+ this.wrapped.trigger("setVisible", [this.visible]);
+ },
- setVisible: function() {
- this.visible = this.data.match(this.meta.condition);
- if (this.wrapped)
- this.wrapped.trigger("setVisible", [this.visible]);
- },
+ validate: function(value) { this.setVisible(); }
+ };
- validate: function(value) { this.setVisible(); }
- };
+ var Field = Widget.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ this.editable = editable && meta.editable;
- var Field = Widget.extend({
- init: function(
- data, name, meta, level, editable, removable
- ) {
- this.editable = editable && meta.editable;
+ var el = this.super(
+ Field,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ );
- var el = this.super(
- Field,
- "init",
- data,
- name,
- meta,
- level,
- editable,
- removable
- );
+ if (this.editable)
+ this.field.change(_.bind(this.validateChange, this));
+
+ return el;
+ },
- if (this.editable)
- this.field.change(_.bind(this.validateChange, this));
-
- return el;
- },
-
- staticRender: function(value, meta) {
- return $("<td>").text(value);
- },
-
- makeEl: function() {
- this.super(Field, "makeEl");
- if (!this.field) this.field = this.el;
- },
-
- createEl: function() { return $("<input>"); },
-
- render: function(value, meta) {
- this.field.attr({type: "text", value: value});
- },
-
- wrap: function() {
- var td = $("<td>");
- this.msg = $("<div>");
- td.append(this.msg);
- td.append(this.el);
- return td;
- },
-
- validate: function(value) {
- this.super(Field, "validate", value);
- if (!this.visible || !this.editable) return;
- this.validateChange();
- },
-
- validateChange: function() {
- this.msg.text("[checking]");
- statusBar.setError("Validating changes", "validate");
-
- var self = this;
-
- this.data.set(this.name, this.get())
- .done(function(txnValid) {
- self.msg.empty()
- self.setStatus(self.data.status(self.name));
- statusBar.validationReady(txnValid);
- self.el.trigger("validated");
-
- })
- .fail(function(xhr) {
- if (_.isString(xhr)) self.msg.text(xhr);
-
- else if (xhr.statusCode().status == 422)
- self.msg.html(
- _.reduce(
- _.map(
- $.parseJSON(xhr.responseText),
- _.escape
- ),
- function(a, b) {
- return a + "<br/>" + b;
- }
- )
- );
-
- else self.msg.text(formatError("Error", xhr));
-
- self.setStatus("invalid");
- statusBar.validationReady(false);
- });
- },
+ staticRender: function(value, meta) {
+ return $("<td>").text(value);
+ },
- get: function() {
- return this.editable ? (
- this.field.val() || null
- ) : this.data.get(this.name);
- }
- });
+ makeEl: function() {
+ this.super(Field, "makeEl");
+ if (!this.field) this.field = this.el;
+ },
+ createEl: function() { return $("<input>"); },
- var ComboBox = Field.extend({
- createEl: function() { return $("<select>"); },
+ render: function(value, meta) {
+ this.field.attr({type: "text", value: value});
+ },
+
+ wrap: function() {
+ var td = $("<td>");
+ this.msg = $("<div>");
+ td.append(this.msg);
+ td.append(this.el);
+ return td;
+ },
+
+ validate: function(value) {
+ this.super(Field, "validate", value);
+ if (!this.visible || !this.editable) return;
+ this.validateChange();
+ },
- staticRender: function(value, meta) {
- return this.super(
- ComboBox,
- "staticRender",
- _.findWhere(meta.choice, {value: value})["ui-value"],
- meta
- );
- },
+ validateChange: function() {
+ this.msg.text("[checking]");
+ statusBar.setError("Validating changes", "validate");
- render: function(value, meta) {
- var el = this.field.empty();
+ var self = this;
+
+ this.data.set(this.name, this.get())
+ .done(function(txnValid) {
+ self.msg.empty()
+ self.setStatus(self.data.status(self.name));
+ statusBar.validationReady(txnValid);
+ self.el.trigger("validated");
+
+ })
+ .fail(function(xhr) {
+ if (_.isString(xhr)) self.msg.text(xhr);
+
+ else if (xhr.statusCode().status == 422)
+ self.msg.html(
+ _.reduce(
+ _.map(
+ $.parseJSON(xhr.responseText),
+ _.escape
+ ),
+ function(a, b) {
+ return a + "<br/>" + b;
+ }
+ )
+ );
+
+ else self.msg.text(formatError("Error", xhr));
+
+ self.setStatus("invalid");
+ statusBar.validationReady(false);
+ });
+ },
- function opt(value, ui_value, selected) {
- el.append($("<option>").attr(
- {value: value, selected: selected}
- ).text(ui_value));
+ get: function() {
+ return this.editable ? (
+ this.field.val() || null
+ ) : this.data.get(this.name);
}
+ });
- if (!meta.required) opt("", "(none)", value == null);
- _.each(
- meta.choice,
- function(choice) {
- var selected = value == choice.value;
- if (choice.enabled || selected)
- opt(choice.value, choice["ui-value"], selected);
- }
- );
- }
- });
+ var ComboBox = Field.extend({
+ createEl: function() { return $("<select>"); },
- var CheckBox = Field.extend({
- staticRender: function(value, meta) {
- return $("<td>").text(value ? "Yes" : "No");
- },
+ staticRender: function(value, meta) {
+ return this.super(
+ ComboBox,
+ "staticRender",
+ _.findWhere(meta.choice, {value: value})["ui-value"],
+ meta
+ );
+ },
- statusEl: function() { return this.el.parent(); },
+ render: function(value, meta) {
+ var el = this.field.empty();
- render: function(value, meta) {
- this.field.attr({type: "checkbox", checked: value});
- },
+ function opt(value, ui_value, selected) {
+ el.append($("<option>").attr(
+ {value: value, selected: selected}
+ ).text(ui_value));
+ }
- get: function() { return this.field.is(":checked"); }
- });
+ if (!meta.required) opt("", "(none)", value == null);
+ _.each(
+ meta.choice,
+ function(choice) {
+ var selected = value == choice.value;
+ if (choice.enabled || selected)
+ opt(choice.value, choice["ui-value"], selected);
+ }
+ );
+ }
+ });
- var Link = Widget.extend({
- staticRender: function(value, meta) {
- return $("<td>").html(objectRef(value));
- },
+ var CheckBox = Field.extend({
+ staticRender: function(value, meta) {
+ return $("<td>").text(value ? "Yes" : "No");
+ },
- createEl: href,
+ statusEl: function() { return this.el.parent(); },
- render: function(value, meta) { objectRef(value, this.el) },
+ render: function(value, meta) {
+ this.field.attr({type: "checkbox", checked: value});
+ },
- wrap: function() { return $("<td>").html(this.el); },
-
- get: function() { return {}; }
- });
+ get: function() { return this.field.is(":checked"); }
+ });
- var Inline = Link.extend({
- init: function(
- data, name, meta, level, editable, removable
- ) {
- return this.super(
- Inline,
- "init",
- data,
- name,
- meta,
- Math.min(6, level + 1),
- editable,
- removable
- );
- },
+ var Link = Widget.extend({
+ staticRender: function(value, meta) {
+ return $("<td>").html(objectRef(value));
+ },
- staticRender: function(value, meta) { return null; },
+ createEl: href,
- createEl: function() { return $("<div>"); },
+ render: function(value, meta) { objectRef(value, this.el) },
- showStatus: false,
-
- requestData: function(value, meta) {
- this.path = value;
- return this.refreshData();
- },
-
- refreshData: function() {
- var def = $.Deferred();
- txnMgr.query(this.path).done(function(data) {
- def.resolve(data, data.meta);
- });
- return def;
- },
+ wrap: function() { return $("<td>").html(this.el); },
+
+ get: function() { return {}; }
+ });
- showHeading: true,
- render: function(data, meta) {
- if (this.showHeading)
- this.el.html(
- $("<h" + this.level + ">").text(meta["ui-name"])
+ var Inline = Link.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ return this.super(
+ Inline,
+ "init",
+ data,
+ name,
+ meta,
+ Math.min(6, level + 1),
+ editable,
+ removable
);
- },
+ },
- wrap: function() { return this.el; },
+ staticRender: function(value, meta) { return null; },
- validate: function(data) {
- this.super(Inline, "validate", data);
+ createEl: function() { return $("<div>"); },
+
+ showStatus: false,
- if (this.data.match(this.meta.condition)) {
- var valid = data.validate();
- this.setStatus(data.status());
- statusBar.validationReady(valid);
- }
-
- if (this.fields)
- _.each(this.fields, function(field) {
- field.trigger("updated");
- });
- }
- });
+ requestData: function(value, meta) {
+ this.path = value;
+ return this.refreshData();
+ },
+ refreshData: function() {
+ var def = $.Deferred();
+ txnMgr.query(this.path).done(function(data) {
+ def.resolve(data, data.meta);
+ });
+ return def;
+ },
- var InlineFields = Inline.extend({
+ showHeading: true,
- render: function(data, meta) {
- this.super(InlineFields, "render", data, meta);
+ render: function(data, meta) {
+ if (this.showHeading)
+ this.el.html(
+ $("<h" + this.level + ">").text(meta["ui-name"])
+ );
+ },
- this.appendAboveFields(data, meta);
+ wrap: function() { return this.el; },
- this.reqData = data;
- var self = this;
-
- if (meta.type == "model") {
- this.fields = {};
- _.each(meta.fields, function(field) {
- if (field.visible)
- self.fields[field.name] = self.renderField(
- field.name,
- field,
- field["ui-name"],
- true,
- false
- );
- });
+ validate: function(data) {
+ this.super(Inline, "validate", data);
- _.each(this.fields, function(f1, name) {
- _.each(self.fields, function(f2) {
- if (f1 != f2)
- f1.on("validated", function(event) {
- f2.trigger("updated", [name]);
- event.stopPropagation();
- });
+ if (this.data.match(this.meta.condition)) {
+ var valid = data.validate();
+ this.setStatus(data.status());
+ statusBar.validationReady(valid);
+ }
+
+ if (this.fields)
+ _.each(this.fields, function(field) {
+ field.trigger("updated");
});
- });
-
- _.each(this.fields, function(field) {
- field.trigger("start");
- });
}
-
- else _.each(data.data, function(value, name) {
- if (meta.type == "set") name = data.data[name];
- else if (_.isArray(data.data)) name++;
- self.renderCollectionMember(name, meta);
- });
+ });
- this.appendBelowFields(data, meta);
- },
-
- appendAboveFields: function(data, meta) {},
- appendBelowFields: function(data, meta) {},
-
- renderField: function(
- name, meta, label, editable, removable
- ) {
- var widget = this.widget(meta).new(
- this.reqData,
- name,
- meta,
- this.level,
- editable,
- removable
- );
- var container = this.appendWidget(widget, label);
- widget.on("setVisible", function(event, visible) {
- if (visible) container.show();
- else container.hide();
- event.stopPropagation();
- });
- return widget;
- },
-
- renderCollectionMember: function(name, meta) {
- var set = meta.type == "set";
- this.renderField(
- name,
- meta.members,
- meta["ui-member"] + " " + name,
- !set,
- !set && _.contains(meta.removable, name)
- ).trigger("start");
- },
-
- widget: function(meta) { return widgets[meta.widget]; }
- });
+ var InlineFields = Inline.extend({
- var Horizontal = InlineFields.extend({
- createEl: function() {
- this.previous = null;
- return $("<tr>").html($("<td>").prop(
- "class", "placeholder"
- ));
- },
+ render: function(data, meta) {
+ this.super(InlineFields, "render", data, meta);
- showHeading: false,
+ this.appendAboveFields(data, meta);
- appendWidget: function(el, label) {
- if (!el.is("td")) return null;
- if (this.previous) this.previous.after(el);
- else {
- var ph = this.el.find(".placeholder");
- ph.after(el);
- ph.remove();
- }
- this.previous = el;
- return el;
- }
- });
+ this.reqData = data;
+ var self = this;
+
+ if (meta.type == "model") {
+ this.fields = {};
+ _.each(meta.fields, function(field) {
+ if (field.visible)
+ self.fields[field.name] = self.renderField(
+ field.name,
+ field,
+ field["ui-name"],
+ true,
+ false
+ );
+ });
+
+ _.each(this.fields, function(f1, name) {
+ _.each(self.fields, function(f2) {
+ if (f1 != f2)
+ f1.on("validated", function(event) {
+ f2.trigger("updated", [name]);
+ event.stopPropagation();
+ });
+ });
+ });
+ _.each(this.fields, function(field) {
+ field.trigger("start");
+ });
+ }
+
+ else _.each(data.data, function(value, name) {
+ if (meta.type == "set") name = data.data[name];
+ else if (_.isArray(data.data)) name++;
+ self.renderCollectionMember(name, meta);
+ });
- var HeaderHorizontal = Horizontal.extend({
- init: function(
- data, name, meta, level, editable, removable
- ) {
- this.header = $("<tr>");
- var table = $("<table>");
- table.append($("<thead>").html(this.header));
- table.append($("<tbody>").html(
- this.super(
- HeaderHorizontal,
- "init",
- data,
+ this.appendBelowFields(data, meta);
+ },
+
+ appendAboveFields: function(data, meta) {},
+ appendBelowFields: function(data, meta) {},
+
+ renderField: function(
+ name, meta, label, editable, removable
+ ) {
+ var widget = this.widget(meta).new(
+ this.reqData,
name,
meta,
- level,
+ this.level,
editable,
removable
- )
- ));
- return table;
- },
-
- appendWidget: function(el, label) {
- el = this.super(
- HeaderHorizontal, "appendWidget", el, label
- );
- if (el) this.header.append($("<th>").text(label));
- return el;
- }
- });
+ );
+ var container = this.appendWidget(widget, label);
+ widget.on("setVisible", function(event, visible) {
+ if (visible) container.show();
+ else container.hide();
+ event.stopPropagation();
+ });
+ return widget;
+ },
+
+ renderCollectionMember: function(name, meta) {
+ var set = meta.type == "set";
+ this.renderField(
+ name,
+ meta.members,
+ meta["ui-member"] + " " + name,
+ !set,
+ !set && _.contains(meta.removable, name)
+ ).trigger("start");
+ },
+
+ widget: function(meta) { return widgets[meta.widget]; }
+ });
- var Vertical = InlineFields.extend({
- wrap: function() { return $("<div>").html(this.el); },
-
- appendAboveFields: function(data, meta) {
- this.div = $("<div>");
- this.el.append(this.div);
+ var Horizontal = InlineFields.extend({
+ createEl: function() {
+ this.previous = null;
+ return $("<tr>").html($("<td>").prop(
+ "class", "placeholder"
+ ));
+ },
+
+ showHeading: false,
+
+ appendWidget: function(el, label) {
+ if (!el.is("td")) return null;
+ if (this.previous) this.previous.after(el);
+ else {
+ var ph = this.el.find(".placeholder");
+ ph.after(el);
+ ph.remove();
+ }
+ this.previous = el;
+ return el;
+ }
+ });
- var self = this;
+
+ var HeaderHorizontal = Horizontal.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ this.header = $("<tr>");
+ var table = $("<table>");
+ table.append($("<thead>").html(this.header));
+ table.append($("<tbody>").html(
+ this.super(
+ HeaderHorizontal,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ )
+ ));
+ return table;
+ },
- if (meta.type == "model")
- _.each(meta.actions, function(action) {
- self.div.append($("<input>").attr(
- {type: "submit", value: action["ui-name"]}
- ).click(function() {
- data.invoke(action.name).done(function() {
- alert("Done");
- }).fail(function() {
- alert("Failed");
- });
- }));
- });
- },
+ appendWidget: function(el, label) {
+ el = this.super(
+ HeaderHorizontal, "appendWidget", el, label
+ );
+ if (el) this.header.append($("<th>").text(label));
+ return el;
+ }
+ });
+
+
+ var Vertical = InlineFields.extend({
+ wrap: function() { return $("<div>").html(this.el); },
- appendBelowFields: function(data, meta) {
- if (meta.editable &&
- _.contains(["collection", "list"], meta.type)) {
- if (!this.table) this.makeSortable(this.div);
+ appendAboveFields: function(data, meta) {
+ this.div = $("<div>");
+ this.el.append(this.div);
var self = this;
- var keys = _.clone(_.keys(data.data));
- var button = $("<input>").attr(
- {type: "submit", value: "Insert"}
- ).click(function() {
-
- var getter;
+ if (meta.type == "model")
+ _.each(meta.actions, function(action) {
+ self.div.append($("<input>").attr(
+ {type: "submit", value: action["ui-name"]}
+ ).click(function() {
+ data.invoke(action.name).done(function() {
+ alert("Done");
+ }).fail(function() {
+ alert("Failed");
+ });
+ }));
+ });
+ },
+
+ appendBelowFields: function(data, meta) {
+ if (meta.editable &&
+ _.contains(["collection", "list"], meta.type)) {
+ if (!this.table) this.makeSortable(this.div);
+
+ var self = this;
+ var keys = _.clone(_.keys(data.data));
- function insert() {
- var name = getter();
+ var button = $("<input>").attr(
+ {type: "submit", value: "Insert"}
+ ).click(function() {
- if (_.contains(keys, name)) {
- button.prop("class", null);
- return;
+ var getter;
+
+ function insert() {
+ var name = getter();
+
+ if (_.contains(keys, name)) {
+ button.prop("class", null);
+ return;
+ }
+ keys.push(name);
+
+ data.set(
+ name,
+ isTreeNode(meta.members) ? {} : null
+ ).done(function(txnValid) {
+ if (_.isObject(meta.removable))
+ meta.removable = [];
+ meta.removable.push(name);
+
+ self.renderCollectionMember(name, meta);
+ button.prop("class", null);
+ statusBar.validationReady(txnValid);
+ });
}
- keys.push(name);
+
+ button.prop("class", "hidden");
- data.set(
- name,
- isTreeNode(meta.members) ? {} : null
- ).done(function(txnValid) {
- if (_.isObject(meta.removable))
- meta.removable = [];
- meta.removable.push(name);
+ if (meta.type == "collection") {
+ var field = $("<input>").attr({type: "text"});
+ var row = $("<tr>").html($("<td>").html(field));
+ getter = function() {
+ var res = field.val();
+ row.remove();
+ return res;
+ }
+ field.change(insert);
+ self.appendRow(row);
+ }
+ else {
+ getter = function() {
+ return data.data.length + 1;
+ };
+ insert();
+ }
+ });
+ this.el.append($("<p>").html(button));
+ }
+ },
- self.renderCollectionMember(name, meta);
- button.prop("class", null);
- statusBar.validationReady(txnValid);
+ appendWidget: function(el, label) {
+ var self = this;
+ el = makeRow(el);
+
+ if (el.is("tr")) {
+ el.prepend($("<td>").text(label));
+ this.appendRow(el);
+ }
+ else {
+ if (el.is("table")) {
+ this.makeSortable(el.find("tbody"));
+ var td;
+ el.find("tr").each(function(index, row) {
+ td = $("<td>");
+ $(row).prepend(td);
});
+ td.text(label);
+ this.table = el;
}
+ else this.table = null;
+ this.div.append(el);
+ }
+
+ return el;
+ },
+
+ appendRow: function(row) {
+ if (!this.table) {
+ this.table = this.makeSortable($("<tbody>"));
+ this.div.append($("<table>").html(this.table));
+ }
+ this.table.append(row);
+ },
- button.prop("class", "hidden");
-
- if (meta.type == "collection") {
- var field = $("<input>").attr({type: "text"});
- var row = $("<tr>").html($("<td>").html(field));
- getter = function() {
- var res = field.val();
- row.remove();
- return res;
+ makeSortable: function(el) {
+ var data = this.reqData;
+
+ if (data.meta.type == "list")
+ el.sortable({
+ start: function(event, ui) {
+ $(":focus").change();
+ ui.item.data("index", ui.item.index());
+ },
+ stop: function(event, ui) {
+ var oldIndex = ui.item.data("index") + 1;
+ var newIndex = ui.item.index() + 1;
+ if (newIndex != oldIndex)
+ data.move(oldIndex, newIndex)
+ .done(function(txnValid) {
+ $("#content").trigger(
+ "reload", [txnValid]
+ );
+ });
}
- field.change(insert);
- self.appendRow(row);
- }
- else {
- getter = function() {
- return data.data.length + 1;
- };
- insert();
- }
- });
- this.el.append($("<p>").html(button));
- }
- },
-
- appendWidget: function(el, label) {
- var self = this;
- el = makeRow(el);
-
- if (el.is("tr")) {
- el.prepend($("<td>").text(label));
- this.appendRow(el);
- }
- else {
- if (el.is("table")) {
- this.makeSortable(el.find("tbody"));
- var td;
- el.find("tr").each(function(index, row) {
- td = $("<td>");
- $(row).prepend(td);
});
- td.text(label);
- this.table = el;
- }
- else this.table = null;
- this.div.append(el);
- }
-
- return el;
- },
-
- appendRow: function(row) {
- if (!this.table) {
- this.table = this.makeSortable($("<tbody>"));
- this.div.append($("<table>").html(this.table));
+ return el;
}
- this.table.append(row);
- },
+ });
- makeSortable: function(el) {
- var data = this.reqData;
- if (data.meta.type == "list")
- el.sortable({
- start: function(event, ui) {
- $(":focus").change();
- ui.item.data("index", ui.item.index());
- },
- stop: function(event, ui) {
- var oldIndex = ui.item.data("index") + 1;
- var newIndex = ui.item.index() + 1;
- if (newIndex != oldIndex)
- data.move(oldIndex, newIndex)
- .done(function(txnValid) {
- $("#content").trigger(
- "reload", [txnValid]
- );
- });
- }
- });
- return el;
- }
- });
+ var CheckBoxes = Inline.extend({
+ showStatus: true,
+ setStatus: function(status) {
+ this.super(
+ CheckBoxes,
+ "setStatus",
+ status == "invalid" ? "invalid" : null
+ );
+ },
+
+ render: function(data, meta) {
+ this.dynamic = meta.members.dynamic;
+
+ this.super(CheckBoxes, "render", data, meta);
+
+ var table = $("<tbody>");
+ this.el.append($("<table>").html(table));
+
+ var self = this;
+
+ _.each(meta.members.choice, function(choice) {
+ var selected = _.contains(data.data, choice.value);
+ if (!(choice.enabled || selected)) return;
+
+ var cbox = $("<input>").attr({
+ type: "checkbox", checked: selected
+ });
+
+ var row = $("<tr>");
+ row.append($("<td>").html(cbox));
+
+ var item = $("<td>");
+ if (choice.ref)
+ item.html(objectRef(choice.ref)
+ .text(choice["ui-value"]));
+ else item.text(choice["ui-value"]);
+ row.append(item);
+
+ function setRowStatus() {
+ setStatus(row, data.status(choice.value));
+ }
+ setRowStatus();
+
+ cbox.change(function() {
+ (
+ cbox.is(":checked") ?
+ data.add(choice.value) :
+ data.delete(choice.value)
+ ).done(function(txnValid) {
+ self.setStatus(data.status());
+ setRowStatus();
+ statusBar.validationReady(txnValid);
+ });
+ });
- var CheckBoxes = Inline.extend({
- showStatus: true,
+ table.append(row);
+ });
+ }
+ });
- setStatus: function(status) {
- this.super(
- CheckBoxes,
- "setStatus",
- status == "invalid" ? "invalid" : null
- );
- },
-
- render: function(data, meta) {
- this.dynamic = meta.members.dynamic;
- this.super(CheckBoxes, "render", data, meta);
+ var Reference = ComboBox.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ this.field = ComboBox.createEl();
+ return this.super(
+ Reference,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ );
+ },
- var table = $("<tbody>");
- this.el.append($("<table>").html(table));
+ staticRender: function(value, meta) {
+ return $("<td>").html(objectRef(value).text(value));
+ },
- var self = this;
+ statusEl: function() { return this.el.find("select"); },
+
+ createEl: function() { return $("<div>"); },
- _.each(meta.members.choice, function(choice) {
- var selected = _.contains(data.data, choice.value);
- if (!(choice.enabled || selected)) return;
-
- var cbox = $("<input>").attr({
- type: "checkbox", checked: selected
- });
+ render: function(value, meta) {
+ this.super(Reference, "render", value, meta);
- var row = $("<tr>");
- row.append($("<td>").html(cbox));
-
- var item = $("<td>");
- if (choice.ref)
- item.html(objectRef(choice.ref)
- .text(choice["ui-value"]));
- else item.text(choice["ui-value"]);
- row.append(item);
+ this.el.html(this.field);
+ this.el.append(" ");
- function setRowStatus() {
- setStatus(row, data.status(choice.value));
- }
- setRowStatus();
+ var link = $("<div>");
+ var update = _.bind(function() {
+ link.html(objectRef(this.get()));
+ }, this);
+ this.el.append(link);
- cbox.change(function() {
- (
- cbox.is(":checked") ?
- data.add(choice.value) :
- data.delete(choice.value)
- ).done(function(txnValid) {
- self.setStatus(data.status());
- setRowStatus();
- statusBar.validationReady(txnValid);
- });
- });
+ this.field.change(update);
+ update();
+ }
+ });
- table.append(row);
- });
- }
- });
+ var widgets = {
+ boolean: CheckBox,
+ checkboxes: CheckBoxes,
+ combobox: ComboBox,
+ field: Field,
+ inline: Vertical,
+ link: Link,
+ reference: Reference
+ };
- var Reference = ComboBox.extend({
- init: function(
- data, name, meta, level, editable, removable
- ) {
- this.field = ComboBox.createEl();
- return this.super(
- Reference,
- "init",
- data,
- name,
- meta,
- level,
- editable,
- removable
- );
- },
-
- staticRender: function(value, meta) {
- return $("<td>").html(objectRef(value).text(value));
- },
-
- statusEl: function() { return this.el.find("select"); },
- createEl: function() { return $("<div>"); },
-
- render: function(value, meta) {
- this.super(Reference, "render", value, meta);
-
- this.el.html(this.field);
- this.el.append(" ");
-
- var link = $("<div>");
- var update = _.bind(function() {
- link.html(objectRef(this.get()));
- }, this);
- this.el.append(link);
+ var Tabular = Vertical.extend({
+ render: function(data, meta) {
+ this.header = true;
+ this.super(Tabular, "render", data, meta);
+ },
- this.field.change(update);
- update();
- }
- });
+ widget: function(meta) {
+ if (!isTreeNode(meta))
+ return this.super(Tabular, "widget", meta);
+ if (!this.header) return Horizontal;
+ this.header = false;
+ return HeaderHorizontal;
+ }
+ });
- var widgets = {
- boolean: CheckBox,
- checkboxes: CheckBoxes,
- combobox: ComboBox,
- field: Field,
- inline: Vertical,
- link: Link,
- reference: Reference
- };
+ var Stacked = Vertical.extend({
+ widget: function(meta) {
+ return isTreeNode(meta) ?
+ Vertical : this.super(Stacked, "widget", meta);
+ }
+ });
- var Tabular = Vertical.extend({
- render: function(data, meta) {
- this.header = true;
- this.super(Tabular, "render", data, meta);
- },
-
- widget: function(meta) {
- if (!isTreeNode(meta))
- return this.super(Tabular, "widget", meta);
- if (!this.header) return Horizontal;
- this.header = false;
- return HeaderHorizontal;
- }
- });
+ var layouts = {stacked: Stacked, tabular: Tabular};
- var Stacked = Vertical.extend({
- widget: function(meta) {
- return isTreeNode(meta) ?
- Vertical : this.super(Stacked, "widget", meta);
- }
- });
+ function redirect(path) { $.bbq.pushState("#" + path); }
+ function renderObject(path, data) {
+ path = path || $.param.fragment();
- var layouts = {stacked: Stacked, tabular: Tabular};
+ return (
+ data ? $.Deferred().resolve(data) : txnMgr.query(path)
+ ).done(function(data) {
+ var layout = data.meta.widget;
+ var name = split(path).pop();
+ (layout ? layouts[layout] : Vertical).extend({
+ createEl: function() { return $("#content").empty(); },
+ wrap: function() { return this.el; },
+ requestData: function(value, meta) {
+ return $.Deferred().resolve(data, data.meta);
+ }
+ }).new(
+ {
+ get: function(name) { return path; },
+ status: function(name) { return null; },
+ match: function(filter) { return true; }
+ },
+ name,
+ {},
+ 0,
+ true,
+ false
+ );
+ }).fail(function() {
+ var comps = split(path);
+ comps.pop();
+ comps.unshift("/");
+ redirect(join.apply(undefined, comps));
+ });
+ };
+ $("#content").on("reload", function(event, txnValid) {
+ statusBar.validationReady(txnValid);
+ renderObject();
+ event.stopPropagation();
+ });
- function redirect(path) { $.bbq.pushState("#" + path); }
- function renderObject(path, data) {
- path = path || $.param.fragment();
+ function render() {
+ var path = $.param.fragment();
- return (
- data ? $.Deferred().resolve(data) : txnMgr.query(path)
- ).done(function(data) {
- var layout = data.meta.widget;
- var name = split(path).pop();
- (layout ? layouts[layout] : Vertical).extend({
- createEl: function() { return $("#content").empty(); },
- wrap: function() { return this.el; },
- requestData: function(value, meta) {
- return $.Deferred().resolve(data, data.meta);
- }
- }).new(
- {
- get: function(name) { return path; },
- status: function(name) { return null; },
- match: function(filter) { return true; }
- },
- name,
- {},
- 0,
- true,
- false
- );
- }).fail(function() {
- var comps = split(path);
- comps.pop();
- comps.unshift("/");
- redirect(join.apply(undefined, comps));
- });
- };
+ function renderMenu(target, path, current, selectFirst) {
+ var def = $.Deferred();
- $("#content").on("reload", function(event, txnValid) {
- statusBar.validationReady(txnValid);
- renderObject();
- event.stopPropagation();
- });
+ txnMgr.query(path).done(function(data) {
+ if (data.meta.type != "model") {
+ def.reject(data);
+ return;
+ }
+ var tnFields = [];
+ var extraFields = false;
- function render() {
- var path = $.param.fragment();
+ _.each(data.meta.fields, function(field) {
+ if (!field.visible) return;
- function renderMenu(target, path, current, selectFirst) {
- var def = $.Deferred();
+ if (!isTreeNode(field)) extraFields = true;
+ else if (data.data[field.name])
+ tnFields.push(field);
+ });
- txnMgr.query(path).done(function(data) {
- if (data.meta.type != "model") {
- def.reject(data);
- return;
- }
+ if (!tnFields.length) {
+ def.reject(data);
+ return;
+ }
+
+ function addItem(path, ui_name, status, current) {
+ var el = $("<li>").html(objectRef(path).text(ui_name));
+ el.prop("class", status);
+ if (current) el.addClass("current");
+ target.append(el);
+ }
- var tnFields = [];
- var extraFields = false;
+ if (extraFields) {
+ addItem(path, "General", null, !current);
+ selectFirst = false;
+ }
- _.each(data.meta.fields, function(field) {
- if (!field.visible) return;
+ _.each(tnFields, function(field, i) {
+ addItem(
+ data.get(field.name),
+ field["ui-name"],
+ data.status(field.name),
+ current == field.name || (
+ !current && !i && selectFirst
+ )
+ );
+ field.visible = false;
+ });
- if (!isTreeNode(field)) extraFields = true;
- else if (data.data[field.name])
- tnFields.push(field);
+ def.resolve(extraFields ? data : tnFields[0].name);
});
- if (!tnFields.length) {
- def.reject(data);
- return;
- }
+ return def;
+ }
- function addItem(path, ui_name, status, current) {
- var el = $("<li>").html(objectRef(path).text(ui_name));
- el.prop("class", status);
- if (current) el.addClass("current");
- target.append(el);
- }
- if (extraFields) {
- addItem(path, "General", null, !current);
- selectFirst = false;
+ if (path > "/") $("#content").text("Loading...");
+
+ txnMgr.start().done(function() {
+ var comps = split(path);
+ renderMenu($("#modules").empty(), "/", comps[0], false);
+ var tabs = $("#tabs").empty();
+
+ if (path == "/") return;
+
+ function renderTabs(p) {
+ p = join(p, comps.shift());
+ renderMenu(tabs, p, comps[0], true)
+ .done(function(data) {
+ var tabLevel = !comps.length;
+ renderObject(
+ (
+ tabLevel && _.isString(data)
+ ) ? join(p, data) : path,
+ tabLevel && _.isObject(data) ? data : null
+ );
+ })
+ .fail(function(data) {
+ if (comps.length) renderTabs(p);
+ else renderObject(p, data);
+ });
}
-
- _.each(tnFields, function(field, i) {
- addItem(
- data.get(field.name),
- field["ui-name"],
- data.status(field.name),
- current == field.name || (
- !current && !i && selectFirst
- )
- );
- field.visible = false;
- });
-
- def.resolve(extraFields ? data : tnFields[0].name);
+ renderTabs("/");
});
-
- return def;
}
-
- if (path > "/") $("#content").text("Loading...");
-
- txnMgr.start().done(function() {
- var comps = split(path);
- renderMenu($("#modules").empty(), "/", comps[0], false);
- var tabs = $("#tabs").empty();
-
- if (path == "/") return;
-
- function renderTabs(p) {
- p = join(p, comps.shift());
- renderMenu(tabs, p, comps[0], true)
- .done(function(data) {
- var tabLevel = !comps.length;
- renderObject(
- (
- tabLevel && _.isString(data)
- ) ? join(p, data) : path,
- tabLevel && _.isObject(data) ? data : null
- );
- })
- .fail(function(data) {
- if (comps.length) renderTabs(p);
- else renderObject(p, data);
- });
- }
- renderTabs("/");
+
+ function clearState() {
+ statusBar.reset();
+ render();
+ $.unblockUI();
+ }
+
+ $("#commit").click(function() {
+ $.blockUI();
+ txnMgr.commit().done(clearState).fail(function(xhr) {
+ statusBar.setError(
+ formatError("Commit failed", xhr), "txn"
+ );
+ })
});
- }
-
-
- function clearState() {
- statusBar.reset();
- render();
- $.unblockUI();
- }
-
- $("#commit").click(function() {
- $.blockUI();
- txnMgr.commit().done(clearState).fail(function(xhr) {
- statusBar.setError(
- formatError("Commit failed", xhr), "txn"
- );
- })
- });
- $("#revert").click(function() {
- $.blockUI();
- txnMgr.abort();
- clearState();
- });
-
- $("#logout").click(function() {
- txnMgr.logout().done(function() {
- $("body").html($("<p>").text("Logged out"));
+ $("#revert").click(function() {
+ $.blockUI();
+ txnMgr.abort();
+ clearState();
});
- });
-
- statusBar.reset();
- $("#content").empty();
+
+ $("#logout").click(function() {
+ txnMgr.logout().done(function() {
+ $("body").html($("<p>").text("Logged out"));
+ });
+ });
+
+ statusBar.reset();
+ $("#content").empty();
- $(window).bind("hashchange", render);
- redirect("/");
+ $(window).bind("hashchange", render);
+ redirect("/");
- }).fail(function() {
- statusBar.setError("Login failed", "login");
- });
+ }).fail(function() {
+ statusBar.setError("Login failed", "login");
+ });
- return false;
- });
+ return false;
+ });
- $("#username").focus();
-});
+ $("#username").focus();
+ }
+);
diff --git a/web/lib/require.js b/web/lib/require.js
new file mode 100644
index 0000000..84d1d67
--- /dev/null
+++ b/web/lib/require.js
@@ -0,0 +1,36 @@
+/*
+ RequireJS 2.1.10 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
+ Available via the MIT or new BSD license.
+ see: http://github.com/jrburke/requirejs for details
+*/
+var requirejs,require,define;
+(function(ca){function G(b){return"[object Function]"===N.call(b)}function H(b){return"[object Array]"===N.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function j(b,c){return s(b,c)&&b[c]}function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof
+RegExp)?(b[h]||(b[h]={}),V(b[h],c,d,g)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function da(b){throw b;}function ea(b){if(!b)return b;var c=ca;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split("/");n=I;var m=l.map,k=m&&m["*"];if(a&&"."===a.charAt(0))if(e){n=
+I.slice(0,I.length-1);a=a.split("/");e=a.length-1;l.nodeIdCompat&&R.test(a[e])&&(a[e]=a[e].replace(R,""));n=a=n.concat(a);d=n.length;for(e=0;e<d;e++)if(c=n[e],"."===c)n.splice(e,1),e-=1;else if(".."===c)if(1===e&&(".."===n[2]||".."===n[0]))break;else 0<e&&(n.splice(e-1,2),e-=2);a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&m&&(I||k)){n=a.split("/");e=n.length;a:for(;0<e;e-=1){d=n.slice(0,e).join("/");if(I)for(c=I.length;0<c;c-=1)if(b=j(m,I.slice(0,c).join("/")))if(b=j(b,d)){f=b;
+g=e;break a}!h&&(k&&j(k,d))&&(h=j(k,d),i=e)}!f&&h&&(f=h,g=i);f&&(n.splice(0,g,f),a=n.join("/"))}return(f=j(l.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(e){if(e.getAttribute("data-requiremodule")===a&&e.getAttribute("data-requirecontext")===i.contextName)return e.parentNode.removeChild(e),!0})}function g(a){var e=j(l.paths,a);if(e&&H(e)&&1<e.length)return e.shift(),i.require.undef(a),i.require([a]),!0}function u(a){var e,b=a?a.indexOf("!"):-1;-1<b&&(e=a.substring(0,
+b),a=a.substring(b+1,a.length));return[e,a]}function m(a,e,b,f){var n,d,g=null,h=e?e.name:null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(N+=1));a=u(a);g=a[0];a=a[1];g&&(g=c(g,h,f),d=j(p,g));a&&(g?k=d&&d.normalize?d.normalize(a,function(a){return c(a,h,f)}):c(a,h,f):(k=c(a,h,f),a=u(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!d&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:e,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(g?g+"!"+k:k)+b}}function q(a){var e=a.id,b=j(k,e);b||(b=k[e]=new i.Module(a));
+return b}function r(a,e,b){var f=a.id,n=j(k,f);if(s(p,f)&&(!n||n.defineEmitComplete))"defined"===e&&b(p[f]);else if(n=q(a),n.error&&"error"===e)b(n.error);else n.on(e,b)}function w(a,e){var b=a.requireModules,f=!1;if(e)e(a);else if(v(b,function(e){if(e=j(k,e))e.error=a,e.events.error&&(f=!0,e.emit("error",a))}),!f)h.onError(a)}function x(){S.length&&(ia.apply(A,[A.length,0].concat(S)),S=[])}function y(a){delete k[a];delete W[a]}function F(a,e,b){var f=a.map.id;a.error?a.emit("error",a.error):(e[f]=
+!0,v(a.depMaps,function(f,c){var d=f.id,g=j(k,d);g&&(!a.depMatched[c]&&!b[d])&&(j(e,d)?(a.defineDep(c,p[d]),a.check()):F(g,e,b))}),b[f]=!0)}function D(){var a,e,b=(a=1E3*l.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],c=[],h=!1,k=!0;if(!X){X=!0;B(W,function(a){var i=a.map,m=i.id;if(a.enabled&&(i.isDefine||c.push(a),!a.error))if(!a.inited&&b)g(m)?h=e=!0:(f.push(m),d(m));else if(!a.inited&&(a.fetched&&i.isDefine)&&(h=!0,!i.prefix))return k=!1});if(b&&f.length)return a=C("timeout","Load timeout for modules: "+
+f,null,f),a.contextName=i.contextName,w(a);k&&v(c,function(a){F(a,{},{})});if((!b||e)&&h)if((z||fa)&&!Y)Y=setTimeout(function(){Y=0;D()},50);X=!1}}function E(a){s(p,a[0])||q(m(a[0],null,!0)).init(a[1],a[2])}function L(a){var a=a.currentTarget||a.srcElement,e=i.onScriptLoad;a.detachEvent&&!Z?a.detachEvent("onreadystatechange",e):a.removeEventListener("load",e,!1);e=i.onScriptError;(!a.detachEvent||Z)&&a.removeEventListener("error",e,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function M(){var a;
+for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var X,$,i,K,Y,l={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k={},W={},aa={},A=[],p={},T={},ba={},N=1,Q=1;K={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?a.module:
+a.module={id:a.map.id,uri:a.map.url,config:function(){return j(l.config,a.map.id)||{}},exports:K.exports(a)}}};$=function(a){this.events=j(aa,a.id)||{};this.map=a;this.shim=j(l.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};$.prototype={init:function(a,e,b,f){f=f||{};if(!this.inited){this.factory=e;if(b)this.on("error",b);else this.events.error&&(b=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=b;this.inited=
+!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,e){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=e)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
+this.map.url;T[a]||(T[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,e,b=this.map.id;e=this.depExports;var f=this.exports,c=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&&
+(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
+this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f);
+if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval",
+"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(K,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b,
+a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(K,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m,
+nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b,
+a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild=
+!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(K,f))return K[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}M();i.nextTick(function(){M();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==
+d&&(!("."===g||".."===g)||1<d))e=b.substring(d,b.length),b=b.substring(0,d);return i.nameToUrl(c(b,a&&a.id,!0),e,!0)},defined:function(b){return s(p,m(b,a,!1,!0).id)},specified:function(b){b=m(b,a,!1,!0).id;return s(p,b)||s(k,b)}});a||(g.undef=function(b){x();var c=m(b,a,!0),e=j(k,b);d(b);delete p[b];delete T[c.url];delete aa[b];U(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&(aa[b]=e.events),y(b))});return g},enable:function(a){j(k,a.id)&&q(a).enable()},completeLoad:function(a){var b,
+c,f=j(l.shim,a)||{},d=f.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=j(k,a);if(!b&&!s(p,a)&&c&&!c.inited){if(l.enforceDefine&&(!d||!ea(d)))return g(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,f.deps||[],f.exportsFn])}D()},nameToUrl:function(a,b,c){var f,d,g;(f=j(l.pkgs,a))&&(a=f);if(f=j(ba,a))return i.nameToUrl(f,b,c);if(h.jsExtRegExp.test(a))f=a+(b||"");else{f=l.paths;a=a.split("/");for(d=a.length;0<d;d-=1)if(g=a.slice(0,
+d).join("/"),g=j(f,g)){H(g)&&(g=g[0]);a.splice(0,d,g);break}f=a.join("/");f+=b||(/^data\:|\?/.test(f)||c?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":l.baseUrl)+f}return l.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+l.urlArgs):f},load:function(a,b){h.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=L(a),i.completeLoad(a.id)},onScriptError:function(a){var b=L(a);if(!g(b.id))return w(C("scripterror",
+"Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var h,x,y,D,L,E,P,M,q,Q,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,R=/\.js$/,ja=/^\.\//;x=Object.prototype;var N=x.toString,ga=x.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),fa=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,
+Z="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},S=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(r=require,require=void 0);h=requirejs=function(b,c,d,g){var u,m="_";!H(b)&&"string"!==typeof b&&(u=b,H(c)?(b=c,c=d,d=g):b=[]);u&&u.context&&(m=u.context);(g=j(F,m))||(g=F[m]=h.s.newContext(m));u&&g.configure(u);return g.require(b,c,d)};h.config=function(b){return h(b)};
+h.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=h);h.version="2.1.10";h.jsExtRegExp=/^\/|:|\?|\.js$/;h.isBrowser=z;x=h.s={contexts:F,newContext:ha};h({});v(["toUrl","undef","defined","specified"],function(b){h[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=x.head=D.parentNode;h.onError=da;h.createNode=function(b){var c=
+b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};h.load=function(b,c,d){var g=b&&b.config||{};if(z)return g=h.createNode(g,c,d),g.setAttribute("data-requirecontext",b.contextName),g.setAttribute("data-requiremodule",c),g.attachEvent&&!(g.attachEvent.toString&&0>g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)):
+(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,M=g,D?y.insertBefore(g,D):y.appendChild(g),M=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(L=b.getAttribute("data-main"))return q=L,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl=
+Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=L),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=M))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b||
+(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);