Commit 0e6d6eca authored by Jérome Perrin's avatar Jérome Perrin

update static version

parent a0b568dd
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
gadget_klass.declareAcquiredMethod("aq_allDocs", "jio_allDocs").declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash").declareAcquiredMethod("whoWantsToDisplayThisDocument", "whoWantsToDisplayThisDocument").declareMethod("render", function() { gadget_klass.declareAcquiredMethod("aq_allDocs", "jio_allDocs").declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash").declareAcquiredMethod("whoWantsToDisplayThisDocument", "whoWantsToDisplayThisDocument").declareMethod("render", function() {
var gadget = this; var gadget = this;
return gadget.aq_allDocs({ return gadget.aq_allDocs({
include_docs: true,
query: 'type:= "Dream"',
select_list: [ "title", "modified" ] select_list: [ "title", "modified" ]
}).push(function(document_list) { }).push(function(document_list) {
var result_list = [], doc, i; var result_list = [], doc, i;
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
} }
throw error; throw error;
}).push(function(sim_json) { }).push(function(sim_json) {
var document = JSON.parse(sim_json), document_list = [], result_list = [], i; var document_list = JSON.parse(sim_json), result_list = [], i;
if (document.result) { if (document.result) {
if (document.result.result_list) { if (document.result.result_list) {
document_list = document.result.result_list; document_list = document.result.result_list;
......
...@@ -18,9 +18,8 @@ ...@@ -18,9 +18,8 @@
<script id="panel-template" type="text/x-handlebars-template"> <script id="panel-template" type="text/x-handlebars-template">
<ul data-role="listview"> <ul data-role="listview">
<li><a class="pre_input_link ui-btn ui-icon-grid ui-btn-icon-left" data-icon="grid">Documents</a></li> <li><a class="home_link ui-btn ui-icon-home ui-btn-icon-left" data-icon="home">Documents</a></li>
<!--li><a class="home_link ui-btn ui-icon-home ui-btn-icon-left" data-icon="home">Documents</a></li--> <li><a class="fast_input_link ui-btn ui-icon-plus ui-btn-icon-left" data-icon="plus">New Document</a></li>
<!--li><a class="fast_input_link ui-btn ui-icon-plus ui-btn-icon-left" data-icon="plus">New Document</a></li-->
{{#navigationlist}} {{#navigationlist}}
<li><a href="{{link}}">{{title}}</a></li> <li><a href="{{link}}">{{title}}</a></li>
{{/navigationlist}} {{/navigationlist}}
......
...@@ -14,22 +14,115 @@ ...@@ -14,22 +14,115 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// XXX we should use lists instead to keep ordering // XXX we should use lists instead to keep ordering
var portal_types = { var portal_types = {
"Pre Input Module": { "Input Module": {
view: { view: {
gadget: "InputModule_viewAddInstanceDefinitionDialog", gadget: "InputModule_viewInputList",
type: "object_list",
title: "Document List"
},
view_fast_input: {
gadget: "InputModule_viewAddDocumentDialog",
type: "object_fast_input", type: "object_fast_input",
title: "Choose Instance Definition" title: "Create Document"
}
},
// TODO: remove this once everything is merged.
Input: {
view: {
gadget: "Input_viewProductionLine",
type: "object_view",
title: "Production Line"
},
view_wip_part_spreadsheet: {
gadget: "Input_viewWipPartSpreadsheet",
type: "object_view",
title: "WIP Part Spreadsheet"
},
view_shift_spreadsheet: {
gadget: "Input_viewShiftSpreadsheet",
type: "object_view",
title: "Shift Spreadsheet"
},
view_available_capacity_spreadsheet: {
gadget: "Input_viewAvailableCapacitySpreadsheet",
type: "object_view",
title: "Available Capacity Spreadsheet"
},
view_required_capacity_spreadsheet: {
gadget: "Input_viewRequiredCapacitySpreadsheet",
type: "object_view",
title: "Required Capacity Spreadsheet"
},
view_dp_capacity_spreadsheet: {
gadget: "Input_viewDemandPlanningCapacitySpreadsheet",
type: "object_view",
title: "Demand Planning Required Capacity Spreadsheet"
},
view_dp_route_spreadsheet: {
gadget: "Input_viewDemandPlanningRouteSpreadsheet",
type: "object_view",
title: "Demand Planning Route Spreadsheet"
},
view_simu: {
gadget: "Input_viewSimulation",
type: "object_view",
title: "Run simulation"
},
view_management: {
gadget: "Input_viewDocumentManagement",
type: "object_view",
title: "Manage document"
},
view_result: {
gadget: "Input_viewResultList",
type: "object_view",
title: "Results"
}
},
Output: {
view: {
gadget: "Output_viewStationUtilisationGraph",
type: "object_view",
title: "Stations Utilization"
},
download_excel_spreadsheet: {
gadget: "Output_viewDownloadExcelSpreadsheet",
type: "object_view",
title: "Download Excel Spreadsheet"
},
view_capacity_utilization: {
gadget: "Output_viewCapacityUtilisationGraph",
type: "object_view",
title: "Capacity Utilization"
},
view_queue_stat: {
gadget: "Output_viewQueueStatGraph",
type: "object_view",
title: "Queues Statistics"
},
view_exit_stat: {
gadget: "Output_viewExitStatistics",
type: "object_view",
title: "Exit Statistics"
},
view_gantt: {
gadget: "Output_viewJobGantt",
type: "object_view",
title: "Job Gantt"
},
view_schedule: {
gadget: "Output_viewJobScheduleSpreadsheet",
type: "object_view",
title: "Job Schedule"
},
view_debug: {
gadget: "Output_viewDebugJson",
type: "object_view",
title: "Debug JSON"
} }
} }
}, panel_template, navigation_template, active_navigation_template, error_template, gadget_klass = rJS(window); }, panel_template, navigation_template, active_navigation_template, error_template, gadget_klass = rJS(window);
function calculateTabHTML(gadget, options, key, title, active) { function calculateTabHTML(gadget, options, key, title, active) {
/*console.log('________________________');
console.log(key);
console.log(gadget);
console.log(options);
console.log(title);
console.log(active);
console.log('________________________');*/
return new RSVP.Queue().push(function() { return new RSVP.Queue().push(function() {
var kw = { var kw = {
action: key, action: key,
...@@ -40,14 +133,6 @@ ...@@ -40,14 +133,6 @@
} }
return gadget.aq_pleasePublishMyState(kw); return gadget.aq_pleasePublishMyState(kw);
}).push(function(url) { }).push(function(url) {
/*console.log('<><><><><><><>><><><><><><><calculating tab url:');
console.log(key);
if (url === undefined) {
console.log('tab url:');
console.log(url);
} else {
console.log('undefined url');
}*/
var kw = { var kw = {
title: title, title: title,
link: url link: url
...@@ -62,9 +147,9 @@ ...@@ -62,9 +147,9 @@
var forward_kw = { var forward_kw = {
action: options.action || "view" action: options.action || "view"
}, queue = new RSVP.Queue(); }, queue = new RSVP.Queue();
if (portal_type === "input") { if (portal_type === "Input") {
forward_kw.id = options.id; forward_kw.id = options.id;
} else if (portal_type === "output") { } else if (portal_type === "Output") {
forward_kw.id = options.id; forward_kw.id = options.id;
queue.push(function() { queue.push(function() {
return gadget.getDeclaredGadget("jio"); return gadget.getDeclaredGadget("jio");
...@@ -81,7 +166,7 @@ ...@@ -81,7 +166,7 @@
forward_kw.result = current + 1; forward_kw.result = current + 1;
} }
}); });
} else if (portal_type !== "Pre Input Module") { } else if (portal_type !== "Input Module") {
throw new Error("Unknown portal type: " + portal_type); throw new Error("Unknown portal type: " + portal_type);
} }
return queue.push(function() { return queue.push(function() {
...@@ -90,9 +175,9 @@ ...@@ -90,9 +175,9 @@
} }
function getTitle(gadget, portal_type, options) { function getTitle(gadget, portal_type, options) {
var title; var title;
if (portal_type === "Pre Input Module") { if (portal_type === "Input Module") {
title = "Documents"; title = "Documents";
} else if (portal_type === "input") { } else if (portal_type === "Input") {
title = gadget.getDeclaredGadget("jio").push(function(jio_gadget) { title = gadget.getDeclaredGadget("jio").push(function(jio_gadget) {
return jio_gadget.get({ return jio_gadget.get({
_id: options.id _id: options.id
...@@ -100,14 +185,14 @@ ...@@ -100,14 +185,14 @@
}).push(function(jio_doc) { }).push(function(jio_doc) {
return jio_doc.data.title + " (" + jio_doc.data.modified + ")"; return jio_doc.data.title + " (" + jio_doc.data.modified + ")";
}); });
} else if (portal_type === "output") { } else if (portal_type === "Output") {
title = gadget.getDeclaredGadget("jio").push(function(jio_gadget) { title = gadget.getDeclaredGadget("jio").push(function(jio_gadget) {
return jio_gadget.getAttachment({ return jio_gadget.getAttachment({
_id: options.id, _id: options.id,
_attachment: "simulation.json" _attachment: "simulation.json"
}); });
}).push(function(sim_json) { }).push(function(sim_json) {
var document_list = JSON.parse(sim_json).result.result_list; var document_list = JSON.parse(sim_json);
return document_list[options.result].score + " " + document_list[options.result].key; return document_list[options.result].score + " " + document_list[options.result].key;
}); });
} else { } else {
...@@ -116,15 +201,6 @@ ...@@ -116,15 +201,6 @@
return title; return title;
} }
function calculateNavigationHTML(gadget, portal_type, options) { function calculateNavigationHTML(gadget, portal_type, options) {
/*console.log('.............................');
console.log(gadget);
console.log(portal_type);
console.log(options);
console.log(options.action);
console.log(portal_types[portal_type]);
console.log(portal_types[portal_type][options.action]);
console.log(portal_types[portal_type][options.action].type);
console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<');*/
var nav_html, action; var nav_html, action;
if (portal_types[portal_type][options.action].type === "object_view") { if (portal_types[portal_type][options.action].type === "object_view") {
return new RSVP.Queue().push(function() { return new RSVP.Queue().push(function() {
...@@ -139,13 +215,8 @@ ...@@ -139,13 +215,8 @@
} }
} }
} }
/*console.log('url_list');
console.log(url_list);
console.log('>>>>>>>>>>>>>>>>>>>>>>>>');*/
return RSVP.all(url_list); return RSVP.all(url_list);
}).push(function(entry_list) { }).push(function(entry_list) {
/*console.log('entry_list');
console.log(entry_list);*/
var i; var i;
nav_html = '<nav data-role="navbar" data-collapsible="true"><ul>'; nav_html = '<nav data-role="navbar" data-collapsible="true"><ul>';
for (i = 0; i < entry_list.length; i += 1) { for (i = 0; i < entry_list.length; i += 1) {
...@@ -157,9 +228,6 @@ ...@@ -157,9 +228,6 @@
} }
} }
initGadgetMixin(gadget_klass); initGadgetMixin(gadget_klass);
/*console.log('AaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa');
console.log(gadget_klass);
console.log('AaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa');*/
gadget_klass.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash").allowPublicAcquisition("jio_allDocs", function(param_list) { gadget_klass.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash").allowPublicAcquisition("jio_allDocs", function(param_list) {
return this.getDeclaredGadget("jio").push(function(jio_gadget) { return this.getDeclaredGadget("jio").push(function(jio_gadget) {
return jio_gadget.allDocs.apply(jio_gadget, param_list); return jio_gadget.allDocs.apply(jio_gadget, param_list);
...@@ -188,21 +256,6 @@ ...@@ -188,21 +256,6 @@
return this.getDeclaredGadget("jio").push(function(jio_gadget) { return this.getDeclaredGadget("jio").push(function(jio_gadget) {
return jio_gadget.getAttachment.apply(jio_gadget, param_list); return jio_gadget.getAttachment.apply(jio_gadget, param_list);
}); });
}).allowPublicAcquisition("startListenTo", function(param_list) {
//console.log('arkoudesarkoudesarkoudesarkoudesarkoudes');
var obj, type, fn;
obj = param_list[0];
type = param_list[1];
fn = param_list[2];
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj.attachEvent) {
obj["e" + type + fn] = fn;
obj[type + fn] = function() {
obj["e" + type + fn](window.event);
};
obj.attachEvent("on" + type, obj[type + fn]);
}
}).allowPublicAcquisition("whoWantsToDisplayHome", function() { }).allowPublicAcquisition("whoWantsToDisplayHome", function() {
// Hey, I want to display some URL // Hey, I want to display some URL
return this.aq_pleasePublishMyState({}); return this.aq_pleasePublishMyState({});
...@@ -215,17 +268,14 @@ ...@@ -215,17 +268,14 @@
if (param_list[0] !== undefined) { if (param_list[0] !== undefined) {
kw.id = param_list[0]; kw.id = param_list[0];
} }
/*console.log(1010101010101);
console.log(kw);
console.log(param_list);*/
return this.aq_pleasePublishMyState(kw); return this.aq_pleasePublishMyState(kw);
}).allowPublicAcquisition("whoWantsToDisplayThisResult", function(param_list) { }).allowPublicAcquisition("whoWantsToDisplayThisResult", function(param_list) {
// Hey, I want to display some jIO document // Hey, I want to display some jIO document
// We'll display the result using the first enabled action // We'll display the result using the first enabled action
var action = "view", action_info, action_id; var action = "view", action_info, action_id;
for (action_id in portal_types.output) { for (action_id in portal_types.Output) {
if (portal_types.output.hasOwnProperty(action_id)) { if (portal_types.Output.hasOwnProperty(action_id)) {
action_info = portal_types.output[action_id]; action_info = portal_types.Output[action_id];
if (action_info.condition === undefined || action_info.condition(this)) { if (action_info.condition === undefined || action_info.condition(this)) {
action = action_id; action = action_id;
break; break;
...@@ -237,74 +287,30 @@ ...@@ -237,74 +287,30 @@
id: param_list[0], id: param_list[0],
result: param_list[1] result: param_list[1]
}); });
}).allowPublicAcquisition("getConfigurationDict", function() {
return this.props.configuration_dict;
}).allowPublicAcquisition("configurationIsSet", function() {
this.props.configSet = true;
}).allowPublicAcquisition("setConfigurationDict", function(conf_dict) {
this.props.configuration_dict = JSON.parse(conf_dict);
}).allowPublicAcquisition("getDefaultConfigurationDict", function() {
var jio_gadget, g = this;
//console.log('@@@@@@@@@@@@@@@getting DeclalredGadget@@@@@@@@@@@@@@@');
//console.log(g);
return g.getDeclaredGadget("jio").push(function(gadget) {
jio_gadget = gadget;
// XXX Hardcoded relative URL
return jio_gadget.ajax({
url: "../../getConfigurationDict"
});
}).push(function(evt) {
g.props.configuration_dict = JSON.parse(evt.target.responseText);
return g.props.configuration_dict;
});
}).ready(function() { }).ready(function() {
if (panel_template === undefined) { if (panel_template === undefined) {
// XXX Only works as root gadget // XXX Only works as root gadget
panel_template = Handlebars.compile(document.getElementById("panel-template").innerHTML); panel_template = Handlebars.compile(document.getElementById("panel-template").innerHTML);
//console.log(123123123123123);
//console.log('panel_template');
//console.log(document.getElementById("panel-template").innerHTML);
navigation_template = Handlebars.compile(document.getElementById("navigation-template").innerHTML); navigation_template = Handlebars.compile(document.getElementById("navigation-template").innerHTML);
/*console.log(123123123123);
console.log('navigation_template');
console.log(document.getElementById("navigation-template")
.innerHTML);*/
active_navigation_template = Handlebars.compile(document.getElementById("active-navigation-template").innerHTML); active_navigation_template = Handlebars.compile(document.getElementById("active-navigation-template").innerHTML);
/*console.log(123123123123);
console.log('active_navigation_template');
console.log(
document.getElementById("active-navigation-template").innerHTML
);*/
error_template = Handlebars.compile(document.getElementById("error-template").innerHTML); error_template = Handlebars.compile(document.getElementById("error-template").innerHTML);
} }
}).ready(function(g) { }).ready(function(g) {
//console.log('ggggggggggggggggggggg');
//console.log(g);
return new RSVP.Queue().push(function() { return new RSVP.Queue().push(function() {
//console.log('**********************************1'); return RSVP.all([ g.aq_pleasePublishMyState({}), g.aq_pleasePublishMyState({
//console.log(g); action: "view_fast_input"
return RSVP.all([ g.aq_pleasePublishMyState({}), //g.aq_pleasePublishMyState({action: "view_fast_input"}),
g.aq_pleasePublishMyState({
action: "view"
}) ]); }) ]);
}).push(function(link_list) { }).push(function(link_list) {
//console.log('____________________link_List*********************');
//console.log(link_list);
//console.log('_________________________*************************');
var panel = g.props.element.querySelector("#leftpanel"); var panel = g.props.element.querySelector("#leftpanel");
panel.innerHTML = panel_template({ panel.innerHTML = panel_template({
navigationlist: [] navigationlist: []
}); });
panel.getElementsByClassName("pre_input_link")[0].href = link_list[0]; panel.getElementsByClassName("home_link")[0].href = link_list[0];
//panel.getElementsByClassName("home_link")[0].href = link_list[0]; panel.getElementsByClassName("fast_input_link")[0].href = link_list[1];
//panel.getElementsByClassName("fast_input_link")[0].href =
// link_list[1];
// XXX JQuery mobile // XXX JQuery mobile
$(panel).trigger("create"); $(panel).trigger("create");
}); });
}).ready(function(g) { }).ready(function(g) {
//console.log('@@@@@@@@@@@@@@@getting DeclalredGadget@@@@@@@@@@@@@@@');
//console.log(g);
return g.getDeclaredGadget("jio").push(function(gadget) { return g.getDeclaredGadget("jio").push(function(gadget) {
return gadget.createJio({ return gadget.createJio({
type: "local", type: "local",
...@@ -315,63 +321,40 @@ ...@@ -315,63 +321,40 @@
}).declareMethod("render", function(options) { }).declareMethod("render", function(options) {
var gadget = this, back_kw = { var gadget = this, back_kw = {
action: "view" action: "view"
}, page_gadget, portal_type = "Pre Input Module", nav_element = gadget.props.element.getElementsByClassName("nav_container")[0], element = gadget.props.element.getElementsByClassName("gadget_container")[0]; }, page_gadget, portal_type = "Input Module", nav_element = gadget.props.element.getElementsByClassName("nav_container")[0], element = gadget.props.element.getElementsByClassName("gadget_container")[0];
console.log("!!!!!!!!!!!!!!!!!!!!!!options!!!!!!!!!!!!!!!!!!!!!!!");
console.log(options);
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
if (options.action === undefined) { if (options.action === undefined) {
// Redirect to the view action // Redirect to the view action
options.action = "view"; options.action = "view";
return gadget.aq_pleasePublishMyState(options).push(gadget.pleaseRedirectMyHash.bind(gadget)); return gadget.aq_pleasePublishMyState(options).push(gadget.pleaseRedirectMyHash.bind(gadget));
} }
/*// if configuration_dict is defined
// then Pre Input Module should not be loaded
if (gadget.props.configSet === true) {
portal_type = "Input Module";
$('.pre_input_link').hide();
}*/
if (gadget.props.configSet === true) {
portal_types.input = gadget.props.configuration_dict.application_configuration.input;
portal_types.output = gadget.props.configuration_dict.application_configuration.output;
}
// Detect what is the kind of document displayed // Detect what is the kind of document displayed
if (options.id !== undefined) { if (options.id !== undefined) {
if (options.result === undefined) { if (options.result === undefined) {
portal_type = "input"; portal_type = "Input";
} else { } else {
portal_type = "output"; portal_type = "Output";
back_kw.action = "view_result"; back_kw.action = "view_result";
back_kw.id = options.id; back_kw.id = options.id;
} }
} }
console.log("__________________portal_types__________________"); return gadget.getDeclaredGadget("jio").push(function(jio_gadget) {
console.log(portal_types); if (options.id) {
console.log(portal_type); return jio_gadget.getAttachment({
console.log(options); _id: options.id,
console.log(portal_types[portal_type]); _attachment: "body.json"
/*return gadget.getDeclaredGadget("jio") });
.push(function(jio_gadget) { }
if (options.id) { }).push(function(result) {
return jio_gadget.getAttachment({ var data;
"_id": options.id, if (result) {
"_attachment": "body.json" data = JSON.parse(result);
}); gadget.props.data = data;
} portal_types.Input = data.application_configuration.input;
}) portal_types.Output = data.application_configuration.output;
.push(function(result) { }
var data; // Get the action information
if (result) { return gadget.declareGadget(portal_types[portal_type][options.action].gadget + ".html");
data = JSON.parse(result); }).push(function(g) {
gadget.props.data = data;
portal_types.input = data.application_configuration.input;
portal_types.output = data.application_configuration.output;
}
// Get the action information
return gadget.declareGadget(
portal_types[portal_type][options.action].gadget + ".html"
);
})*/
return gadget.declareGadget(portal_types[portal_type][options.action].gadget + ".html").push(function(g) {
page_gadget = g; page_gadget = g;
if (page_gadget.render !== undefined) { if (page_gadget.render !== undefined) {
return page_gadget.render(options); return page_gadget.render(options);
...@@ -379,9 +362,6 @@ ...@@ -379,9 +362,6 @@
}).push(function() { }).push(function() {
return RSVP.all([ page_gadget.getElement(), calculateNavigationHTML(gadget, portal_type, options), gadget.aq_pleasePublishMyState(back_kw), getTitle(gadget, portal_type, options), getNextLink(gadget, portal_type, options) ]); return RSVP.all([ page_gadget.getElement(), calculateNavigationHTML(gadget, portal_type, options), gadget.aq_pleasePublishMyState(back_kw), getTitle(gadget, portal_type, options), getNextLink(gadget, portal_type, options) ]);
}).push(function(result_list) { }).push(function(result_list) {
console.log("????????????????????????????????????????????");
console.log(result_list);
console.log("????????????????????????????????????????????");
var nav_html = result_list[1], page_element = result_list[0]; var nav_html = result_list[1], page_element = result_list[0];
// Update title // Update title
gadget.props.element.querySelector("header h1").textContent = result_list[3]; gadget.props.element.querySelector("header h1").textContent = result_list[3];
......
/*global rJS, RSVP, jQuery, Handlebars, /*global rJS, RSVP, jQuery, Handlebars,
promiseEventListener, initGadgetMixin, console */ promiseEventListener, initGadgetMixin*/
/*jslint nomen: true */ /*jslint nomen: true */
(function(window, rJS, RSVP, Handlebars, initGadgetMixin) { (function(window, rJS, RSVP, Handlebars, initGadgetMixin) {
"use strict"; "use strict";
...@@ -13,9 +13,6 @@ ...@@ -13,9 +13,6 @@
// XXX node_id is added like a property so that one can change the node // XXX node_id is added like a property so that one can change the node
// id // id
var gadget = this, queue; var gadget = this, queue;
console.log("FIELDSET RENDER 1");
console.log(options);
console.log(node_id);
gadget.props.key = options.key; gadget.props.key = options.key;
// used for recursive fieldsets // used for recursive fieldsets
gadget.props.field_gadget_list = []; gadget.props.field_gadget_list = [];
...@@ -24,27 +21,10 @@ ...@@ -24,27 +21,10 @@
queue.push(function() { queue.push(function() {
// XXX this is incorrect for recursive fieldsets. // XXX this is incorrect for recursive fieldsets.
// we should use nested fieldset with legend // we should use nested fieldset with legend
console.log("insertingAdjacentHTML for:" + property_id);
gadget.props.element.insertAdjacentHTML("beforeend", label_template({ gadget.props.element.insertAdjacentHTML("beforeend", label_template({
"for": property_id, "for": property_id,
name: property_definition.name || property_id name: property_definition.name || property_definition.description || property_id
})); }));
console.log("....................");
console.log(property_id);
console.log(property_definition);
console.log(value);
// XXX maybe type should be used instead
if (property_definition.allOf) {
// if there is type property then remove it
if (property_definition.allOf[0].type) {
delete property_definition.allOf[0].type;
}
return gadget.declareGadget("../expandable_field/index.html");
}
if (property_definition.properties) {
// Create a recursive fieldset for this key.
return gadget.declareGadget("../fieldset/index.html");
}
if (property_definition.type === "object") { if (property_definition.type === "object") {
// Create a recursive fieldset for this key. // Create a recursive fieldset for this key.
return gadget.declareGadget("../fieldset/index.html"); return gadget.declareGadget("../fieldset/index.html");
...@@ -71,63 +51,22 @@ ...@@ -71,63 +51,22 @@
}); });
} }
queue = new RSVP.Queue().push(function() { queue = new RSVP.Queue().push(function() {
var reserved_keys = [];
if (node_id) { if (node_id) {
addField("id", { addField("id", {
type: "string" type: "string"
}, node_id); }, node_id);
} }
Object.keys(options.property_definition.properties).forEach(function(property_name) { Object.keys(options.property_definition.properties).forEach(function(property_name) {
var property_definition = options.property_definition.properties[property_name], value, i = 0, property, index; var property_definition = options.property_definition.properties[property_name], value = (options.value || {})[property_name] === undefined ? property_definition._default : options.value[property_name];
if (property_definition) { // XXX some properties are not editable
value = property_definition.default || {}; // XXX should not be defined here
if (property_definition.allOf) { if (property_name !== "coordinate" && property_name !== "_class") {
if (property_definition.allOf[0].properties) {
for (property in property_definition.allOf[0].properties) {
if (property_definition.allOf[0].properties.hasOwnProperty(property)) {
i += 1;
if (i > 1) {
console.log("something is wrong!");
}
value = property_definition.allOf[0].properties[property].default;
}
}
}
}
}
console.log("TRYING TO FIND A VALUE!!!!");
console.log(options);
console.log(options.value);
console.log(property_name);
// XXX if the field is complex then the value may be complex
// eg options.value > "time_to_failure":{},"time_to_repair":{}...
// while the property_names are abstract as allOf_1 corresponding
// to (for example) time_to_failure
if (options.property_definition.properties[property_name].allOf) {
if ((options.value || {})[property_name] === undefined) {
if (typeof options.value === "object") {
if (Object.keys(options.value).length > 0) {
for (index = 0; index < Object.keys(options.value).length - 1; index += 1) {
if (!(reserved_keys.indexOf(Object.keys(options.value)[index]) > -1)) {
reserved_keys.push(Object.keys(options.value)[index]);
value = options.value[Object.keys(options.value)[index]];
break;
}
}
}
}
}
}
value = (options.value || {})[property_name] === undefined ? value : options.value[property_name];
if (property_name !== "coordinate" && property_name !== "_class" && property_name !== "id") {
console.log("ADDING FIELD FOR " + property_name + "!!!!!!!");
addField(property_name, property_definition, value); addField(property_name, property_definition, value);
} }
}); });
}); });
return queue; return queue;
}).declareMethod("getContent", function() { }).declareMethod("getContent", function() {
console.log("GET CONTENT SIMPLE FIELDSET");
var i, promise_list = [], gadget = this; var i, promise_list = [], gadget = this;
for (i = 0; i < this.props.field_gadget_list.length; i += 1) { for (i = 0; i < this.props.field_gadget_list.length; i += 1) {
promise_list.push(this.props.field_gadget_list[i].getContent()); promise_list.push(this.props.field_gadget_list[i].getContent());
...@@ -135,8 +74,6 @@ ...@@ -135,8 +74,6 @@
return RSVP.Queue().push(function() { return RSVP.Queue().push(function() {
return RSVP.all(promise_list); return RSVP.all(promise_list);
}).push(function(result_list) { }).push(function(result_list) {
console.log("(*)(/)(*)");
console.log(result_list);
var name, result = {}, content = result; var name, result = {}, content = result;
if (gadget.props.key) { if (gadget.props.key) {
content = result[gadget.props.key] = {}; content = result[gadget.props.key] = {};
...@@ -148,19 +85,7 @@ ...@@ -148,19 +85,7 @@
} }
} }
} }
console.log("GET CONTENT SIMPLE FIELDSET 2");
console.log(result);
return result; return result;
}); });
}).declareMethod("startService", function() {
console.log("startservice FIElDSET 1");
var gadget = this, i, promise_list = [];
for (i = 0; i < gadget.props.field_gadget_list.length; i += 1) {
if (gadget.props.field_gadget_list[i].startService) {
promise_list.push(gadget.props.field_gadget_list[i].startService());
}
}
console.log("there are " + promise_list.length + " subgadget promises");
return RSVP.all(promise_list);
}); });
})(window, rJS, RSVP, Handlebars, initGadgetMixin); })(window, rJS, RSVP, Handlebars, initGadgetMixin);
\ No newline at end of file
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* along with DREAM. If not, see <http://www.gnu.org/licenses/>. * along with DREAM. If not, see <http://www.gnu.org/licenses/>.
* ==========================================================================*/ * ==========================================================================*/
/*global RSVP, rJS, $, jsPlumb, Handlebars, /*global RSVP, rJS, $, jsPlumb, Handlebars,
loopEventListener, promiseEventListener, DOMParser, confirm, console*/ loopEventListener, promiseEventListener, DOMParser */
/*jslint unparam: true todo: true */ /*jslint unparam: true todo: true */
(function(RSVP, rJS, $, jsPlumb, Handlebars, loopEventListener, promiseEventListener, DOMParser) { (function(RSVP, rJS, $, jsPlumb, Handlebars, loopEventListener, promiseEventListener, DOMParser) {
"use strict"; "use strict";
...@@ -71,7 +71,6 @@ ...@@ -71,7 +71,6 @@
return new RSVP.Promise(resolver, canceller); return new RSVP.Promise(resolver, canceller);
} }
function getNodeId(gadget, element_id) { function getNodeId(gadget, element_id) {
console.log("getNODEID 1");
// returns the ID of the node in the graph from its DOM element id // returns the ID of the node in the graph from its DOM element id
var node_id; var node_id;
$.each(gadget.props.node_id_to_dom_element_id, function(k, v) { $.each(gadget.props.node_id_to_dom_element_id, function(k, v) {
...@@ -83,9 +82,8 @@ ...@@ -83,9 +82,8 @@
return node_id; return node_id;
} }
function generateNodeId(gadget, element) { function generateNodeId(gadget, element) {
console.log("generateNODEID 1");
// Generate a node id // Generate a node id
var n = 1, class_def = gadget.props.data.class_definition[element._class], id = class_def.allOf[1].properties.id.default || element._class; var n = 1, class_def = gadget.props.data.class_definition[element._class], id = class_def.short_id || element._class;
while (gadget.props.data.graph.node[id + n] !== undefined) { while (gadget.props.data.graph.node[id + n] !== undefined) {
n += 1; n += 1;
} }
...@@ -130,7 +128,6 @@ ...@@ -130,7 +128,6 @@
return [ left, top ]; return [ left, top ];
} }
function updateElementCoordinate(gadget, node_id, coordinate) { function updateElementCoordinate(gadget, node_id, coordinate) {
console.log("updateELEMENTCOORDINATE 1");
var element_id = gadget.props.node_id_to_dom_element_id[node_id], element, relative_position; var element_id = gadget.props.node_id_to_dom_element_id[node_id], element, relative_position;
if (coordinate === undefined) { if (coordinate === undefined) {
element = $(gadget.props.element).find("#" + element_id); element = $(gadget.props.element).find("#" + element_id);
...@@ -174,7 +171,7 @@ ...@@ -174,7 +171,7 @@
anchor: "Continuous" anchor: "Continuous"
}); });
} }
function updateNodeStyle(gadget, element_id, class_definition) { function updateNodeStyle(gadget, element_id) {
// Update node size according to the zoom level // Update node size according to the zoom level
// XXX does nothing for now // XXX does nothing for now
var zoom_level = gadget.props.zoom_level * 1.1111, element = $(gadget.props.element).find("#" + element_id), new_value; var zoom_level = gadget.props.zoom_level * 1.1111, element = $(gadget.props.element).find("#" + element_id), new_value;
...@@ -182,9 +179,6 @@ ...@@ -182,9 +179,6 @@
new_value = $(gadget.props.element).find(".dummy_window").css(j).replace("px", "") * zoom_level + "px"; new_value = $(gadget.props.element).find(".dummy_window").css(j).replace("px", "") * zoom_level + "px";
element.css(j, new_value); element.css(j, new_value);
}); });
Object.keys(class_definition.css || {}).forEach(function(k) {
element.css(k, class_definition.css[k]);
});
} }
// function positionGraph(gadget) { // function positionGraph(gadget) {
// $.ajax( // $.ajax(
...@@ -211,38 +205,31 @@ ...@@ -211,38 +205,31 @@
// ); // );
// } // }
function removeElement(gadget, node_id) { function removeElement(gadget, node_id) {
console.log("removeELEMENT 1");
var element_id = gadget.props.node_id_to_dom_element_id[node_id]; var element_id = gadget.props.node_id_to_dom_element_id[node_id];
gadget.props.jsplumb_instance.removeAllEndpoints($(gadget.props.element).find("#" + element_id)); gadget.props.jsplumb_instance.removeAllEndpoints($(gadget.props.element).find("#" + element_id));
$(gadget.props.element).find("#" + element_id).remove(); $(gadget.props.element).find("#" + element_id).remove();
delete gadget.props.data.graph.node[node_id]; delete gadget.props.data.graph.node[node_id];
delete gadget.props.node_id_to_dom_element_id[node_id]; delete gadget.props.node_id_to_dom_element_id[node_id];
//$.each(gadget.props.data.graph.main_graph.node, function (k, v) {
$.each(gadget.props.data.graph.edge, function(k, v) { $.each(gadget.props.data.graph.edge, function(k, v) {
if (node_id === v.source || node_id === v.destination) { if (node_id === v.source || node_id === v.destination) {
delete gadget.props.data.graph.edge[k]; delete gadget.props.data.graph.edge[k];
} }
}); });
gadget.notifyDataChanged(); gadget.notifyDataChanged();
console.log("removeELEMENT 4");
} }
function updateElementData(gadget, node_id, data) { function updateElementData(gadget, node_id, data) {
console.log("updateELEMENTDATA 1");
var element_id = gadget.props.node_id_to_dom_element_id[node_id], new_id = data.id; var element_id = gadget.props.node_id_to_dom_element_id[node_id], new_id = data.id;
if (data.data.name) { if (data.data.name) {
$(gadget.props.element).find("#" + element_id).text(data.data.name).attr("title", data.data.name).append('<div class="ep"></div></div>'); $(gadget.props.element).find("#" + element_id).text(data.data.name).attr("title", data.data.name).append('<div class="ep"></div></div>');
gadget.props.data.graph.node[node_id].name = data.data.name; gadget.props.data.graph.node[node_id].name = data.data.name;
} }
delete data.id; delete data.id;
//$.extend(gadget.props.data.graph.main_graph.node[node_id], data.data);
$.extend(gadget.props.data.graph.node[node_id], data.data); $.extend(gadget.props.data.graph.node[node_id], data.data);
if (new_id && new_id !== node_id) { if (new_id && new_id !== node_id) {
gadget.props.data.graph.node[new_id] = gadget.props.data.graph.node[node_id]; gadget.props.data.graph.node[new_id] = gadget.props.data.graph.node[node_id];
delete gadget.props.data.graph.node[node_id]; delete gadget.props.data.graph.node[node_id];
gadget.props.node_id_to_dom_element_id[new_id] = gadget.props.node_id_to_dom_element_id[node_id]; gadget.props.node_id_to_dom_element_id[new_id] = gadget.props.node_id_to_dom_element_id[node_id];
delete gadget.props.node_id_to_dom_element_id[node_id]; delete gadget.props.node_id_to_dom_element_id[node_id];
//delete gadget.props.data.graph.main_graph.node[new_id].id;
//$.each(gadget.props.data.graph.main_graph.node, function (k, v) {
delete gadget.props.data.graph.node[new_id].id; delete gadget.props.data.graph.node[new_id].id;
$.each(gadget.props.data.graph.edge, function(k, v) { $.each(gadget.props.data.graph.edge, function(k, v) {
if (v.source === node_id) { if (v.source === node_id) {
...@@ -253,7 +240,6 @@ ...@@ -253,7 +240,6 @@
} }
}); });
} }
console.log("updateELEMENTDATA 7");
gadget.notifyDataChanged(); gadget.notifyDataChanged();
} }
function addEdge(gadget, edge_id, edge_data) { function addEdge(gadget, edge_id, edge_data) {
...@@ -301,259 +287,31 @@ ...@@ -301,259 +287,31 @@
// jsplumb assigned an id, but we are controlling ids ourselves. // jsplumb assigned an id, but we are controlling ids ourselves.
connection.id = edge_id; connection.id = edge_id;
} }
/* function expandSchema(class_definition, full_schema) {
// minimal expanding of json schema, supports merging allOf and $ref
// references
// TODO: check for a library that would provide full support
var property, referenced, i, j, len,
expanded_class_definition = {properties:
class_definition.properties || {}},
ref_word_list, ref_word, ref_definition_list,
ref_definition_word, ref_definition_root, ref_definition,
sub_ref_def, sub_ref_def_list,
sub_ref_def_word, sub_ref_def_root, prop;
console.log("expandSCHEMA 1");
console.log(class_definition);
console.log(full_schema);
console.log(expanded_class_definition);
if (class_definition.allOf) {
for (i = 0; i < class_definition.allOf.length; i += 1) {
referenced = class_definition.allOf[i];
if (referenced.$ref) {
ref_word_list = referenced.$ref.split("/");
ref_word = ref_word_list[ref_word_list.length-1];
referenced = expandSchema(
full_schema.class_definition[ref_word],
full_schema);
}
// console.log(full_schema.class_definition.definitions);
if (referenced.properties) {
console.log("[[[[[[[[[[]]]]]]]]]]");
console.log(referenced.properties);
for (property in referenced.properties) {
if (referenced.properties.hasOwnProperty(property)) {
if (referenced.properties[property].type ||
referenced.properties[property].$ref) {
console.log("..");
console.log(property);
console.log(referenced.properties[property]);
if (referenced.properties[property].$ref) {
ref_definition_list
= referenced.properties[property].$ref.split("/");
ref_definition_word
= ref_definition_list[ref_definition_list.length-1];
ref_definition
= full_schema.class_definition
.definitions[ref_definition_word];
if (ref_definition.allOf) {
if (ref_definition.allOf[1].oneOf) {
len = ref_definition.allOf[1].oneOf.length - 1;
for (j = 0; j <= len; j += 1) {
if (ref_definition.allOf[1]
.oneOf[j].$ref) {
sub_ref_def_list = ref_definition.allOf[1]
.oneOf[j].$ref.split("/");
sub_ref_def_word
= sub_ref_def_list[sub_ref_def_list.length-1];
sub_ref_def_root
= sub_ref_def_list[sub_ref_def_list.length-2];
sub_ref_def = full_schema.class_definition
.definitions[sub_ref_def_root][sub_ref_def_word];
ref_definition.allOf[1].oneOf[j] = sub_ref_def;
}
}
}
}
expanded_class_definition.properties[property]
= ref_definition;
//console.log("for property " + property + ", definition:");
//console.log(ref_definition);
} else {
if (referenced.properties[property].properties) {
console.log("not a reference");
console.log(referenced.properties[property].properties);
for (prop in referenced.properties[property]
.properties) {
if (referenced.properties[property]
.properties.hasOwnProperty(prop)) {
console.log(7);
console.log(prop);
console.log(referenced.properties[property]
.properties[prop]);
if (referenced.properties[property]
.properties[prop].$ref) {
console.log("!!!!");
ref_definition_list
= referenced.properties[property]
.properties[prop].$ref.split("/");
console.log(ref_definition_list);
ref_definition_word
= ref_definition_list[
ref_definition_list.length-1
];
console.log(ref_definition_word);
ref_definition_root
= ref_definition_list[
ref_definition_list.length-2
];
console.log(ref_definition_root);
ref_definition = full_schema
.class_definition[
ref_definition_root
][ref_definition_word];
console.log(ref_definition);
if (ref_definition.allOf) {
if (ref_definition.allOf[1].oneOf) {
len = ref_definition.allOf[1].oneOf.length - 1;
for (j = 0; j <= len; j += 1) {
if (ref_definition.allOf[1]
.oneOf[j].$ref) {
sub_ref_def_list = ref_definition.allOf[1]
.oneOf[j].$ref.split("/");
sub_ref_def_word
= sub_ref_def_list[
sub_ref_def_list.length-1
];
sub_ref_def_root
= sub_ref_def_list[
sub_ref_def_list.length-2
];
sub_ref_def = full_schema.class_definition
.definitions[
sub_ref_def_root
][sub_ref_def_word];
ref_definition.allOf[1].oneOf[j]
= sub_ref_def;
}
}
}
}
referenced.properties[property].properties[prop]
= ref_definition;
}
}
}
}
expanded_class_definition.properties[property]
= referenced.properties[property];
}
}
}
}
}
}
}
// console.log("expandSCHEMA 2");
// console.log(expanded_class_definition);
return expanded_class_definition;
} */
function expandOneOf(definition, fullSchema) {
var j, len = definition.allOf[1].oneOf.length - 1, def_ref_list, def_ref_word, def_ref_root, referenced_def;
for (j = 0; j <= len; j += 1) {
if (definition.allOf[1].oneOf[j].$ref) {
def_ref_list = definition.allOf[1].oneOf[j].$ref.split("/");
def_ref_word = def_ref_list[def_ref_list.length - 1];
def_ref_root = def_ref_list[def_ref_list.length - 2];
referenced_def = fullSchema.class_definition.definitions[def_ref_root][def_ref_word];
definition.allOf[1].oneOf[j] = referenced_def;
}
}
return definition;
}
function expandReference(definition, fullSchema) {
var ref_definition_list = definition.$ref.split("/"), ref_definition_word = ref_definition_list[ref_definition_list.length - 1], ref_definition_root = ref_definition_list[ref_definition_list.length - 2], ref_definition = fullSchema.class_definition[ref_definition_root][ref_definition_word];
console.log("expandingReference");
if (ref_definition.allOf) {
if (ref_definition.allOf[1].oneOf) {
console.log("there is oneOf");
ref_definition = expandOneOf(ref_definition, fullSchema);
}
}
definition = ref_definition;
console.log("* * *");
console.log(definition);
return definition;
}
function expandProperties(definition, expanded_class_def, fullSchema) {
console.log("expanding properties");
console.log(definition);
var property, temp1, temp2, i, subProp, temp3;
for (property in definition.properties) {
if (definition.properties.hasOwnProperty(property)) {
console.log("...");
console.log(property);
if (definition.properties[property].allOf || definition.properties[property].properties || definition.properties[property].type || definition.properties[property].$ref) {
if (definition.properties[property].$ref) {
temp1 = expandReference(definition.properties[property], fullSchema);
console.log("there is a referenced property # #");
console.log(property);
expanded_class_def.properties[property] = temp1;
if (temp1.allOf) {
if (temp1.allOf[1].oneOf) {
for (i = 0; i <= temp1.allOf[1].oneOf.length - 1; i += 1) {
if (temp1.allOf[1].oneOf[i].properties) {
for (subProp in temp1.allOf[1].oneOf[i].properties) {
if (temp1.allOf[1].oneOf[i].properties.hasOwnProperty(subProp)) {
if (temp1.allOf[1].oneOf[i].properties[subProp].$ref) {
console.log("there is referenced sub-property");
console.log(subProp);
temp3 = expandReference(temp1.allOf[1].oneOf[i].properties[subProp], fullSchema);
expanded_class_def.properties[property].allOf[1].oneOf[i].properties[subProp] = temp3;
}
}
}
}
}
}
}
} else {
if (definition.properties[property].properties) {
console.log("there is a property property --> recursive");
console.log(property);
expanded_class_def.properties[property] = {
properties: {}
};
temp2 = expandProperties(definition.properties[property], expanded_class_def.properties[property], fullSchema);
definition.properties[property] = temp2;
}
console.log("before expanding definition");
console.log(property);
expanded_class_def.properties[property] = definition.properties[property];
}
}
}
}
console.log("- * - * -");
console.log(expanded_class_def);
return expanded_class_def;
}
function expandSchema(class_definition, full_schema) { function expandSchema(class_definition, full_schema) {
// minimal expanding of json schema, supports merging allOf and $ref // minimal expanding of json schema, supports merging allOf and $ref
// references // references
// TODO: check for a library that would provide full support // TODO: check for a library that would provide full support
console.log("EXPANDING SCHEMA FOR :"); var property, referenced, i, expanded_class_definition = {
console.log(class_definition);
var referenced, i, expanded_class_definition = {
properties: class_definition.properties || {} properties: class_definition.properties || {}
}, ref_word_list, ref_word; };
if (class_definition.allOf) { if (class_definition.allOf) {
for (i = 0; i < class_definition.allOf.length; i += 1) { for (i = 0; i < class_definition.allOf.length; i += 1) {
referenced = class_definition.allOf[i]; referenced = class_definition.allOf[i];
if (referenced.$ref) { if (referenced.$ref) {
ref_word_list = referenced.$ref.split("/"); referenced = expandSchema(full_schema.class_definition[// 2 here is for #/
ref_word = ref_word_list[ref_word_list.length - 1]; referenced.$ref.substr(2, referenced.$ref.length)], full_schema);
console.log("# there is reference");
referenced = expandSchema(full_schema.class_definition[ref_word], full_schema);
} }
if (referenced.properties) { if (referenced.properties) {
console.log("# there are properties"); for (property in referenced.properties) {
expanded_class_definition = expandProperties(referenced, expanded_class_definition, full_schema); if (referenced.properties.hasOwnProperty(property)) {
if (referenced.properties[property].type) {
expanded_class_definition.properties[property] = referenced.properties[property];
}
}
}
} }
} }
} }
console.log("EXPANDED SCHEMA FOR : 2");
console.log(expanded_class_definition);
return expanded_class_definition; return expanded_class_definition;
} }
function openEdgeEditionDialog(gadget, connection) { function openEdgeEditionDialog(gadget, connection) {
...@@ -620,32 +378,17 @@ ...@@ -620,32 +378,17 @@
}); });
} }
function openNodeEditionDialog(gadget, element) { function openNodeEditionDialog(gadget, element) {
console.log("openNODEDIALOG 1");
var node_id = getNodeId(gadget, element.id), node_data = gadget.props.data.graph.node[node_id], node_edit_popup = $(gadget.props.element).find("#popup-edit-template"), schema, fieldset_element, delete_promise; var node_id = getNodeId(gadget, element.id), node_data = gadget.props.data.graph.node[node_id], node_edit_popup = $(gadget.props.element).find("#popup-edit-template"), schema, fieldset_element, delete_promise;
// If we have no definition for this, we do not allow edition. // If we have no definition for this, we do not allow edition.
//TODO: node_data._class may not exist
if (gadget.props.data.class_definition[node_data._class] === undefined) { if (gadget.props.data.class_definition[node_data._class] === undefined) {
return; return;
} }
console.log("OPEN DIALOG FOR NODE");
console.log(gadget.props);
console.log(gadget.props.data.class_definition);
console.log(node_data);
schema = expandSchema(gadget.props.data.class_definition[node_data._class], gadget.props.data); schema = expandSchema(gadget.props.data.class_definition[node_data._class], gadget.props.data);
console.log("----schema----");
console.log(schema);
console.log("----schema----");
if (node_edit_popup.length !== 0) { if (node_edit_popup.length !== 0) {
node_edit_popup.remove(); node_edit_popup.remove();
} }
gadget.props.element.appendChild(document.importNode(popup_edit_template.content, true).children[0]); gadget.props.element.appendChild(document.importNode(popup_edit_template.content, true).children[0]);
node_edit_popup = $(gadget.props.element).find("#edit-popup"); node_edit_popup = $(gadget.props.element).find("#edit-popup");
console.log("openNODEDIALOG 1.3");
console.log(node_edit_popup);
console.log(node_edit_popup.find(".node_class"));
console.log(gadget.props.data.graph.node);
console.log(node_data);
console.log(node_edit_popup.find(".node_class").text(node_data._class));
// Set the name of the popup to the node class // Set the name of the popup to the node class
node_edit_popup.find(".node_class").text(node_data._class); node_edit_popup.find(".node_class").text(node_data._class);
fieldset_element = node_edit_popup.find("fieldset")[0]; fieldset_element = node_edit_popup.find("fieldset")[0];
...@@ -662,59 +405,31 @@ ...@@ -662,59 +405,31 @@
data: {} data: {}
}; };
return fieldset_gadget.getContent().then(function(r) { return fieldset_gadget.getContent().then(function(r) {
console.log("******");
console.log("******");
console.log("******");
console.log(r);
console.log("******");
console.log("******");
console.log("******");
$.extend(data.data, r); $.extend(data.data, r);
updateElementData(gadget, node_id, data); updateElementData(gadget, node_id, data);
}); });
}); });
} }
console.log("openNODEDIALOG 3");
delete_promise = new RSVP.Queue().push(function() { delete_promise = new RSVP.Queue().push(function() {
return promiseEventListener(node_edit_popup.find("form [type='button']")[0], "click", false); return promiseEventListener(node_edit_popup.find("form [type='button']")[0], "click", false);
}).push(function() { }).push(function() {
return removeElement(gadget, node_id); return removeElement(gadget, node_id);
}); });
console.log("openNODEDIALOG 4");
return gadget.declareGadget("../fieldset/index.html", { return gadget.declareGadget("../fieldset/index.html", {
element: fieldset_element, element: fieldset_element,
scope: "fieldset" scope: "fieldset"
}).push(function(fieldset_gadget) { }).push(function(fieldset_gadget) {
console.log("^^^^^^^^^^^^^^^^^^^");
console.log("^^^^^^^^^^^^^^^^^^^");
console.log("^^^^^^^^^^^^^^^^^^^");
console.log(fieldset_gadget);
console.log("^^^^^^^^^^^^^^^^^^^");
console.log("^^^^^^^^^^^^^^^^^^^");
console.log("^^^^^^^^^^^^^^^^^^^");
return RSVP.all([ fieldset_gadget, fieldset_gadget.render({ return RSVP.all([ fieldset_gadget, fieldset_gadget.render({
value: node_data, value: node_data,
property_definition: schema property_definition: schema
}, node_id) ]); }, node_id) ]);
}).push(function(fieldset_gadget) { }).push(function(fieldset_gadget) {
console.log(fieldset_gadget[0]); node_edit_popup.enhanceWithin();
return RSVP.Queue().push(function() { node_edit_popup.popup("open");
console.log(fieldset_gadget[0]); return fieldset_gadget[0];
fieldset_gadget[0].startService();
}).push(function() {
console.log(":::::::::::::::::::::::::::");
console.log(fieldset_gadget);
console.log(":::::::::::::::::::::::::::");
node_edit_popup.enhanceWithin();
node_edit_popup.popup("open");
return fieldset_gadget[0];
});
}).push(function(fieldset_gadget) { }).push(function(fieldset_gadget) {
// Expose the dialog handling promise so that we can wait for it in // Expose the dialog handling promise so that we can wait for it in
// test. // test.
console.log("=======:::::::::::::::::::=======");
console.log(fieldset_gadget);
console.log("=======:::::::::::::::::::=======");
gadget.props.dialog_promise = RSVP.any([ save_promise(fieldset_gadget, node_id), delete_promise ]); gadget.props.dialog_promise = RSVP.any([ save_promise(fieldset_gadget, node_id), delete_promise ]);
return gadget.props.dialog_promise; return gadget.props.dialog_promise;
}).push(function() { }).push(function() {
...@@ -723,9 +438,7 @@ ...@@ -723,9 +438,7 @@
delete gadget.props.dialog_promise; delete gadget.props.dialog_promise;
}); });
} }
//function waitForNodeClick(gadget, node, config_dict) {
function waitForNodeClick(gadget, node) { function waitForNodeClick(gadget, node) {
console.log("waitFORNODEclick 1");
gadget.props.nodes_click_monitor.monitor(loopEventListener(node, "dblclick", false, openNodeEditionDialog.bind(null, gadget, node))); gadget.props.nodes_click_monitor.monitor(loopEventListener(node, "dblclick", false, openNodeEditionDialog.bind(null, gadget, node)));
} }
function waitForConnection(gadget) { function waitForConnection(gadget) {
...@@ -744,12 +457,10 @@ ...@@ -744,12 +457,10 @@
}); });
} }
function addNode(gadget, node_id, node_data) { function addNode(gadget, node_id, node_data) {
console.log("addNODE 0");
var render_element = $(gadget.props.main), class_definition = gadget.props.data.class_definition[node_data._class], coordinate = node_data.coordinate, dom_element_id, box, absolute_position, domElement; var render_element = $(gadget.props.main), class_definition = gadget.props.data.class_definition[node_data._class], coordinate = node_data.coordinate, dom_element_id, box, absolute_position, domElement;
dom_element_id = generateDomElementId(gadget.props.element); dom_element_id = generateDomElementId(gadget.props.element);
gadget.props.node_id_to_dom_element_id[node_id] = dom_element_id; gadget.props.node_id_to_dom_element_id[node_id] = dom_element_id;
node_data.name = node_data.name || class_definition.name; node_data.name = node_data.name || class_definition.name;
//gadget.props.data.graph.main_graph.node[node_id] = node_data;
gadget.props.data.graph.node[node_id] = node_data; gadget.props.data.graph.node[node_id] = node_data;
if (coordinate === undefined) { if (coordinate === undefined) {
coordinate = { coordinate = {
...@@ -768,12 +479,11 @@ ...@@ -768,12 +479,11 @@
}), "text/html").querySelector(".window"); }), "text/html").querySelector(".window");
render_element.append(domElement); render_element.append(domElement);
waitForNodeClick(gadget, domElement); waitForNodeClick(gadget, domElement);
//waitForNodeClick(gadget, domElement, class_definition);
box = $(gadget.props.element).find("#" + dom_element_id); box = $(gadget.props.element).find("#" + dom_element_id);
absolute_position = convertToAbsolutePosition(gadget, coordinate.left, coordinate.top); absolute_position = convertToAbsolutePosition(gadget, coordinate.left, coordinate.top);
box.css("top", absolute_position[1]); box.css("top", absolute_position[1]);
box.css("left", absolute_position[0]); box.css("left", absolute_position[0]);
updateNodeStyle(gadget, dom_element_id, class_definition); updateNodeStyle(gadget, dom_element_id);
draggable(gadget); draggable(gadget);
// XXX make only this element draggable. // XXX make only this element draggable.
// Add some flowchart endpoints // Add some flowchart endpoints
...@@ -799,21 +509,16 @@ ...@@ -799,21 +509,16 @@
uuid: node_id + ".flowChartLeftMiddle" uuid: node_id + ".flowChartLeftMiddle"
}); });
gadget.notifyDataChanged(); gadget.notifyDataChanged();
console.log("addNODE 7");
} }
function waitForDrop(gadget) { function waitForDrop(gadget) {
console.log("wait for DROP 1");
var callback; var callback;
function canceller() { function canceller() {
console.log("wait for DROP canceler1");
if (callback !== undefined) { if (callback !== undefined) {
console.log("wait for DROP canceller2");
gadget.props.main.removeEventListener("drop", callback, false); gadget.props.main.removeEventListener("drop", callback, false);
} }
} }
/*jslint unparam: true*/ /*jslint unparam: true*/
function resolver(resolve, reject) { function resolver(resolve, reject) {
console.log("wait for DROP resolver1");
callback = function(evt) { callback = function(evt) {
try { try {
var class_name = JSON.parse(evt.dataTransfer.getData("application/json")), offset = $(gadget.props.main).offset(), relative_position = convertToRelativePosition(gadget, evt.clientX - offset.left + "px", evt.clientY - offset.top + "px"); var class_name = JSON.parse(evt.dataTransfer.getData("application/json")), offset = $(gadget.props.main).offset(), relative_position = convertToRelativePosition(gadget, evt.clientX - offset.left + "px", evt.clientY - offset.top + "px");
...@@ -827,20 +532,17 @@ ...@@ -827,20 +532,17 @@
_class: class_name _class: class_name
}); });
} catch (e) { } catch (e) {
console.log("wait for DROP resolver100");
reject(e); reject(e);
} }
}; };
gadget.props.main.addEventListener("drop", callback, false); gadget.props.main.addEventListener("drop", callback, false);
} }
console.log("wait for DROP 2");
return new RSVP.all([ // loopEventListener adds an event listener that will prevent default for return new RSVP.all([ // loopEventListener adds an event listener that will prevent default for
// dragover // dragover
loopEventListener(gadget.props.main, "dragover", false, function() { loopEventListener(gadget.props.main, "dragover", false, function() {
return undefined; return undefined;
}), RSVP.Promise(resolver, canceller) ]); }), RSVP.Promise(resolver, canceller) ]);
} }
//initGadgetMixin(gadget_klass);
gadget_klass.ready(function(g) { gadget_klass.ready(function(g) {
g.props = {}; g.props = {};
g.props.node_id_to_dom_element_id = {}; g.props.node_id_to_dom_element_id = {};
...@@ -851,21 +553,11 @@ ...@@ -851,21 +553,11 @@
}); });
}).declareAcquiredMethod("notifyDataChanged", "notifyDataChanged").declareMethod("render", function(data) { }).declareAcquiredMethod("notifyDataChanged", "notifyDataChanged").declareMethod("render", function(data) {
// var gadget = this; // var gadget = this;
console.log("RENDEERING WORKFLOW EDITOR1");
this.props.data = JSON.parse(data); this.props.data = JSON.parse(data);
this.props.jsplumb_instance = jsPlumb.getInstance(); this.props.jsplumb_instance = jsPlumb.getInstance();
console.log("RENDEERING WORKFLOW EDITOR3");
}).declareMethod("getContent", function() { }).declareMethod("getContent", function() {
console.log("£££££££");
console.log("£££££££");
console.log("£££££££");
console.log(this.props.data);
console.log("£££££££");
console.log("£££££££");
console.log("£££££££");
return JSON.stringify(this.props.data); return JSON.stringify(this.props.data);
}).declareMethod("startService", function() { }).declareMethod("startService", function() {
console.log("startservice WORKFLOW EDITOR1");
var gadget = this, jsplumb_instance = gadget.props.jsplumb_instance; var gadget = this, jsplumb_instance = gadget.props.jsplumb_instance;
this.props.main = this.props.element.querySelector("#main"); this.props.main = this.props.element.querySelector("#main");
jsplumb_instance.setRenderMode(jsplumb_instance.SVG); jsplumb_instance.setRenderMode(jsplumb_instance.SVG);
...@@ -885,18 +577,15 @@ ...@@ -885,18 +577,15 @@
} ] ], } ] ],
Container: this.props.main Container: this.props.main
}); });
console.log("startservice WORKFLOW EDITOR2");
draggable(gadget); draggable(gadget);
this.props.nodes_click_monitor = RSVP.Monitor(); this.props.nodes_click_monitor = RSVP.Monitor();
// load the data // load the data
$.each(this.props.data.graph.node, function(key, value) { $.each(this.props.data.graph.node, function(key, value) {
addNode(gadget, key, value); addNode(gadget, key, value);
}); });
console.log("startservice WORKFLOW EDITOR3");
$.each(this.props.data.graph.edge, function(key, value) { $.each(this.props.data.graph.edge, function(key, value) {
addEdge(gadget, key, value); addEdge(gadget, key, value);
}); });
console.log("startservice WORKFLOW EDITOR4");
return RSVP.all([ waitForDrop(gadget), waitForConnection(gadget), waitForConnectionDetached(gadget), waitForConnectionClick(gadget), gadget.props.nodes_click_monitor ]); return RSVP.all([ waitForDrop(gadget), waitForConnection(gadget), waitForConnectionDetached(gadget), waitForConnectionClick(gadget), gadget.props.nodes_click_monitor ]);
}); });
})(RSVP, rJS, $, jsPlumb, Handlebars, loopEventListener, promiseEventListener, DOMParser); })(RSVP, rJS, $, jsPlumb, Handlebars, loopEventListener, promiseEventListener, DOMParser);
\ No newline at end of file
/*! /*!
handlebars v2.0.0 handlebars v2.0.0-alpha.4
Copyright (C) 2011-2014 by Yehuda Katz Copyright (C) 2011-2014 by Yehuda Katz
...@@ -24,5 +24,5 @@ THE SOFTWARE. ...@@ -24,5 +24,5 @@ THE SOFTWARE.
@license @license
*/ */
!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.Handlebars=a.Handlebars||b()}(this,function(){var a=function(){"use strict";function a(a){this.string=a}var b;return a.prototype.toString=function(){return""+this.string},b=a}(),b=function(a){"use strict";function b(a){return i[a]}function c(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])Object.prototype.hasOwnProperty.call(arguments[b],c)&&(a[c]=arguments[b][c]);return a}function d(a){return a instanceof h?a.toString():null==a?"":a?(a=""+a,k.test(a)?a.replace(j,b):a):a+""}function e(a){return a||0===a?n(a)&&0===a.length?!0:!1:!0}function f(a,b){return(a?a+".":"")+b}var g={},h=a,i={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},j=/[&<>"'`]/g,k=/[&<>"'`]/;g.extend=c;var l=Object.prototype.toString;g.toString=l;var m=function(a){return"function"==typeof a};m(/x/)&&(m=function(a){return"function"==typeof a&&"[object Function]"===l.call(a)});var m;g.isFunction=m;var n=Array.isArray||function(a){return a&&"object"==typeof a?"[object Array]"===l.call(a):!1};return g.isArray=n,g.escapeExpression=d,g.isEmpty=e,g.appendContextPath=f,g}(a),c=function(){"use strict";function a(a,b){var d;b&&b.firstLine&&(d=b.firstLine,a+=" - "+d+":"+b.firstColumn);for(var e=Error.prototype.constructor.call(this,a),f=0;f<c.length;f++)this[c[f]]=e[c[f]];d&&(this.lineNumber=d,this.column=b.firstColumn)}var b,c=["description","fileName","lineNumber","message","name","number","stack"];return a.prototype=new Error,b=a}(),d=function(a,b){"use strict";function c(a,b){this.helpers=a||{},this.partials=b||{},d(this)}function d(a){a.registerHelper("helperMissing",function(){if(1===arguments.length)return void 0;throw new g("Missing helper: '"+arguments[arguments.length-1].name+"'")}),a.registerHelper("blockHelperMissing",function(b,c){var d=c.inverse,e=c.fn;if(b===!0)return e(this);if(b===!1||null==b)return d(this);if(k(b))return b.length>0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):d(this);if(c.data&&c.ids){var g=q(c.data);g.contextPath=f.appendContextPath(c.data.contextPath,c.name),c={data:g}}return e(b,c)}),a.registerHelper("each",function(a,b){if(!b)throw new g("Must pass iterator to #each");var c,d,e=b.fn,h=b.inverse,i=0,j="";if(b.data&&b.ids&&(d=f.appendContextPath(b.data.contextPath,b.ids[0])+"."),l(a)&&(a=a.call(this)),b.data&&(c=q(b.data)),a&&"object"==typeof a)if(k(a))for(var m=a.length;m>i;i++)c&&(c.index=i,c.first=0===i,c.last=i===a.length-1,d&&(c.contextPath=d+i)),j+=e(a[i],{data:c});else for(var n in a)a.hasOwnProperty(n)&&(c&&(c.key=n,c.index=i,c.first=0===i,d&&(c.contextPath=d+n)),j+=e(a[n],{data:c}),i++);return 0===i&&(j=h(this)),j}),a.registerHelper("if",function(a,b){return l(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||f.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper("unless",function(b,c){return a.helpers["if"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})}),a.registerHelper("with",function(a,b){l(a)&&(a=a.call(this));var c=b.fn;if(f.isEmpty(a))return b.inverse(this);if(b.data&&b.ids){var d=q(b.data);d.contextPath=f.appendContextPath(b.data.contextPath,b.ids[0]),b={data:d}}return c(a,b)}),a.registerHelper("log",function(b,c){var d=c.data&&null!=c.data.level?parseInt(c.data.level,10):1;a.log(d,b)}),a.registerHelper("lookup",function(a,b){return a&&a[b]})}var e={},f=a,g=b,h="2.0.0";e.VERSION=h;var i=6;e.COMPILER_REVISION=i;var j={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1"};e.REVISION_CHANGES=j;var k=f.isArray,l=f.isFunction,m=f.toString,n="[object Object]";e.HandlebarsEnvironment=c,c.prototype={constructor:c,logger:o,log:p,registerHelper:function(a,b){if(m.call(a)===n){if(b)throw new g("Arg not supported with multiple helpers");f.extend(this.helpers,a)}else this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){m.call(a)===n?f.extend(this.partials,a):this.partials[a]=b},unregisterPartial:function(a){delete this.partials[a]}};var o={methodMap:{0:"debug",1:"info",2:"warn",3:"error"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(a,b){if(o.level<=a){var c=o.methodMap[a];"undefined"!=typeof console&&console[c]&&console[c].call(console,b)}}};e.logger=o;var p=o.log;e.log=p;var q=function(a){var b=f.extend({},a);return b._parent=a,b};return e.createFrame=q,e}(b,c),e=function(a,b,c){"use strict";function d(a){var b=a&&a[0]||1,c=m;if(b!==c){if(c>b){var d=n[c],e=n[b];throw new l("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+d+") or downgrade your runtime to an older version ("+e+").")}throw new l("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+a[1]+").")}}function e(a,b){if(!b)throw new l("No environment passed to template");if(!a||!a.main)throw new l("Unknown template object: "+typeof a);b.VM.checkRevision(a.compiler);var c=function(c,d,e,f,g,h,i,j,m){g&&(f=k.extend({},f,g));var n=b.VM.invokePartial.call(this,c,e,f,h,i,j,m);if(null==n&&b.compile){var o={helpers:h,partials:i,data:j,depths:m};i[e]=b.compile(c,{data:void 0!==j,compat:a.compat},b),n=i[e](f,o)}if(null!=n){if(d){for(var p=n.split("\n"),q=0,r=p.length;r>q&&(p[q]||q+1!==r);q++)p[q]=d+p[q];n=p.join("\n")}return n}throw new l("The partial "+e+" could not be compiled when running in runtime-only mode")},d={lookup:function(a,b){for(var c=a.length,d=0;c>d;d++)if(a[d]&&null!=a[d][b])return a[d][b]},lambda:function(a,b){return"function"==typeof a?a.call(b):a},escapeExpression:k.escapeExpression,invokePartial:c,fn:function(b){return a[b]},programs:[],program:function(a,b,c){var d=this.programs[a],e=this.fn(a);return b||c?d=f(this,a,e,b,c):d||(d=this.programs[a]=f(this,a,e)),d},data:function(a,b){for(;a&&b--;)a=a._parent;return a},merge:function(a,b){var c=a||b;return a&&b&&a!==b&&(c=k.extend({},b,a)),c},noop:b.VM.noop,compilerInfo:a.compiler},e=function(b,c){c=c||{};var f=c.data;e._setup(c),!c.partial&&a.useData&&(f=i(b,f));var g;return a.useDepths&&(g=c.depths?[b].concat(c.depths):[b]),a.main.call(d,b,d.helpers,d.partials,f,g)};return e.isTop=!0,e._setup=function(c){c.partial?(d.helpers=c.helpers,d.partials=c.partials):(d.helpers=d.merge(c.helpers,b.helpers),a.usePartial&&(d.partials=d.merge(c.partials,b.partials)))},e._child=function(b,c,e){if(a.useDepths&&!e)throw new l("must pass parent depths");return f(d,b,a[b],c,e)},e}function f(a,b,c,d,e){var f=function(b,f){return f=f||{},c.call(a,b,a.helpers,a.partials,f.data||d,e&&[b].concat(e))};return f.program=b,f.depth=e?e.length:0,f}function g(a,b,c,d,e,f,g){var h={partial:!0,helpers:d,partials:e,data:f,depths:g};if(void 0===a)throw new l("The partial "+b+" could not be found");return a instanceof Function?a(c,h):void 0}function h(){return""}function i(a,b){return b&&"root"in b||(b=b?o(b):{},b.root=a),b}var j={},k=a,l=b,m=c.COMPILER_REVISION,n=c.REVISION_CHANGES,o=c.createFrame;return j.checkRevision=d,j.template=e,j.program=f,j.invokePartial=g,j.noop=h,j}(b,c,d),f=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c,j=d,k=e,l=function(){var a=new g.HandlebarsEnvironment;return j.extend(a,g),a.SafeString=h,a.Exception=i,a.Utils=j,a.escapeExpression=j.escapeExpression,a.VM=k,a.template=function(b){return k.template(b,a)},a},m=l();return m.create=l,m["default"]=m,f=m}(d,a,c,b,e),g=function(a){"use strict";function b(a){a=a||{},this.firstLine=a.first_line,this.firstColumn=a.first_column,this.lastColumn=a.last_column,this.lastLine=a.last_line}var c,d=a,e={ProgramNode:function(a,c,d){b.call(this,d),this.type="program",this.statements=a,this.strip=c},MustacheNode:function(a,c,d,f,g){if(b.call(this,g),this.type="mustache",this.strip=f,null!=d&&d.charAt){var h=d.charAt(3)||d.charAt(2);this.escaped="{"!==h&&"&"!==h}else this.escaped=!!d;this.sexpr=a instanceof e.SexprNode?a:new e.SexprNode(a,c),this.id=this.sexpr.id,this.params=this.sexpr.params,this.hash=this.sexpr.hash,this.eligibleHelper=this.sexpr.eligibleHelper,this.isHelper=this.sexpr.isHelper},SexprNode:function(a,c,d){b.call(this,d),this.type="sexpr",this.hash=c;var e=this.id=a[0],f=this.params=a.slice(1);this.isHelper=!(!f.length&&!c),this.eligibleHelper=this.isHelper||e.isSimple},PartialNode:function(a,c,d,e,f){b.call(this,f),this.type="partial",this.partialName=a,this.context=c,this.hash=d,this.strip=e,this.strip.inlineStandalone=!0},BlockNode:function(a,c,d,e,f){b.call(this,f),this.type="block",this.mustache=a,this.program=c,this.inverse=d,this.strip=e,d&&!c&&(this.isInverse=!0)},RawBlockNode:function(a,c,f,g){if(b.call(this,g),a.sexpr.id.original!==f)throw new d(a.sexpr.id.original+" doesn't match "+f,this);c=new e.ContentNode(c,g),this.type="block",this.mustache=a,this.program=new e.ProgramNode([c],{},g)},ContentNode:function(a,c){b.call(this,c),this.type="content",this.original=this.string=a},HashNode:function(a,c){b.call(this,c),this.type="hash",this.pairs=a},IdNode:function(a,c){b.call(this,c),this.type="ID";for(var e="",f=[],g=0,h="",i=0,j=a.length;j>i;i++){var k=a[i].part;if(e+=(a[i].separator||"")+k,".."===k||"."===k||"this"===k){if(f.length>0)throw new d("Invalid path: "+e,this);".."===k?(g++,h+="../"):this.isScoped=!0}else f.push(k)}this.original=e,this.parts=f,this.string=f.join("."),this.depth=g,this.idName=h+this.string,this.isSimple=1===a.length&&!this.isScoped&&0===g,this.stringModeValue=this.string},PartialNameNode:function(a,c){b.call(this,c),this.type="PARTIAL_NAME",this.name=a.original},DataNode:function(a,c){b.call(this,c),this.type="DATA",this.id=a,this.stringModeValue=a.stringModeValue,this.idName="@"+a.stringModeValue},StringNode:function(a,c){b.call(this,c),this.type="STRING",this.original=this.string=this.stringModeValue=a},NumberNode:function(a,c){b.call(this,c),this.type="NUMBER",this.original=this.number=a,this.stringModeValue=Number(a)},BooleanNode:function(a,c){b.call(this,c),this.type="BOOLEAN",this.bool=a,this.stringModeValue="true"===a},CommentNode:function(a,c){b.call(this,c),this.type="comment",this.comment=a,this.strip={inlineStandalone:!0}}};return c=e}(c),h=function(){"use strict";var a,b=function(){function a(){this.yy={}}var b={trace:function(){},yy:{},symbols_:{error:2,root:3,program:4,EOF:5,program_repetition0:6,statement:7,mustache:8,block:9,rawBlock:10,partial:11,CONTENT:12,COMMENT:13,openRawBlock:14,END_RAW_BLOCK:15,OPEN_RAW_BLOCK:16,sexpr:17,CLOSE_RAW_BLOCK:18,openBlock:19,block_option0:20,closeBlock:21,openInverse:22,block_option1:23,OPEN_BLOCK:24,CLOSE:25,OPEN_INVERSE:26,inverseAndProgram:27,INVERSE:28,OPEN_ENDBLOCK:29,path:30,OPEN:31,OPEN_UNESCAPED:32,CLOSE_UNESCAPED:33,OPEN_PARTIAL:34,partialName:35,param:36,partial_option0:37,partial_option1:38,sexpr_repetition0:39,sexpr_option0:40,dataName:41,STRING:42,NUMBER:43,BOOLEAN:44,OPEN_SEXPR:45,CLOSE_SEXPR:46,hash:47,hash_repetition_plus0:48,hashSegment:49,ID:50,EQUALS:51,DATA:52,pathSegments:53,SEP:54,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]],performAction:function(a,b,c,d,e,f){var g=f.length-1;switch(e){case 1:return d.prepareProgram(f[g-1].statements,!0),f[g-1];case 2:this.$=new d.ProgramNode(d.prepareProgram(f[g]),{},this._$);break;case 3:this.$=f[g];break;case 4:this.$=f[g];break;case 5:this.$=f[g];break;case 6:this.$=f[g];break;case 7:this.$=new d.ContentNode(f[g],this._$);break;case 8:this.$=new d.CommentNode(f[g],this._$);break;case 9:this.$=new d.RawBlockNode(f[g-2],f[g-1],f[g],this._$);break;case 10:this.$=new d.MustacheNode(f[g-1],null,"","",this._$);break;case 11:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!1,this._$);break;case 12:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!0,this._$);break;case 13:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 14:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 15:this.$={strip:d.stripFlags(f[g-1],f[g-1]),program:f[g]};break;case 16:this.$={path:f[g-1],strip:d.stripFlags(f[g-2],f[g])};break;case 17:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 18:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 19:this.$=new d.PartialNode(f[g-3],f[g-2],f[g-1],d.stripFlags(f[g-4],f[g]),this._$);break;case 20:this.$=new d.PartialNode(f[g-2],void 0,f[g-1],d.stripFlags(f[g-3],f[g]),this._$);break;case 21:this.$=new d.SexprNode([f[g-2]].concat(f[g-1]),f[g],this._$);break;case 22:this.$=new d.SexprNode([f[g]],null,this._$);break;case 23:this.$=f[g];break;case 24:this.$=new d.StringNode(f[g],this._$);break;case 25:this.$=new d.NumberNode(f[g],this._$);break;case 26:this.$=new d.BooleanNode(f[g],this._$);break;case 27:this.$=f[g];break;case 28:f[g-1].isHelper=!0,this.$=f[g-1];break;case 29:this.$=new d.HashNode(f[g],this._$);break;case 30:this.$=[f[g-2],f[g]];break;case 31:this.$=new d.PartialNameNode(f[g],this._$);break;case 32:this.$=new d.PartialNameNode(new d.StringNode(f[g],this._$),this._$);break;case 33:this.$=new d.PartialNameNode(new d.NumberNode(f[g],this._$));break;case 34:this.$=new d.DataNode(f[g],this._$);break;case 35:this.$=new d.IdNode(f[g],this._$);break;case 36:f[g-2].push({part:f[g],separator:f[g-1]}),this.$=f[g-2];break;case 37:this.$=[{part:f[g]}];break;case 38:this.$=[];break;case 39:f[g-1].push(f[g]);break;case 48:this.$=[];break;case 49:f[g-1].push(f[g]);break;case 52:this.$=[f[g]];break;case 53:f[g-1].push(f[g])}},table:[{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}],defaultActions:{4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]},parseError:function(a){throw new Error(a)},parse:function(a){function b(){var a;return a=c.lexer.lex()||1,"number"!=typeof a&&(a=c.symbols_[a]||a),a}var c=this,d=[0],e=[null],f=[],g=this.table,h="",i=0,j=0,k=0;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var l=this.lexer.yylloc;f.push(l);var m=this.lexer.options&&this.lexer.options.ranges;"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var n,o,p,q,r,s,t,u,v,w={};;){if(p=d[d.length-1],this.defaultActions[p]?q=this.defaultActions[p]:((null===n||"undefined"==typeof n)&&(n=b()),q=g[p]&&g[p][n]),"undefined"==typeof q||!q.length||!q[0]){var x="";if(!k){v=[];for(s in g[p])this.terminals_[s]&&s>2&&v.push("'"+this.terminals_[s]+"'");x=this.lexer.showPosition?"Parse error on line "+(i+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[n]||n)+"'":"Parse error on line "+(i+1)+": Unexpected "+(1==n?"end of input":"'"+(this.terminals_[n]||n)+"'"),this.parseError(x,{text:this.lexer.match,token:this.terminals_[n]||n,line:this.lexer.yylineno,loc:l,expected:v})}}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+n);switch(q[0]){case 1:d.push(n),e.push(this.lexer.yytext),f.push(this.lexer.yylloc),d.push(q[1]),n=null,o?(n=o,o=null):(j=this.lexer.yyleng,h=this.lexer.yytext,i=this.lexer.yylineno,l=this.lexer.yylloc,k>0&&k--);break;case 2:if(t=this.productions_[q[1]][1],w.$=e[e.length-t],w._$={first_line:f[f.length-(t||1)].first_line,last_line:f[f.length-1].last_line,first_column:f[f.length-(t||1)].first_column,last_column:f[f.length-1].last_column},m&&(w._$.range=[f[f.length-(t||1)].range[0],f[f.length-1].range[1]]),r=this.performAction.call(w,h,j,i,this.yy,q[1],e,f),"undefined"!=typeof r)return r;t&&(d=d.slice(0,-1*t*2),e=e.slice(0,-1*t),f=f.slice(0,-1*t)),d.push(this.productions_[q[1]][0]),e.push(w.$),f.push(w._$),u=g[d[d.length-2]][d[d.length-1]],d.push(u);break;case 3:return!0}}return!0}},c=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parser)throw new Error(a);this.yy.parser.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var b=a.match(/(?:\r\n?|\n).*/g);return b?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var b=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-b-1),this.offset-=b;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-b},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-b]),this},more:function(){return this._more=!0,this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c,d,e;this._more||(this.yytext="",this.match="");for(var f=this._currentRules(),g=0;g<f.length&&(c=this._input.match(this.rules[f[g]]),!c||b&&!(c[0].length>b[0].length)||(b=c,d=g,this.options.flex));g++);return b?(e=b[0].match(/(?:\r\n?|\n).*/g),e&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,f[d],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a?a:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.options={},a.performAction=function(a,b,c,d){function e(a,c){return b.yytext=b.yytext.substr(a,b.yyleng-c)}switch(c){case 0:if("\\\\"===b.yytext.slice(-2)?(e(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(e(0,1),this.begin("emu")):this.begin("mu"),b.yytext)return 12;break;case 1:return 12;case 2:return this.popState(),12;case 3:return b.yytext=b.yytext.substr(5,b.yyleng-9),this.popState(),15;case 4:return 12;case 5:return e(0,4),this.popState(),13;case 6:return 45;case 7:return 46;case 8:return 16;case 9:return this.popState(),this.begin("raw"),18;case 10:return 34;case 11:return 24;case 12:return 29;case 13:return this.popState(),28;case 14:return this.popState(),28;case 15:return 26;case 16:return 26;case 17:return 32;case 18:return 31;case 19:this.popState(),this.begin("com");break;case 20:return e(3,5),this.popState(),13;case 21:return 31;case 22:return 51;case 23:return 50;case 24:return 50;case 25:return 54;case 26:break;case 27:return this.popState(),33;case 28:return this.popState(),25;case 29:return b.yytext=e(1,2).replace(/\\"/g,'"'),42;case 30:return b.yytext=e(1,2).replace(/\\'/g,"'"),42;case 31:return 52;case 32:return 44;case 33:return 44;case 34:return 43;case 35:return 50;case 36:return b.yytext=e(1,2),50;case 37:return"INVALID";case 38:return 5}},a.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/],a.conditions={mu:{rules:[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[5],inclusive:!1},raw:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,1,38],inclusive:!0}},a}();return b.lexer=c,a.prototype=b,b.Parser=a,new a}();return a=b}(),i=function(a){"use strict";function b(a,b){return{left:"~"===a.charAt(2),right:"~"===b.charAt(b.length-3)}}function c(a,b,c,d,i,k){if(a.sexpr.id.original!==d.path.original)throw new j(a.sexpr.id.original+" doesn't match "+d.path.original,a);var l=c&&c.program,m={left:a.strip.left,right:d.strip.right,openStandalone:f(b.statements),closeStandalone:e((l||b).statements)};if(a.strip.right&&g(b.statements,null,!0),l){var n=c.strip;n.left&&h(b.statements,null,!0),n.right&&g(l.statements,null,!0),d.strip.left&&h(l.statements,null,!0),e(b.statements)&&f(l.statements)&&(h(b.statements),g(l.statements))}else d.strip.left&&h(b.statements,null,!0);return i?new this.BlockNode(a,l,b,m,k):new this.BlockNode(a,b,l,m,k)}function d(a,b){for(var c=0,d=a.length;d>c;c++){var i=a[c],j=i.strip;if(j){var k=e(a,c,b,"partial"===i.type),l=f(a,c,b),m=j.openStandalone&&k,n=j.closeStandalone&&l,o=j.inlineStandalone&&k&&l;j.right&&g(a,c,!0),j.left&&h(a,c,!0),o&&(g(a,c),h(a,c)&&"partial"===i.type&&(i.indent=/([ \t]+$)/.exec(a[c-1].original)?RegExp.$1:"")),m&&(g((i.program||i.inverse).statements),h(a,c)),n&&(g(a,c),h((i.inverse||i.program).statements))}}return a}function e(a,b,c){void 0===b&&(b=a.length);var d=a[b-1],e=a[b-2];return d?"content"===d.type?(e||!c?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(d.original):void 0:c}function f(a,b,c){void 0===b&&(b=-1);var d=a[b+1],e=a[b+2];return d?"content"===d.type?(e||!c?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(d.original):void 0:c}function g(a,b,c){var d=a[null==b?0:b+1];if(d&&"content"===d.type&&(c||!d.rightStripped)){var e=d.string;d.string=d.string.replace(c?/^\s+/:/^[ \t]*\r?\n?/,""),d.rightStripped=d.string!==e}}function h(a,b,c){var d=a[null==b?a.length-1:b-1];if(d&&"content"===d.type&&(c||!d.leftStripped)){var e=d.string;return d.string=d.string.replace(c?/\s+$/:/[ \t]+$/,""),d.leftStripped=d.string!==e,d.leftStripped}}var i={},j=a;return i.stripFlags=b,i.prepareBlock=c,i.prepareProgram=d,i}(c),j=function(a,b,c,d){"use strict";function e(a){return a.constructor===h.ProgramNode?a:(g.yy=k,g.parse(a))}var f={},g=a,h=b,i=c,j=d.extend;f.parser=g;var k={};return j(k,i,h),f.parse=e,f}(h,g,i,b),k=function(a,b){"use strict";function c(){}function d(a,b,c){if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new h("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var d=c.parse(a),e=(new c.Compiler).compile(d,b);return(new c.JavaScriptCompiler).compile(e,b)}function e(a,b,c){function d(){var d=c.parse(a),e=(new c.Compiler).compile(d,b),f=(new c.JavaScriptCompiler).compile(e,b,void 0,!0);return c.template(f)}if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new h("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var e,f=function(a,b){return e||(e=d()),e.call(this,a,b)};return f._setup=function(a){return e||(e=d()),e._setup(a)},f._child=function(a,b,c){return e||(e=d()),e._child(a,b,c)},f}function f(a,b){if(a===b)return!0;if(i(a)&&i(b)&&a.length===b.length){for(var c=0;c<a.length;c++)if(!f(a[c],b[c]))return!1;return!0}}var g={},h=a,i=b.isArray,j=[].slice;return g.Compiler=c,c.prototype={compiler:c,equals:function(a){var b=this.opcodes.length;if(a.opcodes.length!==b)return!1;for(var c=0;b>c;c++){var d=this.opcodes[c],e=a.opcodes[c];if(d.opcode!==e.opcode||!f(d.args,e.args))return!1}for(b=this.children.length,c=0;b>c;c++)if(!this.children[c].equals(a.children[c]))return!1;return!0},guid:0,compile:function(a,b){this.opcodes=[],this.children=[],this.depths={list:[]},this.options=b,this.stringParams=b.stringParams,this.trackIds=b.trackIds;var c=this.options.knownHelpers;if(this.options.knownHelpers={helperMissing:!0,blockHelperMissing:!0,each:!0,"if":!0,unless:!0,"with":!0,log:!0,lookup:!0},c)for(var d in c)this.options.knownHelpers[d]=c[d];return this.accept(a)},accept:function(a){return this[a.type](a)},program:function(a){for(var b=a.statements,c=0,d=b.length;d>c;c++)this.accept(b[c]);return this.isSimple=1===d,this.depths.list=this.depths.list.sort(function(a,b){return a-b}),this},compileProgram:function(a){var b,c=(new this.compiler).compile(a,this.options),d=this.guid++; this.Handlebars=function(){var a=function(){"use strict";function a(a){this.string=a}var b;return a.prototype.toString=function(){return""+this.string},b=a}(),b=function(a){"use strict";function b(a){return i[a]||"&amp;"}function c(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])Object.prototype.hasOwnProperty.call(arguments[b],c)&&(a[c]=arguments[b][c]);return a}function d(a){return a instanceof h?a.toString():a||0===a?(a=""+a,k.test(a)?a.replace(j,b):a):""}function e(a){return a||0===a?n(a)&&0===a.length?!0:!1:!0}function f(a,b){return(a?a+".":"")+b}var g={},h=a,i={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},j=/[&<>"'`]/g,k=/[&<>"'`]/;g.extend=c;var l=Object.prototype.toString;g.toString=l;var m=function(a){return"function"==typeof a};m(/x/)&&(m=function(a){return"function"==typeof a&&"[object Function]"===l.call(a)});var m;g.isFunction=m;var n=Array.isArray||function(a){return a&&"object"==typeof a?"[object Array]"===l.call(a):!1};return g.isArray=n,g.escapeExpression=d,g.isEmpty=e,g.appendContextPath=f,g}(a),c=function(){"use strict";function a(a,b){var d;b&&b.firstLine&&(d=b.firstLine,a+=" - "+d+":"+b.firstColumn);for(var e=Error.prototype.constructor.call(this,a),f=0;f<c.length;f++)this[c[f]]=e[c[f]];d&&(this.lineNumber=d,this.column=b.firstColumn)}var b,c=["description","fileName","lineNumber","message","name","number","stack"];return a.prototype=new Error,b=a}(),d=function(a,b){"use strict";function c(a,b){this.helpers=a||{},this.partials=b||{},d(this)}function d(a){a.registerHelper("helperMissing",function(){if(1===arguments.length)return void 0;throw new h("Missing helper: '"+arguments[arguments.length-1].name+"'")}),a.registerHelper("blockHelperMissing",function(b,c){var d=c.inverse||function(){},e=c.fn;if(m(b)&&(b=b.call(this)),b===!0)return e(this);if(b===!1||null==b)return d(this);if(l(b))return b.length>0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):d(this);if(c.data&&c.ids){var f=q(c.data);f.contextPath=g.appendContextPath(c.data.contextPath,c.name),c={data:f}}return e(b,c)}),a.registerHelper("each",function(a,b){b||(b=a,a=this);var c,d,e=b.fn,f=b.inverse,h=0,i="";if(b.data&&b.ids&&(d=g.appendContextPath(b.data.contextPath,b.ids[0])+"."),m(a)&&(a=a.call(this)),b.data&&(c=q(b.data)),a&&"object"==typeof a)if(l(a))for(var j=a.length;j>h;h++)c&&(c.index=h,c.first=0===h,c.last=h===a.length-1,d&&(c.contextPath=d+h)),i+=e(a[h],{data:c});else for(var k in a)a.hasOwnProperty(k)&&(c&&(c.key=k,c.index=h,c.first=0===h,d&&(c.contextPath=d+k)),i+=e(a[k],{data:c}),h++);return 0===h&&(i=f(this)),i}),a.registerHelper("if",function(a,b){return m(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||g.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper("unless",function(b,c){return a.helpers["if"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})}),a.registerHelper("with",function(a,b){m(a)&&(a=a.call(this));var c=b.fn;if(!g.isEmpty(a)){if(b.data&&b.ids){var d=q(b.data);d.contextPath=g.appendContextPath(b.data.contextPath,b.ids[0]),b={data:d}}return c(a,b)}}),a.registerHelper("log",function(b,c){var d=c.data&&null!=c.data.level?parseInt(c.data.level,10):1;a.log(d,b)}),a.registerHelper("lookup",function(a,b){return a&&a[b]})}function e(a,b){p.log(a,b)}var f={},g=a,h=b,i="2.0.0-alpha.4";f.VERSION=i;var j=5;f.COMPILER_REVISION=j;var k={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:">= 2.0.0"};f.REVISION_CHANGES=k;var l=g.isArray,m=g.isFunction,n=g.toString,o="[object Object]";f.HandlebarsEnvironment=c,c.prototype={constructor:c,logger:p,log:e,registerHelper:function(a,b,c){if(n.call(a)===o){if(c||b)throw new h("Arg not supported with multiple helpers");g.extend(this.helpers,a)}else c&&(b.not=c),this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){n.call(a)===o?g.extend(this.partials,a):this.partials[a]=b},unregisterPartial:function(a){delete this.partials[a]}};var p={methodMap:{0:"debug",1:"info",2:"warn",3:"error"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(a,b){if(p.level<=a){var c=p.methodMap[a];"undefined"!=typeof console&&console[c]&&console[c].call(console,b)}}};f.logger=p,f.log=e;var q=function(a){var b=g.extend({},a);return b._parent=a,b};return f.createFrame=q,f}(b,c),e=function(a,b,c){"use strict";function d(a){var b=a&&a[0]||1,c=n;if(b!==c){if(c>b){var d=o[c],e=o[b];throw new m("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+d+") or downgrade your runtime to an older version ("+e+").")}throw new m("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+a[1]+").")}}function e(a,b){if(!b)throw new m("No environment passed to template");b.VM.checkRevision(a.compiler);var c=function(a,c,d,e,f,g,h){e&&(d=l.extend({},d,e));var i=b.VM.invokePartial.call(this,a,c,d,f,g,h);if(null!=i)return i;if(b.compile){var j={helpers:f,partials:g,data:h};return g[c]=b.compile(a,{data:void 0!==h},b),g[c](d,j)}throw new m("The partial "+c+" could not be compiled when running in runtime-only mode")},d={escapeExpression:l.escapeExpression,invokePartial:c,fn:function(b){return a[b]},programs:[],program:function(a,b){var c=this.programs[a],d=this.fn(a);return b?c=g(this,a,d,b):c||(c=this.programs[a]=g(this,a,d)),c},programWithDepth:b.VM.programWithDepth,data:function(a,b){for(;a&&b--;)a=a._parent;return a},merge:function(a,b){var c=a||b;return a&&b&&a!==b&&(c=l.extend({},b,a)),c},noop:b.VM.noop,compilerInfo:a.compiler},e=function(b,c){c=c||{};var f=c.data;return e._setup(c),!c.partial&&a.useData&&(f=j(b,f)),a.main.call(d,b,d.helpers,d.partials,f)};return e._setup=function(c){c.partial?(d.helpers=c.helpers,d.partials=c.partials):(d.helpers=d.merge(c.helpers,b.helpers),a.usePartial&&(d.partials=d.merge(c.partials,b.partials)))},e._child=function(a){return d.programWithDepth(a)},e}function f(a,b){var c=Array.prototype.slice.call(arguments,2),d=this,e=d.fn(a),f=function(a,f){return f=f||{},e.apply(d,[a,d.helpers,d.partials,f.data||b].concat(c))};return f.program=a,f.depth=c.length,f}function g(a,b,c,d){var e=function(b,e){return e=e||{},c.call(a,b,a.helpers,a.partials,e.data||d)};return e.program=b,e.depth=0,e}function h(a,b,c,d,e,f){var g={partial:!0,helpers:d,partials:e,data:f};if(void 0===a)throw new m("The partial "+b+" could not be found");return a instanceof Function?a(c,g):void 0}function i(){return""}function j(a,b){return b&&"root"in b||(b=b?p(b):{},b.root=a),b}var k={},l=a,m=b,n=c.COMPILER_REVISION,o=c.REVISION_CHANGES,p=c.createFrame;return k.checkRevision=d,k.template=e,k.programWithDepth=f,k.program=g,k.invokePartial=h,k.noop=i,k}(b,c,d),f=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c,j=d,k=e,l=function(){var a=new g.HandlebarsEnvironment;return j.extend(a,g),a.SafeString=h,a.Exception=i,a.Utils=j,a.VM=k,a.template=function(b){return k.template(b,a)},a},m=l();return m.create=l,f=m}(d,a,c,b,e),g=function(a){"use strict";function b(a){a=a||{},this.firstLine=a.first_line,this.firstColumn=a.first_column,this.lastColumn=a.last_column,this.lastLine=a.last_line}var c,d=a,e={ProgramNode:function(a,c,d,f){var g,h;3===arguments.length?(f=d,d=null):2===arguments.length&&(f=c,c=null),b.call(this,f),this.type="program",this.statements=a,this.strip={},d?(h=d[0],h?(g={first_line:h.firstLine,last_line:h.lastLine,last_column:h.lastColumn,first_column:h.firstColumn},this.inverse=new e.ProgramNode(d,c,g)):this.inverse=new e.ProgramNode(d,c),this.strip.right=c.left):c&&(this.strip.left=c.right)},MustacheNode:function(a,c,d,f,g){if(b.call(this,g),this.type="mustache",this.strip=f,null!=d&&d.charAt){var h=d.charAt(3)||d.charAt(2);this.escaped="{"!==h&&"&"!==h}else this.escaped=!!d;this.sexpr=a instanceof e.SexprNode?a:new e.SexprNode(a,c),this.sexpr.isRoot=!0,this.id=this.sexpr.id,this.params=this.sexpr.params,this.hash=this.sexpr.hash,this.eligibleHelper=this.sexpr.eligibleHelper,this.isHelper=this.sexpr.isHelper},SexprNode:function(a,c,d){b.call(this,d),this.type="sexpr",this.hash=c;var e=this.id=a[0],f=this.params=a.slice(1);this.isHelper=!(!f.length&&!c),this.eligibleHelper=this.isHelper||e.isSimple},PartialNode:function(a,c,d,e,f){b.call(this,f),this.type="partial",this.partialName=a,this.context=c,this.hash=d,this.strip=e},BlockNode:function(a,c,e,f,g){if(b.call(this,g),a.sexpr.id.original!==f.path.original)throw new d(a.sexpr.id.original+" doesn't match "+f.path.original,this);this.type="block",this.mustache=a,this.program=c,this.inverse=e,this.strip={left:a.strip.left,right:f.strip.right},(c||e).strip.left=a.strip.right,(e||c).strip.right=f.strip.left,e&&!c&&(this.isInverse=!0)},RawBlockNode:function(a,c,f,g){if(b.call(this,g),a.sexpr.id.original!==f)throw new d(a.sexpr.id.original+" doesn't match "+f,this);c=new e.ContentNode(c,g),this.type="block",this.mustache=a,this.program=new e.ProgramNode([c],g)},ContentNode:function(a,c){b.call(this,c),this.type="content",this.string=a},HashNode:function(a,c){b.call(this,c),this.type="hash",this.pairs=a},IdNode:function(a,c){b.call(this,c),this.type="ID";for(var e="",f=[],g=0,h="",i=0,j=a.length;j>i;i++){var k=a[i].part;if(e+=(a[i].separator||"")+k,".."===k||"."===k||"this"===k){if(f.length>0)throw new d("Invalid path: "+e,this);".."===k?(g++,h+="../"):this.isScoped=!0}else f.push(k)}this.original=e,this.parts=f,this.string=f.join("."),this.depth=g,this.idName=h+this.string,this.isSimple=1===a.length&&!this.isScoped&&0===g,this.stringModeValue=this.string},PartialNameNode:function(a,c){b.call(this,c),this.type="PARTIAL_NAME",this.name=a.original},DataNode:function(a,c){b.call(this,c),this.type="DATA",this.id=a,this.stringModeValue=a.stringModeValue,this.idName="@"+a.stringModeValue},StringNode:function(a,c){b.call(this,c),this.type="STRING",this.original=this.string=this.stringModeValue=a},NumberNode:function(a,c){b.call(this,c),this.type="NUMBER",this.original=this.number=a,this.stringModeValue=Number(a)},BooleanNode:function(a,c){b.call(this,c),this.type="BOOLEAN",this.bool=a,this.stringModeValue="true"===a},CommentNode:function(a,c){b.call(this,c),this.type="comment",this.comment=a}};return c=e}(c),h=function(){"use strict";var a,b=function(){function a(a,b){return{left:"~"===a.charAt(2),right:"~"===b.charAt(0)||"~"===b.charAt(1)}}function b(){this.yy={}}var c={trace:function(){},yy:{},symbols_:{error:2,root:3,statements:4,EOF:5,program:6,simpleInverse:7,statement:8,openRawBlock:9,CONTENT:10,END_RAW_BLOCK:11,openInverse:12,closeBlock:13,openBlock:14,mustache:15,partial:16,COMMENT:17,OPEN_RAW_BLOCK:18,sexpr:19,CLOSE_RAW_BLOCK:20,OPEN_BLOCK:21,CLOSE:22,OPEN_INVERSE:23,OPEN_ENDBLOCK:24,path:25,OPEN:26,OPEN_UNESCAPED:27,CLOSE_UNESCAPED:28,OPEN_PARTIAL:29,partialName:30,param:31,partial_option0:32,partial_option1:33,sexpr_repetition0:34,sexpr_option0:35,dataName:36,STRING:37,NUMBER:38,BOOLEAN:39,OPEN_SEXPR:40,CLOSE_SEXPR:41,hash:42,hash_repetition_plus0:43,hashSegment:44,ID:45,EQUALS:46,DATA:47,pathSegments:48,SEP:49,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",10:"CONTENT",11:"END_RAW_BLOCK",17:"COMMENT",18:"OPEN_RAW_BLOCK",20:"CLOSE_RAW_BLOCK",21:"OPEN_BLOCK",22:"CLOSE",23:"OPEN_INVERSE",24:"OPEN_ENDBLOCK",26:"OPEN",27:"OPEN_UNESCAPED",28:"CLOSE_UNESCAPED",29:"OPEN_PARTIAL",37:"STRING",38:"NUMBER",39:"BOOLEAN",40:"OPEN_SEXPR",41:"CLOSE_SEXPR",45:"ID",46:"EQUALS",47:"DATA",49:"SEP"},productions_:[0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[9,3],[14,3],[12,3],[13,3],[15,3],[15,3],[16,5],[16,4],[7,2],[19,3],[19,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[42,1],[44,3],[30,1],[30,1],[30,1],[36,2],[25,1],[48,3],[48,1],[32,0],[32,1],[33,0],[33,1],[34,0],[34,2],[35,0],[35,1],[43,1],[43,2]],performAction:function(b,c,d,e,f,g){var h=g.length-1;switch(f){case 1:return new e.ProgramNode(g[h-1],this._$);case 2:return new e.ProgramNode([],this._$);case 3:this.$=new e.ProgramNode([],g[h-1],g[h],this._$);break;case 4:this.$=new e.ProgramNode(g[h-2],g[h-1],g[h],this._$);break;case 5:this.$=new e.ProgramNode(g[h-1],g[h],[],this._$);break;case 6:this.$=new e.ProgramNode(g[h],this._$);break;case 7:this.$=new e.ProgramNode([],this._$);break;case 8:this.$=new e.ProgramNode([],this._$);break;case 9:this.$=[g[h]];break;case 10:g[h-1].push(g[h]),this.$=g[h-1];break;case 11:this.$=new e.RawBlockNode(g[h-2],g[h-1],g[h],this._$);break;case 12:this.$=new e.BlockNode(g[h-2],g[h-1].inverse,g[h-1],g[h],this._$);break;case 13:this.$=new e.BlockNode(g[h-2],g[h-1],g[h-1].inverse,g[h],this._$);break;case 14:this.$=g[h];break;case 15:this.$=g[h];break;case 16:this.$=new e.ContentNode(g[h],this._$);break;case 17:this.$=new e.CommentNode(g[h],this._$);break;case 18:this.$=new e.MustacheNode(g[h-1],null,"","",this._$);break;case 19:this.$=new e.MustacheNode(g[h-1],null,g[h-2],a(g[h-2],g[h]),this._$);break;case 20:this.$=new e.MustacheNode(g[h-1],null,g[h-2],a(g[h-2],g[h]),this._$);break;case 21:this.$={path:g[h-1],strip:a(g[h-2],g[h])};break;case 22:this.$=new e.MustacheNode(g[h-1],null,g[h-2],a(g[h-2],g[h]),this._$);break;case 23:this.$=new e.MustacheNode(g[h-1],null,g[h-2],a(g[h-2],g[h]),this._$);break;case 24:this.$=new e.PartialNode(g[h-3],g[h-2],g[h-1],a(g[h-4],g[h]),this._$);break;case 25:this.$=new e.PartialNode(g[h-2],void 0,g[h-1],a(g[h-3],g[h]),this._$);break;case 26:this.$=a(g[h-1],g[h]);break;case 27:this.$=new e.SexprNode([g[h-2]].concat(g[h-1]),g[h],this._$);break;case 28:this.$=new e.SexprNode([g[h]],null,this._$);break;case 29:this.$=g[h];break;case 30:this.$=new e.StringNode(g[h],this._$);break;case 31:this.$=new e.NumberNode(g[h],this._$);break;case 32:this.$=new e.BooleanNode(g[h],this._$);break;case 33:this.$=g[h];break;case 34:g[h-1].isHelper=!0,this.$=g[h-1];break;case 35:this.$=new e.HashNode(g[h],this._$);break;case 36:this.$=[g[h-2],g[h]];break;case 37:this.$=new e.PartialNameNode(g[h],this._$);break;case 38:this.$=new e.PartialNameNode(new e.StringNode(g[h],this._$),this._$);break;case 39:this.$=new e.PartialNameNode(new e.NumberNode(g[h],this._$));break;case 40:this.$=new e.DataNode(g[h],this._$);break;case 41:this.$=new e.IdNode(g[h],this._$);break;case 42:g[h-2].push({part:g[h],separator:g[h-1]}),this.$=g[h-2];break;case 43:this.$=[{part:g[h]}];break;case 48:this.$=[];break;case 49:g[h-1].push(g[h]);break;case 52:this.$=[g[h]];break;case 53:g[h-1].push(g[h])}},table:[{3:1,4:2,5:[1,3],8:4,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,13],26:[1,15],27:[1,16],29:[1,17]},{1:[3]},{5:[1,18],8:19,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,13],26:[1,15],27:[1,16],29:[1,17]},{1:[2,2]},{5:[2,9],10:[2,9],17:[2,9],18:[2,9],21:[2,9],23:[2,9],24:[2,9],26:[2,9],27:[2,9],29:[2,9]},{10:[1,20]},{4:23,6:21,7:22,8:4,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,24],24:[2,8],26:[1,15],27:[1,16],29:[1,17]},{4:23,6:25,7:22,8:4,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,24],24:[2,8],26:[1,15],27:[1,16],29:[1,17]},{5:[2,14],10:[2,14],17:[2,14],18:[2,14],21:[2,14],23:[2,14],24:[2,14],26:[2,14],27:[2,14],29:[2,14]},{5:[2,15],10:[2,15],17:[2,15],18:[2,15],21:[2,15],23:[2,15],24:[2,15],26:[2,15],27:[2,15],29:[2,15]},{5:[2,16],10:[2,16],17:[2,16],18:[2,16],21:[2,16],23:[2,16],24:[2,16],26:[2,16],27:[2,16],29:[2,16]},{5:[2,17],10:[2,17],17:[2,17],18:[2,17],21:[2,17],23:[2,17],24:[2,17],26:[2,17],27:[2,17],29:[2,17]},{19:26,25:27,36:28,45:[1,31],47:[1,30],48:29},{19:32,25:27,36:28,45:[1,31],47:[1,30],48:29},{19:33,25:27,36:28,45:[1,31],47:[1,30],48:29},{19:34,25:27,36:28,45:[1,31],47:[1,30],48:29},{19:35,25:27,36:28,45:[1,31],47:[1,30],48:29},{25:37,30:36,37:[1,38],38:[1,39],45:[1,31],48:29},{1:[2,1]},{5:[2,10],10:[2,10],17:[2,10],18:[2,10],21:[2,10],23:[2,10],24:[2,10],26:[2,10],27:[2,10],29:[2,10]},{11:[1,40]},{13:41,24:[1,42]},{4:43,8:4,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,13],24:[2,7],26:[1,15],27:[1,16],29:[1,17]},{7:44,8:19,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,24],24:[2,6],26:[1,15],27:[1,16],29:[1,17]},{19:32,22:[1,45],25:27,36:28,45:[1,31],47:[1,30],48:29},{13:46,24:[1,42]},{20:[1,47]},{20:[2,48],22:[2,48],28:[2,48],34:48,37:[2,48],38:[2,48],39:[2,48],40:[2,48],41:[2,48],45:[2,48],47:[2,48]},{20:[2,28],22:[2,28],28:[2,28],41:[2,28]},{20:[2,41],22:[2,41],28:[2,41],37:[2,41],38:[2,41],39:[2,41],40:[2,41],41:[2,41],45:[2,41],47:[2,41],49:[1,49]},{25:50,45:[1,31],48:29},{20:[2,43],22:[2,43],28:[2,43],37:[2,43],38:[2,43],39:[2,43],40:[2,43],41:[2,43],45:[2,43],47:[2,43],49:[2,43]},{22:[1,51]},{22:[1,52]},{22:[1,53]},{28:[1,54]},{22:[2,46],25:57,31:55,33:56,36:61,37:[1,58],38:[1,59],39:[1,60],40:[1,62],42:63,43:64,44:66,45:[1,65],47:[1,30],48:29},{22:[2,37],37:[2,37],38:[2,37],39:[2,37],40:[2,37],45:[2,37],47:[2,37]},{22:[2,38],37:[2,38],38:[2,38],39:[2,38],40:[2,38],45:[2,38],47:[2,38]},{22:[2,39],37:[2,39],38:[2,39],39:[2,39],40:[2,39],45:[2,39],47:[2,39]},{5:[2,11],10:[2,11],17:[2,11],18:[2,11],21:[2,11],23:[2,11],24:[2,11],26:[2,11],27:[2,11],29:[2,11]},{5:[2,12],10:[2,12],17:[2,12],18:[2,12],21:[2,12],23:[2,12],24:[2,12],26:[2,12],27:[2,12],29:[2,12]},{25:67,45:[1,31],48:29},{8:19,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,13],24:[2,3],26:[1,15],27:[1,16],29:[1,17]},{4:68,8:4,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,13],24:[2,5],26:[1,15],27:[1,16],29:[1,17]},{10:[2,26],17:[2,26],18:[2,26],21:[2,26],23:[2,26],24:[2,26],26:[2,26],27:[2,26],29:[2,26]},{5:[2,13],10:[2,13],17:[2,13],18:[2,13],21:[2,13],23:[2,13],24:[2,13],26:[2,13],27:[2,13],29:[2,13]},{10:[2,18]},{20:[2,50],22:[2,50],25:57,28:[2,50],31:70,35:69,36:61,37:[1,58],38:[1,59],39:[1,60],40:[1,62],41:[2,50],42:71,43:64,44:66,45:[1,65],47:[1,30],48:29},{45:[1,72]},{20:[2,40],22:[2,40],28:[2,40],37:[2,40],38:[2,40],39:[2,40],40:[2,40],41:[2,40],45:[2,40],47:[2,40]},{10:[2,20],17:[2,20],18:[2,20],21:[2,20],23:[2,20],24:[2,20],26:[2,20],27:[2,20],29:[2,20]},{10:[2,19],17:[2,19],18:[2,19],21:[2,19],23:[2,19],24:[2,19],26:[2,19],27:[2,19],29:[2,19]},{5:[2,22],10:[2,22],17:[2,22],18:[2,22],21:[2,22],23:[2,22],24:[2,22],26:[2,22],27:[2,22],29:[2,22]},{5:[2,23],10:[2,23],17:[2,23],18:[2,23],21:[2,23],23:[2,23],24:[2,23],26:[2,23],27:[2,23],29:[2,23]},{22:[2,44],32:73,42:74,43:64,44:66,45:[1,75]},{22:[1,76]},{20:[2,29],22:[2,29],28:[2,29],37:[2,29],38:[2,29],39:[2,29],40:[2,29],41:[2,29],45:[2,29],47:[2,29]},{20:[2,30],22:[2,30],28:[2,30],37:[2,30],38:[2,30],39:[2,30],40:[2,30],41:[2,30],45:[2,30],47:[2,30]},{20:[2,31],22:[2,31],28:[2,31],37:[2,31],38:[2,31],39:[2,31],40:[2,31],41:[2,31],45:[2,31],47:[2,31]},{20:[2,32],22:[2,32],28:[2,32],37:[2,32],38:[2,32],39:[2,32],40:[2,32],41:[2,32],45:[2,32],47:[2,32]},{20:[2,33],22:[2,33],28:[2,33],37:[2,33],38:[2,33],39:[2,33],40:[2,33],41:[2,33],45:[2,33],47:[2,33]},{19:77,25:27,36:28,45:[1,31],47:[1,30],48:29},{22:[2,47]},{20:[2,35],22:[2,35],28:[2,35],41:[2,35],44:78,45:[1,75]},{20:[2,43],22:[2,43],28:[2,43],37:[2,43],38:[2,43],39:[2,43],40:[2,43],41:[2,43],45:[2,43],46:[1,79],47:[2,43],49:[2,43]},{20:[2,52],22:[2,52],28:[2,52],41:[2,52],45:[2,52]},{22:[1,80]},{8:19,9:5,10:[1,10],12:6,14:7,15:8,16:9,17:[1,11],18:[1,12],21:[1,14],23:[1,13],24:[2,4],26:[1,15],27:[1,16],29:[1,17]},{20:[2,27],22:[2,27],28:[2,27],41:[2,27]},{20:[2,49],22:[2,49],28:[2,49],37:[2,49],38:[2,49],39:[2,49],40:[2,49],41:[2,49],45:[2,49],47:[2,49]},{20:[2,51],22:[2,51],28:[2,51],41:[2,51]},{20:[2,42],22:[2,42],28:[2,42],37:[2,42],38:[2,42],39:[2,42],40:[2,42],41:[2,42],45:[2,42],47:[2,42],49:[2,42]},{22:[1,81]},{22:[2,45]},{46:[1,79]},{5:[2,25],10:[2,25],17:[2,25],18:[2,25],21:[2,25],23:[2,25],24:[2,25],26:[2,25],27:[2,25],29:[2,25]},{41:[1,82]},{20:[2,53],22:[2,53],28:[2,53],41:[2,53],45:[2,53]},{25:57,31:83,36:61,37:[1,58],38:[1,59],39:[1,60],40:[1,62],45:[1,31],47:[1,30],48:29},{5:[2,21],10:[2,21],17:[2,21],18:[2,21],21:[2,21],23:[2,21],24:[2,21],26:[2,21],27:[2,21],29:[2,21]},{5:[2,24],10:[2,24],17:[2,24],18:[2,24],21:[2,24],23:[2,24],24:[2,24],26:[2,24],27:[2,24],29:[2,24]},{20:[2,34],22:[2,34],28:[2,34],37:[2,34],38:[2,34],39:[2,34],40:[2,34],41:[2,34],45:[2,34],47:[2,34]},{20:[2,36],22:[2,36],28:[2,36],41:[2,36],45:[2,36]}],defaultActions:{3:[2,2],18:[2,1],47:[2,18],63:[2,47],74:[2,45]},parseError:function(a){throw new Error(a)},parse:function(a){function b(){var a;return a=c.lexer.lex()||1,"number"!=typeof a&&(a=c.symbols_[a]||a),a}var c=this,d=[0],e=[null],f=[],g=this.table,h="",i=0,j=0,k=0;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var l=this.lexer.yylloc;f.push(l);var m=this.lexer.options&&this.lexer.options.ranges;"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var n,o,p,q,r,s,t,u,v,w={};;){if(p=d[d.length-1],this.defaultActions[p]?q=this.defaultActions[p]:((null===n||"undefined"==typeof n)&&(n=b()),q=g[p]&&g[p][n]),"undefined"==typeof q||!q.length||!q[0]){var x="";if(!k){v=[];for(s in g[p])this.terminals_[s]&&s>2&&v.push("'"+this.terminals_[s]+"'");x=this.lexer.showPosition?"Parse error on line "+(i+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[n]||n)+"'":"Parse error on line "+(i+1)+": Unexpected "+(1==n?"end of input":"'"+(this.terminals_[n]||n)+"'"),this.parseError(x,{text:this.lexer.match,token:this.terminals_[n]||n,line:this.lexer.yylineno,loc:l,expected:v})}}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+n);switch(q[0]){case 1:d.push(n),e.push(this.lexer.yytext),f.push(this.lexer.yylloc),d.push(q[1]),n=null,o?(n=o,o=null):(j=this.lexer.yyleng,h=this.lexer.yytext,i=this.lexer.yylineno,l=this.lexer.yylloc,k>0&&k--);break;case 2:if(t=this.productions_[q[1]][1],w.$=e[e.length-t],w._$={first_line:f[f.length-(t||1)].first_line,last_line:f[f.length-1].last_line,first_column:f[f.length-(t||1)].first_column,last_column:f[f.length-1].last_column},m&&(w._$.range=[f[f.length-(t||1)].range[0],f[f.length-1].range[1]]),r=this.performAction.call(w,h,j,i,this.yy,q[1],e,f),"undefined"!=typeof r)return r;t&&(d=d.slice(0,-1*t*2),e=e.slice(0,-1*t),f=f.slice(0,-1*t)),d.push(this.productions_[q[1]][0]),e.push(w.$),f.push(w._$),u=g[d[d.length-2]][d[d.length-1]],d.push(u);break;case 3:return!0}}return!0}},d=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parser)throw new Error(a);this.yy.parser.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var b=a.match(/(?:\r\n?|\n).*/g);return b?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var b=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-b-1),this.offset-=b;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-b},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-b]),this},more:function(){return this._more=!0,this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c,d,e;this._more||(this.yytext="",this.match="");for(var f=this._currentRules(),g=0;g<f.length&&(c=this._input.match(this.rules[f[g]]),!c||b&&!(c[0].length>b[0].length)||(b=c,d=g,this.options.flex));g++);return b?(e=b[0].match(/(?:\r\n?|\n).*/g),e&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,f[d],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a?a:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.options={},a.performAction=function(a,b,c,d){function e(a,c){return b.yytext=b.yytext.substr(a,b.yyleng-c)}switch(c){case 0:if("\\\\"===b.yytext.slice(-2)?(e(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(e(0,1),this.begin("emu")):this.begin("mu"),b.yytext)return 10;break;case 1:return 10;case 2:return this.popState(),10;case 3:return b.yytext=b.yytext.substr(5,b.yyleng-9),this.popState(),11;case 4:return 10;case 5:return e(0,4),this.popState(),17;case 6:return 40;case 7:return 41;case 8:return 18;case 9:return this.popState(),this.begin("raw"),20;case 10:return b.yytext=b.yytext.substr(4,b.yyleng-8),this.popState(),"RAW_BLOCK";case 11:return 29;case 12:return 21;case 13:return 24;case 14:return 23;case 15:return 23;case 16:return 27;case 17:return 26;case 18:this.popState(),this.begin("com");break;case 19:return e(3,5),this.popState(),17;case 20:return 26;case 21:return 46;case 22:return 45;case 23:return 45;case 24:return 49;case 25:break;case 26:return this.popState(),28;case 27:return this.popState(),22;case 28:return b.yytext=e(1,2).replace(/\\"/g,'"'),37;case 29:return b.yytext=e(1,2).replace(/\\'/g,"'"),37;case 30:return 47;case 31:return 39;case 32:return 39;case 33:return 38;case 34:return 45;case 35:return b.yytext=e(1,2),45;case 36:return"INVALID";case 37:return 5}},a.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{\{\{[^\x00]*\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/],a.conditions={mu:{rules:[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[5],inclusive:!1},raw:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,1,37],inclusive:!0}},a}();return c.lexer=d,b.prototype=c,c.Parser=b,new b}();return a=b}(),i=function(a,b){"use strict";function c(a){return a.constructor===f.ProgramNode?a:(e.yy=f,e.parse(a))}var d={},e=a,f=b;return d.parser=e,d.parse=c,d}(h,g),j=function(a){"use strict";function b(){}function c(a,b,c){if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new f("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+a);b=b||{},"data"in b||(b.data=!0);var d=c.parse(a),e=(new c.Compiler).compile(d,b);return(new c.JavaScriptCompiler).compile(e,b)}function d(a,b,c){function d(){var d=c.parse(a),e=(new c.Compiler).compile(d,b),f=(new c.JavaScriptCompiler).compile(e,b,void 0,!0);return c.template(f)}if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new f("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+a);b=b||{},"data"in b||(b.data=!0);var e,g=function(a,b){return e||(e=d()),e.call(this,a,b)};return g._setup=function(a){return e||(e=d()),e._setup(a)},g._child=function(a){return e||(e=d()),e._child(a)},g}var e={},f=a;return e.Compiler=b,b.prototype={compiler:b,disassemble:function(){for(var a,b,c,d=this.opcodes,e=[],f=0,g=d.length;g>f;f++)if(a=d[f],"DECLARE"===a.opcode)e.push("DECLARE "+a.name+"="+a.value);else{b=[];for(var h=0;h<a.args.length;h++)c=a.args[h],"string"==typeof c&&(c='"'+c.replace("\n","\\n")+'"'),b.push(c);e.push(a.opcode+" "+b.join(" "))}return e.join("\n")},equals:function(a){var b=this.opcodes.length;if(a.opcodes.length!==b)return!1;for(var c=0;b>c;c++){var d=this.opcodes[c],e=a.opcodes[c];if(d.opcode!==e.opcode||d.args.length!==e.args.length)return!1;for(var f=0;f<d.args.length;f++)if(d.args[f]!==e.args[f])return!1}if(b=this.children.length,a.children.length!==b)return!1;for(c=0;b>c;c++)if(!this.children[c].equals(a.children[c]))return!1;return!0},guid:0,compile:function(a,b){this.opcodes=[],this.children=[],this.depths={list:[]},this.options=b,this.stringParams=b.stringParams,this.trackIds=b.trackIds;var c=this.options.knownHelpers;if(this.options.knownHelpers={helperMissing:!0,blockHelperMissing:!0,each:!0,"if":!0,unless:!0,"with":!0,log:!0,lookup:!0},c)for(var d in c)this.options.knownHelpers[d]=c[d];return this.accept(a)},accept:function(a){var b,c=a.strip||{};return c.left&&this.opcode("strip"),b=this[a.type](a),c.right&&this.opcode("strip"),b},program:function(a){for(var b=a.statements,c=0,d=b.length;d>c;c++)this.accept(b[c]);return this.isSimple=1===d,this.depths.list=this.depths.list.sort(function(a,b){return a-b}),this},compileProgram:function(a){var b,c=(new this.compiler).compile(a,this.options),d=this.guid++;this.usePartial=this.usePartial||c.usePartial,this.children[d]=c;for(var e=0,f=c.depths.list.length;f>e;e++)b=c.depths.list[e],2>b||this.addDepth(b-1);return d},block:function(a){var b=a.mustache,c=a.program,d=a.inverse;c&&(c=this.compileProgram(c)),d&&(d=this.compileProgram(d));var e=b.sexpr,f=this.classifySexpr(e);"helper"===f?this.helperSexpr(e,c,d):"simple"===f?(this.simpleSexpr(e),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("blockValue",e.id.original)):(this.ambiguousSexpr(e,c,d),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue")),this.opcode("append")},hash:function(a){var b,c,d=a.pairs;for(this.opcode("pushHash"),b=0,c=d.length;c>b;b++)this.pushParam(d[b][1]);for(;b--;)this.opcode("assignToHash",d[b][0]);this.opcode("popHash")},partial:function(a){var b=a.partialName;this.usePartial=!0,a.hash?this.accept(a.hash):this.opcode("push","undefined"),a.context?this.accept(a.context):this.opcode("push","depth0"),this.opcode("invokePartial",b.name),this.opcode("append")
this.usePartial=this.usePartial||c.usePartial,this.children[d]=c;for(var e=0,f=c.depths.list.length;f>e;e++)b=c.depths.list[e],2>b||this.addDepth(b-1);return d},block:function(a){var b=a.mustache,c=a.program,d=a.inverse;c&&(c=this.compileProgram(c)),d&&(d=this.compileProgram(d));var e=b.sexpr,f=this.classifySexpr(e);"helper"===f?this.helperSexpr(e,c,d):"simple"===f?(this.simpleSexpr(e),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("blockValue",e.id.original)):(this.ambiguousSexpr(e,c,d),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue")),this.opcode("append")},hash:function(a){var b,c,d=a.pairs;for(this.opcode("pushHash"),b=0,c=d.length;c>b;b++)this.pushParam(d[b][1]);for(;b--;)this.opcode("assignToHash",d[b][0]);this.opcode("popHash")},partial:function(a){var b=a.partialName;this.usePartial=!0,a.hash?this.accept(a.hash):this.opcode("push","undefined"),a.context?this.accept(a.context):(this.opcode("getContext",0),this.opcode("pushContext")),this.opcode("invokePartial",b.name,a.indent||""),this.opcode("append")},content:function(a){a.string&&this.opcode("appendContent",a.string)},mustache:function(a){this.sexpr(a.sexpr),a.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},ambiguousSexpr:function(a,b,c){var d=a.id,e=d.parts[0],f=null!=b||null!=c;this.opcode("getContext",d.depth),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.ID(d),this.opcode("invokeAmbiguous",e,f)},simpleSexpr:function(a){var b=a.id;"DATA"===b.type?this.DATA(b):b.parts.length?this.ID(b):(this.addDepth(b.depth),this.opcode("getContext",b.depth),this.opcode("pushContext")),this.opcode("resolvePossibleLambda")},helperSexpr:function(a,b,c){var d=this.setupFullMustacheParams(a,b,c),e=a.id,f=e.parts[0];if(this.options.knownHelpers[f])this.opcode("invokeKnownHelper",d.length,f);else{if(this.options.knownHelpersOnly)throw new h("You specified knownHelpersOnly, but used the unknown helper "+f,a);e.falsy=!0,this.ID(e),this.opcode("invokeHelper",d.length,e.original,e.isSimple)}},sexpr:function(a){var b=this.classifySexpr(a);"simple"===b?this.simpleSexpr(a):"helper"===b?this.helperSexpr(a):this.ambiguousSexpr(a)},ID:function(a){this.addDepth(a.depth),this.opcode("getContext",a.depth);var b=a.parts[0];b?this.opcode("lookupOnContext",a.parts,a.falsy,a.isScoped):this.opcode("pushContext")},DATA:function(a){this.options.data=!0,this.opcode("lookupData",a.id.depth,a.id.parts)},STRING:function(a){this.opcode("pushString",a.string)},NUMBER:function(a){this.opcode("pushLiteral",a.number)},BOOLEAN:function(a){this.opcode("pushLiteral",a.bool)},comment:function(){},opcode:function(a){this.opcodes.push({opcode:a,args:j.call(arguments,1)})},addDepth:function(a){0!==a&&(this.depths[a]||(this.depths[a]=!0,this.depths.list.push(a)))},classifySexpr:function(a){var b=a.isHelper,c=a.eligibleHelper,d=this.options;if(c&&!b){var e=a.id.parts[0];d.knownHelpers[e]?b=!0:d.knownHelpersOnly&&(c=!1)}return b?"helper":c?"ambiguous":"simple"},pushParams:function(a){for(var b=0,c=a.length;c>b;b++)this.pushParam(a[b])},pushParam:function(a){this.stringParams?(a.depth&&this.addDepth(a.depth),this.opcode("getContext",a.depth||0),this.opcode("pushStringParam",a.stringModeValue,a.type),"sexpr"===a.type&&this.sexpr(a)):(this.trackIds&&this.opcode("pushId",a.type,a.idName||a.stringModeValue),this.accept(a))},setupFullMustacheParams:function(a,b,c){var d=a.params;return this.pushParams(d),this.opcode("pushProgram",b),this.opcode("pushProgram",c),a.hash?this.hash(a.hash):this.opcode("emptyHash"),d}},g.precompile=d,g.compile=e,g}(c,b),l=function(a,b){"use strict";function c(a){this.value=a}function d(){}var e,f=a.COMPILER_REVISION,g=a.REVISION_CHANGES,h=b;d.prototype={nameLookup:function(a,b){return d.isValidJavaScriptVariableName(b)?a+"."+b:a+"['"+b+"']"},depthedLookup:function(a){return this.aliases.lookup="this.lookup",'lookup(depths, "'+a+'")'},compilerInfo:function(){var a=f,b=g[a];return[a,b]},appendToBuffer:function(a){return this.environment.isSimple?"return "+a+";":{appendToBuffer:!0,content:a,toString:function(){return"buffer += "+a+";"}}},initializeBuffer:function(){return this.quotedString("")},namespace:"Handlebars",compile:function(a,b,c,d){this.environment=a,this.options=b,this.stringParams=this.options.stringParams,this.trackIds=this.options.trackIds,this.precompile=!d,this.name=this.environment.name,this.isChild=!!c,this.context=c||{programs:[],environments:[]},this.preamble(),this.stackSlot=0,this.stackVars=[],this.aliases={},this.registers={list:[]},this.hashes=[],this.compileStack=[],this.inlineStack=[],this.compileChildren(a,b),this.useDepths=this.useDepths||a.depths.list.length||this.options.compat;var e,f,g,i=a.opcodes;for(f=0,g=i.length;g>f;f++)e=i[f],this[e.opcode].apply(this,e.args);if(this.pushSource(""),this.stackSlot||this.inlineStack.length||this.compileStack.length)throw new h("Compile completed with content left on stack");var j=this.createFunctionContext(d);if(this.isChild)return j;var k={compiler:this.compilerInfo(),main:j},l=this.context.programs;for(f=0,g=l.length;g>f;f++)l[f]&&(k[f]=l[f]);return this.environment.usePartial&&(k.usePartial=!0),this.options.data&&(k.useData=!0),this.useDepths&&(k.useDepths=!0),this.options.compat&&(k.compat=!0),d||(k.compiler=JSON.stringify(k.compiler),k=this.objectLiteral(k)),k},preamble:function(){this.lastContext=0,this.source=[]},createFunctionContext:function(a){var b="",c=this.stackVars.concat(this.registers.list);c.length>0&&(b+=", "+c.join(", "));for(var d in this.aliases)this.aliases.hasOwnProperty(d)&&(b+=", "+d+"="+this.aliases[d]);var e=["depth0","helpers","partials","data"];this.useDepths&&e.push("depths");var f=this.mergeSource(b);return a?(e.push(f),Function.apply(this,e)):"function("+e.join(",")+") {\n "+f+"}"},mergeSource:function(a){for(var b,c,d="",e=!this.forceBuffer,f=0,g=this.source.length;g>f;f++){var h=this.source[f];h.appendToBuffer?b=b?b+"\n + "+h.content:h.content:(b&&(d?d+="buffer += "+b+";\n ":(c=!0,d=b+";\n "),b=void 0),d+=h+"\n ",this.environment.isSimple||(e=!1))}return e?(b||!d)&&(d+="return "+(b||'""')+";\n"):(a+=", buffer = "+(c?"":this.initializeBuffer()),d+=b?"return buffer + "+b+";\n":"return buffer;\n"),a&&(d="var "+a.substring(2)+(c?"":";\n ")+d),d},blockValue:function(a){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var b=[this.contextName(0)];this.setupParams(a,0,b);var c=this.popStack();b.splice(1,0,c),this.push("blockHelperMissing.call("+b.join(", ")+")")},ambiguousBlockValue:function(){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var a=[this.contextName(0)];this.setupParams("",0,a,!0),this.flushInline();var b=this.topStack();a.splice(1,0,b),this.pushSource("if (!"+this.lastHelper+") { "+b+" = blockHelperMissing.call("+a.join(", ")+"); }")},appendContent:function(a){this.pendingContent&&(a=this.pendingContent+a),this.pendingContent=a},append:function(){this.flushInline();var a=this.popStack();this.pushSource("if ("+a+" != null) { "+this.appendToBuffer(a)+" }"),this.environment.isSimple&&this.pushSource("else { "+this.appendToBuffer("''")+" }")},appendEscaped:function(){this.aliases.escapeExpression="this.escapeExpression",this.pushSource(this.appendToBuffer("escapeExpression("+this.popStack()+")"))},getContext:function(a){this.lastContext=a},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(a,b,c){var d=0,e=a.length;for(c||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(a[d++]));e>d;d++)this.replaceStack(function(c){var e=this.nameLookup(c,a[d],"context");return b?" && "+e:" != null ? "+e+" : "+c})},lookupData:function(a,b){a?this.pushStackLiteral("this.data(data, "+a+")"):this.pushStackLiteral("data");for(var c=b.length,d=0;c>d;d++)this.replaceStack(function(a){return" && "+this.nameLookup(a,b[d],"data")})},resolvePossibleLambda:function(){this.aliases.lambda="this.lambda",this.push("lambda("+this.popStack()+", "+this.contextName(0)+")")},pushStringParam:function(a,b){this.pushContext(),this.pushString(b),"sexpr"!==b&&("string"==typeof a?this.pushString(a):this.pushStackLiteral(a))},emptyHash:function(){this.pushStackLiteral("{}"),this.trackIds&&this.push("{}"),this.stringParams&&(this.push("{}"),this.push("{}"))},pushHash:function(){this.hash&&this.hashes.push(this.hash),this.hash={values:[],types:[],contexts:[],ids:[]}},popHash:function(){var a=this.hash;this.hash=this.hashes.pop(),this.trackIds&&this.push("{"+a.ids.join(",")+"}"),this.stringParams&&(this.push("{"+a.contexts.join(",")+"}"),this.push("{"+a.types.join(",")+"}")),this.push("{\n "+a.values.join(",\n ")+"\n }")},pushString:function(a){this.pushStackLiteral(this.quotedString(a))},push:function(a){return this.inlineStack.push(a),a},pushLiteral:function(a){this.pushStackLiteral(a)},pushProgram:function(a){null!=a?this.pushStackLiteral(this.programExpression(a)):this.pushStackLiteral(null)},invokeHelper:function(a,b,c){this.aliases.helperMissing="helpers.helperMissing";var d=this.popStack(),e=this.setupHelper(a,b),f=(c?e.name+" || ":"")+d+" || helperMissing";this.push("(("+f+").call("+e.callParams+"))")},invokeKnownHelper:function(a,b){var c=this.setupHelper(a,b);this.push(c.name+".call("+c.callParams+")")},invokeAmbiguous:function(a,b){this.aliases.functionType='"function"',this.aliases.helperMissing="helpers.helperMissing",this.useRegister("helper");var c=this.popStack();this.emptyHash();var d=this.setupHelper(0,a,b),e=this.lastHelper=this.nameLookup("helpers",a,"helper");this.push("((helper = (helper = "+e+" || "+c+") != null ? helper : helperMissing"+(d.paramsInit?"),("+d.paramsInit:"")+"),(typeof helper === functionType ? helper.call("+d.callParams+") : helper))")},invokePartial:function(a,b){var c=[this.nameLookup("partials",a,"partial"),"'"+b+"'","'"+a+"'",this.popStack(),this.popStack(),"helpers","partials"];this.options.data?c.push("data"):this.options.compat&&c.push("undefined"),this.options.compat&&c.push("depths"),this.push("this.invokePartial("+c.join(", ")+")")},assignToHash:function(a){var b,c,d,e=this.popStack();this.trackIds&&(d=this.popStack()),this.stringParams&&(c=this.popStack(),b=this.popStack());var f=this.hash;b&&f.contexts.push("'"+a+"': "+b),c&&f.types.push("'"+a+"': "+c),d&&f.ids.push("'"+a+"': "+d),f.values.push("'"+a+"': ("+e+")")},pushId:function(a,b){"ID"===a||"DATA"===a?this.pushString(b):"sexpr"===a?this.pushStackLiteral("true"):this.pushStackLiteral("null")},compiler:d,compileChildren:function(a,b){for(var c,d,e=a.children,f=0,g=e.length;g>f;f++){c=e[f],d=new this.compiler;var h=this.matchExistingProgram(c);null==h?(this.context.programs.push(""),h=this.context.programs.length,c.index=h,c.name="program"+h,this.context.programs[h]=d.compile(c,b,this.context,!this.precompile),this.context.environments[h]=c,this.useDepths=this.useDepths||d.useDepths):(c.index=h,c.name="program"+h)}},matchExistingProgram:function(a){for(var b=0,c=this.context.environments.length;c>b;b++){var d=this.context.environments[b];if(d&&d.equals(a))return b}},programExpression:function(a){var b=this.environment.children[a],c=(b.depths.list,this.useDepths),d=[b.index,"data"];return c&&d.push("depths"),"this.program("+d.join(", ")+")"},useRegister:function(a){this.registers[a]||(this.registers[a]=!0,this.registers.list.push(a))},pushStackLiteral:function(a){return this.push(new c(a))},pushSource:function(a){this.pendingContent&&(this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent))),this.pendingContent=void 0),a&&this.source.push(a)},pushStack:function(a){this.flushInline();var b=this.incrStack();return this.pushSource(b+" = "+a+";"),this.compileStack.push(b),b},replaceStack:function(a){{var b,d,e,f="";this.isInline()}if(!this.isInline())throw new h("replaceStack on non-inline");var g=this.popStack(!0);if(g instanceof c)f=b=g.value,e=!0;else{d=!this.stackSlot;var i=d?this.incrStack():this.topStackName();f="("+this.push(i)+" = "+g+")",b=this.topStack()}var j=a.call(this,b);e||this.popStack(),d&&this.stackSlot--,this.push("("+f+j+")")},incrStack:function(){return this.stackSlot++,this.stackSlot>this.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;if(a.length){this.inlineStack=[];for(var b=0,d=a.length;d>b;b++){var e=a[b];e instanceof c?this.compileStack.push(e):this.pushStack(e)}}},isInline:function(){return this.inlineStack.length},popStack:function(a){var b=this.isInline(),d=(b?this.inlineStack:this.compileStack).pop();if(!a&&d instanceof c)return d.value;if(!b){if(!this.stackSlot)throw new h("Invalid stack pop");this.stackSlot--}return d},topStack:function(){var a=this.isInline()?this.inlineStack:this.compileStack,b=a[a.length-1];return b instanceof c?b.value:b},contextName:function(a){return this.useDepths&&a?"depths["+a+"]":"depth"+a},quotedString:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+'"'},objectLiteral:function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(this.quotedString(c)+":"+a[c]);return"{"+b.join(",")+"}"},setupHelper:function(a,b,c){var d=[],e=this.setupParams(b,a,d,c),f=this.nameLookup("helpers",b,"helper");return{params:d,paramsInit:e,name:f,callParams:[this.contextName(0)].concat(d).join(", ")}},setupOptions:function(a,b,c){var d,e,f,g={},h=[],i=[],j=[];g.name=this.quotedString(a),g.hash=this.popStack(),this.trackIds&&(g.hashIds=this.popStack()),this.stringParams&&(g.hashTypes=this.popStack(),g.hashContexts=this.popStack()),e=this.popStack(),f=this.popStack(),(f||e)&&(f||(f="this.noop"),e||(e="this.noop"),g.fn=f,g.inverse=e);for(var k=b;k--;)d=this.popStack(),c[k]=d,this.trackIds&&(j[k]=this.popStack()),this.stringParams&&(i[k]=this.popStack(),h[k]=this.popStack());return this.trackIds&&(g.ids="["+j.join(",")+"]"),this.stringParams&&(g.types="["+i.join(",")+"]",g.contexts="["+h.join(",")+"]"),this.options.data&&(g.data="data"),g},setupParams:function(a,b,c,d){var e=this.objectLiteral(this.setupOptions(a,b,c));return d?(this.useRegister("options"),c.push("options"),"options="+e):(c.push(e),"")}};for(var i="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield".split(" "),j=d.RESERVED_WORDS={},k=0,l=i.length;l>k;k++)j[i[k]]=!0;return d.isValidJavaScriptVariableName=function(a){return!d.RESERVED_WORDS[a]&&/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(a)},e=d}(d,c),m=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c.parser,j=c.parse,k=d.Compiler,l=d.compile,m=d.precompile,n=e,o=g.create,p=function(){var a=o();return a.compile=function(b,c){return l(b,c,a)},a.precompile=function(b,c){return m(b,c,a)},a.AST=h,a.Compiler=k,a.JavaScriptCompiler=n,a.Parser=i,a.parse=j,a};return g=p(),g.create=p,g["default"]=g,f=g}(f,g,j,k,l);return m}); },content:function(a){this.opcode("appendContent",a.string)},mustache:function(a){this.sexpr(a.sexpr),a.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},ambiguousSexpr:function(a,b,c){var d=a.id,e=d.parts[0],f=null!=b||null!=c;this.opcode("getContext",d.depth),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.opcode("invokeAmbiguous",e,f)},simpleSexpr:function(a){var b=a.id;"DATA"===b.type?this.DATA(b):b.parts.length?this.ID(b):(this.addDepth(b.depth),this.opcode("getContext",b.depth),this.opcode("pushContext")),this.opcode("resolvePossibleLambda")},helperSexpr:function(a,b,c){var d=this.setupFullMustacheParams(a,b,c),e=a.id,g=e.parts[0];if(this.options.knownHelpers[g])this.opcode("invokeKnownHelper",d.length,g);else{if(this.options.knownHelpersOnly)throw new f("You specified knownHelpersOnly, but used the unknown helper "+g,a);this.ID(e),this.opcode("invokeHelper",d.length,e.original,a.isRoot)}},sexpr:function(a){var b=this.classifySexpr(a);"simple"===b?this.simpleSexpr(a):"helper"===b?this.helperSexpr(a):this.ambiguousSexpr(a)},ID:function(a){this.addDepth(a.depth),this.opcode("getContext",a.depth);var b=a.parts[0];b?this.opcode("lookupOnContext",a.parts[0]):this.opcode("pushContext");for(var c=1,d=a.parts.length;d>c;c++)this.opcode("lookup",a.parts[c])},DATA:function(a){this.options.data=!0,this.opcode("lookupData",a.id.depth);for(var b=a.id.parts,c=0,d=b.length;d>c;c++)this.opcode("lookup",b[c])},STRING:function(a){this.opcode("pushString",a.string)},NUMBER:function(a){this.opcode("pushLiteral",a.number)},BOOLEAN:function(a){this.opcode("pushLiteral",a.bool)},comment:function(){},opcode:function(a){this.opcodes.push({opcode:a,args:[].slice.call(arguments,1)})},declare:function(a,b){this.opcodes.push({opcode:"DECLARE",name:a,value:b})},addDepth:function(a){0!==a&&(this.depths[a]||(this.depths[a]=!0,this.depths.list.push(a)))},classifySexpr:function(a){var b=a.isHelper,c=a.eligibleHelper,d=this.options;if(c&&!b){var e=a.id.parts[0];d.knownHelpers[e]?b=!0:d.knownHelpersOnly&&(c=!1)}return b?"helper":c?"ambiguous":"simple"},pushParams:function(a){for(var b=0,c=a.length;c>b;b++)this.pushParam(a[b])},pushParam:function(a){this.stringParams?(a.depth&&this.addDepth(a.depth),this.opcode("getContext",a.depth||0),this.opcode("pushStringParam",a.stringModeValue,a.type),"sexpr"===a.type&&this.sexpr(a)):(this.trackIds&&this.opcode("pushId",a.type,a.idName||a.stringModeValue),this.accept(a))},setupFullMustacheParams:function(a,b,c){var d=a.params;return this.pushParams(d),this.opcode("pushProgram",b),this.opcode("pushProgram",c),a.hash?this.hash(a.hash):this.opcode("emptyHash"),d}},e.precompile=c,e.compile=d,e}(c),k=function(a,b){"use strict";function c(a){this.value=a}function d(){}var e,f=a.COMPILER_REVISION,g=a.REVISION_CHANGES,h=a.log,i=b;d.prototype={nameLookup:function(a,b){var c,e;return 0===a.indexOf("depth")&&(c=!0),e=d.isValidJavaScriptVariableName(b)?a+"."+b:a+"['"+b+"']",c?"("+a+" && "+e+")":e},compilerInfo:function(){var a=f,b=g[a];return[a,b]},appendToBuffer:function(a){return this.environment.isSimple?"return "+a+";":{appendToBuffer:!0,content:a,toString:function(){return"buffer += "+a+";"}}},initializeBuffer:function(){return this.quotedString("")},namespace:"Handlebars",compile:function(a,b,c,d){this.environment=a,this.options=b||{},this.stringParams=this.options.stringParams,this.trackIds=this.options.trackIds,this.precompile=!d,h("debug",this.environment.disassemble()+"\n\n"),this.name=this.environment.name,this.isChild=!!c,this.context=c||{programs:[],environments:[]},this.preamble(),this.stackSlot=0,this.stackVars=[],this.aliases={},this.registers={list:[]},this.hashes=[],this.compileStack=[],this.inlineStack=[],this.compileChildren(a,b);var e,f,g,j=a.opcodes;for(f=0,g=j.length;g>f;f++)e=j[f],"DECLARE"===e.opcode?this[e.name]=e.value:this[e.opcode].apply(this,e.args),e.opcode!==this.stripNext&&(this.stripNext=!1);if(this.pushSource(""),this.stackSlot||this.inlineStack.length||this.compileStack.length)throw new i("Compile completed with content left on stack");var k=this.createFunctionContext(d);if(this.isChild)return k;var l={compiler:this.compilerInfo(),main:k},m=this.context.programs;for(f=0,g=m.length;g>f;f++)m[f]&&(l[f]=m[f]);return this.environment.usePartial&&(l.usePartial=!0),this.options.data&&(l.useData=!0),d||(l.compiler=JSON.stringify(l.compiler),l=this.objectLiteral(l)),l},preamble:function(){this.lastContext=0,this.source=[]},createFunctionContext:function(a){var b="",c=this.stackVars.concat(this.registers.list);c.length>0&&(b+=", "+c.join(", "));for(var d in this.aliases)this.aliases.hasOwnProperty(d)&&(b+=", "+d+"="+this.aliases[d]);for(var e=["depth0","helpers","partials","data"],f=0,g=this.environment.depths.list.length;g>f;f++)e.push("depth"+this.environment.depths.list[f]);var h=this.mergeSource(b);return a?(e.push(h),Function.apply(this,e)):"function("+e.join(",")+") {\n "+h+"}"},mergeSource:function(a){for(var b,c,d="",e=!this.forceBuffer,f=0,g=this.source.length;g>f;f++){var h=this.source[f];h.appendToBuffer?b=b?b+"\n + "+h.content:h.content:(b&&(d?d+="buffer += "+b+";\n ":(c=!0,d=b+";\n "),b=void 0),d+=h+"\n ",this.environment.isSimple||(e=!1))}return e?(b||!d)&&(d+="return "+(b||'""')+";\n"):(a+=", buffer = "+(c?"":this.initializeBuffer()),d+=b?"return buffer + "+b+";\n":"return buffer;\n"),a&&(d="var "+a.substring(2)+(c?"":";\n ")+d),d},blockValue:function(a){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var b=["depth0"];this.setupParams(a,0,b),this.replaceStack(function(a){return b.splice(1,0,a),"blockHelperMissing.call("+b.join(", ")+")"})},ambiguousBlockValue:function(){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var a=["depth0"];this.setupParams("",0,a,!0),this.flushInline();var b=this.topStack();a.splice(1,0,b),this.pushSource("if (!"+this.lastHelper+") { "+b+" = blockHelperMissing.call("+a.join(", ")+"); }")},appendContent:function(a){this.pendingContent&&(a=this.pendingContent+a),this.stripNext&&(a=a.replace(/^\s+/,"")),this.pendingContent=a},strip:function(){this.pendingContent&&(this.pendingContent=this.pendingContent.replace(/\s+$/,"")),this.stripNext="strip"},append:function(){this.flushInline();var a=this.popStack();this.pushSource("if("+a+" || "+a+" === 0) { "+this.appendToBuffer(a)+" }"),this.environment.isSimple&&this.pushSource("else { "+this.appendToBuffer("''")+" }")},appendEscaped:function(){this.aliases.escapeExpression="this.escapeExpression",this.pushSource(this.appendToBuffer("escapeExpression("+this.popStack()+")"))},getContext:function(a){this.lastContext!==a&&(this.lastContext=a)},lookupOnContext:function(a){this.push(this.nameLookup("depth"+this.lastContext,a,"context"))},pushContext:function(){this.pushStackLiteral("depth"+this.lastContext)},resolvePossibleLambda:function(){this.aliases.functionType='"function"',this.replaceStack(function(a){return"typeof "+a+" === functionType ? "+a+".apply(depth0) : "+a})},lookup:function(a){this.replaceStack(function(b){return b+" == null || "+b+" === false ? "+b+" : "+this.nameLookup(b,a,"context")})},lookupData:function(a){a?this.pushStackLiteral("this.data(data, "+a+")"):this.pushStackLiteral("data")},pushStringParam:function(a,b){this.pushStackLiteral("depth"+this.lastContext),this.pushString(b),"sexpr"!==b&&("string"==typeof a?this.pushString(a):this.pushStackLiteral(a))},emptyHash:function(){this.pushStackLiteral("{}"),this.trackIds&&this.push("{}"),this.stringParams&&(this.push("{}"),this.push("{}"))},pushHash:function(){this.hash&&this.hashes.push(this.hash),this.hash={values:[],types:[],contexts:[],ids:[]}},popHash:function(){var a=this.hash;this.hash=this.hashes.pop(),this.trackIds&&this.push("{"+a.ids.join(",")+"}"),this.stringParams&&(this.push("{"+a.contexts.join(",")+"}"),this.push("{"+a.types.join(",")+"}")),this.push("{\n "+a.values.join(",\n ")+"\n }")},pushString:function(a){this.pushStackLiteral(this.quotedString(a))},push:function(a){return this.inlineStack.push(a),a},pushLiteral:function(a){this.pushStackLiteral(a)},pushProgram:function(a){null!=a?this.pushStackLiteral(this.programExpression(a)):this.pushStackLiteral(null)},invokeHelper:function(a,b,c){this.aliases.helperMissing="helpers.helperMissing",this.useRegister("helper");var d=this.popStack(),e=this.setupHelper(a,b),f="helper = "+e.name+" || "+d+" || helperMissing";e.paramsInit&&(f+=","+e.paramsInit),this.push("("+f+",helper.call("+e.callParams+"))"),c||this.flushInline()},invokeKnownHelper:function(a,b){var c=this.setupHelper(a,b);this.push(c.name+".call("+c.callParams+")")},invokeAmbiguous:function(a,b){this.aliases.functionType='"function"',this.useRegister("helper"),this.emptyHash();var c=this.setupHelper(0,a,b),d=this.lastHelper=this.nameLookup("helpers",a,"helper"),e=this.nameLookup("depth"+this.lastContext,a,"context");this.push("((helper = "+d+" || "+e+(c.paramsInit?"),("+c.paramsInit:"")+"),(typeof helper === functionType ? helper.call("+c.callParams+") : helper))")},invokePartial:function(a){var b=[this.nameLookup("partials",a,"partial"),"'"+a+"'",this.popStack(),this.popStack(),"helpers","partials"];this.options.data&&b.push("data"),this.push("this.invokePartial("+b.join(", ")+")")},assignToHash:function(a){var b,c,d,e=this.popStack();this.trackIds&&(d=this.popStack()),this.stringParams&&(c=this.popStack(),b=this.popStack());var f=this.hash;b&&f.contexts.push("'"+a+"': "+b),c&&f.types.push("'"+a+"': "+c),d&&f.ids.push("'"+a+"': "+d),f.values.push("'"+a+"': ("+e+")")},pushId:function(a,b){"ID"===a||"DATA"===a?this.pushString(b):"sexpr"===a?this.pushStackLiteral("true"):this.pushStackLiteral("null")},compiler:d,compileChildren:function(a,b){for(var c,d,e=a.children,f=0,g=e.length;g>f;f++){c=e[f],d=new this.compiler;var h=this.matchExistingProgram(c);null==h?(this.context.programs.push(""),h=this.context.programs.length,c.index=h,c.name="program"+h,this.context.programs[h]=d.compile(c,b,this.context,!this.precompile),this.context.environments[h]=c):(c.index=h,c.name="program"+h)}},matchExistingProgram:function(a){for(var b=0,c=this.context.environments.length;c>b;b++){var d=this.context.environments[b];if(d&&d.equals(a))return b}},programExpression:function(a){if(null==a)return"this.noop";for(var b,c=this.environment.children[a],d=c.depths.list,e=[c.index,"data"],f=0,g=d.length;g>f;f++)b=d[f],e.push("depth"+(b-1));return(0===d.length?"this.program(":"this.programWithDepth(")+e.join(", ")+")"},register:function(a,b){this.useRegister(a),this.pushSource(a+" = "+b+";")},useRegister:function(a){this.registers[a]||(this.registers[a]=!0,this.registers.list.push(a))},pushStackLiteral:function(a){return this.push(new c(a))},pushSource:function(a){this.pendingContent&&(this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent))),this.pendingContent=void 0),a&&this.source.push(a)},pushStack:function(a){this.flushInline();var b=this.incrStack();return a&&this.pushSource(b+" = "+a+";"),this.compileStack.push(b),b},replaceStack:function(a){var b,d,e,f="",g=this.isInline();if(g){var h=this.popStack(!0);if(h instanceof c)b=h.value,e=!0;else{d=!this.stackSlot;var i=d?this.incrStack():this.topStackName();f="("+this.push(i)+" = "+h+"),",b=this.topStack()}}else b=this.topStack();var j=a.call(this,b);return g?(e||this.popStack(),d&&this.stackSlot--,this.push("("+f+j+")")):(/^stack/.test(b)||(b=this.nextStack()),this.pushSource(b+" = ("+f+j+");")),b},nextStack:function(){return this.pushStack()},incrStack:function(){return this.stackSlot++,this.stackSlot>this.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;if(a.length){this.inlineStack=[];for(var b=0,d=a.length;d>b;b++){var e=a[b];e instanceof c?this.compileStack.push(e):this.pushStack(e)}}},isInline:function(){return this.inlineStack.length},popStack:function(a){var b=this.isInline(),d=(b?this.inlineStack:this.compileStack).pop();if(!a&&d instanceof c)return d.value;if(!b){if(!this.stackSlot)throw new i("Invalid stack pop");this.stackSlot--}return d},topStack:function(a){var b=this.isInline()?this.inlineStack:this.compileStack,d=b[b.length-1];return!a&&d instanceof c?d.value:d},quotedString:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+'"'},objectLiteral:function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(this.quotedString(c)+":"+a[c]);return"{"+b.join(",")+"}"},setupHelper:function(a,b,c){var d=[],e=this.setupParams(b,a,d,c),f=this.nameLookup("helpers",b,"helper");return{params:d,paramsInit:e,name:f,callParams:["depth0"].concat(d).join(", ")}},setupOptions:function(a,b,c){var d,e,f,g={},h=[],i=[],j=[];g.name=this.quotedString(a),g.hash=this.popStack(),this.trackIds&&(g.hashIds=this.popStack()),this.stringParams&&(g.hashTypes=this.popStack(),g.hashContexts=this.popStack()),e=this.popStack(),f=this.popStack(),(f||e)&&(f||(f="this.noop"),e||(e="this.noop"),g.fn=f,g.inverse=e);for(var k=b;k--;)d=this.popStack(),c[k]=d,this.trackIds&&(j[k]=this.popStack()),this.stringParams&&(i[k]=this.popStack(),h[k]=this.popStack());return this.trackIds&&(g.ids="["+j.join(",")+"]"),this.stringParams&&(g.types="["+i.join(",")+"]",g.contexts="["+h.join(",")+"]"),this.options.data&&(g.data="data"),g},setupParams:function(a,b,c,d){var e=this.objectLiteral(this.setupOptions(a,b,c));return d?(this.useRegister("options"),c.push("options"),"options="+e):(c.push(e),"")}};for(var j="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield".split(" "),k=d.RESERVED_WORDS={},l=0,m=j.length;m>l;l++)k[j[l]]=!0;return d.isValidJavaScriptVariableName=function(a){return!d.RESERVED_WORDS[a]&&/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(a)},e=d}(d,c),l=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c.parser,j=c.parse,k=d.Compiler,l=d.compile,m=d.precompile,n=e,o=g.create,p=function(){var a=o();return a.compile=function(b,c){return l(b,c,a)},a.precompile=function(b,c){return m(b,c,a)},a.AST=h,a.Compiler=k,a.JavaScriptCompiler=n,a.Parser=i,a.parse=j,a};return g=p(),g.create=p,f=g}(f,g,i,j,k);return l}();
\ No newline at end of file \ No newline at end of file
...@@ -2915,9 +2915,6 @@ function restCommandRejecter(param, args) { ...@@ -2915,9 +2915,6 @@ function restCommandRejecter(param, args) {
if (arg.columnNumber !== undefined && arg.columnNumber !== null) { if (arg.columnNumber !== undefined && arg.columnNumber !== null) {
current_priority.columnNumber = arg.columnNumber; current_priority.columnNumber = arg.columnNumber;
} }
if (arg.fileName !== undefined && arg.fileName !== null) {
current_priority.fileName = arg.fileName;
}
if (arg.filename !== undefined && arg.filename !== null) { if (arg.filename !== undefined && arg.filename !== null) {
current_priority.filename = arg.filename; current_priority.filename = arg.filename;
} }
...@@ -4150,7 +4147,7 @@ function enableRestParamChecker(jio, shared) { ...@@ -4150,7 +4147,7 @@ function enableRestParamChecker(jio, shared) {
} }
}); });
["removeAttachment"].forEach(function (method) { ["getAttachment", "removeAttachment"].forEach(function (method) {
shared.on(method, function (param) { shared.on(method, function (param) {
if (!checkId(param)) { if (!checkId(param)) {
checkAttachmentId(param); checkAttachmentId(param);
...@@ -4158,26 +4155,6 @@ function enableRestParamChecker(jio, shared) { ...@@ -4158,26 +4155,6 @@ function enableRestParamChecker(jio, shared) {
}); });
}); });
["getAttachment"].forEach(function (method) {
shared.on(method, function (param) {
if (param.storage_spec.type !== "indexeddb" &&
param.storage_spec.type !== "dav" &&
(param.kwargs._start !== undefined
|| param.kwargs._end !== undefined)) {
restCommandRejecter(param, [
'bad_request',
'unsupport',
'_start, _end not support'
]);
return false;
}
if (!checkId(param)) {
checkAttachmentId(param);
}
});
});
["check", "repair"].forEach(function (method) { ["check", "repair"].forEach(function (method) {
shared.on(method, function (param) { shared.on(method, function (param) {
if (param.kwargs._id !== undefined) { if (param.kwargs._id !== undefined) {
......
/*! /*!
* QUnit 1.15.0 * QUnit 1.14.0
* http://qunitjs.com/ * http://qunitjs.com/
* *
* Copyright 2014 jQuery Foundation and other contributors * Copyright 2013 jQuery Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* http://jquery.org/license * http://jquery.org/license
* *
* Date: 2014-08-08T16:00Z * Date: 2014-01-31T16:40Z
*/ */
/** Font Family and Sizes */ /** Font Family and Sizes */
...@@ -62,14 +62,14 @@ ...@@ -62,14 +62,14 @@
} }
#qunit-testrunner-toolbar { #qunit-testrunner-toolbar {
padding: 0.5em 1em 0.5em 1em; padding: 0.5em 0 0.5em 2em;
color: #5E740B; color: #5E740B;
background-color: #EEE; background-color: #EEE;
overflow: hidden; overflow: hidden;
} }
#qunit-userAgent { #qunit-userAgent {
padding: 0.5em 1em 0.5em 1em; padding: 0.5em 0 0.5em 2.5em;
background-color: #2B81AF; background-color: #2B81AF;
color: #FFF; color: #FFF;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
} }
#qunit-tests li { #qunit-tests li {
padding: 0.4em 1em 0.4em 1em; padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #FFF; border-bottom: 1px solid #FFF;
list-style-position: inside; list-style-position: inside;
} }
...@@ -215,7 +215,7 @@ ...@@ -215,7 +215,7 @@
/** Result */ /** Result */
#qunit-testresult { #qunit-testresult {
padding: 0.5em 1em 0.5em 1em; padding: 0.5em 0.5em 0.5em 2.5em;
color: #2B81AF; color: #2B81AF;
background-color: #D2E0E6; background-color: #D2E0E6;
......
/*! /*!
* QUnit 1.15.0 * QUnit 1.14.0
* http://qunitjs.com/ * http://qunitjs.com/
* *
* Copyright 2014 jQuery Foundation and other contributors * Copyright 2013 jQuery Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* http://jquery.org/license * http://jquery.org/license
* *
* Date: 2014-08-08T16:00Z * Date: 2014-01-31T16:40Z
*/ */
(function( window ) { (function( window ) {
var QUnit, var QUnit,
assert,
config, config,
onErrorFnPrev, onErrorFnPrev,
fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\d+)+\)?/, "" ).replace( /.+\//, "" ), testId = 0,
fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
toString = Object.prototype.toString, toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty, hasOwn = Object.prototype.hasOwnProperty,
// Keep a local reference to Date (GH-283) // Keep a local reference to Date (GH-283)
Date = window.Date, Date = window.Date,
now = Date.now || function() {
return new Date().getTime();
},
setTimeout = window.setTimeout, setTimeout = window.setTimeout,
clearTimeout = window.clearTimeout, clearTimeout = window.clearTimeout,
defined = { defined = {
...@@ -33,7 +32,7 @@ var QUnit, ...@@ -33,7 +32,7 @@ var QUnit,
sessionStorage.setItem( x, x ); sessionStorage.setItem( x, x );
sessionStorage.removeItem( x ); sessionStorage.removeItem( x );
return true; return true;
} catch ( e ) { } catch( e ) {
return false; return false;
} }
}()) }())
...@@ -75,17 +74,20 @@ var QUnit, ...@@ -75,17 +74,20 @@ var QUnit,
* @return {Object} New object with only the own properties (recursively). * @return {Object} New object with only the own properties (recursively).
*/ */
objectValues = function( obj ) { objectValues = function( obj ) {
// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
/*jshint newcap: false */
var key, val, var key, val,
vals = QUnit.is( "array", obj ) ? [] : {}; vals = QUnit.is( "array", obj ) ? [] : {};
for ( key in obj ) { for ( key in obj ) {
if ( hasOwn.call( obj, key ) ) { if ( hasOwn.call( obj, key ) ) {
val = obj[ key ]; val = obj[key];
vals[ key ] = val === Object( val ) ? objectValues( val ) : val; vals[key] = val === Object(val) ? objectValues(val) : val;
} }
} }
return vals; return vals;
}; };
// Root QUnit object. // Root QUnit object.
// `QUnit` initialized at top of scope // `QUnit` initialized at top of scope
QUnit = { QUnit = {
...@@ -94,7 +96,7 @@ QUnit = { ...@@ -94,7 +96,7 @@ QUnit = {
module: function( name, testEnvironment ) { module: function( name, testEnvironment ) {
config.currentModule = name; config.currentModule = name;
config.currentModuleTestEnvironment = testEnvironment; config.currentModuleTestEnvironment = testEnvironment;
config.modules[ name ] = true; config.modules[name] = true;
}, },
asyncTest: function( testName, expected, callback ) { asyncTest: function( testName, expected, callback ) {
...@@ -107,14 +109,20 @@ QUnit = { ...@@ -107,14 +109,20 @@ QUnit = {
}, },
test: function( testName, expected, callback, async ) { test: function( testName, expected, callback, async ) {
var test; var test,
nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
if ( arguments.length === 2 ) { if ( arguments.length === 2 ) {
callback = expected; callback = expected;
expected = null; expected = null;
} }
if ( config.currentModule ) {
nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
}
test = new Test({ test = new Test({
nameHtml: nameHtml,
testName: testName, testName: testName,
expected: expected, expected: expected,
async: async, async: async,
...@@ -131,9 +139,16 @@ QUnit = { ...@@ -131,9 +139,16 @@ QUnit = {
test.queue(); test.queue();
}, },
start: function( count ) { // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
var message; expect: function( asserts ) {
if (arguments.length === 1) {
config.current.expected = asserts;
} else {
return config.current.expected;
}
},
start: function( count ) {
// QUnit hasn't been initialized yet. // QUnit hasn't been initialized yet.
// Note: RequireJS (et al) may delay onLoad // Note: RequireJS (et al) may delay onLoad
if ( config.semaphore === undefined ) { if ( config.semaphore === undefined ) {
...@@ -151,21 +166,10 @@ QUnit = { ...@@ -151,21 +166,10 @@ QUnit = {
if ( config.semaphore > 0 ) { if ( config.semaphore > 0 ) {
return; return;
} }
// Set the starting time when the first test is run
QUnit.config.started = QUnit.config.started || now();
// ignore if start is called more often then stop // ignore if start is called more often then stop
if ( config.semaphore < 0 ) { if ( config.semaphore < 0 ) {
config.semaphore = 0; config.semaphore = 0;
QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
message = "Called start() while already started (QUnit.config.semaphore was 0 already)";
if ( config.current ) {
QUnit.pushFailure( message, sourceFromStacktrace( 2 ) );
} else {
throw new Error( message );
}
return; return;
} }
// A slight delay, to avoid any current callbacks // A slight delay, to avoid any current callbacks
...@@ -180,7 +184,7 @@ QUnit = { ...@@ -180,7 +184,7 @@ QUnit = {
config.blocking = false; config.blocking = false;
process( true ); process( true );
}, 13 ); }, 13);
} else { } else {
config.blocking = false; config.blocking = false;
process( true ); process( true );
...@@ -208,7 +212,6 @@ QUnit = { ...@@ -208,7 +212,6 @@ QUnit = {
function F() {} function F() {}
F.prototype = QUnit; F.prototype = QUnit;
QUnit = new F(); QUnit = new F();
// Make F QUnit's constructor so that we can add to the prototype later // Make F QUnit's constructor so that we can add to the prototype later
QUnit.constructor = F; QUnit.constructor = F;
}()); }());
...@@ -260,7 +263,14 @@ config = { ...@@ -260,7 +263,14 @@ config = {
// Set of all modules. // Set of all modules.
modules: {}, modules: {},
callbacks: {} // logging callback queues
begin: [],
done: [],
log: [],
testStart: [],
testDone: [],
moduleStart: [],
moduleDone: []
}; };
// Initialize more QUnit.config and QUnit.urlParams // Initialize more QUnit.config and QUnit.urlParams
...@@ -313,6 +323,71 @@ extend( QUnit, { ...@@ -313,6 +323,71 @@ extend( QUnit, {
config: config, config: config,
// Initialize the configuration options
init: function() {
extend( config, {
stats: { all: 0, bad: 0 },
moduleStats: { all: 0, bad: 0 },
started: +new Date(),
updateRate: 1000,
blocking: false,
autostart: true,
autorun: false,
filter: "",
queue: [],
semaphore: 1
});
var tests, banner, result,
qunit = id( "qunit" );
if ( qunit ) {
qunit.innerHTML =
"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
"<h2 id='qunit-banner'></h2>" +
"<div id='qunit-testrunner-toolbar'></div>" +
"<h2 id='qunit-userAgent'></h2>" +
"<ol id='qunit-tests'></ol>";
}
tests = id( "qunit-tests" );
banner = id( "qunit-banner" );
result = id( "qunit-testresult" );
if ( tests ) {
tests.innerHTML = "";
}
if ( banner ) {
banner.className = "";
}
if ( result ) {
result.parentNode.removeChild( result );
}
if ( tests ) {
result = document.createElement( "p" );
result.id = "qunit-testresult";
result.className = "result";
tests.parentNode.insertBefore( result, tests );
result.innerHTML = "Running...<br/>&nbsp;";
}
},
// Resets the test setup. Useful for tests that modify the DOM.
/*
DEPRECATED: Use multiple tests instead of resetting inside a test.
Use testStart or testDone for custom cleanup.
This method will throw an error in 2.0, and will be removed in 2.1
*/
reset: function() {
var fixture = id( "qunit-fixture" );
if ( fixture ) {
fixture.innerHTML = config.fixture;
}
},
// Safe object type checking // Safe object type checking
is: function( type, obj ) { is: function( type, obj ) {
return QUnit.objectType( obj ) === type; return QUnit.objectType( obj ) === type;
...@@ -328,12 +403,12 @@ extend( QUnit, { ...@@ -328,12 +403,12 @@ extend( QUnit, {
return "null"; return "null";
} }
var match = toString.call( obj ).match( /^\[object\s(.*)\]$/ ), var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
type = match && match[ 1 ] || ""; type = match && match[1] || "";
switch ( type ) { switch ( type ) {
case "Number": case "Number":
if ( isNaN( obj ) ) { if ( isNaN(obj) ) {
return "nan"; return "nan";
} }
return "number"; return "number";
...@@ -351,6 +426,91 @@ extend( QUnit, { ...@@ -351,6 +426,91 @@ extend( QUnit, {
return undefined; return undefined;
}, },
push: function( result, actual, expected, message ) {
if ( !config.current ) {
throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
}
var output, source,
details = {
module: config.current.module,
name: config.current.testName,
result: result,
message: message,
actual: actual,
expected: expected
};
message = escapeText( message ) || ( result ? "okay" : "failed" );
message = "<span class='test-message'>" + message + "</span>";
output = message;
if ( !result ) {
expected = escapeText( QUnit.jsDump.parse(expected) );
actual = escapeText( QUnit.jsDump.parse(actual) );
output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
if ( actual !== expected ) {
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
}
source = sourceFromStacktrace();
if ( source ) {
details.source = source;
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
}
output += "</table>";
}
runLoggingCallbacks( "log", QUnit, details );
config.current.assertions.push({
result: !!result,
message: output
});
},
pushFailure: function( message, source, actual ) {
if ( !config.current ) {
throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
}
var output,
details = {
module: config.current.module,
name: config.current.testName,
result: false,
message: message
};
message = escapeText( message ) || "error";
message = "<span class='test-message'>" + message + "</span>";
output = message;
output += "<table>";
if ( actual ) {
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
}
if ( source ) {
details.source = source;
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
}
output += "</table>";
runLoggingCallbacks( "log", QUnit, details );
config.current.assertions.push({
result: false,
message: output
});
},
url: function( params ) { url: function( params ) {
params = extend( extend( {}, QUnit.urlParams ), params ); params = extend( extend( {}, QUnit.urlParams ), params );
var key, var key,
...@@ -366,7 +526,13 @@ extend( QUnit, { ...@@ -366,7 +526,13 @@ extend( QUnit, {
window.location.pathname + querystring.slice( 0, -1 ); window.location.pathname + querystring.slice( 0, -1 );
}, },
extend: extend extend: extend,
id: id,
addEvent: addEvent,
addClass: addClass,
hasClass: hasClass,
removeClass: removeClass
// load, equiv, jsDump, diff: Attached later
}); });
/** /**
...@@ -401,29 +567,215 @@ extend( QUnit.constructor.prototype, { ...@@ -401,29 +567,215 @@ extend( QUnit.constructor.prototype, {
moduleDone: registerLoggingCallback( "moduleDone" ) moduleDone: registerLoggingCallback( "moduleDone" )
}); });
if ( !defined.document || document.readyState === "complete" ) {
config.autorun = true;
}
QUnit.load = function() { QUnit.load = function() {
runLoggingCallbacks( "begin", { runLoggingCallbacks( "begin", QUnit, {} );
totalTests: Test.count
});
// Initialize the configuration options // Initialize the config, saving the execution queue
extend( config, { var banner, filter, i, j, label, len, main, ol, toolbar, val, selection,
stats: { all: 0, bad: 0 }, urlConfigContainer, moduleFilter, userAgent,
moduleStats: { all: 0, bad: 0 }, numModules = 0,
started: 0, moduleNames = [],
updateRate: 1000, moduleFilterHtml = "",
autostart: true, urlConfigHtml = "",
filter: "", oldconfig = extend( {}, config );
semaphore: 1
}, true ); QUnit.init();
extend(config, oldconfig);
config.blocking = false; config.blocking = false;
len = config.urlConfig.length;
for ( i = 0; i < len; i++ ) {
val = config.urlConfig[i];
if ( typeof val === "string" ) {
val = {
id: val,
label: val
};
}
config[ val.id ] = QUnit.urlParams[ val.id ];
if ( !val.value || typeof val.value === "string" ) {
urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
"' name='" + escapeText( val.id ) +
"' type='checkbox'" +
( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
( config[ val.id ] ? " checked='checked'" : "" ) +
" title='" + escapeText( val.tooltip ) +
"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
} else {
urlConfigHtml += "<label for='qunit-urlconfig-" + escapeText( val.id ) +
"' title='" + escapeText( val.tooltip ) +
"'>" + val.label +
": </label><select id='qunit-urlconfig-" + escapeText( val.id ) +
"' name='" + escapeText( val.id ) +
"' title='" + escapeText( val.tooltip ) +
"'><option></option>";
selection = false;
if ( QUnit.is( "array", val.value ) ) {
for ( j = 0; j < val.value.length; j++ ) {
urlConfigHtml += "<option value='" + escapeText( val.value[j] ) + "'" +
( config[ val.id ] === val.value[j] ?
(selection = true) && " selected='selected'" :
"" ) +
">" + escapeText( val.value[j] ) + "</option>";
}
} else {
for ( j in val.value ) {
if ( hasOwn.call( val.value, j ) ) {
urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
( config[ val.id ] === j ?
(selection = true) && " selected='selected'" :
"" ) +
">" + escapeText( val.value[j] ) + "</option>";
}
}
}
if ( config[ val.id ] && !selection ) {
urlConfigHtml += "<option value='" + escapeText( config[ val.id ] ) +
"' selected='selected' disabled='disabled'>" +
escapeText( config[ val.id ] ) +
"</option>";
}
urlConfigHtml += "</select>";
}
}
for ( i in config.modules ) {
if ( config.modules.hasOwnProperty( i ) ) {
moduleNames.push(i);
}
}
numModules = moduleNames.length;
moduleNames.sort( function( a, b ) {
return a.localeCompare( b );
});
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
( config.module === undefined ? "selected='selected'" : "" ) +
">< All Modules ></option>";
for ( i = 0; i < numModules; i++) {
moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
">" + escapeText(moduleNames[i]) + "</option>";
}
moduleFilterHtml += "</select>";
// `userAgent` initialized at top of scope
userAgent = id( "qunit-userAgent" );
if ( userAgent ) {
userAgent.innerHTML = navigator.userAgent;
}
// `banner` initialized at top of scope
banner = id( "qunit-header" );
if ( banner ) {
banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
}
// `toolbar` initialized at top of scope
toolbar = id( "qunit-testrunner-toolbar" );
if ( toolbar ) {
// `filter` initialized at top of scope
filter = document.createElement( "input" );
filter.type = "checkbox";
filter.id = "qunit-filter-pass";
addEvent( filter, "click", function() {
var tmp,
ol = id( "qunit-tests" );
if ( filter.checked ) {
ol.className = ol.className + " hidepass";
} else {
tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
ol.className = tmp.replace( / hidepass /, " " );
}
if ( defined.sessionStorage ) {
if (filter.checked) {
sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
} else {
sessionStorage.removeItem( "qunit-filter-passed-tests" );
}
}
});
if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
filter.checked = true;
// `ol` initialized at top of scope
ol = id( "qunit-tests" );
ol.className = ol.className + " hidepass";
}
toolbar.appendChild( filter );
// `label` initialized at top of scope
label = document.createElement( "label" );
label.setAttribute( "for", "qunit-filter-pass" );
label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
label.innerHTML = "Hide passed tests";
toolbar.appendChild( label );
urlConfigContainer = document.createElement("span");
urlConfigContainer.innerHTML = urlConfigHtml;
// For oldIE support:
// * Add handlers to the individual elements instead of the container
// * Use "click" instead of "change" for checkboxes
// * Fallback from event.target to event.srcElement
addEvents( urlConfigContainer.getElementsByTagName("input"), "click", function( event ) {
var params = {},
target = event.target || event.srcElement;
params[ target.name ] = target.checked ?
target.defaultValue || true :
undefined;
window.location = QUnit.url( params );
});
addEvents( urlConfigContainer.getElementsByTagName("select"), "change", function( event ) {
var params = {},
target = event.target || event.srcElement;
params[ target.name ] = target.options[ target.selectedIndex ].value || undefined;
window.location = QUnit.url( params );
});
toolbar.appendChild( urlConfigContainer );
if (numModules > 1) {
moduleFilter = document.createElement( "span" );
moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
moduleFilter.innerHTML = moduleFilterHtml;
addEvent( moduleFilter.lastChild, "change", function() {
var selectBox = moduleFilter.getElementsByTagName("select")[0],
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
window.location = QUnit.url({
module: ( selectedModule === "" ) ? undefined : selectedModule,
// Remove any existing filters
filter: undefined,
testNumber: undefined
});
});
toolbar.appendChild(moduleFilter);
}
}
// `main` initialized at top of scope
main = id( "qunit-fixture" );
if ( main ) {
config.fixture = main.innerHTML;
}
if ( config.autostart ) { if ( config.autostart ) {
QUnit.start(); QUnit.start();
} }
}; };
if ( defined.document ) {
addEvent( window, "load", QUnit.load );
}
// `onErrorFnPrev` initialized at top of scope // `onErrorFnPrev` initialized at top of scope
// Preserve other handlers // Preserve other handlers
onErrorFnPrev = window.onerror; onErrorFnPrev = window.onerror;
...@@ -431,7 +783,7 @@ onErrorFnPrev = window.onerror; ...@@ -431,7 +783,7 @@ onErrorFnPrev = window.onerror;
// Cover uncaught exceptions // Cover uncaught exceptions
// Returning true will suppress the default browser handler, // Returning true will suppress the default browser handler,
// returning false will let it run. // returning false will let it run.
window.onerror = function( error, filePath, linerNr ) { window.onerror = function ( error, filePath, linerNr ) {
var ret = false; var ret = false;
if ( onErrorFnPrev ) { if ( onErrorFnPrev ) {
ret = onErrorFnPrev( error, filePath, linerNr ); ret = onErrorFnPrev( error, filePath, linerNr );
...@@ -446,7 +798,7 @@ window.onerror = function( error, filePath, linerNr ) { ...@@ -446,7 +798,7 @@ window.onerror = function( error, filePath, linerNr ) {
} }
QUnit.pushFailure( error, filePath + ":" + linerNr ); QUnit.pushFailure( error, filePath + ":" + linerNr );
} else { } else {
QUnit.test( "global failure", extend(function() { QUnit.test( "global failure", extend( function() {
QUnit.pushFailure( error, filePath + ":" + linerNr ); QUnit.pushFailure( error, filePath + ":" + linerNr );
}, { validTest: validTest } ) ); }, { validTest: validTest } ) );
} }
...@@ -461,7 +813,7 @@ function done() { ...@@ -461,7 +813,7 @@ function done() {
// Log the last module results // Log the last module results
if ( config.previousModule ) { if ( config.previousModule ) {
runLoggingCallbacks( "moduleDone", { runLoggingCallbacks( "moduleDone", QUnit, {
name: config.previousModule, name: config.previousModule,
failed: config.moduleStats.bad, failed: config.moduleStats.bad,
passed: config.moduleStats.all - config.moduleStats.bad, passed: config.moduleStats.all - config.moduleStats.bad,
...@@ -470,10 +822,58 @@ function done() { ...@@ -470,10 +822,58 @@ function done() {
} }
delete config.previousModule; delete config.previousModule;
var runtime = now() - config.started, var i, key,
passed = config.stats.all - config.stats.bad; banner = id( "qunit-banner" ),
tests = id( "qunit-tests" ),
runtime = +new Date() - config.started,
passed = config.stats.all - config.stats.bad,
html = [
"Tests completed in ",
runtime,
" milliseconds.<br/>",
"<span class='passed'>",
passed,
"</span> assertions of <span class='total'>",
config.stats.all,
"</span> passed, <span class='failed'>",
config.stats.bad,
"</span> failed."
].join( "" );
if ( banner ) {
banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
}
if ( tests ) {
id( "qunit-testresult" ).innerHTML = html;
}
if ( config.altertitle && defined.document && document.title ) {
// show ✖ for good, ✔ for bad suite result in title
// use escape sequences in case file gets loaded with non-utf-8-charset
document.title = [
( config.stats.bad ? "\u2716" : "\u2714" ),
document.title.replace( /^[\u2714\u2716] /i, "" )
].join( " " );
}
// clear own sessionStorage items if all tests passed
if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
// `key` & `i` initialized at top of scope
for ( i = 0; i < sessionStorage.length; i++ ) {
key = sessionStorage.key( i++ );
if ( key.indexOf( "qunit-test-" ) === 0 ) {
sessionStorage.removeItem( key );
}
}
}
// scroll back to top to show results
if ( config.scrolltop && window.scrollTo ) {
window.scrollTo(0, 0);
}
runLoggingCallbacks( "done", { runLoggingCallbacks( "done", QUnit, {
failed: config.stats.bad, failed: config.stats.bad,
passed: passed, passed: passed,
total: config.stats.all, total: config.stats.all,
...@@ -522,22 +922,21 @@ function validTest( test ) { ...@@ -522,22 +922,21 @@ function validTest( test ) {
return !include; return !include;
} }
// Doesn't support IE6 to IE9 // so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
// Later Safari and IE10 are supposed to support error.stack as well
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
function extractStacktrace( e, offset ) { function extractStacktrace( e, offset ) {
offset = offset === undefined ? 4 : offset; offset = offset === undefined ? 3 : offset;
var stack, include, i; var stack, include, i;
if ( e.stacktrace ) { if ( e.stacktrace ) {
// Opera
// Opera 12.x
return e.stacktrace.split( "\n" )[ offset + 3 ]; return e.stacktrace.split( "\n" )[ offset + 3 ];
} else if ( e.stack ) { } else if ( e.stack ) {
// Firefox, Chrome
// Firefox, Chrome, Safari 6+, IE10+, PhantomJS and Node
stack = e.stack.split( "\n" ); stack = e.stack.split( "\n" );
if ( /^error$/i.test( stack[ 0 ] ) ) { if (/^error$/i.test( stack[0] ) ) {
stack.shift(); stack.shift();
} }
if ( fileName ) { if ( fileName ) {
...@@ -554,13 +953,12 @@ function extractStacktrace( e, offset ) { ...@@ -554,13 +953,12 @@ function extractStacktrace( e, offset ) {
} }
return stack[ offset ]; return stack[ offset ];
} else if ( e.sourceURL ) { } else if ( e.sourceURL ) {
// Safari, PhantomJS
// Safari < 6 // hopefully one day Safari provides actual stacktraces
// exclude useless self-reference for generated Error objects // exclude useless self-reference for generated Error objects
if ( /qunit.js$/.test( e.sourceURL ) ) { if ( /qunit.js$/.test( e.sourceURL ) ) {
return; return;
} }
// for actual exceptions, this is useful // for actual exceptions, this is useful
return e.sourceURL + ":" + e.line; return e.sourceURL + ":" + e.line;
} }
...@@ -573,6 +971,31 @@ function sourceFromStacktrace( offset ) { ...@@ -573,6 +971,31 @@ function sourceFromStacktrace( offset ) {
} }
} }
/**
* Escape text for attribute or text content.
*/
function escapeText( s ) {
if ( !s ) {
return "";
}
s = s + "";
// Both single quotes and double quotes (for attributes)
return s.replace( /['"<>&]/g, function( s ) {
switch( s ) {
case "'":
return "&#039;";
case "\"":
return "&quot;";
case "<":
return "&lt;";
case ">":
return "&gt;";
case "&":
return "&amp;";
}
});
}
function synchronize( callback, last ) { function synchronize( callback, last ) {
config.queue.push( callback ); config.queue.push( callback );
...@@ -585,11 +1008,11 @@ function process( last ) { ...@@ -585,11 +1008,11 @@ function process( last ) {
function next() { function next() {
process( last ); process( last );
} }
var start = now(); var start = new Date().getTime();
config.depth = config.depth ? config.depth + 1 : 1; config.depth = config.depth ? config.depth + 1 : 1;
while ( config.queue.length && !config.blocking ) { while ( config.queue.length && !config.blocking ) {
if ( !defined.setTimeout || config.updateRate <= 0 || ( ( now() - start ) < config.updateRate ) ) { if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
config.queue.shift()(); config.queue.shift()();
} else { } else {
setTimeout( next, 13 ); setTimeout( next, 13 );
...@@ -627,12 +1050,12 @@ function checkPollution() { ...@@ -627,12 +1050,12 @@ function checkPollution() {
newGlobals = diff( config.pollution, old ); newGlobals = diff( config.pollution, old );
if ( newGlobals.length > 0 ) { if ( newGlobals.length > 0 ) {
QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join( ", " ) ); QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
} }
deletedGlobals = diff( old, config.pollution ); deletedGlobals = diff( old, config.pollution );
if ( deletedGlobals.length > 0 ) { if ( deletedGlobals.length > 0 ) {
QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join( ", " ) ); QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
} }
} }
...@@ -643,7 +1066,7 @@ function diff( a, b ) { ...@@ -643,7 +1066,7 @@ function diff( a, b ) {
for ( i = 0; i < result.length; i++ ) { for ( i = 0; i < result.length; i++ ) {
for ( j = 0; j < b.length; j++ ) { for ( j = 0; j < b.length; j++ ) {
if ( result[ i ] === b[ j ] ) { if ( result[i] === b[j] ) {
result.splice( i, 1 ); result.splice( i, 1 );
i--; i--;
break; break;
...@@ -653,15 +1076,14 @@ function diff( a, b ) { ...@@ -653,15 +1076,14 @@ function diff( a, b ) {
return result; return result;
} }
function extend( a, b, undefOnly ) { function extend( a, b ) {
for ( var prop in b ) { for ( var prop in b ) {
if ( hasOwn.call( b, prop ) ) { if ( hasOwn.call( b, prop ) ) {
// Avoid "Member not found" error in IE8 caused by messing with window.constructor // Avoid "Member not found" error in IE8 caused by messing with window.constructor
if ( !( prop === "constructor" && a === window ) ) { if ( !( prop === "constructor" && a === window ) ) {
if ( b[ prop ] === undefined ) { if ( b[ prop ] === undefined ) {
delete a[ prop ]; delete a[ prop ];
} else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) { } else {
a[ prop ] = b[ prop ]; a[ prop ] = b[ prop ];
} }
} }
...@@ -671,29 +1093,84 @@ function extend( a, b, undefOnly ) { ...@@ -671,29 +1093,84 @@ function extend( a, b, undefOnly ) {
return a; return a;
} }
function registerLoggingCallback( key ) { /**
* @param {HTMLElement} elem
* @param {string} type
* @param {Function} fn
*/
function addEvent( elem, type, fn ) {
if ( elem.addEventListener ) {
// Initialize key collection of logging callback // Standards-based browsers
if ( QUnit.objectType( config.callbacks[ key ] ) === "undefined" ) { elem.addEventListener( type, fn, false );
config.callbacks[ key ] = []; } else if ( elem.attachEvent ) {
}
return function( callback ) { // support: IE <9
config.callbacks[ key ].push( callback ); elem.attachEvent( "on" + type, fn );
}; } else {
}
function runLoggingCallbacks( key, args ) { // Caller must ensure support for event listeners is present
var i, l, callbacks; throw new Error( "addEvent() was called in a context without event listener support" );
}
}
callbacks = config.callbacks[ key ]; /**
for ( i = 0, l = callbacks.length; i < l; i++ ) { * @param {Array|NodeList} elems
callbacks[ i ]( args ); * @param {string} type
* @param {Function} fn
*/
function addEvents( elems, type, fn ) {
var i = elems.length;
while ( i-- ) {
addEvent( elems[i], type, fn );
} }
} }
// from jquery.js function hasClass( elem, name ) {
function inArray( elem, array ) { return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
}
function addClass( elem, name ) {
if ( !hasClass( elem, name ) ) {
elem.className += (elem.className ? " " : "") + name;
}
}
function removeClass( elem, name ) {
var set = " " + elem.className + " ";
// Class name may appear multiple times
while ( set.indexOf(" " + name + " ") > -1 ) {
set = set.replace(" " + name + " " , " ");
}
// If possible, trim it for prettiness, but not necessarily
elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
}
function id( name ) {
return defined.document && document.getElementById && document.getElementById( name );
}
function registerLoggingCallback( key ) {
return function( callback ) {
config[key].push( callback );
};
}
// Supports deprecated method of completely overwriting logging callbacks
function runLoggingCallbacks( key, scope, args ) {
var i, callbacks;
if ( QUnit.hasOwnProperty( key ) ) {
QUnit[ key ].call(scope, args );
} else {
callbacks = config[ key ];
for ( i = 0; i < callbacks.length; i++ ) {
callbacks[ i ].call( scope, args );
}
}
}
// from jquery.js
function inArray( elem, array ) {
if ( array.indexOf ) { if ( array.indexOf ) {
return array.indexOf( elem ); return array.indexOf( elem );
} }
...@@ -709,7 +1186,6 @@ function inArray( elem, array ) { ...@@ -709,7 +1186,6 @@ function inArray( elem, array ) {
function Test( settings ) { function Test( settings ) {
extend( this, settings ); extend( this, settings );
this.assert = new Assert( this );
this.assertions = []; this.assertions = [];
this.testNumber = ++Test.count; this.testNumber = ++Test.count;
} }
...@@ -717,12 +1193,32 @@ function Test( settings ) { ...@@ -717,12 +1193,32 @@ function Test( settings ) {
Test.count = 0; Test.count = 0;
Test.prototype = { Test.prototype = {
init: function() {
var a, b, li,
tests = id( "qunit-tests" );
if ( tests ) {
b = document.createElement( "strong" );
b.innerHTML = this.nameHtml;
// `a` initialized at top of scope
a = document.createElement( "a" );
a.innerHTML = "Rerun";
a.href = QUnit.url({ testNumber: this.testNumber });
li = document.createElement( "li" );
li.appendChild( b );
li.appendChild( a );
li.className = "running";
li.id = this.id = "qunit-test-output" + testId++;
tests.appendChild( li );
}
},
setup: function() { setup: function() {
if ( if (
// Emit moduleStart when we're switching from one module to another // Emit moduleStart when we're switching from one module to another
this.module !== config.previousModule || this.module !== config.previousModule ||
// They could be equal (both undefined) but if the previousModule property doesn't // They could be equal (both undefined) but if the previousModule property doesn't
// yet exist it means this is the first test in a suite that isn't wrapped in a // yet exist it means this is the first test in a suite that isn't wrapped in a
// module, in which case we'll just emit a moduleStart event for 'undefined'. // module, in which case we'll just emit a moduleStart event for 'undefined'.
...@@ -730,7 +1226,7 @@ Test.prototype = { ...@@ -730,7 +1226,7 @@ Test.prototype = {
!hasOwn.call( config, "previousModule" ) !hasOwn.call( config, "previousModule" )
) { ) {
if ( hasOwn.call( config, "previousModule" ) ) { if ( hasOwn.call( config, "previousModule" ) ) {
runLoggingCallbacks( "moduleDone", { runLoggingCallbacks( "moduleDone", QUnit, {
name: config.previousModule, name: config.previousModule,
failed: config.moduleStats.bad, failed: config.moduleStats.bad,
passed: config.moduleStats.all - config.moduleStats.bad, passed: config.moduleStats.all - config.moduleStats.bad,
...@@ -739,7 +1235,7 @@ Test.prototype = { ...@@ -739,7 +1235,7 @@ Test.prototype = {
} }
config.previousModule = this.module; config.previousModule = this.module;
config.moduleStats = { all: 0, bad: 0 }; config.moduleStats = { all: 0, bad: 0 };
runLoggingCallbacks( "moduleStart", { runLoggingCallbacks( "moduleStart", QUnit, {
name: this.module name: this.module
}); });
} }
...@@ -751,49 +1247,65 @@ Test.prototype = { ...@@ -751,49 +1247,65 @@ Test.prototype = {
teardown: function() {} teardown: function() {}
}, this.moduleTestEnvironment ); }, this.moduleTestEnvironment );
this.started = now(); this.started = +new Date();
runLoggingCallbacks( "testStart", { runLoggingCallbacks( "testStart", QUnit, {
name: this.testName, name: this.testName,
module: this.module, module: this.module
testNumber: this.testNumber
}); });
/*jshint camelcase:false */
/**
* Expose the current test environment.
*
* @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
*/
QUnit.current_testEnvironment = this.testEnvironment;
/*jshint camelcase:true */
if ( !config.pollution ) { if ( !config.pollution ) {
saveGlobal(); saveGlobal();
} }
if ( config.notrycatch ) { if ( config.notrycatch ) {
this.testEnvironment.setup.call( this.testEnvironment, this.assert ); this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
return; return;
} }
try { try {
this.testEnvironment.setup.call( this.testEnvironment, this.assert ); this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
} catch ( e ) { } catch( e ) {
this.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
} }
}, },
run: function() { run: function() {
config.current = this; config.current = this;
var running = id( "qunit-testresult" );
if ( running ) {
running.innerHTML = "Running: <br/>" + this.nameHtml;
}
if ( this.async ) { if ( this.async ) {
QUnit.stop(); QUnit.stop();
} }
this.callbackStarted = now(); this.callbackStarted = +new Date();
if ( config.notrycatch ) { if ( config.notrycatch ) {
this.callback.call( this.testEnvironment, this.assert ); this.callback.call( this.testEnvironment, QUnit.assert );
this.callbackRuntime = now() - this.callbackStarted; this.callbackRuntime = +new Date() - this.callbackStarted;
return; return;
} }
try { try {
this.callback.call( this.testEnvironment, this.assert ); this.callback.call( this.testEnvironment, QUnit.assert );
this.callbackRuntime = now() - this.callbackStarted; this.callbackRuntime = +new Date() - this.callbackStarted;
} catch ( e ) { } catch( e ) {
this.callbackRuntime = now() - this.callbackStarted; this.callbackRuntime = +new Date() - this.callbackStarted;
this.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
// else next test will carry the responsibility // else next test will carry the responsibility
saveGlobal(); saveGlobal();
...@@ -807,15 +1319,15 @@ Test.prototype = { ...@@ -807,15 +1319,15 @@ Test.prototype = {
config.current = this; config.current = this;
if ( config.notrycatch ) { if ( config.notrycatch ) {
if ( typeof this.callbackRuntime === "undefined" ) { if ( typeof this.callbackRuntime === "undefined" ) {
this.callbackRuntime = now() - this.callbackStarted; this.callbackRuntime = +new Date() - this.callbackStarted;
} }
this.testEnvironment.teardown.call( this.testEnvironment, this.assert ); this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
return; return;
} else { } else {
try { try {
this.testEnvironment.teardown.call( this.testEnvironment, this.assert ); this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
} catch ( e ) { } catch( e ) {
this.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
} }
} }
checkPollution(); checkPollution();
...@@ -823,44 +1335,115 @@ Test.prototype = { ...@@ -823,44 +1335,115 @@ Test.prototype = {
finish: function() { finish: function() {
config.current = this; config.current = this;
if ( config.requireExpects && this.expected === null ) { if ( config.requireExpects && this.expected === null ) {
this.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
} else if ( this.expected !== null && this.expected !== this.assertions.length ) { } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
this.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
} else if ( this.expected === null && !this.assertions.length ) { } else if ( this.expected === null && !this.assertions.length ) {
this.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
} }
var i, var i, assertion, a, b, time, li, ol,
bad = 0; test = this,
good = 0,
bad = 0,
tests = id( "qunit-tests" );
this.runtime = now() - this.started; this.runtime = +new Date() - this.started;
config.stats.all += this.assertions.length; config.stats.all += this.assertions.length;
config.moduleStats.all += this.assertions.length; config.moduleStats.all += this.assertions.length;
for ( i = 0; i < this.assertions.length; i++ ) { if ( tests ) {
if ( !this.assertions[ i ].result ) { ol = document.createElement( "ol" );
bad++; ol.className = "qunit-assert-list";
config.stats.bad++;
config.moduleStats.bad++; for ( i = 0; i < this.assertions.length; i++ ) {
assertion = this.assertions[i];
li = document.createElement( "li" );
li.className = assertion.result ? "pass" : "fail";
li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
ol.appendChild( li );
if ( assertion.result ) {
good++;
} else {
bad++;
config.stats.bad++;
config.moduleStats.bad++;
}
}
// store result when possible
if ( QUnit.config.reorder && defined.sessionStorage ) {
if ( bad ) {
sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
} else {
sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
}
}
if ( bad === 0 ) {
addClass( ol, "qunit-collapsed" );
}
// `b` initialized at top of scope
b = document.createElement( "strong" );
b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
addEvent(b, "click", function() {
var next = b.parentNode.lastChild,
collapsed = hasClass( next, "qunit-collapsed" );
( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
});
addEvent(b, "dblclick", function( e ) {
var target = e && e.target ? e.target : window.event.srcElement;
if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
target = target.parentNode;
}
if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
window.location = QUnit.url({ testNumber: test.testNumber });
}
});
// `time` initialized at top of scope
time = document.createElement( "span" );
time.className = "runtime";
time.innerHTML = this.runtime + " ms";
// `li` initialized at top of scope
li = id( this.id );
li.className = bad ? "fail" : "pass";
li.removeChild( li.firstChild );
a = li.firstChild;
li.appendChild( b );
li.appendChild( a );
li.appendChild( time );
li.appendChild( ol );
} else {
for ( i = 0; i < this.assertions.length; i++ ) {
if ( !this.assertions[i].result ) {
bad++;
config.stats.bad++;
config.moduleStats.bad++;
}
} }
} }
runLoggingCallbacks( "testDone", { runLoggingCallbacks( "testDone", QUnit, {
name: this.testName, name: this.testName,
module: this.module, module: this.module,
failed: bad, failed: bad,
passed: this.assertions.length - bad, passed: this.assertions.length - bad,
total: this.assertions.length, total: this.assertions.length,
runtime: this.runtime, runtime: this.runtime,
// HTML Reporter use
assertions: this.assertions,
testNumber: this.testNumber,
// DEPRECATED: this property will be removed in 2.0.0, use runtime instead // DEPRECATED: this property will be removed in 2.0.0, use runtime instead
duration: this.runtime duration: this.runtime
}); });
QUnit.reset();
config.current = undefined; config.current = undefined;
}, },
...@@ -868,6 +1451,9 @@ Test.prototype = { ...@@ -868,6 +1451,9 @@ Test.prototype = {
var bad, var bad,
test = this; test = this;
synchronize(function() {
test.init();
});
function run() { function run() {
// each of these can by async // each of these can by async
synchronize(function() { synchronize(function() {
...@@ -887,129 +1473,59 @@ Test.prototype = { ...@@ -887,129 +1473,59 @@ Test.prototype = {
// `bad` initialized at top of scope // `bad` initialized at top of scope
// defer when previous test run passed, if storage is available // defer when previous test run passed, if storage is available
bad = QUnit.config.reorder && defined.sessionStorage && bad = QUnit.config.reorder && defined.sessionStorage &&
+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
if ( bad ) { if ( bad ) {
run(); run();
} else { } else {
synchronize( run, true ); synchronize( run, true );
} }
}, }
};
// `assert` initialized at top of scope
// Assert helpers
// All of these must either call QUnit.push() or manually do:
// - runLoggingCallbacks( "log", .. );
// - config.current.assertions.push({ .. });
assert = QUnit.assert = {
/**
* Asserts rough true-ish result.
* @name ok
* @function
* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
*/
ok: function( result, msg ) {
if ( !config.current ) {
throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
}
result = !!result;
msg = msg || ( result ? "okay" : "failed" );
push: function( result, actual, expected, message ) {
var source, var source,
details = { details = {
module: this.module, module: config.current.module,
name: this.testName, name: config.current.testName,
result: result, result: result,
message: message, message: msg
actual: actual,
expected: expected,
testNumber: this.testNumber
}; };
if ( !result ) { msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
source = sourceFromStacktrace();
if ( !result ) {
source = sourceFromStacktrace( 2 );
if ( source ) { if ( source ) {
details.source = source; details.source = source;
msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" +
escapeText( source ) +
"</pre></td></tr></table>";
} }
} }
runLoggingCallbacks( "log", QUnit, details );
runLoggingCallbacks( "log", details ); config.current.assertions.push({
result: result,
this.assertions.push({ message: msg
result: !!result,
message: message
});
},
pushFailure: function( message, source, actual ) {
if ( !this instanceof Test ) {
throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace( 2 ) );
}
var details = {
module: this.module,
name: this.testName,
result: false,
message: message || "error",
actual: actual || null,
testNumber: this.testNumber
};
if ( source ) {
details.source = source;
}
runLoggingCallbacks( "log", details );
this.assertions.push({
result: false,
message: message
}); });
}
};
QUnit.pushFailure = function() {
if ( !QUnit.config.current ) {
throw new Error( "pushFailure() assertion outside test context, in " + sourceFromStacktrace( 2 ) );
}
// Gets current test obj
var currentTest = QUnit.config.current.assert.test;
return currentTest.pushFailure.apply( currentTest, arguments );
};
function Assert( testContext ) {
this.test = testContext;
}
// Assert helpers
QUnit.assert = Assert.prototype = {
// Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
expect: function( asserts ) {
if ( arguments.length === 1 ) {
this.test.expected = asserts;
} else {
return this.test.expected;
}
},
// Exports test.push() to the user API
push: function() {
var assert = this;
// Backwards compatibility fix.
// Allows the direct use of global exported assertions and QUnit.assert.*
// Although, it's use is not recommended as it can leak assertions
// to other tests from async tests, because we only get a reference to the current test,
// not exactly the test where assertion were intended to be called.
if ( !QUnit.config.current ) {
throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );
}
if ( !( assert instanceof Assert ) ) {
assert = QUnit.config.current.assert;
}
return assert.test.push.apply( assert.test, arguments );
},
/**
* Asserts rough true-ish result.
* @name ok
* @function
* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
*/
ok: function( result, message ) {
message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
QUnit.dump.parse( result ) );
if ( !!result ) {
this.push( true, result, true, message );
} else {
this.test.pushFailure( message, null, result );
}
}, },
/** /**
...@@ -1021,7 +1537,7 @@ QUnit.assert = Assert.prototype = { ...@@ -1021,7 +1537,7 @@ QUnit.assert = Assert.prototype = {
*/ */
equal: function( actual, expected, message ) { equal: function( actual, expected, message ) {
/*jshint eqeqeq:false */ /*jshint eqeqeq:false */
this.push( expected == actual, actual, expected, message ); QUnit.push( expected == actual, actual, expected, message );
}, },
/** /**
...@@ -1030,7 +1546,7 @@ QUnit.assert = Assert.prototype = { ...@@ -1030,7 +1546,7 @@ QUnit.assert = Assert.prototype = {
*/ */
notEqual: function( actual, expected, message ) { notEqual: function( actual, expected, message ) {
/*jshint eqeqeq:false */ /*jshint eqeqeq:false */
this.push( expected != actual, actual, expected, message ); QUnit.push( expected != actual, actual, expected, message );
}, },
/** /**
...@@ -1038,9 +1554,9 @@ QUnit.assert = Assert.prototype = { ...@@ -1038,9 +1554,9 @@ QUnit.assert = Assert.prototype = {
* @function * @function
*/ */
propEqual: function( actual, expected, message ) { propEqual: function( actual, expected, message ) {
actual = objectValues( actual ); actual = objectValues(actual);
expected = objectValues( expected ); expected = objectValues(expected);
this.push( QUnit.equiv( actual, expected ), actual, expected, message ); QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
}, },
/** /**
...@@ -1048,9 +1564,9 @@ QUnit.assert = Assert.prototype = { ...@@ -1048,9 +1564,9 @@ QUnit.assert = Assert.prototype = {
* @function * @function
*/ */
notPropEqual: function( actual, expected, message ) { notPropEqual: function( actual, expected, message ) {
actual = objectValues( actual ); actual = objectValues(actual);
expected = objectValues( expected ); expected = objectValues(expected);
this.push( !QUnit.equiv( actual, expected ), actual, expected, message ); QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
}, },
/** /**
...@@ -1058,7 +1574,7 @@ QUnit.assert = Assert.prototype = { ...@@ -1058,7 +1574,7 @@ QUnit.assert = Assert.prototype = {
* @function * @function
*/ */
deepEqual: function( actual, expected, message ) { deepEqual: function( actual, expected, message ) {
this.push( QUnit.equiv( actual, expected ), actual, expected, message ); QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
}, },
/** /**
...@@ -1066,7 +1582,7 @@ QUnit.assert = Assert.prototype = { ...@@ -1066,7 +1582,7 @@ QUnit.assert = Assert.prototype = {
* @function * @function
*/ */
notDeepEqual: function( actual, expected, message ) { notDeepEqual: function( actual, expected, message ) {
this.push( !QUnit.equiv( actual, expected ), actual, expected, message ); QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
}, },
/** /**
...@@ -1074,7 +1590,7 @@ QUnit.assert = Assert.prototype = { ...@@ -1074,7 +1590,7 @@ QUnit.assert = Assert.prototype = {
* @function * @function
*/ */
strictEqual: function( actual, expected, message ) { strictEqual: function( actual, expected, message ) {
this.push( expected === actual, actual, expected, message ); QUnit.push( expected === actual, actual, expected, message );
}, },
/** /**
...@@ -1082,67 +1598,91 @@ QUnit.assert = Assert.prototype = { ...@@ -1082,67 +1598,91 @@ QUnit.assert = Assert.prototype = {
* @function * @function
*/ */
notStrictEqual: function( actual, expected, message ) { notStrictEqual: function( actual, expected, message ) {
this.push( expected !== actual, actual, expected, message ); QUnit.push( expected !== actual, actual, expected, message );
}, },
"throws": function( block, expected, message ) { "throws": function( block, expected, message ) {
var actual, expectedType, var actual,
expectedOutput = expected, expectedOutput = expected,
ok = false; ok = false;
// 'expected' is optional unless doing string comparison // 'expected' is optional
if ( message == null && typeof expected === "string" ) { if ( !message && typeof expected === "string" ) {
message = expected; message = expected;
expected = null; expected = null;
} }
this.test.ignoreGlobalErrors = true; config.current.ignoreGlobalErrors = true;
try { try {
block.call( this.test.testEnvironment ); block.call( config.current.testEnvironment );
} catch (e) { } catch (e) {
actual = e; actual = e;
} }
this.test.ignoreGlobalErrors = false; config.current.ignoreGlobalErrors = false;
if ( actual ) { if ( actual ) {
expectedType = QUnit.objectType( expected );
// we don't want to validate thrown error // we don't want to validate thrown error
if ( !expected ) { if ( !expected ) {
ok = true; ok = true;
expectedOutput = null; expectedOutput = null;
// expected is an Error object
} else if ( expected instanceof Error ) {
ok = actual instanceof Error &&
actual.name === expected.name &&
actual.message === expected.message;
// expected is a regexp // expected is a regexp
} else if ( expectedType === "regexp" ) { } else if ( QUnit.objectType( expected ) === "regexp" ) {
ok = expected.test( errorString( actual ) ); ok = expected.test( errorString( actual ) );
// expected is a string // expected is a string
} else if ( expectedType === "string" ) { } else if ( QUnit.objectType( expected ) === "string" ) {
ok = expected === errorString( actual ); ok = expected === errorString( actual );
// expected is a constructor, maybe an Error constructor // expected is a constructor
} else if ( expectedType === "function" && actual instanceof expected ) { } else if ( actual instanceof expected ) {
ok = true; ok = true;
// expected is an Error object // expected is a validation function which returns true is validation passed
} else if ( expectedType === "object" ) { } else if ( expected.call( {}, actual ) === true ) {
ok = actual instanceof expected.constructor &&
actual.name === expected.name &&
actual.message === expected.message;
// expected is a validation function which returns true if validation passed
} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
expectedOutput = null; expectedOutput = null;
ok = true; ok = true;
} }
this.push( ok, actual, expectedOutput, message ); QUnit.push( ok, actual, expectedOutput, message );
} else { } else {
this.test.pushFailure( message, null, "No exception was thrown." ); QUnit.pushFailure( message, null, "No exception was thrown." );
} }
} }
}; };
/**
* @deprecated since 1.8.0
* Kept assertion helpers in root for backwards compatibility.
*/
extend( QUnit.constructor.prototype, assert );
/**
* @deprecated since 1.9.0
* Kept to avoid TypeErrors for undefined methods.
*/
QUnit.constructor.prototype.raises = function() {
QUnit.push( false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead" );
};
/**
* @deprecated since 1.0.0, replaced with error pushes since 1.3.0
* Kept to avoid TypeErrors for undefined methods.
*/
QUnit.constructor.prototype.equals = function() {
QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
};
QUnit.constructor.prototype.same = function() {
QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
};
// Test for equality any JavaScript type. // Test for equality any JavaScript type.
// Author: Philippe Rathé <prathe@gmail.com> // Author: Philippe Rathé <prathe@gmail.com>
QUnit.equiv = (function() { QUnit.equiv = (function() {
...@@ -1161,26 +1701,22 @@ QUnit.equiv = (function() { ...@@ -1161,26 +1701,22 @@ QUnit.equiv = (function() {
// the real equiv function // the real equiv function
var innerEquiv, var innerEquiv,
// stack to decide between skip/abort functions // stack to decide between skip/abort functions
callers = [], callers = [],
// stack to avoiding loops from circular referencing // stack to avoiding loops from circular referencing
parents = [], parents = [],
parentsB = [], parentsB = [],
getProto = Object.getPrototypeOf || function( obj ) { getProto = Object.getPrototypeOf || function ( obj ) {
/* jshint camelcase: false, proto: true */ /*jshint camelcase:false */
return obj.__proto__; return obj.__proto__;
}, },
callbacks = (function() { callbacks = (function () {
// for string, boolean, number and null // for string, boolean, number and null
function useStrictEquality( b, a ) { function useStrictEquality( b, a ) {
/*jshint eqeqeq:false */ /*jshint eqeqeq:false */
if ( b instanceof a.constructor || a instanceof b.constructor ) { if ( b instanceof a.constructor || a instanceof b.constructor ) {
// to catch short annotation VS 'new' annotation of a // to catch short annotation VS 'new' annotation of a
// declaration // declaration
// e.g. var i = 1; // e.g. var i = 1;
...@@ -1208,13 +1744,10 @@ QUnit.equiv = (function() { ...@@ -1208,13 +1744,10 @@ QUnit.equiv = (function() {
"regexp": function( b, a ) { "regexp": function( b, a ) {
return QUnit.objectType( b ) === "regexp" && return QUnit.objectType( b ) === "regexp" &&
// the regex itself // the regex itself
a.source === b.source && a.source === b.source &&
// and its modifiers // and its modifiers
a.global === b.global && a.global === b.global &&
// (gmi) ... // (gmi) ...
a.ignoreCase === b.ignoreCase && a.ignoreCase === b.ignoreCase &&
a.multiline === b.multiline && a.multiline === b.multiline &&
...@@ -1225,7 +1758,7 @@ QUnit.equiv = (function() { ...@@ -1225,7 +1758,7 @@ QUnit.equiv = (function() {
// - abort otherwise, // - abort otherwise,
// initial === would have catch identical references anyway // initial === would have catch identical references anyway
"function": function() { "function": function() {
var caller = callers[ callers.length - 1 ]; var caller = callers[callers.length - 1];
return caller !== Object && typeof caller !== "undefined"; return caller !== Object && typeof caller !== "undefined";
}, },
...@@ -1249,10 +1782,10 @@ QUnit.equiv = (function() { ...@@ -1249,10 +1782,10 @@ QUnit.equiv = (function() {
for ( i = 0; i < len; i++ ) { for ( i = 0; i < len; i++ ) {
loop = false; loop = false;
for ( j = 0; j < parents.length; j++ ) { for ( j = 0; j < parents.length; j++ ) {
aCircular = parents[ j ] === a[ i ]; aCircular = parents[j] === a[i];
bCircular = parentsB[ j ] === b[ i ]; bCircular = parentsB[j] === b[i];
if ( aCircular || bCircular ) { if ( aCircular || bCircular ) {
if ( a[ i ] === b[ i ] || aCircular && bCircular ) { if ( a[i] === b[i] || aCircular && bCircular ) {
loop = true; loop = true;
} else { } else {
parents.pop(); parents.pop();
...@@ -1261,7 +1794,7 @@ QUnit.equiv = (function() { ...@@ -1261,7 +1794,7 @@ QUnit.equiv = (function() {
} }
} }
} }
if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) { if ( !loop && !innerEquiv(a[i], b[i]) ) {
parents.pop(); parents.pop();
parentsB.pop(); parentsB.pop();
return false; return false;
...@@ -1273,7 +1806,6 @@ QUnit.equiv = (function() { ...@@ -1273,7 +1806,6 @@ QUnit.equiv = (function() {
}, },
"object": function( b, a ) { "object": function( b, a ) {
/*jshint forin:false */ /*jshint forin:false */
var i, j, loop, aCircular, bCircular, var i, j, loop, aCircular, bCircular,
// Default to true // Default to true
...@@ -1284,12 +1816,11 @@ QUnit.equiv = (function() { ...@@ -1284,12 +1816,11 @@ QUnit.equiv = (function() {
// comparing constructors is more strict than using // comparing constructors is more strict than using
// instanceof // instanceof
if ( a.constructor !== b.constructor ) { if ( a.constructor !== b.constructor ) {
// Allow objects with no prototype to be equivalent to // Allow objects with no prototype to be equivalent to
// objects with Object as their constructor. // objects with Object as their constructor.
if ( !( ( getProto( a ) === null && getProto( b ) === Object.prototype ) || if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
( getProto( b ) === null && getProto( a ) === Object.prototype ) ) ) { ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
return false; return false;
} }
} }
...@@ -1304,10 +1835,10 @@ QUnit.equiv = (function() { ...@@ -1304,10 +1835,10 @@ QUnit.equiv = (function() {
for ( i in a ) { for ( i in a ) {
loop = false; loop = false;
for ( j = 0; j < parents.length; j++ ) { for ( j = 0; j < parents.length; j++ ) {
aCircular = parents[ j ] === a[ i ]; aCircular = parents[j] === a[i];
bCircular = parentsB[ j ] === b[ i ]; bCircular = parentsB[j] === b[i];
if ( aCircular || bCircular ) { if ( aCircular || bCircular ) {
if ( a[ i ] === b[ i ] || aCircular && bCircular ) { if ( a[i] === b[i] || aCircular && bCircular ) {
loop = true; loop = true;
} else { } else {
eq = false; eq = false;
...@@ -1315,8 +1846,8 @@ QUnit.equiv = (function() { ...@@ -1315,8 +1846,8 @@ QUnit.equiv = (function() {
} }
} }
} }
aProperties.push( i ); aProperties.push(i);
if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) { if ( !loop && !innerEquiv(a[i], b[i]) ) {
eq = false; eq = false;
break; break;
} }
...@@ -1342,29 +1873,35 @@ QUnit.equiv = (function() { ...@@ -1342,29 +1873,35 @@ QUnit.equiv = (function() {
return true; // end transition return true; // end transition
} }
return ( (function( a, b ) { return (function( a, b ) {
if ( a === b ) { if ( a === b ) {
return true; // catch the most you can return true; // catch the most you can
} else if ( a === null || b === null || typeof a === "undefined" || } else if ( a === null || b === null || typeof a === "undefined" ||
typeof b === "undefined" || typeof b === "undefined" ||
QUnit.objectType( a ) !== QUnit.objectType( b ) ) { QUnit.objectType(a) !== QUnit.objectType(b) ) {
return false; // don't lose time with error prone cases
// don't lose time with error prone cases
return false;
} else { } else {
return bindCallbacks( a, callbacks, [ b, a ] ); return bindCallbacks(a, callbacks, [ b, a ]);
} }
// apply transition with (1..n) arguments // apply transition with (1..n) arguments
}( args[ 0 ], args[ 1 ] ) ) && innerEquiv.apply( this, args.splice( 1, args.length - 1 ) ) ); }( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
}; };
return innerEquiv; return innerEquiv;
}()); }());
// Based on jsDump by Ariel Flesler /**
// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
QUnit.dump = (function() { * http://flesler.blogspot.com Licensed under BSD
* (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
*
* @projectDescription Advanced and extensible data dumping for Javascript.
* @version 1.0.0
* @author Ariel Flesler
* @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
*/
QUnit.jsDump = (function() {
function quote( str ) { function quote( str ) {
return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\""; return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
} }
...@@ -1372,43 +1909,42 @@ QUnit.dump = (function() { ...@@ -1372,43 +1909,42 @@ QUnit.dump = (function() {
return o + ""; return o + "";
} }
function join( pre, arr, post ) { function join( pre, arr, post ) {
var s = dump.separator(), var s = jsDump.separator(),
base = dump.indent(), base = jsDump.indent(),
inner = dump.indent( 1 ); inner = jsDump.indent(1);
if ( arr.join ) { if ( arr.join ) {
arr = arr.join( "," + s + inner ); arr = arr.join( "," + s + inner );
} }
if ( !arr ) { if ( !arr ) {
return pre + post; return pre + post;
} }
return [ pre, inner + arr, base + post ].join( s ); return [ pre, inner + arr, base + post ].join(s);
} }
function array( arr, stack ) { function array( arr, stack ) {
var i = arr.length, var i = arr.length, ret = new Array(i);
ret = new Array( i );
this.up(); this.up();
while ( i-- ) { while ( i-- ) {
ret[ i ] = this.parse( arr[ i ], undefined, stack ); ret[i] = this.parse( arr[i] , undefined , stack);
} }
this.down(); this.down();
return join( "[", ret, "]" ); return join( "[", ret, "]" );
} }
var reName = /^function (\w+)/, var reName = /^function (\w+)/,
dump = { jsDump = {
// type is used mostly internally, you can fix a (custom)type in advance // type is used mostly internally, you can fix a (custom)type in advance
parse: function( obj, type, stack ) { parse: function( obj, type, stack ) {
stack = stack || []; stack = stack || [ ];
var inStack, res, var inStack, res,
parser = this.parsers[ type || this.typeOf( obj ) ]; parser = this.parsers[ type || this.typeOf(obj) ];
type = typeof parser; type = typeof parser;
inStack = inArray( obj, stack ); inStack = inArray( obj, stack );
if ( inStack !== -1 ) { if ( inStack !== -1 ) {
return "recursion(" + ( inStack - stack.length ) + ")"; return "recursion(" + (inStack - stack.length) + ")";
} }
if ( type === "function" ) { if ( type === "function" ) {
stack.push( obj ); stack.push( obj );
res = parser.call( this, obj, stack ); res = parser.call( this, obj, stack );
stack.pop(); stack.pop();
...@@ -1422,11 +1958,11 @@ QUnit.dump = (function() { ...@@ -1422,11 +1958,11 @@ QUnit.dump = (function() {
type = "null"; type = "null";
} else if ( typeof obj === "undefined" ) { } else if ( typeof obj === "undefined" ) {
type = "undefined"; type = "undefined";
} else if ( QUnit.is( "regexp", obj ) ) { } else if ( QUnit.is( "regexp", obj) ) {
type = "regexp"; type = "regexp";
} else if ( QUnit.is( "date", obj ) ) { } else if ( QUnit.is( "date", obj) ) {
type = "date"; type = "date";
} else if ( QUnit.is( "function", obj ) ) { } else if ( QUnit.is( "function", obj) ) {
type = "function"; type = "function";
} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
type = "window"; type = "window";
...@@ -1435,12 +1971,10 @@ QUnit.dump = (function() { ...@@ -1435,12 +1971,10 @@ QUnit.dump = (function() {
} else if ( obj.nodeType ) { } else if ( obj.nodeType ) {
type = "node"; type = "node";
} else if ( } else if (
// native arrays // native arrays
toString.call( obj ) === "[object Array]" || toString.call( obj ) === "[object Array]" ||
// NodeList objects // NodeList objects
( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null && typeof obj[ 0 ] === "undefined" ) ) ) ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
) { ) {
type = "array"; type = "array";
} else if ( obj.constructor === Error.prototype.constructor ) { } else if ( obj.constructor === Error.prototype.constructor ) {
...@@ -1451,7 +1985,7 @@ QUnit.dump = (function() { ...@@ -1451,7 +1985,7 @@ QUnit.dump = (function() {
return type; return type;
}, },
separator: function() { separator: function() {
return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " "; return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
}, },
// extra can be a number, shortcut for increasing-calling-decreasing // extra can be a number, shortcut for increasing-calling-decreasing
indent: function( extra ) { indent: function( extra ) {
...@@ -1462,7 +1996,7 @@ QUnit.dump = (function() { ...@@ -1462,7 +1996,7 @@ QUnit.dump = (function() {
if ( this.HTML ) { if ( this.HTML ) {
chr = chr.replace( /\t/g, " " ).replace( / /g, "&nbsp;" ); chr = chr.replace( /\t/g, " " ).replace( / /g, "&nbsp;" );
} }
return new Array( this.depth + ( extra || 0 ) ).join( chr ); return new Array( this.depth + ( extra || 0 ) ).join(chr);
}, },
up: function( a ) { up: function( a ) {
this.depth += a || 1; this.depth += a || 1;
...@@ -1471,7 +2005,7 @@ QUnit.dump = (function() { ...@@ -1471,7 +2005,7 @@ QUnit.dump = (function() {
this.depth -= a || 1; this.depth -= a || 1;
}, },
setParser: function( name, parser ) { setParser: function( name, parser ) {
this.parsers[ name ] = parser; this.parsers[name] = parser;
}, },
// The next 3 are exposed so you can use them // The next 3 are exposed so you can use them
quote: quote, quote: quote,
...@@ -1479,11 +2013,11 @@ QUnit.dump = (function() { ...@@ -1479,11 +2013,11 @@ QUnit.dump = (function() {
join: join, join: join,
// //
depth: 1, depth: 1,
// This is the list of parsers, to modify them, use dump.setParser // This is the list of parsers, to modify them, use jsDump.setParser
parsers: { parsers: {
window: "[Window]", window: "[Window]",
document: "[Document]", document: "[Document]",
error: function( error ) { error: function(error) {
return "Error(\"" + error.message + "\")"; return "Error(\"" + error.message + "\")";
}, },
unknown: "[Unknown]", unknown: "[Unknown]",
...@@ -1492,61 +2026,51 @@ QUnit.dump = (function() { ...@@ -1492,61 +2026,51 @@ QUnit.dump = (function() {
"function": function( fn ) { "function": function( fn ) {
var ret = "function", var ret = "function",
// functions never have name in IE // functions never have name in IE
name = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ]; name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
if ( name ) { if ( name ) {
ret += " " + name; ret += " " + name;
} }
ret += "( "; ret += "( ";
ret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" ); ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
return join( ret, dump.parse( fn, "functionCode" ), "}" ); return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
}, },
array: array, array: array,
nodelist: array, nodelist: array,
"arguments": array, "arguments": array,
object: function( map, stack ) { object: function( map, stack ) {
/*jshint forin:false */ /*jshint forin:false */
var ret = [], keys, key, val, i, nonEnumerableProperties; var ret = [ ], keys, key, val, i;
dump.up(); QUnit.jsDump.up();
keys = []; keys = [];
for ( key in map ) { for ( key in map ) {
keys.push( key ); keys.push( key );
} }
// Some properties are not always enumerable on Error objects.
nonEnumerableProperties = [ "message", "name" ];
for ( i in nonEnumerableProperties ) {
key = nonEnumerableProperties[ i ];
if ( key in map && !( key in keys ) ) {
keys.push( key );
}
}
keys.sort(); keys.sort();
for ( i = 0; i < keys.length; i++ ) { for ( i = 0; i < keys.length; i++ ) {
key = keys[ i ]; key = keys[ i ];
val = map[ key ]; val = map[ key ];
ret.push( dump.parse( key, "key" ) + ": " + dump.parse( val, undefined, stack ) ); ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
} }
dump.down(); QUnit.jsDump.down();
return join( "{", ret, "}" ); return join( "{", ret, "}" );
}, },
node: function( node ) { node: function( node ) {
var len, i, val, var len, i, val,
open = dump.HTML ? "&lt;" : "<", open = QUnit.jsDump.HTML ? "&lt;" : "<",
close = dump.HTML ? "&gt;" : ">", close = QUnit.jsDump.HTML ? "&gt;" : ">",
tag = node.nodeName.toLowerCase(), tag = node.nodeName.toLowerCase(),
ret = open + tag, ret = open + tag,
attrs = node.attributes; attrs = node.attributes;
if ( attrs ) { if ( attrs ) {
for ( i = 0, len = attrs.length; i < len; i++ ) { for ( i = 0, len = attrs.length; i < len; i++ ) {
val = attrs[ i ].nodeValue; val = attrs[i].nodeValue;
// IE6 includes all attributes in .attributes, even ones not explicitly set. // IE6 includes all attributes in .attributes, even ones not explicitly set.
// Those have values like undefined, null, 0, false, "" or "inherit". // Those have values like undefined, null, 0, false, "" or "inherit".
if ( val && val !== "inherit" ) { if ( val && val !== "inherit" ) {
ret += " " + attrs[ i ].nodeName + "=" + dump.parse( val, "attribute" ); ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
} }
} }
} }
...@@ -1559,7 +2083,6 @@ QUnit.dump = (function() { ...@@ -1559,7 +2083,6 @@ QUnit.dump = (function() {
return ret + open + "/" + tag + close; return ret + open + "/" + tag + close;
}, },
// function calls it internally, it's the arguments part of the function // function calls it internally, it's the arguments part of the function
functionArgs: function( fn ) { functionArgs: function( fn ) {
var args, var args,
...@@ -1569,11 +2092,10 @@ QUnit.dump = (function() { ...@@ -1569,11 +2092,10 @@ QUnit.dump = (function() {
return ""; return "";
} }
args = new Array( l ); args = new Array(l);
while ( l-- ) { while ( l-- ) {
// 97 is 'a' // 97 is 'a'
args[ l ] = String.fromCharCode( 97 + l ); args[l] = String.fromCharCode(97+l);
} }
return " " + args.join( ", " ) + " "; return " " + args.join( ", " ) + " ";
}, },
...@@ -1597,73 +2119,9 @@ QUnit.dump = (function() { ...@@ -1597,73 +2119,9 @@ QUnit.dump = (function() {
multiline: true multiline: true
}; };
return dump; return jsDump;
}()); }());
// back compat
QUnit.jsDump = QUnit.dump;
// For browser, export only select globals
if ( typeof window !== "undefined" ) {
// Deprecated
// Extend assert methods to QUnit and Global scope through Backwards compatibility
(function() {
var i,
assertions = Assert.prototype;
function applyCurrent( current ) {
return function() {
var assert = new Assert( QUnit.config.current );
current.apply( assert, arguments );
};
}
for ( i in assertions ) {
QUnit[ i ] = applyCurrent( assertions[ i ] );
}
})();
(function() {
var i, l,
keys = [
"test",
"module",
"expect",
"asyncTest",
"start",
"stop",
"ok",
"equal",
"notEqual",
"propEqual",
"notPropEqual",
"deepEqual",
"notDeepEqual",
"strictEqual",
"notStrictEqual",
"throws"
];
for ( i = 0, l = keys.length; i < l; i++ ) {
window[ keys[ i ] ] = QUnit[ keys[ i ] ];
}
})();
window.QUnit = QUnit;
}
// For CommonJS environments, export everything
if ( typeof module !== "undefined" && module.exports ) {
module.exports = QUnit;
}
// Get a reference to the global object, like window in browsers
}( (function() {
return this;
})() ));
/*istanbul ignore next */
/* /*
* Javascript Diff Algorithm * Javascript Diff Algorithm
* By John Resig (http://ejohn.org/) * By John Resig (http://ejohn.org/)
...@@ -1679,8 +2137,6 @@ if ( typeof module !== "undefined" && module.exports ) { ...@@ -1679,8 +2137,6 @@ if ( typeof module !== "undefined" && module.exports ) {
* QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over" * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
*/ */
QUnit.diff = (function() { QUnit.diff = (function() {
var hasOwn = Object.prototype.hasOwnProperty;
/*jshint eqeqeq:false, eqnull:true */ /*jshint eqeqeq:false, eqnull:true */
function diff( o, n ) { function diff( o, n ) {
var i, var i,
...@@ -1688,65 +2144,65 @@ QUnit.diff = (function() { ...@@ -1688,65 +2144,65 @@ QUnit.diff = (function() {
os = {}; os = {};
for ( i = 0; i < n.length; i++ ) { for ( i = 0; i < n.length; i++ ) {
if ( !hasOwn.call( ns, n[ i ] ) ) { if ( !hasOwn.call( ns, n[i] ) ) {
ns[ n[ i ] ] = { ns[ n[i] ] = {
rows: [], rows: [],
o: null o: null
}; };
} }
ns[ n[ i ] ].rows.push( i ); ns[ n[i] ].rows.push( i );
} }
for ( i = 0; i < o.length; i++ ) { for ( i = 0; i < o.length; i++ ) {
if ( !hasOwn.call( os, o[ i ] ) ) { if ( !hasOwn.call( os, o[i] ) ) {
os[ o[ i ] ] = { os[ o[i] ] = {
rows: [], rows: [],
n: null n: null
}; };
} }
os[ o[ i ] ].rows.push( i ); os[ o[i] ].rows.push( i );
} }
for ( i in ns ) { for ( i in ns ) {
if ( hasOwn.call( ns, i ) ) { if ( hasOwn.call( ns, i ) ) {
if ( ns[ i ].rows.length === 1 && hasOwn.call( os, i ) && os[ i ].rows.length === 1 ) { if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
n[ ns[ i ].rows[ 0 ] ] = { n[ ns[i].rows[0] ] = {
text: n[ ns[ i ].rows[ 0 ] ], text: n[ ns[i].rows[0] ],
row: os[ i ].rows[ 0 ] row: os[i].rows[0]
}; };
o[ os[ i ].rows[ 0 ] ] = { o[ os[i].rows[0] ] = {
text: o[ os[ i ].rows[ 0 ] ], text: o[ os[i].rows[0] ],
row: ns[ i ].rows[ 0 ] row: ns[i].rows[0]
}; };
} }
} }
} }
for ( i = 0; i < n.length - 1; i++ ) { for ( i = 0; i < n.length - 1; i++ ) {
if ( n[ i ].text != null && n[ i + 1 ].text == null && n[ i ].row + 1 < o.length && o[ n[ i ].row + 1 ].text == null && if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
n[ i + 1 ] == o[ n[ i ].row + 1 ] ) { n[ i + 1 ] == o[ n[i].row + 1 ] ) {
n[ i + 1 ] = { n[ i + 1 ] = {
text: n[ i + 1 ], text: n[ i + 1 ],
row: n[ i ].row + 1 row: n[i].row + 1
}; };
o[ n[ i ].row + 1 ] = { o[ n[i].row + 1 ] = {
text: o[ n[ i ].row + 1 ], text: o[ n[i].row + 1 ],
row: i + 1 row: i + 1
}; };
} }
} }
for ( i = n.length - 1; i > 0; i-- ) { for ( i = n.length - 1; i > 0; i-- ) {
if ( n[ i ].text != null && n[ i - 1 ].text == null && n[ i ].row > 0 && o[ n[ i ].row - 1 ].text == null && if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
n[ i - 1 ] == o[ n[ i ].row - 1 ] ) { n[ i - 1 ] == o[ n[i].row - 1 ]) {
n[ i - 1 ] = { n[ i - 1 ] = {
text: n[ i - 1 ], text: n[ i - 1 ],
row: n[ i ].row - 1 row: n[i].row - 1
}; };
o[ n[ i ].row - 1 ] = { o[ n[i].row - 1 ] = {
text: o[ n[ i ].row - 1 ], text: o[ n[i].row - 1 ],
row: i - 1 row: i - 1
}; };
} }
...@@ -1764,45 +2220,48 @@ QUnit.diff = (function() { ...@@ -1764,45 +2220,48 @@ QUnit.diff = (function() {
var i, pre, var i, pre,
str = "", str = "",
out = diff( o === "" ? [] : o.split( /\s+/ ), n === "" ? [] : n.split( /\s+/ ) ), out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
oSpace = o.match( /\s+/g ), oSpace = o.match(/\s+/g),
nSpace = n.match( /\s+/g ); nSpace = n.match(/\s+/g);
if ( oSpace == null ) { if ( oSpace == null ) {
oSpace = [ " " ]; oSpace = [ " " ];
} else { }
else {
oSpace.push( " " ); oSpace.push( " " );
} }
if ( nSpace == null ) { if ( nSpace == null ) {
nSpace = [ " " ]; nSpace = [ " " ];
} else { }
else {
nSpace.push( " " ); nSpace.push( " " );
} }
if ( out.n.length === 0 ) { if ( out.n.length === 0 ) {
for ( i = 0; i < out.o.length; i++ ) { for ( i = 0; i < out.o.length; i++ ) {
str += "<del>" + out.o[ i ] + oSpace[ i ] + "</del>"; str += "<del>" + out.o[i] + oSpace[i] + "</del>";
} }
} else { }
if ( out.n[ 0 ].text == null ) { else {
for ( n = 0; n < out.o.length && out.o[ n ].text == null; n++ ) { if ( out.n[0].text == null ) {
str += "<del>" + out.o[ n ] + oSpace[ n ] + "</del>"; for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
str += "<del>" + out.o[n] + oSpace[n] + "</del>";
} }
} }
for ( i = 0; i < out.n.length; i++ ) { for ( i = 0; i < out.n.length; i++ ) {
if ( out.n[ i ].text == null ) { if (out.n[i].text == null) {
str += "<ins>" + out.n[ i ] + nSpace[ i ] + "</ins>"; str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
} else { }
else {
// `pre` initialized at top of scope // `pre` initialized at top of scope
pre = ""; pre = "";
for ( n = out.n[ i ].row + 1; n < out.o.length && out.o[ n ].text == null; n++ ) { for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
pre += "<del>" + out.o[ n ] + oSpace[ n ] + "</del>"; pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
} }
str += " " + out.n[ i ].text + nSpace[ i ] + pre; str += " " + out.n[i].text + nSpace[i] + pre;
} }
} }
} }
...@@ -1811,685 +2270,19 @@ QUnit.diff = (function() { ...@@ -1811,685 +2270,19 @@ QUnit.diff = (function() {
}; };
}()); }());
(function() { // For browser, export only select globals
if ( typeof window !== "undefined" ) {
// Deprecated QUnit.init - Ref #530 extend( window, QUnit.constructor.prototype );
// Re-initialize the configuration options window.QUnit = QUnit;
QUnit.init = function() { }
var tests, banner, result, qunit,
config = QUnit.config;
config.stats = { all: 0, bad: 0 };
config.moduleStats = { all: 0, bad: 0 };
config.started = 0;
config.updateRate = 1000;
config.blocking = false;
config.autostart = true;
config.autorun = false;
config.filter = "";
config.queue = [];
config.semaphore = 1;
// Return on non-browser environments
// This is necessary to not break on node tests
if ( typeof window === "undefined" ) {
return;
}
qunit = id( "qunit" );
if ( qunit ) {
qunit.innerHTML =
"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
"<h2 id='qunit-banner'></h2>" +
"<div id='qunit-testrunner-toolbar'></div>" +
"<h2 id='qunit-userAgent'></h2>" +
"<ol id='qunit-tests'></ol>";
}
tests = id( "qunit-tests" );
banner = id( "qunit-banner" );
result = id( "qunit-testresult" );
if ( tests ) {
tests.innerHTML = "";
}
if ( banner ) {
banner.className = "";
}
if ( result ) {
result.parentNode.removeChild( result );
}
if ( tests ) {
result = document.createElement( "p" );
result.id = "qunit-testresult";
result.className = "result";
tests.parentNode.insertBefore( result, tests );
result.innerHTML = "Running...<br/>&nbsp;";
}
};
// Resets the test setup. Useful for tests that modify the DOM.
/*
DEPRECATED: Use multiple tests instead of resetting inside a test.
Use testStart or testDone for custom cleanup.
This method will throw an error in 2.0, and will be removed in 2.1
*/
QUnit.reset = function() {
// Return on non-browser environments
// This is necessary to not break on node tests
if ( typeof window === "undefined" ) {
return;
}
var fixture = id( "qunit-fixture" );
if ( fixture ) {
fixture.innerHTML = config.fixture;
}
};
// Don't load the HTML Reporter on non-Browser environments // For CommonJS environments, export everything
if ( typeof window === "undefined" ) { if ( typeof module !== "undefined" && module.exports ) {
return; module.exports = QUnit;
} }
var config = QUnit.config,
hasOwn = Object.prototype.hasOwnProperty,
defined = {
document: typeof window.document !== "undefined",
sessionStorage: (function() {
var x = "qunit-test-string";
try {
sessionStorage.setItem( x, x );
sessionStorage.removeItem( x );
return true;
} catch ( e ) {
return false;
}
}())
};
/**
* Escape text for attribute or text content.
*/
function escapeText( s ) {
if ( !s ) {
return "";
}
s = s + "";
// Both single quotes and double quotes (for attributes)
return s.replace( /['"<>&]/g, function( s ) {
switch ( s ) {
case "'":
return "&#039;";
case "\"":
return "&quot;";
case "<":
return "&lt;";
case ">":
return "&gt;";
case "&":
return "&amp;";
}
});
}
/**
* @param {HTMLElement} elem
* @param {string} type
* @param {Function} fn
*/
function addEvent( elem, type, fn ) {
if ( elem.addEventListener ) {
// Standards-based browsers
elem.addEventListener( type, fn, false );
} else if ( elem.attachEvent ) {
// support: IE <9
elem.attachEvent( "on" + type, fn );
}
}
/**
* @param {Array|NodeList} elems
* @param {string} type
* @param {Function} fn
*/
function addEvents( elems, type, fn ) {
var i = elems.length;
while ( i-- ) {
addEvent( elems[ i ], type, fn );
}
}
function hasClass( elem, name ) {
return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0;
}
function addClass( elem, name ) {
if ( !hasClass( elem, name ) ) {
elem.className += ( elem.className ? " " : "" ) + name;
}
}
function toggleClass( elem, name ) {
if ( hasClass( elem, name ) ) {
removeClass( elem, name );
} else {
addClass( elem, name );
}
}
function removeClass( elem, name ) {
var set = " " + elem.className + " ";
// Class name may appear multiple times
while ( set.indexOf( " " + name + " " ) >= 0 ) {
set = set.replace( " " + name + " ", " " );
}
// trim for prettiness
elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" );
}
function id( name ) {
return defined.document && document.getElementById && document.getElementById( name );
}
function getUrlConfigHtml() {
var i, j, val,
escaped, escapedTooltip,
selection = false,
len = config.urlConfig.length,
urlConfigHtml = "";
for ( i = 0; i < len; i++ ) {
val = config.urlConfig[ i ];
if ( typeof val === "string" ) {
val = {
id: val,
label: val
};
}
escaped = escapeText( val.id );
escapedTooltip = escapeText( val.tooltip );
config[ val.id ] = QUnit.urlParams[ val.id ];
if ( !val.value || typeof val.value === "string" ) {
urlConfigHtml += "<input id='qunit-urlconfig-" + escaped +
"' name='" + escaped + "' type='checkbox'" +
( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
( config[ val.id ] ? " checked='checked'" : "" ) +
" title='" + escapedTooltip + "'><label for='qunit-urlconfig-" + escaped +
"' title='" + escapedTooltip + "'>" + val.label + "</label>";
} else {
urlConfigHtml += "<label for='qunit-urlconfig-" + escaped +
"' title='" + escapedTooltip + "'>" + val.label +
": </label><select id='qunit-urlconfig-" + escaped +
"' name='" + escaped + "' title='" + escapedTooltip + "'><option></option>";
if ( QUnit.is( "array", val.value ) ) {
for ( j = 0; j < val.value.length; j++ ) {
escaped = escapeText( val.value[ j ] );
urlConfigHtml += "<option value='" + escaped + "'" +
( config[ val.id ] === val.value[ j ] ?
( selection = true ) && " selected='selected'" : "" ) +
">" + escaped + "</option>";
}
} else {
for ( j in val.value ) {
if ( hasOwn.call( val.value, j ) ) {
urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
( config[ val.id ] === j ?
( selection = true ) && " selected='selected'" : "" ) +
">" + escapeText( val.value[ j ] ) + "</option>";
}
}
}
if ( config[ val.id ] && !selection ) {
escaped = escapeText( config[ val.id ] );
urlConfigHtml += "<option value='" + escaped +
"' selected='selected' disabled='disabled'>" + escaped + "</option>";
}
urlConfigHtml += "</select>";
}
}
return urlConfigHtml;
}
function toolbarUrlConfigContainer() {
var urlConfigContainer = document.createElement( "span" );
urlConfigContainer.innerHTML = getUrlConfigHtml();
// For oldIE support:
// * Add handlers to the individual elements instead of the container
// * Use "click" instead of "change" for checkboxes
// * Fallback from event.target to event.srcElement
addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", function( event ) {
var params = {},
target = event.target || event.srcElement;
params[ target.name ] = target.checked ?
target.defaultValue || true :
undefined;
window.location = QUnit.url( params );
});
addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", function( event ) {
var params = {},
target = event.target || event.srcElement;
params[ target.name ] = target.options[ target.selectedIndex ].value || undefined;
window.location = QUnit.url( params );
});
return urlConfigContainer;
}
function getModuleNames() {
var i,
moduleNames = [];
for ( i in config.modules ) {
if ( config.modules.hasOwnProperty( i ) ) {
moduleNames.push( i );
}
}
moduleNames.sort(function( a, b ) {
return a.localeCompare( b );
});
return moduleNames;
}
function toolbarModuleFilterHtml() {
var i,
moduleFilterHtml = "",
moduleNames = getModuleNames();
if ( moduleNames.length <= 1 ) {
return false;
}
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label>" +
"<select id='qunit-modulefilter' name='modulefilter'><option value='' " +
( config.module === undefined ? "selected='selected'" : "" ) +
">< All Modules ></option>";
for ( i = 0; i < moduleNames.length; i++ ) {
moduleFilterHtml += "<option value='" +
escapeText( encodeURIComponent( moduleNames[ i ] ) ) + "' " +
( config.module === moduleNames[ i ] ? "selected='selected'" : "" ) +
">" + escapeText( moduleNames[ i ] ) + "</option>";
}
moduleFilterHtml += "</select>";
return moduleFilterHtml;
}
function toolbarModuleFilter() {
var moduleFilter = document.createElement( "span" ),
moduleFilterHtml = toolbarModuleFilterHtml();
if ( !moduleFilterHtml ) {
return false;
}
moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
moduleFilter.innerHTML = moduleFilterHtml;
addEvent( moduleFilter.lastChild, "change", function() {
var selectBox = moduleFilter.getElementsByTagName( "select" )[ 0 ],
selectedModule = decodeURIComponent( selectBox.options[ selectBox.selectedIndex ].value );
window.location = QUnit.url({
module: ( selectedModule === "" ) ? undefined : selectedModule,
// Remove any existing filters
filter: undefined,
testNumber: undefined
});
});
return moduleFilter;
}
function toolbarFilter() {
var testList = id( "qunit-tests" ),
filter = document.createElement( "input" );
filter.type = "checkbox";
filter.id = "qunit-filter-pass";
addEvent( filter, "click", function() {
if ( filter.checked ) {
addClass( testList, "hidepass" );
if ( defined.sessionStorage ) {
sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
}
} else {
removeClass( testList, "hidepass" );
if ( defined.sessionStorage ) {
sessionStorage.removeItem( "qunit-filter-passed-tests" );
}
}
});
if ( config.hidepassed || defined.sessionStorage &&
sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
filter.checked = true;
addClass( testList, "hidepass" );
}
return filter;
}
function toolbarLabel() {
var label = document.createElement( "label" );
label.setAttribute( "for", "qunit-filter-pass" );
label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
label.innerHTML = "Hide passed tests";
return label;
}
function appendToolbar() { // Get a reference to the global object, like window in browsers
var moduleFilter, }( (function() {
toolbar = id( "qunit-testrunner-toolbar" ); return this;
})() ));
if ( toolbar ) {
toolbar.appendChild( toolbarFilter() );
toolbar.appendChild( toolbarLabel() );
toolbar.appendChild( toolbarUrlConfigContainer() );
moduleFilter = toolbarModuleFilter();
if ( moduleFilter ) {
toolbar.appendChild( moduleFilter );
}
}
}
function appendBanner() {
var banner = id( "qunit-banner" );
if ( banner ) {
banner.className = "";
banner.innerHTML = "<a href='" +
QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) +
"'>" + banner.innerHTML + "</a> ";
}
}
function appendTestResults() {
var tests = id( "qunit-tests" ),
result = id( "qunit-testresult" );
if ( result ) {
result.parentNode.removeChild( result );
}
if ( tests ) {
tests.innerHTML = "";
result = document.createElement( "p" );
result.id = "qunit-testresult";
result.className = "result";
tests.parentNode.insertBefore( result, tests );
result.innerHTML = "Running...<br>&nbsp;";
}
}
function storeFixture() {
var fixture = id( "qunit-fixture" );
if ( fixture ) {
config.fixture = fixture.innerHTML;
}
}
function appendUserAgent() {
var userAgent = id( "qunit-userAgent" );
if ( userAgent ) {
userAgent.innerHTML = navigator.userAgent;
}
}
// HTML Reporter initialization and load
QUnit.begin(function() {
var qunit = id( "qunit" );
if ( qunit ) {
qunit.innerHTML =
"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
"<h2 id='qunit-banner'></h2>" +
"<div id='qunit-testrunner-toolbar'></div>" +
"<h2 id='qunit-userAgent'></h2>" +
"<ol id='qunit-tests'></ol>";
}
appendBanner();
appendTestResults();
appendUserAgent();
appendToolbar();
storeFixture();
});
QUnit.done(function( details ) {
var i, key,
banner = id( "qunit-banner" ),
tests = id( "qunit-tests" ),
html = [
"Tests completed in ",
details.runtime,
" milliseconds.<br>",
"<span class='passed'>",
details.passed,
"</span> assertions of <span class='total'>",
details.total,
"</span> passed, <span class='failed'>",
details.failed,
"</span> failed."
].join( "" );
if ( banner ) {
banner.className = details.failed ? "qunit-fail" : "qunit-pass";
}
if ( tests ) {
id( "qunit-testresult" ).innerHTML = html;
}
if ( config.altertitle && defined.document && document.title ) {
// show ✖ for good, ✔ for bad suite result in title
// use escape sequences in case file gets loaded with non-utf-8-charset
document.title = [
( details.failed ? "\u2716" : "\u2714" ),
document.title.replace( /^[\u2714\u2716] /i, "" )
].join( " " );
}
// clear own sessionStorage items if all tests passed
if ( config.reorder && defined.sessionStorage && details.failed === 0 ) {
for ( i = 0; i < sessionStorage.length; i++ ) {
key = sessionStorage.key( i++ );
if ( key.indexOf( "qunit-test-" ) === 0 ) {
sessionStorage.removeItem( key );
}
}
}
// scroll back to top to show results
if ( config.scrolltop && window.scrollTo ) {
window.scrollTo( 0, 0 );
}
});
function getNameHtml( name, module ) {
var nameHtml = "";
if ( module ) {
nameHtml = "<span class='module-name'>" + escapeText( module ) + "</span>: ";
}
nameHtml += "<span class='test-name'>" + escapeText( name ) + "</span>";
return nameHtml;
}
QUnit.testStart(function( details ) {
var a, b, li, running, assertList,
name = getNameHtml( details.name, details.module ),
tests = id( "qunit-tests" );
if ( tests ) {
b = document.createElement( "strong" );
b.innerHTML = name;
a = document.createElement( "a" );
a.innerHTML = "Rerun";
a.href = QUnit.url({ testNumber: details.testNumber });
li = document.createElement( "li" );
li.appendChild( b );
li.appendChild( a );
li.className = "running";
li.id = "qunit-test-output" + details.testNumber;
assertList = document.createElement( "ol" );
assertList.className = "qunit-assert-list";
li.appendChild( assertList );
tests.appendChild( li );
}
running = id( "qunit-testresult" );
if ( running ) {
running.innerHTML = "Running: <br>" + name;
}
});
QUnit.log(function( details ) {
var assertList, assertLi,
message, expected, actual,
testItem = id( "qunit-test-output" + details.testNumber );
if ( !testItem ) {
return;
}
message = escapeText( details.message ) || ( details.result ? "okay" : "failed" );
message = "<span class='test-message'>" + message + "</span>";
// pushFailure doesn't provide details.expected
// when it calls, it's implicit to also not show expected and diff stuff
// Also, we need to check details.expected existence, as it can exist and be undefined
if ( !details.result && hasOwn.call( details, "expected" ) ) {
expected = escapeText( QUnit.dump.parse( details.expected ) );
actual = escapeText( QUnit.dump.parse( details.actual ) );
message += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" +
expected +
"</pre></td></tr>";
if ( actual !== expected ) {
message += "<tr class='test-actual'><th>Result: </th><td><pre>" +
actual + "</pre></td></tr>" +
"<tr class='test-diff'><th>Diff: </th><td><pre>" +
QUnit.diff( expected, actual ) + "</pre></td></tr>";
}
if ( details.source ) {
message += "<tr class='test-source'><th>Source: </th><td><pre>" +
escapeText( details.source ) + "</pre></td></tr>";
}
message += "</table>";
// this occours when pushFailure is set and we have an extracted stack trace
} else if ( !details.result && details.source ) {
message += "<table>" +
"<tr class='test-source'><th>Source: </th><td><pre>" +
escapeText( details.source ) + "</pre></td></tr>" +
"</table>";
}
assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
assertLi = document.createElement( "li" );
assertLi.className = details.result ? "pass" : "fail";
assertLi.innerHTML = message;
assertList.appendChild( assertLi );
});
QUnit.testDone(function( details ) {
var testTitle, time, testItem, assertList,
good, bad, testCounts,
tests = id( "qunit-tests" );
// QUnit.reset() is deprecated and will be replaced for a new
// fixture reset function on QUnit 2.0/2.1.
// It's still called here for backwards compatibility handling
QUnit.reset();
if ( !tests ) {
return;
}
testItem = id( "qunit-test-output" + details.testNumber );
assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
good = details.passed;
bad = details.failed;
// store result when possible
if ( config.reorder && defined.sessionStorage ) {
if ( bad ) {
sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad );
} else {
sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name );
}
}
if ( bad === 0 ) {
addClass( assertList, "qunit-collapsed" );
}
// testItem.firstChild is the test name
testTitle = testItem.firstChild;
testCounts = bad ?
"<b class='failed'>" + bad + "</b>, " + "<b class='passed'>" + good + "</b>, " :
"";
testTitle.innerHTML += " <b class='counts'>(" + testCounts +
details.assertions.length + ")</b>";
addEvent( testTitle, "click", function() {
toggleClass( assertList, "qunit-collapsed" );
});
time = document.createElement( "span" );
time.className = "runtime";
time.innerHTML = details.runtime + " ms";
testItem.className = bad ? "fail" : "pass";
testItem.insertBefore( time, assertList );
});
if ( !defined.document || document.readyState === "complete" ) {
config.autorun = true;
}
if ( defined.document ) {
addEvent( window, "load", QUnit.load );
}
})();
...@@ -30,21 +30,19 @@ ...@@ -30,21 +30,19 @@
*/ */
tools_container.className = "tools-container"; tools_container.className = "tools-container";
Object.keys(data.class_definition).forEach(function(key) { Object.keys(data.class_definition).forEach(function(key) {
var _class_object = data.class_definition[key], tool; var _class = data.class_definition[key], tool;
// XXX "expand" the json schema "allOF" etc // XXX "expand" the json schema "allOF" etc
if (_class_object.allOf) { if (_class._class === "node") {
if (_class_object.allOf[0].$ref === "#/node") { tool = document.createElement("div");
tool = document.createElement("div"); // XXX maybe allow to configure the class name ?
// XXX maybe allow to configure the class name ? tool.className = "tool " + key;
tool.className = "tool " + key; tool.textContent = _class.name || key;
tool.textContent = _class_object.name || key; tool.draggable = true;
tool.draggable = true; tool.dataset.class_name = JSON.stringify(key);
tool.dataset.class_name = JSON.stringify(key); Object.keys(_class.css || {}).forEach(function(k) {
Object.keys(_class_object.css || {}).forEach(function(k) { tool.style[k] = _class.css[k];
tool.style[k] = _class_object.css[k]; });
}); tools_container.appendChild(tool);
tools_container.appendChild(tool);
}
} }
}); });
this.props.element.querySelector(".tools").appendChild(tools_container); this.props.element.querySelector(".tools").appendChild(tools_container);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment