diff --git a/ajax/libs/bootbox.js/1.0.0/.gitignore b/ajax/libs/bootbox.js/1.0.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.0.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/1.0.0/bootbox.js b/ajax/libs/bootbox.js/1.0.0/bootbox.js
new file mode 100755
index 000000000..c30eabebf
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.0.0/bootbox.js
@@ -0,0 +1,290 @@
+var bootbox = window.bootbox || (function() {
+ var that = {};
+
+ var _locale = _defaultLocale = 'en';
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Kündigen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "";
+ var label = _translate('OK');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+
+ };
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "";
+ var labelCancel = _translate('CANCEL');
+ var labelOk = _translate('CONFIRM');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null;
+ var buttons = "";
+ var callbacks = [];
+ var options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null;
+ var _class = null;
+ var callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+ var propCount = 0; // condensed will only match if this == 1
+ var property = null; // save the last property we found
+ for (var j in handlers[i]) {
+ property = j;
+ propCount ++;
+ if (propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ _class = 'primary';
+ } else if (i == 0 && handlers.length == 2) {
+ _class = 'danger';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ buttons += ""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var div = $([
+ "
",
+ "
",
+ str,
+ "
",
+ "",
+ "
"
+ ].join("\n"));
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.primary:last", div).focus();
+ });
+
+ $("a", div).click(function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+ div.modal({
+ "backdrop" : options.backdrop || "static",
+ "show" : options.show || true,
+ "keyboard" : options.keyboard
+ });
+
+ $("body").append(div);
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/1.0.0/bootbox.min.js b/ajax/libs/bootbox.js/1.0.0/bootbox.min.js
new file mode 100755
index 000000000..669f2f1db
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.0.0/bootbox.min.js
@@ -0,0 +1,6 @@
+var bootbox=window.bootbox||function(){function h(b,a){a==null&&(a=k);return typeof i[a][b]=="string"?i[a][b]:a!=_defaultLocale?h(b,_defaultLocale):b}var e={},k=_defaultLocale="en",i={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"K\u00fcndigen",CONFIRM:"Akzeptieren"}};e.setLocale=function(b){for(var a in i)if(a==b){k=b;return}throw Error("Invalid locale: "+b);};e.addLocale=function(b,a){typeof i[b]=="undefined"&&(i[b]={});for(var c in a)i[b][c]=
+a[c]};e.alert=function(){var b="",a=h("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];typeof arguments[1]=="function"?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(b,{label:a,callback:c},{onEscape:c})};e.confirm=function(){var b="",a=h("CANCEL"),c=h("CONFIRM"),f=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=
+arguments[0];typeof arguments[1]=="function"?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];typeof arguments[2]=="function"?f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(b,[{label:a,callback:function(){typeof f=="function"&&f(false)}},{label:c,callback:function(){typeof f=="function"&&f(true)}}])};e.dialog=function(b,a,c){var f=
+null,e="",i=[],c=c||{};a==null?a=[]:typeof a.length=="undefined"&&(a=[a]);for(var d=a.length;d--;){var j=null,h=null,k=null;if(typeof a[d].label=="undefined"&&typeof a[d]["class"]=="undefined"&&typeof a[d].callback=="undefined"){var j=0,m=null,l;for(l in a[d])if(m=l,j++,j>1)break;if(j==1&&typeof a[d][l]=="function")a[d].label=m,a[d].callback=a[d][l]}typeof a[d].callback=="function"&&(k=a[d].callback);a[d]["class"]?h=a[d]["class"]:d==a.length-1&&a.length<=2?h="primary":d==0&&a.length==2&&(h="danger");
+j=a[d].label?a[d].label:"Option "+(d+1);e+=""+j+"";i[d]=k}var g=$(["
\n
",b,"
\n\n
"].join("\n"));g.bind("hidden",function(){g.remove()});g.bind("hide",function(){if(f=="escape"&&typeof c.onEscape=="function")c.onEscape()});$(document).bind("keyup.modal",function(a){a.which==27&&(f="escape")});g.bind("shown",function(){$("a.primary:last",
+g).focus()});$("a",g).click(function(a){a.preventDefault();f="button";g.modal("hide");a=$(this).data("handler");a=i[a];typeof a=="function"&&a()});if(c.keyboard==null)c.keyboard=typeof c.onEscape=="function";g.modal({backdrop:c.backdrop||"static",show:c.show||true,keyboard:c.keyboard});$("body").append(g);return g};e.hideAll=function(){$(".bootbox").modal("hide")};return e}();
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/1.1.0/.gitignore b/ajax/libs/bootbox.js/1.1.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/1.1.0/bootbox.js b/ajax/libs/bootbox.js/1.1.0/bootbox.js
new file mode 100755
index 000000000..f5d30a06e
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.0/bootbox.js
@@ -0,0 +1,346 @@
+var bootbox = window.bootbox || (function() {
+ var that = {};
+
+ var _locale = _defaultLocale = 'en';
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Kündigen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "";
+ var label = _translate('OK');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "";
+ var labelCancel = _translate('CANCEL');
+ var labelOk = _translate('CONFIRM');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null;
+ var buttons = "";
+ var callbacks = [];
+ var options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null;
+ var _class = null;
+ var callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+ var propCount = 0; // condensed will only match if this == 1
+ var property = null; // save the last property we found
+ for (var j in handlers[i]) {
+ property = j;
+ propCount ++;
+ if (propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ buttons += ""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.primary:last", div).focus();
+ });
+
+ $("a", div).click(function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+ div.modal({
+ "backdrop" : options.backdrop || "static",
+ "show" : options.show || true,
+ "keyboard" : options.keyboard
+ });
+
+ $("body").append(div);
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/1.1.0/bootbox.min.js b/ajax/libs/bootbox.js/1.1.0/bootbox.min.js
new file mode 100755
index 000000000..25d4f5de8
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.0/bootbox.min.js
@@ -0,0 +1,8 @@
+var bootbox=window.bootbox||function(){function i(c,a){null==a&&(a=k);return"string"==typeof h[a][c]?h[a][c]:a!=_defaultLocale?i(c,_defaultLocale):c}var e={},k=_defaultLocale="en",h={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"K\u00fcndigen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"}};e.setLocale=function(c){for(var a in h)if(a==c){k=c;return}throw Error("Invalid locale: "+c);};e.addLocale=function(c,a){"undefined"==
+typeof h[c]&&(h[c]={});for(var b in a)h[c][b]=a[b]};e.alert=function(){var c="",a=i("OK"),b=null;switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(c,{label:a,callback:b},{onEscape:b})};e.confirm=function(){var c="",a=i("CANCEL"),b=i("CONFIRM"),f=null;switch(arguments.length){case 1:c=
+arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:b=arguments[2];break;case 4:c=arguments[0];a=arguments[1];b=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(c,[{label:a,callback:function(){"function"==typeof f&&f(!1)}},{label:b,callback:function(){"function"==typeof f&&f(!0)}}])};e.modal=
+function(){var c,a,b,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"object"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;b="object"==typeof b?$.extend(f,b):f;return e.dialog(c,[],b)};e.dialog=function(c,a,b){var f=null,e="",h=[],b=b||{};null==a?a=[]:"undefined"==typeof a.length&&(a=
+[a]);for(var d=a.length;d--;){var j=null,i=null,k=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var j=0,m=null,l;for(l in a[d])if(m=l,j++,1=a.length&&(i="primary");j=a[d].label?a[d].label:"Option "+(d+1);e+=""+
+j+"";h[d]=k}a=["
");var g=$(a.join("\n"));$(".modal-body",g).html(c);g.bind("hidden",function(){g.remove()});g.bind("hide",function(){if("escape"==f&&"function"==
+typeof b.onEscape)b.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});g.bind("shown",function(){$("a.primary:last",g).focus()});$("a",g).click(function(a){a.preventDefault();f="button";g.modal("hide");a=$(this).data("handler");a=h[a];"function"==typeof a&&a()});if(null==b.keyboard)b.keyboard="function"==typeof b.onEscape;g.modal({backdrop:b.backdrop||"static",show:b.show||!0,keyboard:b.keyboard});$("body").append(g);return g};e.hideAll=function(){$(".bootbox").modal("hide")};
+return e}();
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/1.1.1/.gitignore b/ajax/libs/bootbox.js/1.1.1/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.1/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/1.1.1/bootbox.js b/ajax/libs/bootbox.js/1.1.1/bootbox.js
new file mode 100755
index 000000000..64e9c5cc1
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.1/bootbox.js
@@ -0,0 +1,346 @@
+var bootbox = window.bootbox || (function() {
+ var that = {};
+
+ var _locale = _defaultLocale = 'en';
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "";
+ var label = _translate('OK');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "";
+ var labelCancel = _translate('CANCEL');
+ var labelOk = _translate('CONFIRM');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null;
+ var buttons = "";
+ var callbacks = [];
+ var options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null;
+ var _class = null;
+ var callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+ var propCount = 0; // condensed will only match if this == 1
+ var property = null; // save the last property we found
+ for (var j in handlers[i]) {
+ property = j;
+ propCount ++;
+ if (propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ buttons += ""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.primary:last", div).focus();
+ });
+
+ $("a", div).click(function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+ div.modal({
+ "backdrop" : options.backdrop || "static",
+ "show" : options.show || true,
+ "keyboard" : options.keyboard
+ });
+
+ $("body").append(div);
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/1.1.1/bootbox.min.js b/ajax/libs/bootbox.js/1.1.1/bootbox.min.js
new file mode 100755
index 000000000..586892765
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.1/bootbox.min.js
@@ -0,0 +1,8 @@
+var bootbox=window.bootbox||function(){function i(c,a){null==a&&(a=k);return"string"==typeof h[a][c]?h[a][c]:a!=_defaultLocale?i(c,_defaultLocale):c}var e={},k=_defaultLocale="en",h={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"}};e.setLocale=function(c){for(var a in h)if(a==c){k=c;return}throw Error("Invalid locale: "+c);};e.addLocale=function(c,a){"undefined"==
+typeof h[c]&&(h[c]={});for(var b in a)h[c][b]=a[b]};e.alert=function(){var c="",a=i("OK"),b=null;switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(c,{label:a,callback:b},{onEscape:b})};e.confirm=function(){var c="",a=i("CANCEL"),b=i("CONFIRM"),f=null;switch(arguments.length){case 1:c=
+arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:b=arguments[2];break;case 4:c=arguments[0];a=arguments[1];b=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(c,[{label:a,callback:function(){"function"==typeof f&&f(!1)}},{label:b,callback:function(){"function"==typeof f&&f(!0)}}])};e.modal=
+function(){var c,a,b,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"object"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;b="object"==typeof b?$.extend(f,b):f;return e.dialog(c,[],b)};e.dialog=function(c,a,b){var f=null,e="",h=[],b=b||{};null==a?a=[]:"undefined"==typeof a.length&&(a=
+[a]);for(var d=a.length;d--;){var j=null,i=null,k=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var j=0,m=null,l;for(l in a[d])if(m=l,j++,1=a.length&&(i="primary");j=a[d].label?a[d].label:"Option "+(d+1);e+=""+
+j+"";h[d]=k}a=["
");var g=$(a.join("\n"));$(".modal-body",g).html(c);g.bind("hidden",function(){g.remove()});g.bind("hide",function(){if("escape"==f&&"function"==
+typeof b.onEscape)b.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});g.bind("shown",function(){$("a.primary:last",g).focus()});$("a",g).click(function(a){a.preventDefault();f="button";g.modal("hide");a=$(this).data("handler");a=h[a];"function"==typeof a&&a()});if(null==b.keyboard)b.keyboard="function"==typeof b.onEscape;g.modal({backdrop:b.backdrop||"static",show:b.show||!0,keyboard:b.keyboard});$("body").append(g);return g};e.hideAll=function(){$(".bootbox").modal("hide")};
+return e}();
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/1.1.2/.gitignore b/ajax/libs/bootbox.js/1.1.2/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.2/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/1.1.2/bootbox.js b/ajax/libs/bootbox.js/1.1.2/bootbox.js
new file mode 100755
index 000000000..64e9c5cc1
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.2/bootbox.js
@@ -0,0 +1,346 @@
+var bootbox = window.bootbox || (function() {
+ var that = {};
+
+ var _locale = _defaultLocale = 'en';
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "";
+ var label = _translate('OK');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "";
+ var labelCancel = _translate('CANCEL');
+ var labelOk = _translate('CONFIRM');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null;
+ var buttons = "";
+ var callbacks = [];
+ var options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null;
+ var _class = null;
+ var callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+ var propCount = 0; // condensed will only match if this == 1
+ var property = null; // save the last property we found
+ for (var j in handlers[i]) {
+ property = j;
+ propCount ++;
+ if (propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ buttons += ""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.primary:last", div).focus();
+ });
+
+ $("a", div).click(function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+ div.modal({
+ "backdrop" : options.backdrop || "static",
+ "show" : options.show || true,
+ "keyboard" : options.keyboard
+ });
+
+ $("body").append(div);
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/1.1.2/bootbox.min.js b/ajax/libs/bootbox.js/1.1.2/bootbox.min.js
new file mode 100755
index 000000000..586892765
--- /dev/null
+++ b/ajax/libs/bootbox.js/1.1.2/bootbox.min.js
@@ -0,0 +1,8 @@
+var bootbox=window.bootbox||function(){function i(c,a){null==a&&(a=k);return"string"==typeof h[a][c]?h[a][c]:a!=_defaultLocale?i(c,_defaultLocale):c}var e={},k=_defaultLocale="en",h={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"}};e.setLocale=function(c){for(var a in h)if(a==c){k=c;return}throw Error("Invalid locale: "+c);};e.addLocale=function(c,a){"undefined"==
+typeof h[c]&&(h[c]={});for(var b in a)h[c][b]=a[b]};e.alert=function(){var c="",a=i("OK"),b=null;switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(c,{label:a,callback:b},{onEscape:b})};e.confirm=function(){var c="",a=i("CANCEL"),b=i("CONFIRM"),f=null;switch(arguments.length){case 1:c=
+arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:b=arguments[2];break;case 4:c=arguments[0];a=arguments[1];b=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(c,[{label:a,callback:function(){"function"==typeof f&&f(!1)}},{label:b,callback:function(){"function"==typeof f&&f(!0)}}])};e.modal=
+function(){var c,a,b,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"object"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;b="object"==typeof b?$.extend(f,b):f;return e.dialog(c,[],b)};e.dialog=function(c,a,b){var f=null,e="",h=[],b=b||{};null==a?a=[]:"undefined"==typeof a.length&&(a=
+[a]);for(var d=a.length;d--;){var j=null,i=null,k=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var j=0,m=null,l;for(l in a[d])if(m=l,j++,1=a.length&&(i="primary");j=a[d].label?a[d].label:"Option "+(d+1);e+=""+
+j+"";h[d]=k}a=["
");var g=$(a.join("\n"));$(".modal-body",g).html(c);g.bind("hidden",function(){g.remove()});g.bind("hide",function(){if("escape"==f&&"function"==
+typeof b.onEscape)b.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});g.bind("shown",function(){$("a.primary:last",g).focus()});$("a",g).click(function(a){a.preventDefault();f="button";g.modal("hide");a=$(this).data("handler");a=h[a];"function"==typeof a&&a()});if(null==b.keyboard)b.keyboard="function"==typeof b.onEscape;g.modal({backdrop:b.backdrop||"static",show:b.show||!0,keyboard:b.keyboard});$("body").append(g);return g};e.hideAll=function(){$(".bootbox").modal("hide")};
+return e}();
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/2.0.0/.gitignore b/ajax/libs/bootbox.js/2.0.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.0.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.0.0/bootbox.js b/ajax/libs/bootbox.js/2.0.0/bootbox.js
new file mode 100755
index 000000000..ca90f7b37
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.0.0/bootbox.js
@@ -0,0 +1,362 @@
+var bootbox = window.bootbox || (function() {
+
+ var _locale = _defaultLocale = 'en',
+ _animate = true,
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "";
+ var label = _translate('OK');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "";
+ var labelCancel = _translate('CANCEL');
+ var labelOk = _translate('CONFIRM');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null;
+ var buttons = "";
+ var callbacks = [];
+ var options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null;
+ var _class = null;
+ var callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+ var propCount = 0; // condensed will only match if this == 1
+ var property = null; // save the last property we found
+ for (var j in handlers[i]) {
+ property = j;
+ propCount ++;
+ if (propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ buttons += ""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ $("a", div).click(function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.0.0/bootbox.min.js b/ajax/libs/bootbox.js/2.0.0/bootbox.min.js
new file mode 100755
index 000000000..0395a4e0a
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.0.0/bootbox.min.js
@@ -0,0 +1,8 @@
+var bootbox=window.bootbox||function(){function i(c,a){null==a&&(a=j);return"string"==typeof g[a][c]?g[a][c]:a!=_defaultLocale?i(c,_defaultLocale):c}var j=_defaultLocale="en",m=!0,e={},g={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"}};e.setLocale=function(c){for(var a in g)if(a==c){j=c;return}throw Error("Invalid locale: "+
+c);};e.addLocale=function(c,a){"undefined"==typeof g[c]&&(g[c]={});for(var b in a)g[c][b]=a[b]};e.alert=function(){var c="",a=i("OK"),b=null;switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(c,{label:a,callback:b},{onEscape:b})};e.confirm=function(){var c="",a=i("CANCEL"),
+b=i("CONFIRM"),f=null;switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:b=arguments[2];break;case 4:c=arguments[0];a=arguments[1];b=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(c,[{label:a,callback:function(){"function"==typeof f&&f(!1)}},{label:b,callback:function(){"function"==
+typeof f&&f(!0)}}])};e.modal=function(){var c,a,b,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"object"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;b="object"==typeof b?$.extend(f,b):f;return e.dialog(c,[],b)};e.dialog=function(c,a,b){var f=null,e="",i=[],b=b||{};null==a?a=[]:"undefined"==
+typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,l=null,j=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,n=null,k;for(k in a[d])if(n=k,g++,1=a.length&&(l="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);e+=""+g+"";i[d]=j}a=["
");var h=$(a.join("\n"));("undefined"===typeof b.animate?m:b.animate)&&h.addClass("fade");$(".modal-body",h).html(c);h.bind("hidden",function(){h.remove()});
+h.bind("hide",function(){if("escape"==f&&"function"==typeof b.onEscape)b.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});h.bind("shown",function(){$("a.btn-primary:last",h).focus()});$("a",h).click(function(a){a.preventDefault();f="button";h.modal("hide");a=$(this).data("handler");a=i[a];"function"==typeof a&&a()});null==b.keyboard&&(b.keyboard="function"==typeof b.onEscape);$("body").append(h);h.modal({backdrop:b.backdrop||!0,keyboard:b.keyboard});return h};e.hideAll=
+function(){$(".bootbox").modal("hide")};e.animate=function(c){m=c};return e}();function hello(i){alert("Hello, "+i)}hello("New user");
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/2.0.1/.gitignore b/ajax/libs/bootbox.js/2.0.1/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.0.1/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.0.1/bootbox.js b/ajax/libs/bootbox.js/2.0.1/bootbox.js
new file mode 100755
index 000000000..ca90f7b37
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.0.1/bootbox.js
@@ -0,0 +1,362 @@
+var bootbox = window.bootbox || (function() {
+
+ var _locale = _defaultLocale = 'en',
+ _animate = true,
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "";
+ var label = _translate('OK');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "";
+ var labelCancel = _translate('CANCEL');
+ var labelOk = _translate('CONFIRM');
+ var cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null;
+ var buttons = "";
+ var callbacks = [];
+ var options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null;
+ var _class = null;
+ var callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+ var propCount = 0; // condensed will only match if this == 1
+ var property = null; // save the last property we found
+ for (var j in handlers[i]) {
+ property = j;
+ propCount ++;
+ if (propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ buttons += ""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ $("a", div).click(function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.0.1/bootbox.min.js b/ajax/libs/bootbox.js/2.0.1/bootbox.min.js
new file mode 100755
index 000000000..a0e77236e
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.0.1/bootbox.min.js
@@ -0,0 +1,8 @@
+var bootbox=window.bootbox||function(){function i(c,a){null==a&&(a=j);return"string"==typeof g[a][c]?g[a][c]:a!=_defaultLocale?i(c,_defaultLocale):c}var j=_defaultLocale="en",m=!0,e={},g={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"}};e.setLocale=function(c){for(var a in g)if(a==c){j=c;return}throw Error("Invalid locale: "+
+c);};e.addLocale=function(c,a){"undefined"==typeof g[c]&&(g[c]={});for(var b in a)g[c][b]=a[b]};e.alert=function(){var c="",a=i("OK"),b=null;switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(c,{label:a,callback:b},{onEscape:b})};e.confirm=function(){var c="",a=i("CANCEL"),
+b=i("CONFIRM"),f=null;switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:b=arguments[2];break;case 4:c=arguments[0];a=arguments[1];b=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(c,[{label:a,callback:function(){"function"==typeof f&&f(!1)}},{label:b,callback:function(){"function"==
+typeof f&&f(!0)}}])};e.modal=function(){var c,a,b,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:c=arguments[0];break;case 2:c=arguments[0];"object"==typeof arguments[1]?b=arguments[1]:a=arguments[1];break;case 3:c=arguments[0];a=arguments[1];b=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;b="object"==typeof b?$.extend(f,b):f;return e.dialog(c,[],b)};e.dialog=function(c,a,b){var f=null,e="",i=[],b=b||{};null==a?a=[]:"undefined"==
+typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,l=null,j=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,n=null,k;for(k in a[d])if(n=k,g++,1=a.length&&(l="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);e+=""+g+"";i[d]=j}a=["
");var h=$(a.join("\n"));("undefined"===typeof b.animate?m:b.animate)&&h.addClass("fade");$(".modal-body",h).html(c);h.bind("hidden",function(){h.remove()});
+h.bind("hide",function(){if("escape"==f&&"function"==typeof b.onEscape)b.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});h.bind("shown",function(){$("a.btn-primary:last",h).focus()});$("a",h).click(function(a){a.preventDefault();f="button";h.modal("hide");a=$(this).data("handler");a=i[a];"function"==typeof a&&a()});null==b.keyboard&&(b.keyboard="function"==typeof b.onEscape);$("body").append(h);h.modal({backdrop:b.backdrop||!0,keyboard:b.keyboard});return h};e.hideAll=
+function(){$(".bootbox").modal("hide")};e.animate=function(c){m=c};return e}();
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/2.1.0/.gitignore b/ajax/libs/bootbox.js/2.1.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.1.0/bootbox.js b/ajax/libs/bootbox.js/2.1.0/bootbox.js
new file mode 100755
index 000000000..9910dd4e4
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.0/bootbox.js
@@ -0,0 +1,396 @@
+/**
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne nick@kurai.co.uk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+ */
+var bootbox = window.bootbox || (function() {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ $("a", div).click(function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.1.0/bootbox.min.js b/ajax/libs/bootbox.js/2.1.0/bootbox.min.js
new file mode 100755
index 000000000..42af11518
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.0/bootbox.min.js
@@ -0,0 +1,19 @@
+/**
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne nick@kurai.co.uk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+ */
+var bootbox=window.bootbox||function(){function j(b,a){null==a&&(a=k);return"string"==typeof g[a][b]?g[a][b]:a!=l?j(b,l):b}var k="en",l="en",n=!0,i={},e={},g={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"}};e.setLocale=function(b){for(var a in g)if(a==b){k=b;return}throw Error("Invalid locale: "+b);};e.addLocale=
+function(b,a){"undefined"==typeof g[b]&&(g[b]={});for(var c in a)g[b][c]=a[c]};e.setIcons=function(b){i=b;if("object"!==typeof i||null==i)i={}};e.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(b,{label:a,icon:i.OK,callback:c},
+{onEscape:c})};e.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),f=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(b,[{label:a,icon:i.CANCEL,
+callback:function(){"function"==typeof f&&f(!1)}},{label:c,icon:i.CONFIRM,callback:function(){"function"==typeof f&&f(!0)}}])};e.modal=function(){var b,a,c,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;c="object"==typeof c?$.extend(f,
+c):f;return e.dialog(b,[],c)};e.dialog=function(b,a,c){var f=null,e="",i=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,k="",l=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,o=null,m;for(m in a[d])if(o=m,1<++g)break;1==g&&"function"==typeof a[d][m]&&(a[d].label=o,a[d].callback=a[d][m])}"function"==typeof a[d].callback&&(l=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==
+a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(k=" ");e+=""+k+""+g+"";i[d]=l}a=["
");var h=$(a.join("\n"));("undefined"===typeof c.animate?n:c.animate)&&h.addClass("fade");$(".modal-body",h).html(b);h.bind("hidden",function(){h.remove()});h.bind("hide",function(){if("escape"==f&&"function"==typeof c.onEscape)c.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});h.bind("shown",function(){$("a.btn-primary:last",h).focus()});$("a",h).click(function(a){a.preventDefault();f="button";h.modal("hide");a=$(this).data("handler");
+a=i[a];"function"==typeof a&&a()});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);$("body").append(h);h.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return h};e.hideAll=function(){$(".bootbox").modal("hide")};e.animate=function(b){n=b};return e}();
diff --git a/ajax/libs/bootbox.js/2.1.1/.gitignore b/ajax/libs/bootbox.js/2.1.1/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.1/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.1.1/bootbox.js b/ajax/libs/bootbox.js/2.1.1/bootbox.js
new file mode 100755
index 000000000..1c6c7a75d
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.1/bootbox.js
@@ -0,0 +1,398 @@
+/**
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne nick@kurai.co.uk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+ */
+var bootbox = window.bootbox || (function() {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a', function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.1.1/bootbox.min.js b/ajax/libs/bootbox.js/2.1.1/bootbox.min.js
new file mode 100755
index 000000000..ea7c04813
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.1/bootbox.min.js
@@ -0,0 +1,19 @@
+/**
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne nick@kurai.co.uk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+ */
+var bootbox=window.bootbox||function(){function j(b,a){null==a&&(a=k);return"string"==typeof g[a][b]?g[a][b]:a!=l?j(b,l):b}var k="en",l="en",n=!0,i={},e={},g={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"}};e.setLocale=function(b){for(var a in g)if(a==b){k=b;return}throw Error("Invalid locale: "+b);};e.addLocale=
+function(b,a){"undefined"==typeof g[b]&&(g[b]={});for(var c in a)g[b][c]=a[c]};e.setIcons=function(b){i=b;if("object"!==typeof i||null==i)i={}};e.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(b,{label:a,icon:i.OK,callback:c},
+{onEscape:c})};e.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),f=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(b,[{label:a,icon:i.CANCEL,
+callback:function(){"function"==typeof f&&f(!1)}},{label:c,icon:i.CONFIRM,callback:function(){"function"==typeof f&&f(!0)}}])};e.modal=function(){var b,a,c,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;c="object"==typeof c?$.extend(f,
+c):f;return e.dialog(b,[],c)};e.dialog=function(b,a,c){var f=null,e="",i=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,k="",l=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,o=null,m;for(m in a[d])if(o=m,1<++g)break;1==g&&"function"==typeof a[d][m]&&(a[d].label=o,a[d].callback=a[d][m])}"function"==typeof a[d].callback&&(l=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==
+a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(k=" ");e+=""+k+""+g+"";i[d]=l}a=["
");var h=$(a.join("\n"));("undefined"===typeof c.animate?n:c.animate)&&h.addClass("fade");$(".modal-body",h).html(b);h.bind("hidden",function(){h.remove()});h.bind("hide",function(){if("escape"==f&&"function"==typeof c.onEscape)c.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});h.bind("shown",function(){$("a.btn-primary:last",h).focus()});h.on("click",".modal-footer a",function(a){a.preventDefault();f="button";h.modal("hide");a=$(this).data("handler");
+a=i[a];"function"==typeof a&&a()});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);$("body").append(h);h.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return h};e.hideAll=function(){$(".bootbox").modal("hide")};e.animate=function(b){n=b};return e}();
diff --git a/ajax/libs/bootbox.js/2.1.2/.gitignore b/ajax/libs/bootbox.js/2.1.2/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.2/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.1.2/bootbox.js b/ajax/libs/bootbox.js/2.1.2/bootbox.js
new file mode 100755
index 000000000..840f511f6
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.2/bootbox.js
@@ -0,0 +1,398 @@
+/**
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne nick@kurai.co.uk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+ */
+var bootbox = window.bootbox || (function() {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ var handler = $(this).data("handler");
+ var cb = callbacks[handler];
+ if (typeof cb == 'function') {
+ cb();
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.1.2/bootbox.min.js b/ajax/libs/bootbox.js/2.1.2/bootbox.min.js
new file mode 100755
index 000000000..8ea0b5daa
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.1.2/bootbox.min.js
@@ -0,0 +1,19 @@
+/**
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne nick@kurai.co.uk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+ */
+var bootbox=window.bootbox||function(){function j(b,a){null==a&&(a=k);return"string"==typeof g[a][b]?g[a][b]:a!=l?j(b,l):b}var k="en",l="en",n=!0,i={},e={},g={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"}};e.setLocale=function(b){for(var a in g)if(a==b){k=b;return}throw Error("Invalid locale: "+b);};e.addLocale=
+function(b,a){"undefined"==typeof g[b]&&(g[b]={});for(var c in a)g[b][c]=a[c]};e.setIcons=function(b){i=b;if("object"!==typeof i||null==i)i={}};e.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(b,{label:a,icon:i.OK,callback:c},
+{onEscape:c})};e.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),f=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(b,[{label:a,icon:i.CANCEL,
+callback:function(){"function"==typeof f&&f(!1)}},{label:c,icon:i.CONFIRM,callback:function(){"function"==typeof f&&f(!0)}}])};e.modal=function(){var b,a,c,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;c="object"==typeof c?$.extend(f,
+c):f;return e.dialog(b,[],c)};e.dialog=function(b,a,c){var f=null,e="",i=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,k="",l=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,o=null,m;for(m in a[d])if(o=m,1<++g)break;1==g&&"function"==typeof a[d][m]&&(a[d].label=o,a[d].callback=a[d][m])}"function"==typeof a[d].callback&&(l=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==
+a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(k=" ");e+=""+k+""+g+"";i[d]=l}a=["
");var h=$(a.join("\n"));("undefined"===typeof c.animate?n:c.animate)&&h.addClass("fade");$(".modal-body",h).html(b);h.bind("hidden",function(){h.remove()});h.bind("hide",function(){if("escape"==f&&"function"==typeof c.onEscape)c.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});h.bind("shown",function(){$("a.btn-primary:last",h).focus()});h.on("click",".modal-footer a, a.close",function(a){a.preventDefault();f="button";h.modal("hide");a=
+$(this).data("handler");a=i[a];"function"==typeof a&&a()});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);$("body").append(h);h.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return h};e.hideAll=function(){$(".bootbox").modal("hide")};e.animate=function(b){n=b};return e}();
diff --git a/ajax/libs/bootbox.js/2.2.0/.gitignore b/ajax/libs/bootbox.js/2.2.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.2.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.2.0/bootbox.js b/ajax/libs/bootbox.js/2.2.0/bootbox.js
new file mode 100755
index 000000000..497172c8f
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.2.0/bootbox.js
@@ -0,0 +1,421 @@
+/**
+ * bootbox.js v2.2.0
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox = window.bootbox || (function() {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.2.0/bootbox.min.js b/ajax/libs/bootbox.js/2.2.0/bootbox.min.js
new file mode 100755
index 000000000..4c31d4704
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.2.0/bootbox.min.js
@@ -0,0 +1,33 @@
+/**
+ * bootbox.js v2.2.0
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox=window.bootbox||function(){function j(b,a){null==a&&(a=k);return"string"==typeof g[a][b]?g[a][b]:a!=l?j(b,l):b}var k="en",l="en",n=!0,i={},e={},g={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"}};e.setLocale=function(b){for(var a in g)if(a==b){k=
+b;return}throw Error("Invalid locale: "+b);};e.addLocale=function(b,a){"undefined"==typeof g[b]&&(g[b]={});for(var c in a)g[b][c]=a[c]};e.setIcons=function(b){i=b;if("object"!==typeof i||null==i)i={}};e.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");
+}return e.dialog(b,{label:a,icon:i.OK,callback:c},{onEscape:c})};e.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),f=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");
+}return e.dialog(b,[{label:a,icon:i.CANCEL,callback:function(){"function"==typeof f&&f(!1)}},{label:c,icon:i.CONFIRM,callback:function(){"function"==typeof f&&f(!0)}}])};e.modal=function(){var b,a,c,f={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");
+}f.header=a;c="object"==typeof c?$.extend(f,c):f;return e.dialog(b,[],c)};e.dialog=function(b,a,c){var f=null,e="",i=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,k="",l=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,o=null,m;for(m in a[d])if(o=m,1<++g)break;1==g&&"function"==typeof a[d][m]&&(a[d].label=o,a[d].callback=a[d][m])}"function"==typeof a[d].callback&&(l=a[d].callback);
+a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(k=" ");e+=""+k+""+g+"";i[d]=l}a=["
");var h=$(a.join("\n"));("undefined"===typeof c.animate?n:c.animate)&&h.addClass("fade");$(".modal-body",h).html(b);h.bind("hidden",function(){h.remove()});h.bind("hide",function(){if("escape"==f&&"function"==typeof c.onEscape)c.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});h.bind("shown",function(){$("a.btn-primary:last",h).focus()});h.on("click",".modal-footer a, a.close",function(a){var b=$(this).data("handler"),
+b=i[b],c=null;"function"==typeof b&&(c=b());!1!==c&&(a.preventDefault(),f="button",h.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);$("body").append(h);h.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return h};e.hideAll=function(){$(".bootbox").modal("hide")};e.animate=function(b){n=b};return e}();
diff --git a/ajax/libs/bootbox.js/2.3.0/.gitignore b/ajax/libs/bootbox.js/2.3.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.3.0/bootbox.js b/ajax/libs/bootbox.js/2.3.0/bootbox.js
new file mode 100755
index 000000000..b1c3240fe
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.0/bootbox.js
@@ -0,0 +1,502 @@
+/**
+ * bootbox.js v2.3.0
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox = window.bootbox || (function() {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+
+ return div;
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.3.0/bootbox.min.js b/ajax/libs/bootbox.js/2.3.0/bootbox.min.js
new file mode 100755
index 000000000..e4e02af6c
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.0/bootbox.min.js
@@ -0,0 +1,35 @@
+/**
+ * bootbox.js v2.3.0
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox=window.bootbox||function(){function j(b,a){null==a&&(a=k);return"string"==typeof h[a][b]?h[a][b]:a!=l?j(b,l):b}var k="en",l="en",o=!0,g={},f={},h={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"}};f.setLocale=function(b){for(var a in h)if(a==b){k=b;return}throw Error("Invalid locale: "+b);};f.addLocale=function(b,a){"undefined"==typeof h[b]&&(h[b]={});for(var c in a)h[b][c]=a[c]};f.setIcons=function(b){g=b;if("object"!==typeof g||null==g)g={}};f.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;
+case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return f.dialog(b,{label:a,icon:g.OK,callback:c},{onEscape:c})};f.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;
+case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return f.dialog(b,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(!1)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==typeof e&&e(!0)}}])};f.prompt=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];
+break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}var m=$("");m.append("");var h=f.dialog(m,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(null)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==typeof e&&e(m.find("input[type=text]").val())}}],
+{header:b});m.on("submit",function(a){a.preventDefault();h.find(".btn-primary").click()});return h};f.modal=function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=a;c="object"==typeof c?$.extend(e,c):e;return f.dialog(b,
+[],c)};f.dialog=function(b,a,c){var e=null,f="",h=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,k="",l=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,p=null,n;for(n in a[d])if(p=n,1<++g)break;1==g&&"function"==typeof a[d][n]&&(a[d].label=p,a[d].callback=a[d][n])}"function"==typeof a[d].callback&&(l=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&
+(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(k=" ");f+=""+k+""+g+"";h[d]=l}a=["
");var i=$(a.join("\n"));("undefined"===typeof c.animate?o:c.animate)&&i.addClass("fade");$(".modal-body",i).html(b);i.bind("hidden",function(){i.remove()});i.bind("hide",function(){if("escape"==e&&"function"==typeof c.onEscape)c.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(e="escape")});i.bind("shown",function(){$("a.btn-primary:last",i).focus()});i.on("click",".modal-footer a, a.close",function(a){var b=$(this).data("handler"),b=h[b],c=null;"function"==typeof b&&
+(c=b());!1!==c&&(a.preventDefault(),e="button",i.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);$("body").append(i);i.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return i};f.hideAll=function(){$(".bootbox").modal("hide")};f.animate=function(b){o=b};return f}();
diff --git a/ajax/libs/bootbox.js/2.3.1/.gitignore b/ajax/libs/bootbox.js/2.3.1/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.1/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.3.1/bootbox.js b/ajax/libs/bootbox.js/2.3.1/bootbox.js
new file mode 100755
index 000000000..7eeeb7f47
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.1/bootbox.js
@@ -0,0 +1,506 @@
+/**
+ * bootbox.js v2.3.1
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox = window.bootbox || (function() {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})();
diff --git a/ajax/libs/bootbox.js/2.3.1/bootbox.min.js b/ajax/libs/bootbox.js/2.3.1/bootbox.min.js
new file mode 100755
index 000000000..c5d103813
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.1/bootbox.min.js
@@ -0,0 +1,35 @@
+/**
+ * bootbox.js v2.3.1
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox=window.bootbox||function(){function j(b,a){null==a&&(a=k);return"string"==typeof h[a][b]?h[a][b]:a!=l?j(b,l):b}var k="en",l="en",o=!0,g={},f={},h={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"}};f.setLocale=function(b){for(var a in h)if(a==b){k=b;return}throw Error("Invalid locale: "+b);};f.addLocale=function(b,a){"undefined"==typeof h[b]&&(h[b]={});for(var c in a)h[b][c]=a[c]};f.setIcons=function(b){g=b;if("object"!==typeof g||null==g)g={}};f.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;
+case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return f.dialog(b,{label:a,icon:g.OK,callback:c},{onEscape:c})};f.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;
+case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return f.dialog(b,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(!1)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==typeof e&&e(!0)}}])};f.prompt=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];
+break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}var m=$("");m.append("");var h=f.dialog(m,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(null)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==typeof e&&e(m.find("input[type=text]").val())}}],
+{header:b});h.on("shown",function(){m.find("input[type=text]").focus();m.on("submit",function(a){a.preventDefault();h.find(".btn-primary").click()})});return h};f.modal=function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=
+a;c="object"==typeof c?$.extend(e,c):e;return f.dialog(b,[],c)};f.dialog=function(b,a,c){var e=null,f="",h=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,k="",l=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,p=null,n;for(n in a[d])if(p=n,1<++g)break;1==g&&"function"==typeof a[d][n]&&(a[d].label=p,a[d].callback=a[d][n])}"function"==typeof a[d].callback&&(l=a[d].callback);
+a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(k=" ");f+=""+k+""+g+"";h[d]=l}a=["
");var i=$(a.join("\n"));("undefined"===typeof c.animate?o:c.animate)&&i.addClass("fade");$(".modal-body",i).html(b);i.bind("hidden",function(){i.remove()});i.bind("hide",function(){if("escape"==e&&"function"==typeof c.onEscape)c.onEscape()});$(document).bind("keyup.modal",function(a){27==a.which&&(e="escape")});i.bind("shown",function(){$("a.btn-primary:last",i).focus()});i.on("click",".modal-footer a, a.close",function(a){var b=$(this).data("handler"),
+b=h[b],c=null;"function"==typeof b&&(c=b());!1!==c&&(a.preventDefault(),e="button",i.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);$("body").append(i);i.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return i};f.hideAll=function(){$(".bootbox").modal("hide")};f.animate=function(b){o=b};return f}();
diff --git a/ajax/libs/bootbox.js/2.3.2/.gitignore b/ajax/libs/bootbox.js/2.3.2/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.2/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.3.2/bootbox.js b/ajax/libs/bootbox.js/2.3.2/bootbox.js
new file mode 100755
index 000000000..699917396
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.2/bootbox.js
@@ -0,0 +1,511 @@
+/**
+ * bootbox.js v2.3.2
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox = window.bootbox || (function($) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})( window.jQuery );
diff --git a/ajax/libs/bootbox.js/2.3.2/bootbox.min.js b/ajax/libs/bootbox.js/2.3.2/bootbox.min.js
new file mode 100755
index 000000000..befbee6e3
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.2/bootbox.min.js
@@ -0,0 +1,35 @@
+/**
+ * bootbox.js v2.3.2
+ *
+ * The MIT License
+ *
+ * Copyright (C) 2011-2012 by Nick Payne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE
+ */
+var bootbox=window.bootbox||function(k){function j(b,a){null==a&&(a=l);return"string"==typeof h[a][b]?h[a][b]:a!=m?j(b,m):b}var l="en",m="en",p=!0,g={},f={},h={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};f.setLocale=function(b){for(var a in h)if(a==b){l=b;return}throw Error("Invalid locale: "+b);};f.addLocale=function(b,a){"undefined"==typeof h[b]&&(h[b]={});for(var c in a)h[b][c]=a[c]};f.setIcons=function(b){g=b;if("object"!==typeof g||null==g)g={}};f.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return f.dialog(b,{label:a,icon:g.OK,callback:c},{onEscape:c})};f.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?
+e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return f.dialog(b,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(!1)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==typeof e&&e(!0)}}])};f.prompt=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}var n=k("");n.append("");var h=f.dialog(n,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(null)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==
+typeof e&&e(n.find("input[type=text]").val())}}],{header:b});h.on("shown",function(){n.find("input[type=text]").focus();n.on("submit",function(a){a.preventDefault();h.find(".btn-primary").click()})});return h};f.modal=function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");
+}e.header=a;c="object"==typeof c?k.extend(e,c):e;return f.dialog(b,[],c)};f.dialog=function(b,a,c){var e=null,f="",h=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,l="",m=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,q=null,o;for(o in a[d])if(q=o,1<++g)break;1==g&&"function"==typeof a[d][o]&&(a[d].label=q,a[d].callback=a[d][o])}"function"==typeof a[d].callback&&(m=a[d].callback);
+a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(l=" ");f+=""+l+""+g+"";h[d]=m}a=["
");var i=k(a.join("\n"));("undefined"===typeof c.animate?p:c.animate)&&i.addClass("fade");k(".modal-body",i).html(b);i.bind("hidden",function(){i.remove()});i.bind("hide",function(){if("escape"==e&&"function"==typeof c.onEscape)c.onEscape()});k(document).bind("keyup.modal",function(a){27==a.which&&(e="escape")});i.bind("shown",function(){k("a.btn-primary:last",i).focus()});i.on("click",".modal-footer a, a.close",function(a){var b=k(this).data("handler"),
+b=h[b],c=null;"function"==typeof b&&(c=b());!1!==c&&(a.preventDefault(),e="button",i.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);k("body").append(i);i.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return i};f.hideAll=function(){k(".bootbox").modal("hide")};f.animate=function(b){p=b};return f}(window.jQuery);
diff --git a/ajax/libs/bootbox.js/2.3.3/.gitignore b/ajax/libs/bootbox.js/2.3.3/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.3/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.3.3/bootbox.js b/ajax/libs/bootbox.js/2.3.3/bootbox.js
new file mode 100755
index 000000000..96bc5ebf7
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.3/bootbox.js
@@ -0,0 +1,495 @@
+/**
+ * bootbox.js v2.3.3
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function($) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": true
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || true,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ return that;
+})( window.jQuery );
diff --git a/ajax/libs/bootbox.js/2.3.3/bootbox.min.js b/ajax/libs/bootbox.js/2.3.3/bootbox.min.js
new file mode 100755
index 000000000..e981669d8
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.3.3/bootbox.min.js
@@ -0,0 +1,15 @@
+/**
+ * bootbox.js v2.3.3
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(k){function j(b,a){null==a&&(a=l);return"string"==typeof h[a][b]?h[a][b]:a!=m?j(b,m):b}var l="en",m="en",p=!0,g={},f={},h={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};f.setLocale=function(b){for(var a in h)if(a==b){l=b;return}throw Error("Invalid locale: "+b);};f.addLocale=function(b,a){"undefined"==typeof h[b]&&(h[b]={});for(var c in a)h[b][c]=a[c]};f.setIcons=function(b){g=b;if("object"!==typeof g||null==g)g={}};f.alert=function(){var b="",a=j("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return f.dialog(b,{label:a,icon:g.OK,callback:c},{onEscape:c})};f.confirm=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?
+e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return f.dialog(b,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(!1)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==typeof e&&e(!0)}}])};f.prompt=function(){var b="",a=j("CANCEL"),c=j("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}var n=k("");n.append("");var h=f.dialog(n,[{label:a,icon:g.CANCEL,callback:function(){"function"==typeof e&&e(null)}},{label:c,icon:g.CONFIRM,callback:function(){"function"==
+typeof e&&e(n.find("input[type=text]").val())}}],{header:b});h.on("shown",function(){n.find("input[type=text]").focus();n.on("submit",function(a){a.preventDefault();h.find(".btn-primary").click()})});return h};f.modal=function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:!0};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");
+}e.header=a;c="object"==typeof c?k.extend(e,c):e;return f.dialog(b,[],c)};f.dialog=function(b,a,c){var e=null,f="",h=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,l="",m=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=0,q=null,o;for(o in a[d])if(q=o,1<++g)break;1==g&&"function"==typeof a[d][o]&&(a[d].label=q,a[d].callback=a[d][o])}"function"==typeof a[d].callback&&(m=a[d].callback);
+a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(l=" ");f+=""+l+""+g+"";h[d]=m}a=["
");var i=k(a.join("\n"));("undefined"===typeof c.animate?p:c.animate)&&i.addClass("fade");k(".modal-body",i).html(b);i.bind("hidden",function(){i.remove()});i.bind("hide",function(){if("escape"==e&&"function"==typeof c.onEscape)c.onEscape()});k(document).bind("keyup.modal",function(a){27==a.which&&(e="escape")});i.bind("shown",function(){k("a.btn-primary:last",i).focus()});i.on("click",
+".modal-footer a, a.close",function(a){var b=k(this).data("handler"),b=h[b],c=null;"function"==typeof b&&(c=b());!1!==c&&(a.preventDefault(),e="button",i.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);k("body").append(i);i.modal({backdrop:c.backdrop||!0,keyboard:c.keyboard});return i};f.hideAll=function(){k(".bootbox").modal("hide")};f.animate=function(b){p=b};return f}(window.jQuery);
diff --git a/ajax/libs/bootbox.js/2.4.0/.gitignore b/ajax/libs/bootbox.js/2.4.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.4.0/bootbox.js b/ajax/libs/bootbox.js/2.4.0/bootbox.js
new file mode 100755
index 000000000..21979375a
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.0/bootbox.js
@@ -0,0 +1,508 @@
+/**
+ * bootbox.js v2.4.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function($) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : options.backdrop || _backdrop,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ }
+
+ return that;
+})( window.jQuery );
diff --git a/ajax/libs/bootbox.js/2.4.0/bootbox.min.js b/ajax/libs/bootbox.js/2.4.0/bootbox.min.js
new file mode 100755
index 000000000..f49a9728e
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.0/bootbox.min.js
@@ -0,0 +1,16 @@
+/**
+ * bootbox.js v2.4.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(k){function g(b,a){null==a&&(a=l);return"string"==typeof j[a][b]?j[a][b]:a!=m?g(b,m):b}var l="en",m="en",r=!0,q=!0,h={},f={},j={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};f.setLocale=function(b){for(var a in j)if(a==b){l=b;return}throw Error("Invalid locale: "+b);};f.addLocale=function(b,a){"undefined"==typeof j[b]&&(j[b]={});for(var c in a)j[b][c]=a[c]};f.setIcons=function(b){h=b;if("object"!==typeof h||null==h)h={}};f.alert=function(){var b="",a=g("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return f.dialog(b,{label:a,icon:h.OK,callback:c},{onEscape:c})};f.confirm=function(){var b="",a=g("CANCEL"),c=g("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?
+e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return f.dialog(b,[{label:a,icon:h.CANCEL,callback:function(){"function"==typeof e&&e(!1)}},{label:c,icon:h.CONFIRM,callback:function(){"function"==typeof e&&e(!0)}}])};f.prompt=function(){var b="",a=g("CANCEL"),c=g("CONFIRM"),e=null,s="";switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==
+typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;case 5:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];s=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var n=k("");n.append("");var d=f.dialog(n,[{label:a,
+icon:h.CANCEL,callback:function(){"function"==typeof e&&e(null)}},{label:c,icon:h.CONFIRM,callback:function(){"function"==typeof e&&e(n.find("input[type=text]").val())}}],{header:b});d.on("shown",function(){n.find("input[type=text]").focus();n.on("submit",function(a){a.preventDefault();d.find(".btn-primary").click()})});return d};f.modal=function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:q};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=a;c="object"==typeof c?k.extend(e,c):e;return f.dialog(b,[],c)};f.dialog=function(b,a,c){var e=null,f="",h=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,l="",m=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=
+0,t=null,p;for(p in a[d])if(t=p,1<++g)break;1==g&&"function"==typeof a[d][p]&&(a[d].label=t,a[d].callback=a[d][p])}"function"==typeof a[d].callback&&(m=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(l=" ");f+=""+l+""+g+"";h[d]=m}a=["
");var i=k(a.join("\n"));("undefined"===typeof c.animate?r:c.animate)&&i.addClass("fade");k(".modal-body",i).html(b);i.bind("hidden",function(){i.remove()});i.bind("hide",function(){if("escape"==e&&"function"==typeof c.onEscape)c.onEscape()});
+k(document).bind("keyup.modal",function(a){27==a.which&&(e="escape")});i.bind("shown",function(){k("a.btn-primary:last",i).focus()});i.on("click",".modal-footer a, a.close",function(a){var b=k(this).data("handler"),b=h[b],c=null;"function"==typeof b&&(c=b());!1!==c&&(a.preventDefault(),e="button",i.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);k("body").append(i);i.modal({backdrop:c.backdrop||q,keyboard:c.keyboard});return i};f.hideAll=function(){k(".bootbox").modal("hide")};
+f.animate=function(b){r=b};f.backdrop=function(b){q=b};return f}(window.jQuery);
diff --git a/ajax/libs/bootbox.js/2.4.1/.gitignore b/ajax/libs/bootbox.js/2.4.1/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.1/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.4.1/bootbox.js b/ajax/libs/bootbox.js/2.4.1/bootbox.js
new file mode 100755
index 000000000..f955bc811
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.1/bootbox.js
@@ -0,0 +1,508 @@
+/**
+ * bootbox.js v2.4.1
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function($) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = true,
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ }
+
+ return that;
+})( window.jQuery );
diff --git a/ajax/libs/bootbox.js/2.4.1/bootbox.min.js b/ajax/libs/bootbox.js/2.4.1/bootbox.min.js
new file mode 100755
index 000000000..368b8f75b
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.1/bootbox.min.js
@@ -0,0 +1,16 @@
+/**
+ * bootbox.js v2.4.1
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(k){function g(b,a){null==a&&(a=l);return"string"==typeof j[a][b]?j[a][b]:a!=m?g(b,m):b}var l="en",m="en",r=!0,q=!0,h={},f={},j={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};f.setLocale=function(b){for(var a in j)if(a==b){l=b;return}throw Error("Invalid locale: "+b);};f.addLocale=function(b,a){"undefined"==typeof j[b]&&(j[b]={});for(var c in a)j[b][c]=a[c]};f.setIcons=function(b){h=b;if("object"!==typeof h||null==h)h={}};f.alert=function(){var b="",a=g("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return f.dialog(b,{label:a,icon:h.OK,callback:c},{onEscape:c})};f.confirm=function(){var b="",a=g("CANCEL"),c=g("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?
+e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return f.dialog(b,[{label:a,icon:h.CANCEL,callback:function(){"function"==typeof e&&e(!1)}},{label:c,icon:h.CONFIRM,callback:function(){"function"==typeof e&&e(!0)}}])};f.prompt=function(){var b="",a=g("CANCEL"),c=g("CONFIRM"),e=null,s="";switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==
+typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;case 5:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];s=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var n=k("");n.append("");var d=f.dialog(n,[{label:a,
+icon:h.CANCEL,callback:function(){"function"==typeof e&&e(null)}},{label:c,icon:h.CONFIRM,callback:function(){"function"==typeof e&&e(n.find("input[type=text]").val())}}],{header:b});d.on("shown",function(){n.find("input[type=text]").focus();n.on("submit",function(a){a.preventDefault();d.find(".btn-primary").click()})});return d};f.modal=function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:q};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=a;c="object"==typeof c?k.extend(e,c):e;return f.dialog(b,[],c)};f.dialog=function(b,a,c){var e=null,f="",h=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,l="",m=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=
+0,t=null,p;for(p in a[d])if(t=p,1<++g)break;1==g&&"function"==typeof a[d][p]&&(a[d].label=t,a[d].callback=a[d][p])}"function"==typeof a[d].callback&&(m=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(l=" ");f+=""+l+""+g+"";h[d]=m}a=["
");var i=k(a.join("\n"));("undefined"===typeof c.animate?r:c.animate)&&i.addClass("fade");k(".modal-body",i).html(b);i.bind("hidden",function(){i.remove()});i.bind("hide",function(){if("escape"==e&&"function"==typeof c.onEscape)c.onEscape()});
+k(document).bind("keyup.modal",function(a){27==a.which&&(e="escape")});i.bind("shown",function(){k("a.btn-primary:last",i).focus()});i.on("click",".modal-footer a, a.close",function(a){var b=k(this).data("handler"),b=h[b],c=null;"function"==typeof b&&(c=b());!1!==c&&(a.preventDefault(),e="button",i.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);k("body").append(i);i.modal({backdrop:"undefined"===typeof c.backdrop?q:c.backdrop,keyboard:c.keyboard});return i};f.hideAll=
+function(){k(".bootbox").modal("hide")};f.animate=function(b){r=b};f.backdrop=function(b){q=b};return f}(window.jQuery);
diff --git a/ajax/libs/bootbox.js/2.4.2/.gitignore b/ajax/libs/bootbox.js/2.4.2/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.2/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.4.2/bootbox.js b/ajax/libs/bootbox.js/2.4.2/bootbox.js
new file mode 100755
index 000000000..d44e16ceb
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.2/bootbox.js
@@ -0,0 +1,508 @@
+/**
+ * bootbox.js v2.4.2
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function($) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = 'static',
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ }
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ }
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ }
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ }
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ }
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ }
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ }
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("")
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+ if (hideModal !== false){
+ e.preventDefault();
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ }
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ }
+
+ that.animate = function(animate) {
+ _animate = animate;
+ }
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ }
+
+ return that;
+})( window.jQuery );
diff --git a/ajax/libs/bootbox.js/2.4.2/bootbox.min.js b/ajax/libs/bootbox.js/2.4.2/bootbox.min.js
new file mode 100755
index 000000000..f53e06e0d
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.4.2/bootbox.min.js
@@ -0,0 +1,16 @@
+/**
+ * bootbox.js v2.4.2
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(k){function g(b,a){null==a&&(a=l);return"string"==typeof j[a][b]?j[a][b]:a!=m?g(b,m):b}var l="en",m="en",r=!0,q="static",h={},f={},j={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};f.setLocale=function(b){for(var a in j)if(a==b){l=b;return}throw Error("Invalid locale: "+b);};f.addLocale=function(b,a){"undefined"==typeof j[b]&&(j[b]={});for(var c in a)j[b][c]=a[c]};f.setIcons=function(b){h=b;if("object"!==typeof h||null==h)h={}};f.alert=function(){var b="",a=g("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return f.dialog(b,{label:a,icon:h.OK,callback:c},{onEscape:c})};f.confirm=function(){var b="",a=g("CANCEL"),c=g("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?
+e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return f.dialog(b,[{label:a,icon:h.CANCEL,callback:function(){"function"==typeof e&&e(!1)}},{label:c,icon:h.CONFIRM,callback:function(){"function"==typeof e&&e(!0)}}])};f.prompt=function(){var b="",a=g("CANCEL"),c=g("CONFIRM"),e=null,s="";switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==
+typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;case 5:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];s=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var n=k("");n.append("");var d=f.dialog(n,[{label:a,
+icon:h.CANCEL,callback:function(){"function"==typeof e&&e(null)}},{label:c,icon:h.CONFIRM,callback:function(){"function"==typeof e&&e(n.find("input[type=text]").val())}}],{header:b});d.on("shown",function(){n.find("input[type=text]").focus();n.on("submit",function(a){a.preventDefault();d.find(".btn-primary").click()})});return d};f.modal=function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:q};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=a;c="object"==typeof c?k.extend(e,c):e;return f.dialog(b,[],c)};f.dialog=function(b,a,c){var e=null,f="",h=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,j=null,l="",m=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var g=
+0,t=null,p;for(p in a[d])if(t=p,1<++g)break;1==g&&"function"==typeof a[d][p]&&(a[d].label=t,a[d].callback=a[d][p])}"function"==typeof a[d].callback&&(m=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(l=" ");f+=""+l+""+g+"";h[d]=m}a=["
");var i=k(a.join("\n"));("undefined"===typeof c.animate?r:c.animate)&&i.addClass("fade");k(".modal-body",i).html(b);i.bind("hidden",function(){i.remove()});i.bind("hide",function(){if("escape"==e&&"function"==typeof c.onEscape)c.onEscape()});
+k(document).bind("keyup.modal",function(a){27==a.which&&(e="escape")});i.bind("shown",function(){k("a.btn-primary:last",i).focus()});i.on("click",".modal-footer a, a.close",function(a){var b=k(this).data("handler"),b=h[b],c=null;"function"==typeof b&&(c=b());!1!==c&&(a.preventDefault(),e="button",i.modal("hide"))});null==c.keyboard&&(c.keyboard="function"==typeof c.onEscape);k("body").append(i);i.modal({backdrop:"undefined"===typeof c.backdrop?q:c.backdrop,keyboard:c.keyboard});return i};f.hideAll=
+function(){k(".bootbox").modal("hide")};f.animate=function(b){r=b};f.backdrop=function(b){q=b};return f}(window.jQuery);
diff --git a/ajax/libs/bootbox.js/2.5.0/.gitignore b/ajax/libs/bootbox.js/2.5.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.5.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.5.0/bootbox.js b/ajax/libs/bootbox.js/2.5.0/bootbox.js
new file mode 100755
index 000000000..ea42e394e
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.5.0/bootbox.js
@@ -0,0 +1,548 @@
+/**
+ * bootbox.js v2.5.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function($) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = 'static',
+ _defaultHref = 'javascript:;',
+ _classes = '',
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ /**
+ * private methods
+ */
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ /**
+ * public API
+ */
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ };
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ };
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ };
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ };
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ };
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ };
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ };
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ href = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ if (handlers[i]['href']) {
+ href = handlers[i]['href'];
+ }
+ else {
+ href = _defaultHref;
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("");
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes;
+ if( optionalClasses ) {
+ div.addClass( optionalClasses );
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted
+ // if we've got a custom href attribute, all bets are off
+ if (typeof handler !== 'undefined' &&
+ typeof handlers[handler]['href'] !== 'undefined') {
+
+ return;
+ }
+
+ e.preventDefault();
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+
+ // the only way hideModal *will* be false is if a callback exists and
+ // returns it as a value. in those situations, don't hide the dialog
+ // @see https://github.com/makeusabrew/bootbox/pull/25
+ if (hideModal !== false) {
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ };
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+ that.animate = function(animate) {
+ _animate = animate;
+ };
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ };
+
+ that.classes = function(classes) {
+ _classes = classes;
+ };
+
+ return that;
+
+})( window.jQuery );
diff --git a/ajax/libs/bootbox.js/2.5.0/bootbox.min.js b/ajax/libs/bootbox.js/2.5.0/bootbox.min.js
new file mode 100755
index 000000000..389a1c689
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.5.0/bootbox.min.js
@@ -0,0 +1,16 @@
+/**
+ * bootbox.js v2.5.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(k){function h(b,a){null==a&&(a=m);return"string"==typeof i[a][b]?i[a][b]:a!=n?h(b,n):b}var m="en",n="en",s=!0,r="static",t="",j={},e={},i={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};e.setLocale=function(b){for(var a in i)if(a==b){m=b;return}throw Error("Invalid locale: "+b);};e.addLocale=function(b,a){"undefined"==typeof i[b]&&(i[b]={});for(var c in a)i[b][c]=a[c]};e.setIcons=function(b){j=b;if("object"!==typeof j||null==j)j={}};e.alert=function(){var b="",a=h("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(b,{label:a,icon:j.OK,callback:c},{onEscape:c})};e.confirm=function(){var b="",a=h("CANCEL"),c=h("CONFIRM"),f=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?
+f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(b,[{label:a,icon:j.CANCEL,callback:function(){"function"==typeof f&&f(!1)}},{label:c,icon:j.CONFIRM,callback:function(){"function"==typeof f&&f(!0)}}])};e.prompt=function(){var b="",a=h("CANCEL"),c=h("CONFIRM"),f=null,u="";switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==
+typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;case 5:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];u=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var p=k("");p.append("");var d=e.dialog(p,[{label:a,
+icon:j.CANCEL,callback:function(){"function"==typeof f&&f(null)}},{label:c,icon:j.CONFIRM,callback:function(){"function"==typeof f&&f(p.find("input[type=text]").val())}}],{header:b});d.on("shown",function(){p.find("input[type=text]").focus();p.on("submit",function(a){a.preventDefault();d.find(".btn-primary").click()})});return d};e.modal=function(){var b,a,c,f={onEscape:null,keyboard:!0,backdrop:r};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;c="object"==typeof c?k.extend(f,c):f;return e.dialog(b,[],c)};e.dialog=function(b,a,c){var f=null,e="",j=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var h=null,i=null,l=null,m="",n=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var h=
+0,i=null,q;for(q in a[d])if(i=q,1<++h)break;1==h&&"function"==typeof a[d][q]&&(a[d].label=i,a[d].callback=a[d][q])}"function"==typeof a[d].callback&&(n=a[d].callback);a[d]["class"]?l=a[d]["class"]:d==a.length-1&&2>=a.length&&(l="btn-primary");h=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(m=" ");i=a[d].href?a[d].href:"javascript:;";e+=""+m+""+h+"";j[d]=n}d=["
");var g=k(d.join("\n"));("undefined"===typeof c.animate?s:c.animate)&&g.addClass("fade");(e="undefined"===typeof c.classes?t:c.classes)&&g.addClass(e);k(".modal-body",g).html(b);g.bind("hidden",
+function(){g.remove()});g.bind("hide",function(){if("escape"==f&&"function"==typeof c.onEscape)c.onEscape()});k(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});g.bind("shown",function(){k("a.btn-primary:last",g).focus()});g.on("click",".modal-footer a, a.close",function(b){var c=k(this).data("handler"),d=j[c],e=null;"undefined"!==typeof c&&"undefined"!==typeof a[c].href||(b.preventDefault(),"function"==typeof d&&(e=d()),!1!==e&&(f="button",g.modal("hide")))});null==c.keyboard&&
+(c.keyboard="function"==typeof c.onEscape);k("body").append(g);g.modal({backdrop:"undefined"===typeof c.backdrop?r:c.backdrop,keyboard:c.keyboard});return g};e.hideAll=function(){k(".bootbox").modal("hide")};e.animate=function(b){s=b};e.backdrop=function(b){r=b};e.classes=function(b){t=b};return e}(window.jQuery);
diff --git a/ajax/libs/bootbox.js/2.5.1/.gitignore b/ajax/libs/bootbox.js/2.5.1/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.5.1/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/2.5.1/bootbox.js b/ajax/libs/bootbox.js/2.5.1/bootbox.js
new file mode 100755
index 000000000..57d8eb553
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.5.1/bootbox.js
@@ -0,0 +1,551 @@
+/**
+ * bootbox.js v2.5.1
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function($) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = 'static',
+ _defaultHref = 'javascript:;',
+ _classes = '',
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ /**
+ * private methods
+ */
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] == 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ /**
+ * public API
+ */
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ };
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] == 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ };
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ };
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ "label": label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ "onEscape": cb
+ });
+ };
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ return that.dialog(str, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(false);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(true);
+ }
+ }
+ }]);
+ };
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var div = that.dialog(form, [{
+ "label": labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(null);
+ }
+ }
+ }, {
+ "label": labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": function() {
+ if (typeof cb == 'function') {
+ cb(
+ form.find("input[type=text]").val()
+ );
+ }
+ }
+ }], {
+ "header": header
+ });
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ return div;
+ };
+
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ };
+
+ that.dialog = function(str, handlers, options) {
+ var hideSource = null,
+ buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ href = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ if (handlers[i]['href']) {
+ href = handlers[i]['href'];
+ }
+ else {
+ href = _defaultHref;
+ }
+
+ buttons += ""+icon+""+label+"";
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("");
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes;
+ if( optionalClasses ) {
+ div.addClass( optionalClasses );
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ $(".modal-body", div).html(str);
+
+ div.bind('hidden', function() {
+ div.remove();
+ });
+
+ div.bind('hide', function() {
+ if (hideSource == 'escape' &&
+ typeof options.onEscape == 'function') {
+ options.onEscape();
+ }
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ $(document).bind('keyup.modal', function ( e ) {
+ if (e.which == 27) {
+ hideSource = 'escape';
+ }
+ });
+
+ // well, *if* we have a primary - give the last dom element (first displayed) focus
+ div.bind('shown', function() {
+ $("a.btn-primary:last", div).focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted
+ // if we've got a custom href attribute, all bets are off
+ if (typeof handler !== 'undefined' &&
+ typeof handlers[handler]['href'] !== 'undefined') {
+
+ return;
+ }
+
+ e.preventDefault();
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+
+ // the only way hideModal *will* be false is if a callback exists and
+ // returns it as a value. in those situations, don't hide the dialog
+ // @see https://github.com/makeusabrew/bootbox/pull/25
+ if (hideModal !== false) {
+ hideSource = 'button';
+ div.modal("hide");
+ }
+ });
+
+ if (options.keyboard == null) {
+ options.keyboard = (typeof options.onEscape == 'function');
+ }
+
+ $("body").append(div);
+
+ div.modal({
+ "backdrop" : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ "keyboard" : options.keyboard
+ });
+
+ return div;
+ };
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+ that.animate = function(animate) {
+ _animate = animate;
+ };
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ };
+
+ that.classes = function(classes) {
+ _classes = classes;
+ };
+
+ return that;
+
+})( window.jQuery );
+
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = bootbox;
diff --git a/ajax/libs/bootbox.js/2.5.1/bootbox.min.js b/ajax/libs/bootbox.js/2.5.1/bootbox.min.js
new file mode 100755
index 000000000..3c75bb1e5
--- /dev/null
+++ b/ajax/libs/bootbox.js/2.5.1/bootbox.min.js
@@ -0,0 +1,16 @@
+/**
+ * bootbox.js v2.5.1
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(k){function h(b,a){null==a&&(a=m);return"string"==typeof i[a][b]?i[a][b]:a!=n?h(b,n):b}var m="en",n="en",s=!0,r="static",t="",j={},e={},i={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};e.setLocale=function(b){for(var a in i)if(a==b){m=b;return}throw Error("Invalid locale: "+b);};e.addLocale=function(b,a){"undefined"==typeof i[b]&&(i[b]={});for(var c in a)i[b][c]=a[c]};e.setIcons=function(b){j=b;if("object"!==typeof j||null==j)j={}};e.alert=function(){var b="",a=h("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return e.dialog(b,{label:a,icon:j.OK,callback:c},{onEscape:c})};e.confirm=function(){var b="",a=h("CANCEL"),c=h("CONFIRM"),f=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?
+f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}return e.dialog(b,[{label:a,icon:j.CANCEL,callback:function(){"function"==typeof f&&f(!1)}},{label:c,icon:j.CONFIRM,callback:function(){"function"==typeof f&&f(!0)}}])};e.prompt=function(){var b="",a=h("CANCEL"),c=h("CONFIRM"),f=null,u="";switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==
+typeof arguments[1]?f=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?f=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];break;case 5:b=arguments[0];a=arguments[1];c=arguments[2];f=arguments[3];u=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var p=k("");p.append("");var d=e.dialog(p,[{label:a,
+icon:j.CANCEL,callback:function(){"function"==typeof f&&f(null)}},{label:c,icon:j.CONFIRM,callback:function(){"function"==typeof f&&f(p.find("input[type=text]").val())}}],{header:b});d.on("shown",function(){p.find("input[type=text]").focus();p.on("submit",function(a){a.preventDefault();d.find(".btn-primary").click()})});return d};e.modal=function(){var b,a,c,f={onEscape:null,keyboard:!0,backdrop:r};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?
+c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}f.header=a;c="object"==typeof c?k.extend(f,c):f;return e.dialog(b,[],c)};e.dialog=function(b,a,c){var f=null,e="",j=[],c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var h=null,i=null,l=null,m="",n=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var h=
+0,i=null,q;for(q in a[d])if(i=q,1<++h)break;1==h&&"function"==typeof a[d][q]&&(a[d].label=i,a[d].callback=a[d][q])}"function"==typeof a[d].callback&&(n=a[d].callback);a[d]["class"]?l=a[d]["class"]:d==a.length-1&&2>=a.length&&(l="btn-primary");h=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(m=" ");i=a[d].href?a[d].href:"javascript:;";e+=""+m+""+h+"";j[d]=n}d=["
");var g=k(d.join("\n"));("undefined"===typeof c.animate?s:c.animate)&&g.addClass("fade");(e="undefined"===typeof c.classes?t:c.classes)&&g.addClass(e);k(".modal-body",g).html(b);g.bind("hidden",
+function(){g.remove()});g.bind("hide",function(){if("escape"==f&&"function"==typeof c.onEscape)c.onEscape()});k(document).bind("keyup.modal",function(a){27==a.which&&(f="escape")});g.bind("shown",function(){k("a.btn-primary:last",g).focus()});g.on("click",".modal-footer a, a.close",function(b){var c=k(this).data("handler"),d=j[c],e=null;"undefined"!==typeof c&&"undefined"!==typeof a[c].href||(b.preventDefault(),"function"==typeof d&&(e=d()),!1!==e&&(f="button",g.modal("hide")))});null==c.keyboard&&
+(c.keyboard="function"==typeof c.onEscape);k("body").append(g);g.modal({backdrop:"undefined"===typeof c.backdrop?r:c.backdrop,keyboard:c.keyboard});return g};e.hideAll=function(){k(".bootbox").modal("hide")};e.animate=function(b){s=b};e.backdrop=function(b){r=b};e.classes=function(b){t=b};return e}(window.jQuery);window.bootbox=bootbox;
diff --git a/ajax/libs/bootbox.js/3.0.0/.gitignore b/ajax/libs/bootbox.js/3.0.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.0.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/3.0.0/bootbox.js b/ajax/libs/bootbox.js/3.0.0/bootbox.js
new file mode 100755
index 000000000..4f2537dd2
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.0.0/bootbox.js
@@ -0,0 +1,603 @@
+/**
+ * bootbox.js v3.0.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function(document, $) {
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = 'static',
+ _defaultHref = 'javascript:;',
+ _classes = '',
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+
+ /**
+ * public API
+ */
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ };
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] === 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ };
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons == null) {
+ _icons = {};
+ }
+ };
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ return that.dialog(str, {
+ // only button (ok)
+ "label" : label,
+ "icon" : _icons.OK,
+ "callback": cb
+ }, {
+ // ensure that the escape key works; either invoking the user's
+ // callback or true to just close the dialog
+ "onEscape": cb || true
+ });
+ };
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ break;
+ }
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ cb(false);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ cb(true);
+ }
+ };
+
+ return that.dialog(str, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // escape key bindings
+ "onEscape": cancelCallback
+ });
+ };
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ break;
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ // yep, native prompts dismiss with null, whereas native
+ // confirms dismiss with false...
+ cb(null);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ cb(form.find("input[type=text]").val());
+ }
+ };
+
+ var div = that.dialog(form, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // prompts need a few extra options
+ "header" : header,
+ // explicitly tell dialog NOT to show the dialog...
+ "show" : false,
+ "onEscape": cancelCallback
+ });
+
+ // ... the reason the prompt needs to be hidden is because we need
+ // to bind our own "shown" handler, after creating the modal but
+ // before any show(n) events are triggered
+ // @see https://github.com/makeusabrew/bootbox/issues/69
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ div.modal("show");
+
+ return div;
+ };
+
+ that.dialog = function(str, handlers, options) {
+ var buttons = "",
+ callbacks = [],
+ options = options || {};
+
+ // check for single object and convert to array if necessary
+ if (handlers == null) {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ href = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ if (handlers[i]['href']) {
+ href = handlers[i]['href'];
+ }
+ else {
+ href = _defaultHref;
+ }
+
+ buttons = ""+icon+""+label+"" + buttons;
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+ // @see https://github.com/twitter/bootstrap/issues/4854
+ // for an explanation of tabIndex=-1
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("");
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes;
+ if (optionalClasses) {
+ div.addClass(optionalClasses);
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ div.find(".modal-body").html(str);
+
+ div.on('hidden', function() {
+ div.remove();
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ div.on('keyup.dismiss.modal', function(e) {
+ // any truthy value passed to onEscape will dismiss the dialog...
+ if (e.which == 27 && options.onEscape) {
+ if (typeof options.onEscape === 'function') {
+ // ... but only a function will be invoked (obviously)
+ options.onEscape();
+ }
+
+ div.modal('hide');
+ }
+ });
+
+ // well, *if* we have a primary - give the first dom element focus
+ div.on('shown', function() {
+ div.find("a.btn-primary:first").focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted
+ // if we've got a custom href attribute, all bets are off
+ if (typeof handler !== 'undefined' &&
+ typeof handlers[handler]['href'] !== 'undefined') {
+
+ return;
+ }
+
+ e.preventDefault();
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+
+ // the only way hideModal *will* be false is if a callback exists and
+ // returns it as a value. in those situations, don't hide the dialog
+ // @see https://github.com/makeusabrew/bootbox/pull/25
+ if (hideModal !== false) {
+ div.modal("hide");
+ }
+ });
+
+ // stick the modal right at the bottom of the main body out of the way
+ $("body").append(div);
+
+ div.modal({
+ // unless explicitly overridden take whatever our default backdrop value is
+ backdrop : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ // ignore bootstrap's keyboard options; we'll handle this ourselves (more fine-grained control)
+ keyboard : false,
+ // @ see https://github.com/makeusabrew/bootbox/issues/69
+ // we *never* want the modal to be shown before we can bind stuff to it
+ // this method can also take a 'show' option, but we'll only use that
+ // later if we need to
+ show : false
+ });
+
+ // @see https://github.com/makeusabrew/bootbox/issues/64
+ // @see https://github.com/makeusabrew/bootbox/issues/60
+ // ...caused by...
+ // @see https://github.com/twitter/bootstrap/issues/4781
+ div.on("show", function(e) {
+ $(document).off("focusin.modal");
+ });
+
+ if (typeof options.show === 'undefined' || options.show === true) {
+ div.modal("show");
+ }
+
+ return div;
+ };
+
+ /**
+ * #modal is deprecated in v3; it can still be used but no guarantees are
+ * made - have never been truly convinced of its merit but perhaps just
+ * needs a tidyup and some TLC
+ */
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ break;
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ };
+
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+ that.animate = function(animate) {
+ _animate = animate;
+ };
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ };
+
+ that.classes = function(classes) {
+ _classes = classes;
+ };
+
+ /**
+ * private API
+ */
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (locale == null) {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] === 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ return that;
+
+}(document, window.jQuery));
+
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = bootbox;
diff --git a/ajax/libs/bootbox.js/3.0.0/bootbox.min.js b/ajax/libs/bootbox.js/3.0.0/bootbox.min.js
new file mode 100755
index 000000000..8721e64ed
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.0.0/bootbox.min.js
@@ -0,0 +1,16 @@
+/**
+ * bootbox.js v3.0.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(v,n){function h(b,a){null==a&&(a=r);return"string"===typeof l[a][b]?l[a][b]:a!=s?h(b,s):b}var r="en",s="en",t=!0,q="static",u="",g={},m={setLocale:function(b){for(var a in l)if(a==b){r=b;return}throw Error("Invalid locale: "+b);},addLocale:function(b,a){"undefined"===typeof l[b]&&(l[b]={});for(var c in a)l[b][c]=a[c]},setIcons:function(b){g=b;if("object"!==typeof g||null==g)g={}},alert:function(){var b="",a=h("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];
+break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return m.dialog(b,{label:a,icon:g.OK,callback:c},{onEscape:c||!0})},confirm:function(){var b="",a=h("CANCEL"),c=h("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=
+arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}var j=function(){"function"===typeof e&&e(!1)};return m.dialog(b,[{label:a,icon:g.CANCEL,callback:j},{label:c,icon:g.CONFIRM,callback:function(){"function"===typeof e&&e(!0)}}],{onEscape:j})},prompt:function(){var b="",a=h("CANCEL"),c=h("CONFIRM"),e=null,j="";switch(arguments.length){case 1:b=
+arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;case 5:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];j=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var d=n("");d.append("");var j=function(){"function"===typeof e&&e(null)},k=m.dialog(d,[{label:a,icon:g.CANCEL,callback:j},{label:c,icon:g.CONFIRM,callback:function(){"function"===typeof e&&e(d.find("input[type=text]").val())}}],{header:b,show:!1,onEscape:j});k.on("shown",function(){d.find("input[type=text]").focus();d.on("submit",function(a){a.preventDefault();k.find(".btn-primary").click()})});k.modal("show");return k},dialog:function(b,a,c){var e="",j=[];c=c||{};null==a?a=[]:"undefined"==typeof a.length&&(a=
+[a]);for(var d=a.length;d--;){var k=null,g=null,h=null,l="",m=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var k=0,g=null,p;for(p in a[d])if(g=p,1<++k)break;1==k&&"function"==typeof a[d][p]&&(a[d].label=g,a[d].callback=a[d][p])}"function"==typeof a[d].callback&&(m=a[d].callback);a[d]["class"]?h=a[d]["class"]:d==a.length-1&&2>=a.length&&(h="btn-primary");k=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(l=" ");
+g=a[d].href?a[d].href:"javascript:;";e=""+l+""+k+""+e;j[d]=m}d=["
");
+var f=n(d.join("\n"));("undefined"===typeof c.animate?t:c.animate)&&f.addClass("fade");(e="undefined"===typeof c.classes?u:c.classes)&&f.addClass(e);f.find(".modal-body").html(b);f.on("hidden",function(){f.remove()});f.on("keyup.dismiss.modal",function(a){if(27==a.which&&c.onEscape){if("function"===typeof c.onEscape)c.onEscape();f.modal("hide")}});f.on("shown",function(){f.find("a.btn-primary:first").focus()});f.on("click",".modal-footer a, a.close",function(b){var c=n(this).data("handler"),d=j[c],
+e=null;"undefined"!==typeof c&&"undefined"!==typeof a[c].href||(b.preventDefault(),"function"==typeof d&&(e=d()),!1!==e&&f.modal("hide"))});n("body").append(f);f.modal({backdrop:"undefined"===typeof c.backdrop?q:c.backdrop,keyboard:!1,show:!1});f.on("show",function(){n(v).off("focusin.modal")});("undefined"===typeof c.show||!0===c.show)&&f.modal("show");return f},modal:function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:q};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];
+"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=a;c="object"==typeof c?n.extend(e,c):e;return m.dialog(b,[],c)},hideAll:function(){n(".bootbox").modal("hide")},animate:function(b){t=b},backdrop:function(b){q=b},classes:function(b){u=b}},l={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",
+CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};return m}(document,window.jQuery);window.bootbox=bootbox;
diff --git a/ajax/libs/bootbox.js/3.1.0/.gitignore b/ajax/libs/bootbox.js/3.1.0/.gitignore
new file mode 100755
index 000000000..5f67ac0df
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.1.0/.gitignore
@@ -0,0 +1,2 @@
+*.swo
+*.swp
diff --git a/ajax/libs/bootbox.js/3.1.0/bootbox.js b/ajax/libs/bootbox.js/3.1.0/bootbox.js
new file mode 100755
index 000000000..8fb9f92dc
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.1.0/bootbox.js
@@ -0,0 +1,616 @@
+/**
+ * bootbox.js v3.1.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function(document, $) {
+ /*jshint scripturl:true sub:true */
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = 'static',
+ _defaultHref = 'javascript:;',
+ _classes = '',
+ _btnClasses = {},
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+
+ /**
+ * public API
+ */
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ };
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] === 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ };
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons === null) {
+ _icons = {};
+ }
+ };
+
+ that.setBtnClasses = function(btnClasses) {
+ _btnClasses = btnClasses;
+ if (typeof _btnClasses !== 'object' || _btnClasses === null) {
+ _btnClasses = {};
+ }
+ };
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ }
+
+ return that.dialog(str, {
+ // only button (ok)
+ "label" : label,
+ "icon" : _icons.OK,
+ "class" : _btnClasses.OK,
+ "callback": cb
+ }, {
+ // ensure that the escape key works; either invoking the user's
+ // callback or true to just close the dialog
+ "onEscape": cb || true
+ });
+ };
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ }
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(false);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(true);
+ }
+ };
+
+ return that.dialog(str, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "class" : _btnClasses.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "class" : _btnClasses.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // escape key bindings
+ "onEscape": cancelCallback
+ });
+ };
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ // yep, native prompts dismiss with null, whereas native
+ // confirms dismiss with false...
+ return cb(null);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(form.find("input[type=text]").val());
+ }
+ };
+
+ var div = that.dialog(form, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "class" : _btnClasses.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "class" : _btnClasses.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // prompts need a few extra options
+ "header" : header,
+ // explicitly tell dialog NOT to show the dialog...
+ "show" : false,
+ "onEscape": cancelCallback
+ });
+
+ // ... the reason the prompt needs to be hidden is because we need
+ // to bind our own "shown" handler, after creating the modal but
+ // before any show(n) events are triggered
+ // @see https://github.com/makeusabrew/bootbox/issues/69
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ div.modal("show");
+
+ return div;
+ };
+
+ that.dialog = function(str, handlers, options) {
+ var buttons = "",
+ callbacks = [];
+
+ if (!options) {
+ options = {};
+ }
+
+ // check for single object and convert to array if necessary
+ if (typeof handlers === 'undefined') {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ href = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ if (handlers[i]['href']) {
+ href = handlers[i]['href'];
+ }
+ else {
+ href = _defaultHref;
+ }
+
+ buttons = ""+icon+""+label+"" + buttons;
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+ // @see https://github.com/twitter/bootstrap/issues/4854
+ // for an explanation of tabIndex=-1
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("");
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes;
+ if (optionalClasses) {
+ div.addClass(optionalClasses);
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ div.find(".modal-body").html(str);
+
+ div.on('hidden', function() {
+ div.remove();
+ });
+
+ // hook into the modal's keyup trigger to check for the escape key
+ div.on('keyup.dismiss.modal', function(e) {
+ // any truthy value passed to onEscape will dismiss the dialog...
+ if (e.which == 27 && options.onEscape) {
+ if (typeof options.onEscape === 'function') {
+ // ... but only a function will be invoked (obviously)
+ options.onEscape();
+ }
+
+ div.modal('hide');
+ }
+ });
+
+ // well, *if* we have a primary - give the first dom element focus
+ div.on('shown', function() {
+ div.find("a.btn-primary:first").focus();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a, a.close', function(e) {
+
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted
+ // if we've got a custom href attribute, all bets are off
+ if (typeof handler !== 'undefined' &&
+ typeof handlers[handler]['href'] !== 'undefined') {
+
+ return;
+ }
+
+ e.preventDefault();
+
+ if (typeof cb == 'function') {
+ hideModal = cb();
+ }
+
+ // the only way hideModal *will* be false is if a callback exists and
+ // returns it as a value. in those situations, don't hide the dialog
+ // @see https://github.com/makeusabrew/bootbox/pull/25
+ if (hideModal !== false) {
+ div.modal("hide");
+ }
+ });
+
+ // stick the modal right at the bottom of the main body out of the way
+ $("body").append(div);
+
+ div.modal({
+ // unless explicitly overridden take whatever our default backdrop value is
+ backdrop : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ // ignore bootstrap's keyboard options; we'll handle this ourselves (more fine-grained control)
+ keyboard : false,
+ // @ see https://github.com/makeusabrew/bootbox/issues/69
+ // we *never* want the modal to be shown before we can bind stuff to it
+ // this method can also take a 'show' option, but we'll only use that
+ // later if we need to
+ show : false
+ });
+
+ // @see https://github.com/makeusabrew/bootbox/issues/64
+ // @see https://github.com/makeusabrew/bootbox/issues/60
+ // ...caused by...
+ // @see https://github.com/twitter/bootstrap/issues/4781
+ div.on("show", function(e) {
+ $(document).off("focusin.modal");
+ });
+
+ if (typeof options.show === 'undefined' || options.show === true) {
+ div.modal("show");
+ }
+
+ return div;
+ };
+
+ /**
+ * #modal is deprecated in v3; it can still be used but no guarantees are
+ * made - have never been truly convinced of its merit but perhaps just
+ * needs a tidyup and some TLC
+ */
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ };
+
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+ that.animate = function(animate) {
+ _animate = animate;
+ };
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ };
+
+ that.classes = function(classes) {
+ _classes = classes;
+ };
+
+ /**
+ * private API
+ */
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (typeof locale === 'undefined') {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] === 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ return that;
+
+}(document, window.jQuery));
+
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = bootbox;
diff --git a/ajax/libs/bootbox.js/3.1.0/bootbox.min.js b/ajax/libs/bootbox.js/3.1.0/bootbox.min.js
new file mode 100755
index 000000000..37e6ac26d
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.1.0/bootbox.min.js
@@ -0,0 +1,17 @@
+/**
+ * bootbox.js v3.1.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(v,p){function m(b,a){"undefined"===typeof a&&(a=r);return"string"===typeof n[a][b]?n[a][b]:a!=s?m(b,s):b}var r="en",s="en",t=!0,q="static",u="",h={},f={},k={setLocale:function(b){for(var a in n)if(a==b){r=b;return}throw Error("Invalid locale: "+b);},addLocale:function(b,a){"undefined"===typeof n[b]&&(n[b]={});for(var c in a)n[b][c]=a[c]},setIcons:function(b){f=b;if("object"!==typeof f||null===f)f={}},setBtnClasses:function(b){h=b;if("object"!==typeof h||null===
+h)h={}},alert:function(){var b="",a=m("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return k.dialog(b,{label:a,icon:f.OK,"class":h.OK,callback:c},{onEscape:c||!0})},confirm:function(){var b="",a=m("CANCEL"),c=m("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];
+break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}var j=function(){if("function"===typeof e)return e(!1)};return k.dialog(b,[{label:a,icon:f.CANCEL,"class":h.CANCEL,callback:j},{label:c,icon:f.CONFIRM,"class":h.CONFIRM,
+callback:function(){if("function"===typeof e)return e(!0)}}],{onEscape:j})},prompt:function(){var b="",a=m("CANCEL"),c=m("CONFIRM"),e=null,j="";switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;case 5:b=arguments[0];a=arguments[1];
+c=arguments[2];e=arguments[3];j=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var d=p("");d.append("");var j=function(){if("function"===typeof e)return e(null)},l=k.dialog(d,[{label:a,icon:f.CANCEL,"class":h.CANCEL,callback:j},{label:c,icon:f.CONFIRM,"class":h.CONFIRM,callback:function(){if("function"===typeof e)return e(d.find("input[type=text]").val())}}],{header:b,show:!1,onEscape:j});l.on("shown",
+function(){d.find("input[type=text]").focus();d.on("submit",function(a){a.preventDefault();l.find(".btn-primary").click()})});l.modal("show");return l},dialog:function(b,a,c){var e="",j=[];c||(c={});"undefined"===typeof a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var l=null,h=null,f=null,m="",n=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==typeof a[d].callback){var l=0,h=null,k;for(k in a[d])if(h=k,1<++l)break;1==l&&"function"==typeof a[d][k]&&
+(a[d].label=h,a[d].callback=a[d][k])}"function"==typeof a[d].callback&&(n=a[d].callback);a[d]["class"]?f=a[d]["class"]:d==a.length-1&&2>=a.length&&(f="btn-primary");l=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(m=" ");h=a[d].href?a[d].href:"javascript:;";e=""+m+""+l+""+e;j[d]=n}d=["
");var g=p(d.join("\n"));("undefined"===typeof c.animate?t:c.animate)&&g.addClass("fade");(e="undefined"===typeof c.classes?u:c.classes)&&g.addClass(e);g.find(".modal-body").html(b);g.on("hidden",function(){g.remove()});g.on("keyup.dismiss.modal",function(a){if(27==
+a.which&&c.onEscape){if("function"===typeof c.onEscape)c.onEscape();g.modal("hide")}});g.on("shown",function(){g.find("a.btn-primary:first").focus()});g.on("click",".modal-footer a, a.close",function(b){var c=p(this).data("handler"),d=j[c],e=null;"undefined"!==typeof c&&"undefined"!==typeof a[c].href||(b.preventDefault(),"function"==typeof d&&(e=d()),!1!==e&&g.modal("hide"))});p("body").append(g);g.modal({backdrop:"undefined"===typeof c.backdrop?q:c.backdrop,keyboard:!1,show:!1});g.on("show",function(){p(v).off("focusin.modal")});
+("undefined"===typeof c.show||!0===c.show)&&g.modal("show");return g},modal:function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:q};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=a;c="object"==typeof c?p.extend(e,c):e;return k.dialog(b,[],c)},hideAll:function(){p(".bootbox").modal("hide")},
+animate:function(b){t=b},backdrop:function(b){q=b},classes:function(b){u=b}},n={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",
+CANCEL:"Annulla",CONFIRM:"Conferma"}};return k}(document,window.jQuery);window.bootbox=bootbox;
diff --git a/ajax/libs/bootbox.js/3.2.0/bootbox.js b/ajax/libs/bootbox.js/3.2.0/bootbox.js
new file mode 100644
index 000000000..e2c4c2a70
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.2.0/bootbox.js
@@ -0,0 +1,631 @@
+/**
+ * bootbox.js v3.2.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function(document, $) {
+ /*jshint scripturl:true sub:true */
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = 'static',
+ _defaultHref = 'javascript:;',
+ _classes = '',
+ _btnClasses = {},
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+
+ /**
+ * public API
+ */
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ };
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] === 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ };
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons === null) {
+ _icons = {};
+ }
+ };
+
+ that.setBtnClasses = function(btnClasses) {
+ _btnClasses = btnClasses;
+ if (typeof _btnClasses !== 'object' || _btnClasses === null) {
+ _btnClasses = {};
+ }
+ };
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ }
+
+ return that.dialog(str, {
+ // only button (ok)
+ "label" : label,
+ "icon" : _icons.OK,
+ "class" : _btnClasses.OK,
+ "callback": cb
+ }, {
+ // ensure that the escape key works; either invoking the user's
+ // callback or true to just close the dialog
+ "onEscape": cb || true
+ });
+ };
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ }
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(false);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(true);
+ }
+ };
+
+ return that.dialog(str, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "class" : _btnClasses.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "class" : _btnClasses.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // escape key bindings
+ "onEscape": cancelCallback
+ });
+ };
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ // yep, native prompts dismiss with null, whereas native
+ // confirms dismiss with false...
+ return cb(null);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(form.find("input[type=text]").val());
+ }
+ };
+
+ var div = that.dialog(form, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "class" : _btnClasses.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "class" : _btnClasses.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // prompts need a few extra options
+ "header" : header,
+ // explicitly tell dialog NOT to show the dialog...
+ "show" : false,
+ "onEscape": cancelCallback
+ });
+
+ // ... the reason the prompt needs to be hidden is because we need
+ // to bind our own "shown" handler, after creating the modal but
+ // before any show(n) events are triggered
+ // @see https://github.com/makeusabrew/bootbox/issues/69
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ div.modal("show");
+
+ return div;
+ };
+
+ that.dialog = function(str, handlers, options) {
+ var buttons = "",
+ callbacks = [];
+
+ if (!options) {
+ options = {};
+ }
+
+ // check for single object and convert to array if necessary
+ if (typeof handlers === 'undefined') {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ href = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ if (handlers[i]['href']) {
+ href = handlers[i]['href'];
+ }
+ else {
+ href = _defaultHref;
+ }
+
+ buttons = ""+icon+""+label+"" + buttons;
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+ // @see https://github.com/twitter/bootstrap/issues/4854
+ // for an explanation of tabIndex=-1
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("");
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes;
+ if (optionalClasses) {
+ div.addClass(optionalClasses);
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ div.find(".modal-body").html(str);
+
+ function onCancel(source) {
+ // for now source is unused, but it will be in future
+ var hideModal = null;
+ if (typeof options.onEscape === 'function') {
+ // @see https://github.com/makeusabrew/bootbox/issues/91
+ hideModal = options.onEscape();
+ }
+
+ if (hideModal !== false) {
+ div.modal('hide');
+ }
+ }
+
+ // hook into the modal's keyup trigger to check for the escape key
+ div.on('keyup.dismiss.modal', function(e) {
+ // any truthy value passed to onEscape will dismiss the dialog
+ // as long as the onEscape function (if defined) doesn't prevent it
+ if (e.which === 27 && options.onEscape) {
+ onCancel('escape');
+ }
+ });
+
+ // handle close buttons too
+ div.on('click', 'a.close', function(e) {
+ e.preventDefault();
+ onCancel('close');
+ });
+
+ // well, *if* we have a primary - give the first dom element focus
+ div.on('shown', function() {
+ div.find("a.btn-primary:first").focus();
+ });
+
+ div.on('hidden', function() {
+ div.remove();
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a', function(e) {
+
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted
+ // if we've got a custom href attribute, all bets are off
+ if (typeof handler !== 'undefined' &&
+ typeof handlers[handler]['href'] !== 'undefined') {
+
+ return;
+ }
+
+ e.preventDefault();
+
+ if (typeof cb === 'function') {
+ hideModal = cb();
+ }
+
+ // the only way hideModal *will* be false is if a callback exists and
+ // returns it as a value. in those situations, don't hide the dialog
+ // @see https://github.com/makeusabrew/bootbox/pull/25
+ if (hideModal !== false) {
+ div.modal("hide");
+ }
+ });
+
+ // stick the modal right at the bottom of the main body out of the way
+ $("body").append(div);
+
+ div.modal({
+ // unless explicitly overridden take whatever our default backdrop value is
+ backdrop : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ // ignore bootstrap's keyboard options; we'll handle this ourselves (more fine-grained control)
+ keyboard : false,
+ // @ see https://github.com/makeusabrew/bootbox/issues/69
+ // we *never* want the modal to be shown before we can bind stuff to it
+ // this method can also take a 'show' option, but we'll only use that
+ // later if we need to
+ show : false
+ });
+
+ // @see https://github.com/makeusabrew/bootbox/issues/64
+ // @see https://github.com/makeusabrew/bootbox/issues/60
+ // ...caused by...
+ // @see https://github.com/twitter/bootstrap/issues/4781
+ div.on("show", function(e) {
+ $(document).off("focusin.modal");
+ });
+
+ if (typeof options.show === 'undefined' || options.show === true) {
+ div.modal("show");
+ }
+
+ return div;
+ };
+
+ /**
+ * #modal is deprecated in v3; it can still be used but no guarantees are
+ * made - have never been truly convinced of its merit but perhaps just
+ * needs a tidyup and some TLC
+ */
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ };
+
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+ that.animate = function(animate) {
+ _animate = animate;
+ };
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ };
+
+ that.classes = function(classes) {
+ _classes = classes;
+ };
+
+ /**
+ * private API
+ */
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (typeof locale === 'undefined') {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] === 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ return that;
+
+}(document, window.jQuery));
+
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = bootbox;
diff --git a/ajax/libs/bootbox.js/3.2.0/bootbox.min.js b/ajax/libs/bootbox.js/3.2.0/bootbox.min.js
new file mode 100644
index 000000000..502a6401b
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.2.0/bootbox.min.js
@@ -0,0 +1,17 @@
+/**
+ * bootbox.js v3.2.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(w,n){function k(b,a){"undefined"===typeof a&&(a=p);return"string"===typeof j[a][b]?j[a][b]:a!=t?k(b,t):b}var p="en",t="en",u=!0,s="static",v="",l={},g={},m={setLocale:function(b){for(var a in j)if(a==b){p=b;return}throw Error("Invalid locale: "+b);},addLocale:function(b,a){"undefined"===typeof j[b]&&(j[b]={});for(var c in a)j[b][c]=a[c]},setIcons:function(b){g=b;if("object"!==typeof g||null===g)g={}},setBtnClasses:function(b){l=b;if("object"!==typeof l||null===
+l)l={}},alert:function(){var b="",a=k("OK"),c=null;switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}return m.dialog(b,{label:a,icon:g.OK,"class":l.OK,callback:c},{onEscape:c||!0})},confirm:function(){var b="",a=k("CANCEL"),c=k("CONFIRM"),e=null;switch(arguments.length){case 1:b=arguments[0];
+break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;default:throw Error("Incorrect number of arguments: expected 1-4");}var h=function(){if("function"===typeof e)return e(!1)};return m.dialog(b,[{label:a,icon:g.CANCEL,"class":l.CANCEL,callback:h},{label:c,icon:g.CONFIRM,"class":l.CONFIRM,
+callback:function(){if("function"===typeof e)return e(!0)}}],{onEscape:h})},prompt:function(){var b="",a=k("CANCEL"),c=k("CONFIRM"),e=null,h="";switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"function"==typeof arguments[1]?e=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];"function"==typeof arguments[2]?e=arguments[2]:c=arguments[2];break;case 4:b=arguments[0];a=arguments[1];c=arguments[2];e=arguments[3];break;case 5:b=arguments[0];a=arguments[1];
+c=arguments[2];e=arguments[3];h=arguments[4];break;default:throw Error("Incorrect number of arguments: expected 1-5");}var q=n("");q.append("");var h=function(){if("function"===typeof e)return e(null)},d=m.dialog(q,[{label:a,icon:g.CANCEL,"class":l.CANCEL,callback:h},{label:c,icon:g.CONFIRM,"class":l.CONFIRM,callback:function(){if("function"===typeof e)return e(q.find("input[type=text]").val())}}],{header:b,show:!1,onEscape:h});d.on("shown",
+function(){q.find("input[type=text]").focus();q.on("submit",function(a){a.preventDefault();d.find(".btn-primary").click()})});d.modal("show");return d},dialog:function(b,a,c){function e(){var a=null;"function"===typeof c.onEscape&&(a=c.onEscape());!1!==a&&f.modal("hide")}var h="",l=[];c||(c={});"undefined"===typeof a?a=[]:"undefined"==typeof a.length&&(a=[a]);for(var d=a.length;d--;){var g=null,k=null,j=null,m="",p=null;if("undefined"==typeof a[d].label&&"undefined"==typeof a[d]["class"]&&"undefined"==
+typeof a[d].callback){var g=0,k=null,r;for(r in a[d])if(k=r,1<++g)break;1==g&&"function"==typeof a[d][r]&&(a[d].label=k,a[d].callback=a[d][r])}"function"==typeof a[d].callback&&(p=a[d].callback);a[d]["class"]?j=a[d]["class"]:d==a.length-1&&2>=a.length&&(j="btn-primary");g=a[d].label?a[d].label:"Option "+(d+1);a[d].icon&&(m=" ");k=a[d].href?a[d].href:"javascript:;";h=""+m+""+g+""+h;l[d]=p}d=["
");var f=n(d.join("\n"));("undefined"===typeof c.animate?u:c.animate)&&f.addClass("fade");(h="undefined"===typeof c.classes?v:c.classes)&&f.addClass(h);f.find(".modal-body").html(b);f.on("keyup.dismiss.modal",
+function(a){27===a.which&&c.onEscape&&e("escape")});f.on("click","a.close",function(a){a.preventDefault();e("close")});f.on("shown",function(){f.find("a.btn-primary:first").focus()});f.on("hidden",function(){f.remove()});f.on("click",".modal-footer a",function(b){var c=n(this).data("handler"),d=l[c],e=null;"undefined"!==typeof c&&"undefined"!==typeof a[c].href||(b.preventDefault(),"function"===typeof d&&(e=d()),!1!==e&&f.modal("hide"))});n("body").append(f);f.modal({backdrop:"undefined"===typeof c.backdrop?
+s:c.backdrop,keyboard:!1,show:!1});f.on("show",function(){n(w).off("focusin.modal")});("undefined"===typeof c.show||!0===c.show)&&f.modal("show");return f},modal:function(){var b,a,c,e={onEscape:null,keyboard:!0,backdrop:s};switch(arguments.length){case 1:b=arguments[0];break;case 2:b=arguments[0];"object"==typeof arguments[1]?c=arguments[1]:a=arguments[1];break;case 3:b=arguments[0];a=arguments[1];c=arguments[2];break;default:throw Error("Incorrect number of arguments: expected 1-3");}e.header=a;
+c="object"==typeof c?n.extend(e,c):e;return m.dialog(b,[],c)},hideAll:function(){n(".bootbox").modal("hide")},animate:function(b){u=b},backdrop:function(b){s=b},classes:function(b){v=b}},j={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},ru:{OK:"OK",CANCEL:"\u041e\u0442\u043c\u0435\u043d\u0430",
+CONFIRM:"\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"}};return m}(document,window.jQuery);window.bootbox=bootbox;
diff --git a/ajax/libs/bootbox.js/3.3.0/bootbox.js b/ajax/libs/bootbox.js/3.3.0/bootbox.js
new file mode 100644
index 000000000..f6c6661cd
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.3.0/bootbox.js
@@ -0,0 +1,660 @@
+/**
+ * bootbox.js v3.3.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox = window.bootbox || (function(document, $) {
+ /*jshint scripturl:true sub:true */
+
+ var _locale = 'en',
+ _defaultLocale = 'en',
+ _animate = true,
+ _backdrop = 'static',
+ _defaultHref = 'javascript:;',
+ _classes = '',
+ _btnClasses = {},
+ _icons = {},
+ /* last var should always be the public object we'll return */
+ that = {};
+
+
+ /**
+ * public API
+ */
+ that.setLocale = function(locale) {
+ for (var i in _locales) {
+ if (i == locale) {
+ _locale = locale;
+ return;
+ }
+ }
+ throw new Error('Invalid locale: '+locale);
+ };
+
+ that.addLocale = function(locale, translations) {
+ if (typeof _locales[locale] === 'undefined') {
+ _locales[locale] = {};
+ }
+ for (var str in translations) {
+ _locales[locale][str] = translations[str];
+ }
+ };
+
+ that.setIcons = function(icons) {
+ _icons = icons;
+ if (typeof _icons !== 'object' || _icons === null) {
+ _icons = {};
+ }
+ };
+
+ that.setBtnClasses = function(btnClasses) {
+ _btnClasses = btnClasses;
+ if (typeof _btnClasses !== 'object' || _btnClasses === null) {
+ _btnClasses = {};
+ }
+ };
+
+ that.alert = function(/*str, label, cb*/) {
+ var str = "",
+ label = _translate('OK'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ // no callback, default button label
+ str = arguments[0];
+ break;
+ case 2:
+ // callback *or* custom button label dependent on type
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ // callback and custom button label
+ str = arguments[0];
+ label = arguments[1];
+ cb = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ }
+
+ return that.dialog(str, {
+ // only button (ok)
+ "label" : label,
+ "icon" : _icons.OK,
+ "class" : _btnClasses.OK,
+ "callback": cb
+ }, {
+ // ensure that the escape key works; either invoking the user's
+ // callback or true to just close the dialog
+ "onEscape": cb || true
+ });
+ };
+
+ that.confirm = function(/*str, labelCancel, labelOk, cb*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null;
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-4");
+ }
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(false);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(true);
+ }
+ };
+
+ return that.dialog(str, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "class" : _btnClasses.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "class" : _btnClasses.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // escape key bindings
+ "onEscape": cancelCallback
+ });
+ };
+
+ that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) {
+ var str = "",
+ labelCancel = _translate('CANCEL'),
+ labelOk = _translate('CONFIRM'),
+ cb = null,
+ defaultVal = "";
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'function') {
+ cb = arguments[1];
+ } else {
+ labelCancel = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ if (typeof arguments[2] == 'function') {
+ cb = arguments[2];
+ } else {
+ labelOk = arguments[2];
+ }
+ break;
+ case 4:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ break;
+ case 5:
+ str = arguments[0];
+ labelCancel = arguments[1];
+ labelOk = arguments[2];
+ cb = arguments[3];
+ defaultVal = arguments[4];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-5");
+ }
+
+ var header = str;
+
+ // let's keep a reference to the form object for later
+ var form = $("");
+ form.append("");
+
+ var cancelCallback = function() {
+ if (typeof cb === 'function') {
+ // yep, native prompts dismiss with null, whereas native
+ // confirms dismiss with false...
+ return cb(null);
+ }
+ };
+
+ var confirmCallback = function() {
+ if (typeof cb === 'function') {
+ return cb(form.find("input[type=text]").val());
+ }
+ };
+
+ var div = that.dialog(form, [{
+ // first button (cancel)
+ "label" : labelCancel,
+ "icon" : _icons.CANCEL,
+ "class" : _btnClasses.CANCEL,
+ "callback": cancelCallback
+ }, {
+ // second button (confirm)
+ "label" : labelOk,
+ "icon" : _icons.CONFIRM,
+ "class" : _btnClasses.CONFIRM,
+ "callback": confirmCallback
+ }], {
+ // prompts need a few extra options
+ "header" : header,
+ // explicitly tell dialog NOT to show the dialog...
+ "show" : false,
+ "onEscape": cancelCallback
+ });
+
+ // ... the reason the prompt needs to be hidden is because we need
+ // to bind our own "shown" handler, after creating the modal but
+ // before any show(n) events are triggered
+ // @see https://github.com/makeusabrew/bootbox/issues/69
+
+ div.on("shown", function() {
+ form.find("input[type=text]").focus();
+
+ // ensure that submitting the form (e.g. with the enter key)
+ // replicates the behaviour of a normal prompt()
+ form.on("submit", function(e) {
+ e.preventDefault();
+ div.find(".btn-primary").click();
+ });
+ });
+
+ div.modal("show");
+
+ return div;
+ };
+
+ that.dialog = function(str, handlers, options) {
+ var buttons = "",
+ callbacks = [];
+
+ if (!options) {
+ options = {};
+ }
+
+ // check for single object and convert to array if necessary
+ if (typeof handlers === 'undefined') {
+ handlers = [];
+ } else if (typeof handlers.length == 'undefined') {
+ handlers = [handlers];
+ }
+
+ var i = handlers.length;
+ while (i--) {
+ var label = null,
+ href = null,
+ _class = null,
+ icon = '',
+ callback = null;
+
+ if (typeof handlers[i]['label'] == 'undefined' &&
+ typeof handlers[i]['class'] == 'undefined' &&
+ typeof handlers[i]['callback'] == 'undefined') {
+ // if we've got nothing we expect, check for condensed format
+
+ var propCount = 0, // condensed will only match if this == 1
+ property = null; // save the last property we found
+
+ // be nicer to count the properties without this, but don't think it's possible...
+ for (var j in handlers[i]) {
+ property = j;
+ if (++propCount > 1) {
+ // forget it, too many properties
+ break;
+ }
+ }
+
+ if (propCount == 1 && typeof handlers[i][j] == 'function') {
+ // matches condensed format of label -> function
+ handlers[i]['label'] = property;
+ handlers[i]['callback'] = handlers[i][j];
+ }
+ }
+
+ if (typeof handlers[i]['callback']== 'function') {
+ callback = handlers[i]['callback'];
+ }
+
+ if (handlers[i]['class']) {
+ _class = handlers[i]['class'];
+ } else if (i == handlers.length -1 && handlers.length <= 2) {
+ // always add a primary to the main option in a two-button dialog
+ _class = 'btn-primary';
+ }
+
+ if (handlers[i]['link'] !== true) {
+ _class = 'btn ' + _class;
+ }
+
+ if (handlers[i]['label']) {
+ label = handlers[i]['label'];
+ } else {
+ label = "Option "+(i+1);
+ }
+
+ if (handlers[i]['icon']) {
+ icon = " ";
+ }
+
+ if (handlers[i]['href']) {
+ href = handlers[i]['href'];
+ }
+ else {
+ href = _defaultHref;
+ }
+
+ buttons = ""+icon+""+label+"" + buttons;
+
+ callbacks[i] = callback;
+ }
+
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+ // @see https://github.com/twitter/bootstrap/issues/4854
+ // for an explanation of tabIndex=-1
+
+ var parts = ["
"];
+
+ if (options['header']) {
+ var closeButton = '';
+ if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
+ closeButton = "×";
+ }
+
+ parts.push("
"+closeButton+"
"+options['header']+"
");
+ }
+
+ // push an empty body into which we'll inject the proper content later
+ parts.push("");
+
+ if (buttons) {
+ parts.push("");
+ }
+
+ parts.push("
");
+
+ var div = $(parts.join("\n"));
+
+ // check whether we should fade in/out
+ var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate;
+
+ if (shouldFade) {
+ div.addClass("fade");
+ }
+
+ var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes;
+ if (optionalClasses) {
+ div.addClass(optionalClasses);
+ }
+
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ div.find(".modal-body").html(str);
+
+ function onCancel(source) {
+ // for now source is unused, but it will be in future
+ var hideModal = null;
+ if (typeof options.onEscape === 'function') {
+ // @see https://github.com/makeusabrew/bootbox/issues/91
+ hideModal = options.onEscape();
+ }
+
+ if (hideModal !== false) {
+ div.modal('hide');
+ }
+ }
+
+ // hook into the modal's keyup trigger to check for the escape key
+ div.on('keyup.dismiss.modal', function(e) {
+ // any truthy value passed to onEscape will dismiss the dialog
+ // as long as the onEscape function (if defined) doesn't prevent it
+ if (e.which === 27 && options.onEscape) {
+ onCancel('escape');
+ }
+ });
+
+ // handle close buttons too
+ div.on('click', 'a.close', function(e) {
+ e.preventDefault();
+ onCancel('close');
+ });
+
+ // well, *if* we have a primary - give the first dom element focus
+ div.on('shown', function() {
+ div.find("a.btn-primary:first").focus();
+ });
+
+ div.on('hidden', function(e) {
+ // @see https://github.com/makeusabrew/bootbox/issues/115
+ // allow for the fact hidden events can propagate up from
+ // child elements like tooltips
+ if (e.target === this) {
+ div.remove();
+ }
+ });
+
+ // wire up button handlers
+ div.on('click', '.modal-footer a', function(e) {
+
+ var handler = $(this).data("handler"),
+ cb = callbacks[handler],
+ hideModal = null;
+
+ // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted
+ // if we've got a custom href attribute, all bets are off
+ if (typeof handler !== 'undefined' &&
+ typeof handlers[handler]['href'] !== 'undefined') {
+
+ return;
+ }
+
+ e.preventDefault();
+
+ if (typeof cb === 'function') {
+ hideModal = cb(e);
+ }
+
+ // the only way hideModal *will* be false is if a callback exists and
+ // returns it as a value. in those situations, don't hide the dialog
+ // @see https://github.com/makeusabrew/bootbox/pull/25
+ if (hideModal !== false) {
+ div.modal("hide");
+ }
+ });
+
+ // stick the modal right at the bottom of the main body out of the way
+ $("body").append(div);
+
+ div.modal({
+ // unless explicitly overridden take whatever our default backdrop value is
+ backdrop : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ // ignore bootstrap's keyboard options; we'll handle this ourselves (more fine-grained control)
+ keyboard : false,
+ // @ see https://github.com/makeusabrew/bootbox/issues/69
+ // we *never* want the modal to be shown before we can bind stuff to it
+ // this method can also take a 'show' option, but we'll only use that
+ // later if we need to
+ show : false
+ });
+
+ // @see https://github.com/makeusabrew/bootbox/issues/64
+ // @see https://github.com/makeusabrew/bootbox/issues/60
+ // ...caused by...
+ // @see https://github.com/twitter/bootstrap/issues/4781
+ div.on("show", function(e) {
+ $(document).off("focusin.modal");
+ });
+
+ if (typeof options.show === 'undefined' || options.show === true) {
+ div.modal("show");
+ }
+
+ return div;
+ };
+
+ /**
+ * #modal is deprecated in v3; it can still be used but no guarantees are
+ * made - have never been truly convinced of its merit but perhaps just
+ * needs a tidyup and some TLC
+ */
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ };
+
+
+ that.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+ that.animate = function(animate) {
+ _animate = animate;
+ };
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ };
+
+ that.classes = function(classes) {
+ _classes = classes;
+ };
+
+ /**
+ * private API
+ */
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var _locales = {
+ 'br' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Sim'
+ },
+ 'da' : {
+ OK : 'OK',
+ CANCEL : 'Annuller',
+ CONFIRM : 'Accepter'
+ },
+ 'de' : {
+ OK : 'OK',
+ CANCEL : 'Abbrechen',
+ CONFIRM : 'Akzeptieren'
+ },
+ 'en' : {
+ OK : 'OK',
+ CANCEL : 'Cancel',
+ CONFIRM : 'OK'
+ },
+ 'es' : {
+ OK : 'OK',
+ CANCEL : 'Cancelar',
+ CONFIRM : 'Aceptar'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'pl' : {
+ OK : 'OK',
+ CANCEL : 'Anuluj',
+ CONFIRM : 'Potwierdź'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'zh_CN' : {
+ OK : 'OK',
+ CANCEL : '取消',
+ CONFIRM : '确认'
+ },
+ 'zh_TW' : {
+ OK : 'OK',
+ CANCEL : '取消',
+ CONFIRM : '確認'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (typeof locale === 'undefined') {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] === 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
+ }
+
+ return that;
+
+}(document, window.jQuery));
+
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = bootbox;
diff --git a/ajax/libs/bootbox.js/3.3.0/bootbox.min.js b/ajax/libs/bootbox.js/3.3.0/bootbox.min.js
new file mode 100644
index 000000000..509f14b15
--- /dev/null
+++ b/ajax/libs/bootbox.js/3.3.0/bootbox.min.js
@@ -0,0 +1,6 @@
+/**
+ * bootbox.js v3.3.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+var bootbox=window.bootbox||function(a,b){function c(a,b){return"undefined"==typeof b&&(b=d),"string"==typeof m[b][a]?m[b][a]:b!=e?c(a,e):a}var d="en",e="en",f=!0,g="static",h="javascript:;",i="",j={},k={},l={};l.setLocale=function(a){for(var b in m)if(b==a)return d=a,void 0;throw new Error("Invalid locale: "+a)},l.addLocale=function(a,b){"undefined"==typeof m[a]&&(m[a]={});for(var c in b)m[a][c]=b[c]},l.setIcons=function(a){k=a,("object"!=typeof k||null===k)&&(k={})},l.setBtnClasses=function(a){j=a,("object"!=typeof j||null===j)&&(j={})},l.alert=function(){var a="",b=c("OK"),d=null;switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"function"==typeof arguments[1]?d=arguments[1]:b=arguments[1];break;case 3:a=arguments[0],b=arguments[1],d=arguments[2];break;default:throw new Error("Incorrect number of arguments: expected 1-3")}return l.dialog(a,{label:b,icon:k.OK,"class":j.OK,callback:d},{onEscape:d||!0})},l.confirm=function(){var a="",b=c("CANCEL"),d=c("CONFIRM"),e=null;switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"function"==typeof arguments[1]?e=arguments[1]:b=arguments[1];break;case 3:a=arguments[0],b=arguments[1],"function"==typeof arguments[2]?e=arguments[2]:d=arguments[2];break;case 4:a=arguments[0],b=arguments[1],d=arguments[2],e=arguments[3];break;default:throw new Error("Incorrect number of arguments: expected 1-4")}var f=function(){return"function"==typeof e?e(!1):void 0},g=function(){return"function"==typeof e?e(!0):void 0};return l.dialog(a,[{label:b,icon:k.CANCEL,"class":j.CANCEL,callback:f},{label:d,icon:k.CONFIRM,"class":j.CONFIRM,callback:g}],{onEscape:f})},l.prompt=function(){var a="",d=c("CANCEL"),e=c("CONFIRM"),f=null,g="";switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"function"==typeof arguments[1]?f=arguments[1]:d=arguments[1];break;case 3:a=arguments[0],d=arguments[1],"function"==typeof arguments[2]?f=arguments[2]:e=arguments[2];break;case 4:a=arguments[0],d=arguments[1],e=arguments[2],f=arguments[3];break;case 5:a=arguments[0],d=arguments[1],e=arguments[2],f=arguments[3],g=arguments[4];break;default:throw new Error("Incorrect number of arguments: expected 1-5")}var h=a,i=b("");i.append("");var m=function(){return"function"==typeof f?f(null):void 0},n=function(){return"function"==typeof f?f(i.find("input[type=text]").val()):void 0},o=l.dialog(i,[{label:d,icon:k.CANCEL,"class":j.CANCEL,callback:m},{label:e,icon:k.CONFIRM,"class":j.CONFIRM,callback:n}],{header:h,show:!1,onEscape:m});return o.on("shown",function(){i.find("input[type=text]").focus(),i.on("submit",function(a){a.preventDefault(),o.find(".btn-primary").click()})}),o.modal("show"),o},l.dialog=function(c,d,e){function j(){var a=null;"function"==typeof e.onEscape&&(a=e.onEscape()),a!==!1&&x.modal("hide")}var k="",l=[];e||(e={}),"undefined"==typeof d?d=[]:"undefined"==typeof d.length&&(d=[d]);for(var m=d.length;m--;){var n=null,o=null,p=null,q="",r=null;if("undefined"==typeof d[m].label&&"undefined"==typeof d[m]["class"]&&"undefined"==typeof d[m].callback){var s=0,t=null;for(var u in d[m])if(t=u,++s>1)break;1==s&&"function"==typeof d[m][u]&&(d[m].label=t,d[m].callback=d[m][u])}"function"==typeof d[m].callback&&(r=d[m].callback),d[m]["class"]?p=d[m]["class"]:m==d.length-1&&d.length<=2&&(p="btn-primary"),d[m].link!==!0&&(p="btn "+p),n=d[m].label?d[m].label:"Option "+(m+1),d[m].icon&&(q=" "),o=d[m].href?d[m].href:h,k=""+q+n+""+k,l[m]=r}var v=["
");var x=b(v.join("\n")),y="undefined"==typeof e.animate?f:e.animate;y&&x.addClass("fade");var z="undefined"==typeof e.classes?i:e.classes;return z&&x.addClass(z),x.find(".modal-body").html(c),x.on("keyup.dismiss.modal",function(a){27===a.which&&e.onEscape&&j("escape")}),x.on("click","a.close",function(a){a.preventDefault(),j("close")}),x.on("shown",function(){x.find("a.btn-primary:first").focus()}),x.on("hidden",function(a){a.target===this&&x.remove()}),x.on("click",".modal-footer a",function(a){var c=b(this).data("handler"),e=l[c],f=null;("undefined"==typeof c||"undefined"==typeof d[c].href)&&(a.preventDefault(),"function"==typeof e&&(f=e(a)),f!==!1&&x.modal("hide"))}),b("body").append(x),x.modal({backdrop:"undefined"==typeof e.backdrop?g:e.backdrop,keyboard:!1,show:!1}),x.on("show",function(){b(a).off("focusin.modal")}),("undefined"==typeof e.show||e.show===!0)&&x.modal("show"),x},l.modal=function(){var a,c,d,e={onEscape:null,keyboard:!0,backdrop:g};switch(arguments.length){case 1:a=arguments[0];break;case 2:a=arguments[0],"object"==typeof arguments[1]?d=arguments[1]:c=arguments[1];break;case 3:a=arguments[0],c=arguments[1],d=arguments[2];break;default:throw new Error("Incorrect number of arguments: expected 1-3")}return e.header=c,d="object"==typeof d?b.extend(e,d):e,l.dialog(a,[],d)},l.hideAll=function(){b(".bootbox").modal("hide")},l.animate=function(a){f=a},l.backdrop=function(a){g=a},l.classes=function(a){i=a};var m={br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return l}(document,window.jQuery);window.bootbox=bootbox;
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/4.0.0/bootbox.js b/ajax/libs/bootbox.js/4.0.0/bootbox.js
new file mode 100644
index 000000000..6da84eb7a
--- /dev/null
+++ b/ajax/libs/bootbox.js/4.0.0/bootbox.js
@@ -0,0 +1,604 @@
+/**
+ * bootbox.js v4.0.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = window.bootbox || (function init($, undefined) {
+ "use strict";
+
+ // the base DOM structure needed to create a modal
+ var templates = {
+ dialog:
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
",
+ header:
+ "
" +
+ "" +
+ "
",
+ footer:
+ "",
+ closeButton:
+ "",
+ form:
+ "",
+ inputs: {
+ text:
+ ""
+ }
+ };
+
+ // cache a reference to the jQueryfied body element
+ var appendTo = $("body");
+
+ var defaults = {
+ // default language
+ locale: "en",
+ // show backdrop or not
+ backdrop: true,
+ // animate the modal in/out
+ animate: true,
+ // additional class string applied to the top level dialog
+ className: null,
+ // whether or not to include a close button
+ closeButton: true,
+ // show the dialog immediately by default
+ show: true
+ };
+
+ // our public object; augmented after our private API
+ var exports = {};
+
+ /**
+ * @private
+ */
+ function _t(key) {
+ var locale = locales[defaults.locale];
+ return locale ? locale[key] : locales.en[key];
+ }
+
+ function processCallback(e, dialog, callback) {
+ e.preventDefault();
+
+ // by default we assume a callback will get rid of the dialog,
+ // although it is given the opportunity to override this
+
+ // so, if the callback can be invoked and it *explicitly returns false*
+ // then we'll set a flag to keep the dialog active...
+ var preserveDialog = $.isFunction(callback) && callback(e) === false;
+
+ // ... otherwise we'll bin it
+ if (!preserveDialog) {
+ dialog.modal("hide");
+ }
+ }
+
+ function getKeyLength(obj) {
+ // @TODO defer to Object.keys(x).length if available?
+ var k, t = 0;
+ for (k in obj) {
+ t ++;
+ }
+ return t;
+ }
+
+ function each(collection, iterator) {
+ var index = 0;
+ $.each(collection, function(key, value) {
+ iterator(key, value, index++);
+ });
+ }
+
+ function sanitize(options) {
+ var buttons;
+ var total;
+
+
+ if (typeof options !== "object") {
+ throw new Error("Please supply an object of options");
+ }
+
+ if (!options.message) {
+ throw new Error("Please specify a message");
+ }
+
+ // make sure any supplied options take precedence over defaults
+ options = $.extend({}, defaults, options);
+
+ if (!options.buttons) {
+ options.buttons = {};
+ }
+
+ // we only support Bootstrap's "static" and false backdrop args
+ // supporting true would mean you could dismiss the dialog without
+ // explicitly interacting with it
+ options.backdrop = options.backdrop ? "static" : false;
+
+ buttons = options.buttons;
+
+ total = getKeyLength(buttons);
+
+ each(buttons, function(key, button, index) {
+
+ if ($.isFunction(button)) {
+ // short form, assume value is our callback. Since button
+ // isn't an object it isn't a reference either so re-assign it
+ button = buttons[key] = {
+ callback: button
+ };
+ }
+
+ // before any further checks make sure by now button is the correct type
+ if ($.type(button) !== "object") {
+ throw new Error("button with key " + key + " must be an object");
+ }
+
+ if (!button.label) {
+ // the lack of an explicit label means we'll assume the key is good enough
+ button.label = key;
+ }
+
+ if (!button.className) {
+ if (total <= 2 && index === total-1) {
+ // always add a primary to the main option in a two-button dialog
+ button.className = "btn-primary";
+ } else {
+ button.className = "btn-default";
+ }
+ }
+ });
+
+ return options;
+ }
+
+ function mapArguments(args, properties) {
+ var argn = args.length;
+ var options = {};
+
+ if (argn < 1 || argn > 2) {
+ throw new Error("Invalid argument length");
+ }
+
+ if (argn === 2 || typeof args[0] === "string") {
+ options[properties[0]] = args[0];
+ options[properties[1]] = args[1];
+ } else {
+ options = args[0];
+ }
+
+ return options;
+ }
+
+ function mergeArguments(defaults, args, properties) {
+ return $.extend(true, {}, defaults, mapArguments(args, properties));
+ }
+
+ function mergeButtons(labels, args, properties) {
+ return validateButtons(
+ mergeArguments(createButtons.apply(null, labels), args, properties),
+ labels
+ );
+ }
+
+ function createLabels() {
+ var buttons = {};
+
+ for (var i = 0, j = arguments.length; i < j; i++) {
+ var argument = arguments[i];
+ var key = argument.toLowerCase();
+ var value = argument.toUpperCase();
+
+ buttons[key] = {
+ label: _t(value)
+ };
+ }
+
+ return buttons;
+ }
+
+ function createButtons() {
+ return {
+ buttons: createLabels.apply(null, arguments)
+ };
+ }
+
+ function validateButtons(options, buttons) {
+ var allowedButtons = {};
+ each(buttons, function(key, value) {
+ allowedButtons[value] = true;
+ });
+
+ each(options.buttons, function(key) {
+ if (allowedButtons[key] === undefined) {
+ throw new Error("button key " + key + " is not allowed (options are " + buttons.join("\n") + ")");
+ }
+ });
+
+ return options;
+ }
+
+ exports.alert = function() {
+ var options;
+
+ options = mergeButtons(["ok"], arguments, ["message", "callback"]);
+
+ if (options.callback && !$.isFunction(options.callback)) {
+ throw new Error("alert requires callback property to be a function when provided");
+ }
+
+ /**
+ * overrides
+ */
+ options.buttons.ok.callback = options.onEscape = function() {
+ if ($.isFunction(options.callback)) {
+ return options.callback();
+ }
+ return true;
+ };
+
+ return exports.dialog(options);
+ };
+
+ exports.confirm = function() {
+ var options;
+
+ options = mergeButtons(["cancel", "confirm"], arguments, ["message", "callback"]);
+
+ /**
+ * overrides; undo anything the user tried to set they shouldn't have
+ */
+ options.buttons.cancel.callback = options.onEscape = function() {
+ return options.callback(false);
+ };
+
+ options.buttons.confirm.callback = function() {
+ return options.callback(true);
+ };
+
+ // confirm specific validation
+ if (!$.isFunction(options.callback)) {
+ throw new Error("confirm requires a callback");
+ }
+
+ return exports.dialog(options);
+ };
+
+ exports.prompt = function() {
+ var options;
+ var defaults;
+ var dialog;
+ var form;
+ var input;
+ var shouldShow;
+
+ // we have to create our form first otherwise
+ // its value is undefined when gearing up our options
+ // @TODO this could be solved by allowing message to
+ // be a function instead...
+ form = $(templates.form);
+
+ defaults = {
+ buttons: createLabels("cancel", "confirm"),
+ value: ""
+ };
+
+ options = validateButtons(
+ mergeArguments(defaults, arguments, ["title", "callback"]),
+ ["cancel", "confirm"]
+ );
+
+ // capture the user's show value; we always set this to false before
+ // spawning the dialog to give us a chance to attach some handlers to
+ // it, but we need to make sure we respect a preference not to show it
+ shouldShow = (options.show === undefined) ? true : options.show;
+
+ /**
+ * overrides; undo anything the user tried to set they shouldn't have
+ */
+ options.message = form;
+
+ options.buttons.cancel.callback = options.onEscape = function() {
+ return options.callback(null);
+ };
+
+ options.buttons.confirm.callback = function() {
+ return options.callback(input.val());
+ };
+
+ options.show = false;
+
+ // prompt specific validation
+ if (!options.title) {
+ throw new Error("prompt requires a title");
+ }
+
+ if (!$.isFunction(options.callback)) {
+ throw new Error("prompt requires a callback");
+ }
+
+ // create the input
+ input = $(templates.inputs.text);
+ input.val(options.value);
+
+ // now place it in our form
+ form.append(input);
+
+ form.on("submit", function(e) {
+ e.preventDefault();
+ // @TODO can we actually click *the* button object instead?
+ // e.g. buttons.confirm.click() or similar
+ dialog.find(".btn-primary").click();
+ });
+
+ dialog = exports.dialog(options);
+
+ // clear the existing handler focusing the submit button...
+ dialog.off("shown.bs.modal");
+
+ // ...and replace it with one focusing our input, if possible
+ dialog.on("shown.bs.modal", function() {
+ input.focus();
+ });
+
+ if (shouldShow === true) {
+ dialog.modal("show");
+ }
+
+ return dialog;
+ };
+
+ exports.dialog = function(options) {
+ options = sanitize(options);
+
+ var dialog = $(templates.dialog);
+ var body = dialog.find(".modal-body");
+ var buttons = options.buttons;
+ var buttonStr = "";
+ var callbacks = {
+ onEscape: options.onEscape
+ };
+
+ each(buttons, function(key, button) {
+
+ // @TODO I don't like this string appending to itself; bit dirty. Needs reworking
+ // can we just build up button elements instead? slower but neater. Then button
+ // can just become a template too
+ buttonStr += "";
+ callbacks[key] = button.callback;
+ });
+
+ body.find(".bootbox-body").html(options.message);
+
+ if (options.animate === true) {
+ dialog.addClass("fade");
+ }
+
+ if (options.className) {
+ dialog.addClass(options.className);
+ }
+
+ if (options.title) {
+ body.before(templates.header);
+ }
+
+ if (options.closeButton) {
+ var closeButton = $(templates.closeButton);
+
+ if (options.title) {
+ dialog.find(".modal-header").prepend(closeButton);
+ } else {
+ closeButton.css("margin-top", "-10px").prependTo(body);
+ }
+ }
+
+ if (options.title) {
+ dialog.find(".modal-title").html(options.title);
+ }
+
+ if (buttonStr.length) {
+ body.after(templates.footer);
+ dialog.find(".modal-footer").html(buttonStr);
+ }
+
+
+ /**
+ * Bootstrap event listeners; used handle extra
+ * setup & teardown required after the underlying
+ * modal has performed certain actions
+ */
+
+ dialog.on("hidden.bs.modal", function(e) {
+ // ensure we don't accidentally intercept hidden events triggered
+ // by children of the current dialog. We shouldn't anymore now BS
+ // namespaces its events; but still worth doing
+ if (e.target === this) {
+ dialog.remove();
+ }
+ });
+
+ /*
+ dialog.on("show.bs.modal", function() {
+ // sadly this doesn't work; show is called *just* before
+ // the backdrop is added so we'd need a setTimeout hack or
+ // otherwise... leaving in as would be nice
+ if (options.backdrop) {
+ dialog.next(".modal-backdrop").addClass("bootbox-backdrop");
+ }
+ });
+ */
+
+ dialog.on("shown.bs.modal", function() {
+ dialog.find(".btn-primary:first").focus();
+ });
+
+ /**
+ * Bootbox event listeners; experimental and may not last
+ * just an attempt to decouple some behaviours from their
+ * respective triggers
+ */
+
+ dialog.on("escape.close.bb", function(e) {
+ if (callbacks.onEscape) {
+ processCallback(e, dialog, callbacks.onEscape);
+ }
+ });
+
+ /**
+ * Standard jQuery event listeners; used to handle user
+ * interaction with our dialog
+ */
+
+ dialog.on("click", ".modal-footer button", function(e) {
+ var callbackKey = $(this).data("bb-handler");
+
+ processCallback(e, dialog, callbacks[callbackKey]);
+
+ });
+
+ dialog.on("click", ".bootbox-close-button", function(e) {
+ // onEscape might be falsy but that's fine; the fact is
+ // if the user has managed to click the close button we
+ // have to close the dialog, callback or not
+ processCallback(e, dialog, callbacks.onEscape);
+ });
+
+ dialog.on("keyup", function(e) {
+ if (e.which === 27) {
+ dialog.trigger("escape.close.bb");
+ }
+ });
+
+ // the remainder of this method simply deals with adding our
+ // dialogent to the DOM, augmenting it with Bootstrap's modal
+ // functionality and then giving the resulting object back
+ // to our caller
+
+ appendTo.append(dialog);
+
+ dialog.modal({
+ backdrop: options.backdrop,
+ keyboard: false,
+ show: false
+ });
+
+ if (options.show) {
+ dialog.modal("show");
+ }
+
+ // @TODO should we return the raw element here or should
+ // we wrap it in an object on which we can expose some neater
+ // methods, e.g. var d = bootbox.alert(); d.hide(); instead
+ // of d.modal("hide");
+
+ /*
+ function BBDialog(elem) {
+ this.elem = elem;
+ }
+
+ BBDialog.prototype = {
+ hide: function() {
+ return this.elem.modal("hide");
+ },
+ show: function() {
+ return this.elem.modal("show");
+ }
+ };
+ */
+
+ return dialog;
+
+ };
+
+ exports.setDefaults = function(values) {
+ $.extend(defaults, values);
+ };
+
+ exports.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var locales = {
+ br : {
+ OK : "OK",
+ CANCEL : "Cancelar",
+ CONFIRM : "Sim"
+ },
+ da : {
+ OK : "OK",
+ CANCEL : "Annuller",
+ CONFIRM : "Accepter"
+ },
+ de : {
+ OK : "OK",
+ CANCEL : "Abbrechen",
+ CONFIRM : "Akzeptieren"
+ },
+ en : {
+ OK : "OK",
+ CANCEL : "Cancel",
+ CONFIRM : "OK"
+ },
+ es : {
+ OK : "OK",
+ CANCEL : "Cancelar",
+ CONFIRM : "Aceptar"
+ },
+ fi : {
+ OK : "OK",
+ CANCEL : "Peruuta",
+ CONFIRM : "OK"
+ },
+ fr : {
+ OK : "OK",
+ CANCEL : "Annuler",
+ CONFIRM : "D'accord"
+ },
+ it : {
+ OK : "OK",
+ CANCEL : "Annulla",
+ CONFIRM : "Conferma"
+ },
+ nl : {
+ OK : "OK",
+ CANCEL : "Annuleren",
+ CONFIRM : "Accepteren"
+ },
+ pl : {
+ OK : "OK",
+ CANCEL : "Anuluj",
+ CONFIRM : "Potwierdź"
+ },
+ ru : {
+ OK : "OK",
+ CANCEL : "Отмена",
+ CONFIRM : "Применить"
+ },
+ zh_CN : {
+ OK : "OK",
+ CANCEL : "取消",
+ CONFIRM : "确认"
+ },
+ zh_TW : {
+ OK : "OK",
+ CANCEL : "取消",
+ CONFIRM : "確認"
+ }
+ };
+
+ exports.init = function(_$) {
+ window.bootbox = init(_$ || $);
+ };
+
+ return exports;
+
+}(window.jQuery));
diff --git a/ajax/libs/bootbox.js/4.1.0/bootbox.js b/ajax/libs/bootbox.js/4.1.0/bootbox.js
new file mode 100644
index 000000000..5df309b5c
--- /dev/null
+++ b/ajax/libs/bootbox.js/4.1.0/bootbox.js
@@ -0,0 +1,784 @@
+/**
+ * bootbox.js [v4.1.0]
+ *
+ * http://bootboxjs.com/license.txt
+ */
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = window.bootbox || (function init($, undefined) {
+ "use strict";
+
+ // the base DOM structure needed to create a modal
+ var templates = {
+ dialog:
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
",
+ header:
+ "
" +
+ "" +
+ "
",
+ footer:
+ "",
+ closeButton:
+ "",
+ form:
+ "",
+ inputs: {
+ text:
+ "",
+ email:
+ "",
+ select:
+ "",
+ checkbox:
+ ""
+ }
+ };
+
+ // cache a reference to the jQueryfied body element
+ var appendTo = $("body");
+
+ var defaults = {
+ // default language
+ locale: "en",
+ // show backdrop or not
+ backdrop: true,
+ // animate the modal in/out
+ animate: true,
+ // additional class string applied to the top level dialog
+ className: null,
+ // whether or not to include a close button
+ closeButton: true,
+ // show the dialog immediately by default
+ show: true
+ };
+
+ // our public object; augmented after our private API
+ var exports = {};
+
+ /**
+ * @private
+ */
+ function _t(key) {
+ var locale = locales[defaults.locale];
+ return locale ? locale[key] : locales.en[key];
+ }
+
+ function processCallback(e, dialog, callback) {
+ e.preventDefault();
+
+ // by default we assume a callback will get rid of the dialog,
+ // although it is given the opportunity to override this
+
+ // so, if the callback can be invoked and it *explicitly returns false*
+ // then we'll set a flag to keep the dialog active...
+ var preserveDialog = $.isFunction(callback) && callback(e) === false;
+
+ // ... otherwise we'll bin it
+ if (!preserveDialog) {
+ dialog.modal("hide");
+ }
+ }
+
+ function getKeyLength(obj) {
+ // @TODO defer to Object.keys(x).length if available?
+ var k, t = 0;
+ for (k in obj) {
+ t ++;
+ }
+ return t;
+ }
+
+ function each(collection, iterator) {
+ var index = 0;
+ $.each(collection, function(key, value) {
+ iterator(key, value, index++);
+ });
+ }
+
+ function sanitize(options) {
+ var buttons;
+ var total;
+
+ if (typeof options !== "object") {
+ throw new Error("Please supply an object of options");
+ }
+
+ if (!options.message) {
+ throw new Error("Please specify a message");
+ }
+
+ // make sure any supplied options take precedence over defaults
+ options = $.extend({}, defaults, options);
+
+ if (!options.buttons) {
+ options.buttons = {};
+ }
+
+ // we only support Bootstrap's "static" and false backdrop args
+ // supporting true would mean you could dismiss the dialog without
+ // explicitly interacting with it
+ options.backdrop = options.backdrop ? "static" : false;
+
+ buttons = options.buttons;
+
+ total = getKeyLength(buttons);
+
+ each(buttons, function(key, button, index) {
+
+ if ($.isFunction(button)) {
+ // short form, assume value is our callback. Since button
+ // isn't an object it isn't a reference either so re-assign it
+ button = buttons[key] = {
+ callback: button
+ };
+ }
+
+ // before any further checks make sure by now button is the correct type
+ if ($.type(button) !== "object") {
+ throw new Error("button with key " + key + " must be an object");
+ }
+
+ if (!button.label) {
+ // the lack of an explicit label means we'll assume the key is good enough
+ button.label = key;
+ }
+
+ if (!button.className) {
+ if (total <= 2 && index === total-1) {
+ // always add a primary to the main option in a two-button dialog
+ button.className = "btn-primary";
+ } else {
+ button.className = "btn-default";
+ }
+ }
+ });
+
+ return options;
+ }
+
+ /**
+ * map a flexible set of arguments into a single returned object
+ * if args.length is already one just return it, otherwise
+ * use the properties argument to map the unnamed args to
+ * object properties
+ * so in the latter case:
+ * mapArguments(["foo", $.noop], ["message", "callback"])
+ * -> { message: "foo", callback: $.noop }
+ */
+ function mapArguments(args, properties) {
+ var argn = args.length;
+ var options = {};
+
+ if (argn < 1 || argn > 2) {
+ throw new Error("Invalid argument length");
+ }
+
+ if (argn === 2 || typeof args[0] === "string") {
+ options[properties[0]] = args[0];
+ options[properties[1]] = args[1];
+ } else {
+ options = args[0];
+ }
+
+ return options;
+ }
+
+ /**
+ * merge a set of default dialog options with user supplied arguments
+ */
+ function mergeArguments(defaults, args, properties) {
+ return $.extend(
+ // deep merge
+ true,
+ // ensure the target is an empty, unreferenced object
+ {},
+ // the base options object for this type of dialog (often just buttons)
+ defaults,
+ // args could be an object or array; if it's an array properties will
+ // map it to a proper options object
+ mapArguments(
+ args,
+ properties
+ )
+ );
+ }
+
+ /**
+ * this entry-level method makes heavy use of composition to take a simple
+ * range of inputs and return valid options suitable for passing to bootbox.dialog
+ */
+ function mergeDialogOptions(className, labels, properties, args) {
+ // build up a base set of dialog properties
+ var baseOptions = {
+ className: "bootbox-" + className,
+ buttons: createLabels.apply(null, labels)
+ };
+
+ // ensure the buttons properties generated, *after* merging
+ // with user args are still valid against the supplied labels
+ return validateButtons(
+ // merge the generated base properties with user supplied arguments
+ mergeArguments(
+ baseOptions,
+ args,
+ // if args.length > 1, properties specify how each arg maps to an object key
+ properties
+ ),
+ labels
+ );
+ }
+
+ /**
+ * from a given list of arguments return a suitable object of button labels
+ * all this does is normalise the given labels and translate them where possible
+ * e.g. "ok", "confirm" -> { ok: "OK, cancel: "Annuleren" }
+ */
+ function createLabels() {
+ var buttons = {};
+
+ for (var i = 0, j = arguments.length; i < j; i++) {
+ var argument = arguments[i];
+ var key = argument.toLowerCase();
+ var value = argument.toUpperCase();
+
+ buttons[key] = {
+ label: _t(value)
+ };
+ }
+
+ return buttons;
+ }
+
+ function validateButtons(options, buttons) {
+ var allowedButtons = {};
+ each(buttons, function(key, value) {
+ allowedButtons[value] = true;
+ });
+
+ each(options.buttons, function(key) {
+ if (allowedButtons[key] === undefined) {
+ throw new Error("button key " + key + " is not allowed (options are " + buttons.join("\n") + ")");
+ }
+ });
+
+ return options;
+ }
+
+ exports.alert = function() {
+ var options;
+
+ options = mergeDialogOptions("alert", ["ok"], ["message", "callback"], arguments);
+
+ if (options.callback && !$.isFunction(options.callback)) {
+ throw new Error("alert requires callback property to be a function when provided");
+ }
+
+ /**
+ * overrides
+ */
+ options.buttons.ok.callback = options.onEscape = function() {
+ if ($.isFunction(options.callback)) {
+ return options.callback();
+ }
+ return true;
+ };
+
+ return exports.dialog(options);
+ };
+
+ exports.confirm = function() {
+ var options;
+
+ options = mergeDialogOptions("confirm", ["cancel", "confirm"], ["message", "callback"], arguments);
+
+ /**
+ * overrides; undo anything the user tried to set they shouldn't have
+ */
+ options.buttons.cancel.callback = options.onEscape = function() {
+ return options.callback(false);
+ };
+
+ options.buttons.confirm.callback = function() {
+ return options.callback(true);
+ };
+
+ // confirm specific validation
+ if (!$.isFunction(options.callback)) {
+ throw new Error("confirm requires a callback");
+ }
+
+ return exports.dialog(options);
+ };
+
+ exports.prompt = function() {
+ var options;
+ var defaults;
+ var dialog;
+ var form;
+ var input;
+ var shouldShow;
+ var inputOptions;
+
+ // we have to create our form first otherwise
+ // its value is undefined when gearing up our options
+ // @TODO this could be solved by allowing message to
+ // be a function instead...
+ form = $(templates.form);
+
+ // prompt defaults are more complex than others in that
+ // users can override more defaults
+ // @TODO I don't like that prompt has to do a lot of heavy
+ // lifting which mergeDialogOptions can *almost* support already
+ // just because of 'value' and 'inputType' - can we refactor?
+ defaults = {
+ className: "bootbox-prompt",
+ buttons: createLabels("cancel", "confirm"),
+ value: "",
+ inputType: "text"
+ };
+
+ options = validateButtons(
+ mergeArguments(defaults, arguments, ["title", "callback"]),
+ ["cancel", "confirm"]
+ );
+
+ // capture the user's show value; we always set this to false before
+ // spawning the dialog to give us a chance to attach some handlers to
+ // it, but we need to make sure we respect a preference not to show it
+ shouldShow = (options.show === undefined) ? true : options.show;
+
+ /**
+ * overrides; undo anything the user tried to set they shouldn't have
+ */
+ options.message = form;
+
+ options.buttons.cancel.callback = options.onEscape = function() {
+ return options.callback(null);
+ };
+
+ options.buttons.confirm.callback = function() {
+ var value;
+
+ switch (options.inputType) {
+ case "text":
+ case "email":
+ case "select":
+ value = input.val();
+ break;
+
+ case "checkbox":
+ var checkedItems = input.find("input:checked");
+
+ // we assume that checkboxes are always multiple,
+ // hence we default to an empty array
+ value = [];
+
+ each(checkedItems, function(_, item) {
+ value.push($(item).val());
+ });
+ break;
+ }
+
+ return options.callback(value);
+ };
+
+ options.show = false;
+
+ // prompt specific validation
+ if (!options.title) {
+ throw new Error("prompt requires a title");
+ }
+
+ if (!$.isFunction(options.callback)) {
+ throw new Error("prompt requires a callback");
+ }
+
+ if (!templates.inputs[options.inputType]) {
+ throw new Error("invalid prompt type");
+ }
+
+ // create the input based on the supplied type
+ input = $(templates.inputs[options.inputType]);
+
+ switch (options.inputType) {
+ case "text":
+ case "email":
+ input.val(options.value);
+ break;
+
+ case "select":
+ var groups = {};
+ inputOptions = options.inputOptions || [];
+
+ if (!inputOptions.length) {
+ throw new Error("prompt with select requires options");
+ }
+
+ each(inputOptions, function(_, option) {
+
+ // assume the element to attach to is the input...
+ var elem = input;
+
+ if (option.value === undefined || option.text === undefined) {
+ throw new Error("given options in wrong format");
+ }
+
+
+ // ... but override that element if this option sits in a group
+
+ if (option.group) {
+ // initialise group if necessary
+ if (!groups[option.group]) {
+ groups[option.group] = $("").attr("label", option.group);
+ }
+
+ elem = groups[option.group];
+ }
+
+ elem.append("");
+ });
+
+ each(groups, function(_, group) {
+ input.append(group);
+ });
+
+ // safe to set a select's value as per a normal input
+ input.val(options.value);
+ break;
+
+ case "checkbox":
+ var values = $.isArray(options.value) ? options.value : [options.value];
+ inputOptions = options.inputOptions || [];
+
+ if (!inputOptions.length) {
+ throw new Error("prompt with checkbox requires options");
+ }
+
+ if (!inputOptions[0].value || !inputOptions[0].text) {
+ throw new Error("given options in wrong format");
+ }
+
+ // checkboxes have to nest within a containing element, so
+ // they break the rules a bit and we end up re-assigning
+ // our 'input' element to this container instead
+ input = $("");
+
+ each(inputOptions, function(_, option) {
+ var checkbox = $(templates.inputs[options.inputType]);
+
+ checkbox.find("input").attr("value", option.value);
+ checkbox.find("label").append(option.text);
+
+ // we've ensured values is an array so we can always iterate over it
+ each(values, function(_, value) {
+ if (value === option.value) {
+ checkbox.find("input").prop("checked", true);
+ }
+ });
+
+ input.append(checkbox);
+ });
+ break;
+ }
+
+ if (options.placeholder) {
+ input.attr("placeholder", options.placeholder);
+ }
+
+ // now place it in our form
+ form.append(input);
+
+ form.on("submit", function(e) {
+ e.preventDefault();
+ // @TODO can we actually click *the* button object instead?
+ // e.g. buttons.confirm.click() or similar
+ dialog.find(".btn-primary").click();
+ });
+
+ dialog = exports.dialog(options);
+
+ // clear the existing handler focusing the submit button...
+ dialog.off("shown.bs.modal");
+
+ // ...and replace it with one focusing our input, if possible
+ dialog.on("shown.bs.modal", function() {
+ input.focus();
+ });
+
+ if (shouldShow === true) {
+ dialog.modal("show");
+ }
+
+ return dialog;
+ };
+
+ exports.dialog = function(options) {
+ options = sanitize(options);
+
+ var dialog = $(templates.dialog);
+ var body = dialog.find(".modal-body");
+ var buttons = options.buttons;
+ var buttonStr = "";
+ var callbacks = {
+ onEscape: options.onEscape
+ };
+
+ each(buttons, function(key, button) {
+
+ // @TODO I don't like this string appending to itself; bit dirty. Needs reworking
+ // can we just build up button elements instead? slower but neater. Then button
+ // can just become a template too
+ buttonStr += "";
+ callbacks[key] = button.callback;
+ });
+
+ body.find(".bootbox-body").html(options.message);
+
+ if (options.animate === true) {
+ dialog.addClass("fade");
+ }
+
+ if (options.className) {
+ dialog.addClass(options.className);
+ }
+
+ if (options.title) {
+ body.before(templates.header);
+ }
+
+ if (options.closeButton) {
+ var closeButton = $(templates.closeButton);
+
+ if (options.title) {
+ dialog.find(".modal-header").prepend(closeButton);
+ } else {
+ closeButton.css("margin-top", "-10px").prependTo(body);
+ }
+ }
+
+ if (options.title) {
+ dialog.find(".modal-title").html(options.title);
+ }
+
+ if (buttonStr.length) {
+ body.after(templates.footer);
+ dialog.find(".modal-footer").html(buttonStr);
+ }
+
+
+ /**
+ * Bootstrap event listeners; used handle extra
+ * setup & teardown required after the underlying
+ * modal has performed certain actions
+ */
+
+ dialog.on("hidden.bs.modal", function(e) {
+ // ensure we don't accidentally intercept hidden events triggered
+ // by children of the current dialog. We shouldn't anymore now BS
+ // namespaces its events; but still worth doing
+ if (e.target === this) {
+ dialog.remove();
+ }
+ });
+
+ /*
+ dialog.on("show.bs.modal", function() {
+ // sadly this doesn't work; show is called *just* before
+ // the backdrop is added so we'd need a setTimeout hack or
+ // otherwise... leaving in as would be nice
+ if (options.backdrop) {
+ dialog.next(".modal-backdrop").addClass("bootbox-backdrop");
+ }
+ });
+ */
+
+ dialog.on("shown.bs.modal", function() {
+ dialog.find(".btn-primary:first").focus();
+ });
+
+ /**
+ * Bootbox event listeners; experimental and may not last
+ * just an attempt to decouple some behaviours from their
+ * respective triggers
+ */
+
+ dialog.on("escape.close.bb", function(e) {
+ if (callbacks.onEscape) {
+ processCallback(e, dialog, callbacks.onEscape);
+ }
+ });
+
+ /**
+ * Standard jQuery event listeners; used to handle user
+ * interaction with our dialog
+ */
+
+ dialog.on("click", ".modal-footer button", function(e) {
+ var callbackKey = $(this).data("bb-handler");
+
+ processCallback(e, dialog, callbacks[callbackKey]);
+
+ });
+
+ dialog.on("click", ".bootbox-close-button", function(e) {
+ // onEscape might be falsy but that's fine; the fact is
+ // if the user has managed to click the close button we
+ // have to close the dialog, callback or not
+ processCallback(e, dialog, callbacks.onEscape);
+ });
+
+ dialog.on("keyup", function(e) {
+ if (e.which === 27) {
+ dialog.trigger("escape.close.bb");
+ }
+ });
+
+ // the remainder of this method simply deals with adding our
+ // dialogent to the DOM, augmenting it with Bootstrap's modal
+ // functionality and then giving the resulting object back
+ // to our caller
+
+ appendTo.append(dialog);
+
+ dialog.modal({
+ backdrop: options.backdrop,
+ keyboard: false,
+ show: false
+ });
+
+ if (options.show) {
+ dialog.modal("show");
+ }
+
+ // @TODO should we return the raw element here or should
+ // we wrap it in an object on which we can expose some neater
+ // methods, e.g. var d = bootbox.alert(); d.hide(); instead
+ // of d.modal("hide");
+
+ /*
+ function BBDialog(elem) {
+ this.elem = elem;
+ }
+
+ BBDialog.prototype = {
+ hide: function() {
+ return this.elem.modal("hide");
+ },
+ show: function() {
+ return this.elem.modal("show");
+ }
+ };
+ */
+
+ return dialog;
+
+ };
+
+ exports.setDefaults = function() {
+ var values = {};
+
+ if (arguments.length === 2) {
+ // allow passing of single key/value...
+ values[arguments[0]] = arguments[1];
+ } else {
+ // ... and as an object too
+ values = arguments[0];
+ }
+
+ $.extend(defaults, values);
+ };
+
+ exports.hideAll = function() {
+ $(".bootbox").modal("hide");
+ };
+
+
+ /**
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
+ */
+ var locales = {
+ br : {
+ OK : "OK",
+ CANCEL : "Cancelar",
+ CONFIRM : "Sim"
+ },
+ da : {
+ OK : "OK",
+ CANCEL : "Annuller",
+ CONFIRM : "Accepter"
+ },
+ de : {
+ OK : "OK",
+ CANCEL : "Abbrechen",
+ CONFIRM : "Akzeptieren"
+ },
+ en : {
+ OK : "OK",
+ CANCEL : "Cancel",
+ CONFIRM : "OK"
+ },
+ es : {
+ OK : "OK",
+ CANCEL : "Cancelar",
+ CONFIRM : "Aceptar"
+ },
+ fi : {
+ OK : "OK",
+ CANCEL : "Peruuta",
+ CONFIRM : "OK"
+ },
+ fr : {
+ OK : "OK",
+ CANCEL : "Annuler",
+ CONFIRM : "D'accord"
+ },
+ it : {
+ OK : "OK",
+ CANCEL : "Annulla",
+ CONFIRM : "Conferma"
+ },
+ nl : {
+ OK : "OK",
+ CANCEL : "Annuleren",
+ CONFIRM : "Accepteren"
+ },
+ no : {
+ OK : "OK",
+ CANCEL : "Avbryt",
+ CONFIRM : "OK"
+ },
+ pl : {
+ OK : "OK",
+ CANCEL : "Anuluj",
+ CONFIRM : "Potwierdź"
+ },
+ ru : {
+ OK : "OK",
+ CANCEL : "Отмена",
+ CONFIRM : "Применить"
+ },
+ zh_CN : {
+ OK : "OK",
+ CANCEL : "取消",
+ CONFIRM : "确认"
+ },
+ zh_TW : {
+ OK : "OK",
+ CANCEL : "取消",
+ CONFIRM : "確認"
+ }
+ };
+
+ exports.init = function(_$) {
+ window.bootbox = init(_$ || $);
+ };
+
+ return exports;
+
+}(window.jQuery));
diff --git a/ajax/libs/bootbox.js/4.1.0/bootbox.min.js b/ajax/libs/bootbox.js/4.1.0/bootbox.min.js
new file mode 100644
index 000000000..4ea792f3a
--- /dev/null
+++ b/ajax/libs/bootbox.js/4.1.0/bootbox.min.js
@@ -0,0 +1,6 @@
+/**
+ * bootbox.js v4.1.0
+ *
+ * http://bootboxjs.com/license.txt
+ */
+window.bootbox=window.bootbox||function a(b,c){"use strict";function d(a){var b=r[p.locale];return b?b[a]:r.en[a]}function e(a,c,d){a.preventDefault();var e=b.isFunction(d)&&d(a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},p,a),a.buttons||(a.buttons={}),a.backdrop=a.backdrop?"static":!1,c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(e.className=2>=d&&f===d-1?"btn-primary":"btn-default")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"
",header:"
",footer:"",closeButton:"",form:"",inputs:{text:"",email:"",select:"",checkbox:""}},o=b("body"),p={locale:"en",backdrop:!0,animate:!0,className:null,closeButton:!0,show:!0},q={};q.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback():!0},q.dialog(a)},q.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback(!1)},a.buttons.confirm.callback=function(){return a.callback(!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return q.dialog(a)},q.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback(null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"email":case"select":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback(c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"email":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("").attr("label",d.group)),e=o[d.group]),e.append("")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var p=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b(""),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(p,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),f.append(h),f.on("submit",function(a){a.preventDefault(),e.find(".btn-primary").click()}),e=q.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},q.dialog=function(a){a=h(a);var c=b(n.dialog),d=c.find(".modal-body"),f=a.buttons,i="",j={onEscape:a.onEscape};if(g(f,function(a,b){i+="",j[a]=b.callback}),d.find(".bootbox-body").html(a.message),a.animate===!0&&c.addClass("fade"),a.className&&c.addClass(a.className),a.title&&d.before(n.header),a.closeButton){var k=b(n.closeButton);a.title?c.find(".modal-header").prepend(k):k.css("margin-top","-10px").prependTo(d)}return a.title&&c.find(".modal-title").html(a.title),i.length&&(d.after(n.footer),c.find(".modal-footer").html(i)),c.on("hidden.bs.modal",function(a){a.target===this&&c.remove()}),c.on("shown.bs.modal",function(){c.find(".btn-primary:first").focus()}),c.on("escape.close.bb",function(a){j.onEscape&&e(a,c,j.onEscape)}),c.on("click",".modal-footer button",function(a){var d=b(this).data("bb-handler");e(a,c,j[d])}),c.on("click",".bootbox-close-button",function(a){e(a,c,j.onEscape)}),c.on("keyup",function(a){27===a.which&&c.trigger("escape.close.bb")}),o.append(c),c.modal({backdrop:a.backdrop,keyboard:!1,show:!1}),a.show&&c.modal("show"),c},q.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(p,a)},q.hideAll=function(){b(".bootbox").modal("hide")};var r={br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return q.init=function(c){window.bootbox=a(c||b)},q}(window.jQuery);
\ No newline at end of file
diff --git a/ajax/libs/bootbox.js/package.json b/ajax/libs/bootbox.js/package.json
index 6fff32560..973aad885 100644
--- a/ajax/libs/bootbox.js/package.json
+++ b/ajax/libs/bootbox.js/package.json
@@ -1,8 +1,8 @@
{
"name": "bootbox.js",
"filename": "bootbox.min.js",
- "version": "4.0.0",
- "description": "Wrappers for JavaScript alert(), confirm() and other flexible dialogs using Twitter's bootstrap framework",
+ "version": "4.1.0",
+ "description": "Wrappers for JavaScript alert(), confirm() and other flexible dialogs using Twitter's Bootstrap framework",
"repository": {
"type": "git",
"url": "git://github.com/makeusabrew/bootbox.git"