String.prototype.create_namespace=function(){var xs=this.split(/\.|::|#/);var o=window;for(var i=0,l=xs.length;i<l;++i)o=o[xs[i]]=o[xs[i]]||{};return o;};String.prototype.resolve_namespace=function(starting_point){
var xs=this.split(/\.|::|#/);var o=starting_point||window;for(var i=0,l=xs.length;i<l;++i)o=o[xs[i]];if(!o)throw new Error("resolve_namespace: The namespace "+this+" does not exist.")
else return o;};function using(){var args=[];for(var i=0,l=arguments.length-1;i<l;++i)if(arguments[i].constructor===String)args.push(arguments[i].resolve_namespace())
else args.push(arguments[i]);return arguments[arguments.length-1].apply(this,args);}"com.spencertipping.ja".create_namespace();"com.spencertipping.ja::types".create_namespace()
using("com.spencertipping.ja::types",function(types){types.defined=function(x){return x!==null&&x!==undefined};types.is_null=function(x){return x===null};types.is_undefined=function(x){return x===undefined}
types.is_number=function(x){return types.defined(x)&&x.constructor===Number};types.is_string=function(x){return types.defined(x)&&x.constructor===String};types.is_boolean=function(x){return x===true||x===false}
types.is_array=function(x){return types.defined(x)&&x.constructor===Array};types.is_object=types.is_hash=function(x){return types.defined(x)&&x.constructor===Object}
types.is_function=function(x){return types.defined(x)&&x.constructor===Function};});"com.spencertipping.ja::fa".create_namespace();using("com.spencertipping.ja::fa",function(fa){
var _pluralize=function(f){return function(){if(arguments.length==1)return f.apply(this,arguments);else if(arguments.length==0)return f.apply(this,[]);else{var result=[]
for(var i=0,l=arguments.length;i<l;++i)result.push(f.apply(this,[arguments[i]]));return result;}};};fa.pluralize=_pluralize(_pluralize);fa.left_fold=fa.pluralize(function(f){
return function(){if(arguments.length<=2)return f.apply(this,arguments);else{var current=f.apply(this,[arguments[0],arguments[1]]);for(var i=2,l=arguments.length;i<l;++i)
current=f.apply(this,[current,arguments[i]]);return current;}};});fa.bind=function(f,x){return function(){return f.apply(x,arguments);};};});"com.spencertipping.ja::test".create_namespace()
"com.spencertipping.ja::test.equality".create_namespace();using("com.spencertipping.ja::test","com.spencertipping.ja::fa",function(test,fa){using("com.spencertipping.ja::types","com.spencertipping.ja::test.equality",function(types,equality){
equality.hash_is_subset=function(x,y){for(var k in x)if(!equality.structurally_equivalent(x[k],y[k]))return false;return true;};equality.structurally_equivalent=function(x,y){
if(x&&y&&x.constructor===y.constructor)if(types.is_array(x)&&x.length==y.length){for(var i=0,l=x.length;i<l;i++)if(!equality.structurally_equivalent(x[i],y[i]))return false
return true;}else if(types.is_object(x))return equality.hash_is_subset(x,y)&&equality.hash_is_subset(y,x);else return x===y;else return x===y;};});test.assert=function(condition,message){
if(condition)return null;else return{assertion:"Generic",message:message||"The condition was not met."};};test.assert.always=function(message){return{assertion:"Always",message:message}
};test.assert.is_true=function(condition,message){if(condition)return null;else return{assertion:"Truth",message:message};};test.assert.is_false=function(condition,message){
if(!condition)return null;else return{assertion:"Falsity",message:message};};test.assert.equal=function(x,y,message){if(x==y)return null;else return{assertion:"Equality",x:x,y:y,message:message}
};test.assert.unequal=function(x,y,message){if(x!=y)return null;else return{assertion:"Inequality",x:x,y:y,message:message};};test.assert.inequal=test.assert.unequal
test.assert.not_equal=test.assert.unequal;test.assert.structurally_equal=function(x,y,message){if(test.equality.structurally_equivalent(x,y))return null;else return{assertion:"Structural equivalence",x:x,y:y,message:message}
};test.assert.seq=test.assert.structurally_equal;test.assert.equiv=test.assert.structurally_equal;test.assert.equivalent=test.assert.structurally_equal;test.assert.error=function(action,message){
var error=false;try{action();}catch(e){error=true;}if(error)return null;else return{assertion:"Error on action",message:message};};test.assert.produces_error=test.assert.error
test.assert.fails=test.assert.error;test.assert.contains=function(list,item,message,comparison){for(var i=list.length;i>=0;--i)if(list[i]==item||(comparison&&comparison(list[i],item)))
return null;return{assertion:"Contains",list:list,item:item,message:message,comparison:comparison};};test.installed_tests=[];test.add=function(name,test_function){
test.installed_tests.push({name:name,test:test_function});};test.run=function(){var result={};for(var i=0,l=test.installed_tests.length;i<l;++i){var start_time=new Date().getTime()
result[test.installed_tests[i].name]=test.installed_tests[i].test()||"pass in "+(new Date().getTime()-start_time)+" ms";}return result;};});"com.spencertipping.ja::require".create_namespace()
using("com.spencertipping.ja::require","com.spencertipping.ja::test#assert","com.spencertipping.ja::types",function(require,assert,types){require.failed_requirements=[]
require.log_failed_requirements=true;require.error_on_failed_requirements=true;require.failed_requirements_mutex_in_use=false;require.log=function(assert_result){
if(!require.failed_requirements_mutex_in_use){require.failed_requirements_mutex_in_use=true;var new_index=require.failed_requirements.length;require.failed_requirements.push(assert_result)
require.failed_requirements_mutex_in_use=false;return new_index;}else throw new Error("require.log: Failed requirements mutex in use when trying to log "+assert_result)
};require.error=function(assert_result,result_index){var result=new Error("Requirement failed: "+(assert_result.message||assert_result.error||"(no message)")+(types.is_number(result_index)?" ["+result_index+"]":" [no result index]"))
result.message_object=assert_result.message||assert_result.error;throw result;};require.fail=function(assert_result){if(assert_result){var result_index=null;if(require.log_failed_requirements)result_index=require.log(assert_result)
if(require.error_on_failed_requirements)require.error(assert_result,result_index);return result_index;}};require.make_require_from_assertion=function(assertion){
return function(){var assert_result=assertion.apply(this,arguments);if(assert_result)require.fail(assert_result);return arguments[0];};};require.always=require.make_require_from_assertion(assert.always)
require.is_true=require.make_require_from_assertion(assert.is_true);require.is_false=require.make_require_from_assertion(assert.is_false);require.equal=require.make_require_from_assertion(assert.equal)
require.unequal=require.make_require_from_assertion(assert.unequal);require.fails=require.make_require_from_assertion(assert.fails);require.inequal=require.unequal
require.not_equal=require.unequal;require.exists=require.is_true;require.structurally_equal=require.make_require_from_assertion(assert.structurally_equal);require.seq=require.structurally_equal
require.equiv=require.structurally_equal;require.equivalent=require.structurally_equal;require.contains=require.make_require_from_assertion(assert.contains);});"com.spencertipping.ja::array".create_namespace()
using("com.spencertipping.ja::array","com.spencertipping.ja::fa","com.spencertipping.ja::types",function(array,fa,types){array.flatten=function(a){var result=[]
for(var i=0,l=a.length;i<l;++i)if(types.is_array(a[i]))result=result.concat(array.flatten(a[i]));else result.push(a[i]);return result;};array.contains=function(xs,x){
for(var i=xs.length;i>=0;--i)if(xs[i]==x)return true;return false;};array.to_set=function(a){var result=[];if(a.length==0)return result;result.has_ordering=(a.length>=2&&(a[0]>a[1])!=(a[1]>a[0]))
if(result.has_ordering){for(var i=a.length;i>=0;--i)a[i]=result[i];result.sort();var current_element=a[0];var new_result=[current_element];for(var i=1;i<result.length;++i)
(result[i]!=current_element)&&new_result.push(current_element=result[i]);new_result.has_ordering=true;new_result.is_set=true;return new_result;}else{for(var i=a.length;i>=0;--i){
var duplicate_found=false;for(var j=result.length;j>=0;--j)if(result[j]==a[i]){duplicate_found=true;break;}duplicate_found||result.push(a[i]);}result.is_set=true
return result;}};array.union=fa.left_fold(function(x,y){if(x.is_set&&y.is_set&&x.has_ordering&&y.has_ordering){var xi=0,xl=x.length;var yi=0,yl=y.length;var result=[]
while(xi<xl&&yi<yl){while(x[xi]<y[yi]&&xi<xl)result.push(x[xi++]);while(y[yi]<x[xi]&&yi<yl)result.push(y[yi++]);while(x[xi]==y[yi]&&xi<xl&&yi<yl){xi++;yi++;}}result.is_set=true
result.has_ordering=true;return result;}});});"com.spencertipping.ja::hash".create_namespace();using("com.spencertipping.ja::hash","com.spencertipping.ja::fa",function(hash,fa){
hash.keys=function(h){var result=[];for(var k in h)result.push(k);return result;};hash.values=function(h){var result=[];for(var k in h)result.push(h[k]);return result
};hash.copy=function(h){var result={};for(var k in h)result[k]=h[k];return result;};hash.merge_in_place=fa.left_fold(function(base,extension){for(var k in extension)base[k]=extension[k]
return base;});var union_function=function(right_wise){return fa.left_fold(function(x,y){var result={};if(right_wise){for(var k in x)result[k]=x[k];for(var k in y)result[k]=y[k]
}else{for(var k in y)result[k]=y[k];for(var k in x)result[k]=x[k];}return result;});};hash.union=hash.union_rw=hash.unionr=hash.merge=hash.merge_rw=hash.merger=union_function(true)
hash.union_lw=hash.unionl=hash.merge_lw=hash.mergel=union_function(false);var intersection_function=function(right_wise){return fa.left_fold(function(x,y){var result={}
if(right_wise){for(var k in y)if(x[k]!==undefined)result[k]=y[k];}else{for(var k in x)if(y[k]!==undefined)result[k]=x[k];}return result;});};hash.intersection=hash.intersection_rw=hash.intersectionr=intersection_function(true)
hash.intersection_lw=hash.intersectionl=intersection_function(false);hash.difference=function(x,y){var result={};for(var k in x)if(y[k]===undefined)result[k]=x[k]
return result;};hash.singleton=function(name,value){var result={};result[name]=value;return result;};hash.from=function(){var result={};for(var i=0,l=arguments.length;i<l;++i)
result[arguments[i][0]]=arguments[i][1];return result;};});"com.spencertipping.ja::string".create_namespace();using("com.spencertipping.ja::string",function(string){
string.capitalize=string.capitalise=function(s){if(s.length==0)return"";else if(s.length==1)return s.substring(0,1).toUpperCase();else return s.substring(0,1).toUpperCase()+s.substring(1,s.length)
};string.css_to_js=function(s){var result="";var fragments=s.split("-");result=fragments[0];for(var i=1,l=fragments.length;i<l;++i)result+=string.capitalize(fragments[i])
return result;};});"com.spencertipping.ja::json".create_namespace();using("com.spencertipping.ja::json","com.spencertipping.ja::types","com.spencertipping.ja::fa",function(json,types,fa){
var join=function(xs,separator){var result='';var actual_separator=separator===undefined?',':separator;if(xs.length==1)return xs[0];else{for(var i=0;i<xs.length-1;++i)result+=xs[i]+actual_separator
return result+xs[xs.length-1];}};json.encode=fa.pluralize(function(o){if(o===null||o===undefined)return'null';else if(types.is_number(o))return String(o);else if(types.is_string(o))return'"'+o.replace(/\\/g,'\\\\').replace(/"/g, '\\"') + '"'
else if(types.is_array(o))return'['+join(json.encode.apply(this,o))+']';else if(types.is_object(o)){var serialized_attributes=[];for(var k in o)serialized_attributes.push(json.encode(k)+':'+json.encode(o[k]))
return'{'+join(serialized_attributes)+'}';}else throw new Error('The object '+o+'cannot be serialized.');});json.decode=function(s){return eval(s)};});"com.spencertipping.ja::oo".create_namespace()
using("com.spencertipping.ja::oo","com.spencertipping.ja::types","com.spencertipping.ja::fa","com.spencertipping.ja::require","com.spencertipping.ja::array","com.spencertipping.ja::hash",function(oo,types,fa,require,array,hash){
var inheritance_sentinel_object={};oo.inherit_before_method=function(obj,base_method,child_method){require.is_true(base_method,"inherit_before_method: base_method must be defined.")
require.is_true(child_method,"inherit_before_method: child_method must be defined.");return function(){child_method.apply(obj,arguments);return base_method.apply(obj,arguments)
};};oo.inherit_after_method=function(obj,base_method,child_method){require.is_true(base_method,"inherit_after_method: base_method must be defined.");require.is_true(child_method,"inherit_after_method: child_method must be defined.")
return function(){return child_method.apply(obj,[base_method.apply(obj,arguments)].concat(Array.prototype.slice.call(arguments)));};};oo.inherit_after_blind_method=function(obj,base_method,child_method){
require.is_true(base_method,"inherit_after_blind_method: base_method must be defined.");require.is_true(child_method,"inherit_after_blind_method: child_method must be defined.")
return function(){base_method.apply(obj,arguments);return child_method.apply(obj,arguments);};};oo.inherit_around_method=function(obj,base_method,child_method){require.is_true(base_method,"inherit_around_method: base_method must be defined.")
require.is_true(child_method,"inherit_around_method: child_method must be defined.");return function(){return child_method.apply(obj,[base_method].concat(Array.prototype.slice.call(arguments)))
};};oo.inherit_replace_method=function(obj,base_method,child_method){require.is_true(child_method,"inherit_replace_method: child_method must be defined.");return function(){
return child_method.apply(obj,arguments);};};oo.inherit_ctor_method=function(obj,base_method,child_method){if(base_method&&child_method)return oo.inherit_after_blind_method(obj,base_method,child_method)
else if(base_method)return oo.inherit_replace_method(obj,null,base_method);else if(child_method)return oo.inherit_replace_method(obj,base_method,child_method);else require.always("inherit_ctor_method: This shouldn't happen, though it isn't anything too awful.")
};oo.inherit_transform_method=function(obj,base_method,child_method){require.is_true(base_method,"inherit_transform_method: No method was provided to transform.")
require.is_true(child_method,"inherit_transform_method: No transformer function was provided.");var result=child_method(base_method);require.is_true(types.is_function(result),{problem:"inherit_transform_method: The transformation resulted in something that isn't a function.",
object:result});return result;};oo.inheritance_sentinel_function=fa.pluralize(function(transform){return function(f){return{sentinel:inheritance_sentinel_object,transform:transform,f:f}
};});oo.before=oo.inheritance_sentinel_function(oo.inherit_before_method);oo.after=oo.inheritance_sentinel_function(oo.inherit_after_method);oo.after_blind=oo.inheritance_sentinel_function(oo.inherit_after_blind_method)
oo.around=oo.inheritance_sentinel_function(oo.inherit_around_method);oo.replace=oo.inheritance_sentinel_function(oo.inherit_replace_method);oo.ctor=oo.inheritance_sentinel_function(oo.inherit_ctor_method)
oo.transform=oo.inheritance_sentinel_function(oo.inherit_transform_method);oo.uninheritable_members=["prototype","constructor","rtti","class_rtti"];oo.inherit=fa.left_fold(function(base,child){
for(var k in child)if(!array.contains(oo.uninheritable_members,k)){var base_method=base[k]||null;var child_method=child[k]||null;if(types.is_function(child_method)){
require.is_false(types.is_function(base_method),"inherit: Method overrides must occur explicitly (use "+k+": oo.replace (...)).");base[k]=oo.inherit_replace_method(base,base_method,child_method)
}else if(types.is_object(child_method)&&child_method.sentinel===inheritance_sentinel_object)base[k]=child_method.transform(base,base_method,child_method.f);else require.is_false(child_method,{note:"inherit: Invalid object specified in class inheritance as a child class member under the "+k+" attribute.",
object:child_method});}return base;});var uid=0;oo.create_object=function(base_object,extensions,initialization_arguments){var result=oo.inherit.apply(this,array.flatten([base_object].concat(extensions)))
if(types.is_function(result.initialize)&&!(initialization_arguments.length>1&&types.is_object(initialization_arguments[1])&&initialization_arguments[1].defer_constructor))
result.initialize(initialization_arguments[0]);return result;};oo.create_class=function(base_class,extensions){var extensions=array.flatten(Array.prototype.slice.call(arguments,1))
var class_rtti={base_class:base_class};var duplicate_extensions=[];class_rtti.classes=hash.copy((base_class.class_rtti&&base_class.class_rtti.classes)||{});for(var i=extensions.length-1;i>=0;--i){
var r=extensions[i].class_rtti;require.exists(r&&r.uid,{note:"create_class: Extension has no RTTI UID.",object:extensions[i]});if(class_rtti.classes[r.uid])duplicate_extensions.push(i)
else class_rtti.classes[r.uid]=extensions[i];}for(var i=duplicate_extensions.length-1;i>=0;--i)extensions.splice(duplicate_extensions[i],1);var result_constructor=function(initialization_hash,options){
var base_instantiation=base_class.apply(this,[initialization_hash,{defer_constructor:true}]);var result=oo.create_object.apply(this,[base_instantiation,extensions,[initialization_hash,options]])
result.rtti={classes:hash.copy(class_rtti.classes),originating_constructor:result_constructor};return result;};result_constructor.class_rtti=class_rtti;return oo.create_constructor(result_constructor)
};oo.create_constructor=function(f){f.class_rtti=f.class_rtti||{};f.class_rtti.is_constructor=true;f.class_rtti.uid=f.class_rtti.uid||++uid;f.class_rtti.classes=f.class_rtti.classes||{}
if(!f.class_rtti.classes[f.class_rtti.uid])f.class_rtti.classes[f.class_rtti.uid]=f;return f;};oo.create_extension=fa.pluralize(function(e){if(types.is_array(e))return oo.create_extension.apply(this,e)
else if(e.class_rtti&&e.class_rtti.uid)return e;else{e.class_rtti={uid:++uid};return e;}});oo.flatten_composite=array.flatten;oo.is_subtype=function(x,y){var x_rtti=x.rtti||x.class_rtti
var y_rtti=y.rtti||y.class_rtti;require.exists(x_rtti,{note:"is_subtype: No RTTI exists for x.",object:x});require.exists(y_rtti,{note:"is_subtype: No RTTI exists for y.",object:y})
for(var k in x_rtti.classes)if(x_rtti.classes[k]&&!y_rtti.classes[k])return false;return true;};oo.type_equal=oo.types_equal=function(x,y){return oo.is_subtype(x,y)&&oo.is_subtype(y,x)
};});"com.spencertipping.ja::ml".create_namespace();using("com.spencertipping.ja::ml","com.spencertipping.ja::hash","com.spencertipping.ja::oo","com.spencertipping.ja::fa",
"com.spencertipping.ja::array",function(ml,hash,oo,fa,array){ml.has_getter=function(name,function_name){return oo.create_extension(hash.singleton(function_name||"get_"+name,function(){
return this[name];}));};ml.has_setter=function(name,function_name){return oo.create_extension(hash.singleton(function_name||"set_"+name,function(value){this[name]=value
}));};ml.has_attribute=function(name){return[ml.has_getter(name),ml.has_setter(name)];};var ensure_event_listener_list_exists=function(obj,name){return obj["listeners_for_"+name]=obj["listeners_for_"+name]||[]
};ml.provides_event_trigger=function(name){return oo.create_extension(hash.singleton("alert_"+name+"_listeners",function(){var listeners=ensure_event_listener_list_exists(this,name)
var result=[];for(var i=0,l=listeners.length;i<l;++i)result.push(listeners[i].apply(this,arguments));return result;}));};ml.provides_event_server_interface=function(name){
return oo.create_extension(hash.from(["add_"+name+"_listener",fa.pluralize(function(listener){var listeners=ensure_event_listener_list_exists(this,name);if(!array.contains(listeners,listener))return listeners.push(listener)
else return false;})],["remove_"+name+"_listener",fa.pluralize(function(listener){var listeners=ensure_event_listener_list_exists(this,name);for(var i=listeners.length-1;i>=0;--i)
if(listeners[i]==listener)return listeners.splice(i,1)[0];return false;})],["get_"+name+"_listeners",function(){return ensure_event_listener_list_exists(this,name)
}]));};ml.provides_event=function(name){return[ml.provides_event_trigger(name),ml.provides_event_server_interface(name)];};ml.eventful_getter=function(name,function_name){
return oo.create_extension(hash.singleton(function_name||"get_"+name,function(){this["alert_"+name+"_retrieved_listeners"]();return this[name];}));};ml.eventful_setter=function(name,function_name){
return oo.create_extension(hash.singleton(function_name||"set_"+name,function(value){this["alert_"+name+"_changed_listeners"](value);this[name]=value;}));};ml.has_eventful_getter=function(name){
return[ml.provides_event(name+"_retrieved"),ml.eventful_getter(name)];};ml.has_eventful_setter=function(name){return[ml.provides_event(name+"_changed"),ml.eventful_setter(name)]
};ml.has_eventful_attribute=function(name){return[ml.has_eventful_getter(name),ml.has_eventful_setter(name)];};});"com.spencertipping.ja::dom".create_namespace()
using("com.spencertipping.ja::dom","com.spencertipping.ja::oo","com.spencertipping.ja::hash","com.spencertipping.ja::ml",function(dom,oo,hash,ml){dom.html_template_base_class=function(element_type,initializer){
return oo.create_constructor(function(args){var result=document.createElement(element_type);result=(initializer&&initializer(result,args))||result;return result
});};dom.a=dom.link=dom.html_template_base_class("a");dom.line_input=dom.html_template_base_class("input",function(result){result.type="text";return result});dom.password_input=dom.html_template_base_class("input",function(result){result.type="password";return result})
dom.check=dom.check_box=dom.html_template_base_class("input",function(result){result.type="check";return result});dom.submit=dom.button=dom.html_template_base_class("input",function(result){result.type="submit";return result})
dom.area_input=dom.html_template_base_class("textarea");dom.select=dom.select_box=dom.html_template_base_class("select");dom.option=dom.html_template_base_class("option")
dom.div=dom.html_template_base_class("div");dom.provides_event_broadcast=function(event_name){return function(result_value){return oo.create_extension(hash.merge({initialize:oo.ctor(function(args){
this["on"+event_name]=function(){this["alert_"+event_name+"_listeners"].apply(this,arguments);return result_value;};})},ml.provides_event(event_name)));};};dom.event_classes=["click","dblclick","mouseover","mouseout","mousedown","mouseup","mousemove",
"keydown","keypress","keyup","load","unload","abort","error","resize","scroll","select","change","submit","focus","blur"];for(var i=dom.event_classes.length-1;i>=0;--i)
dom["listens_for_"+dom.event_classes[i]]=dom["has_"+dom.event_classes[i]]=dom.provides_event_broadcast(dom.event_classes[i]);"com.spencertipping.ja::dom.event".create_namespace()
using("com.spencertipping.ja::dom.event",function(event){event.event_object=function(e){return e||window.event;};event.stop=function(e){e=dom.event_object(e);(e.stopPropagation&&(e.stopPropagation()||true))||(e.cancelBubble=true)
};event.target=function(e){e=dom.event_object(e);var result=e.target||e.srcElement;return result.nodeType==3?result.parentNode:result;};event.key_code=function(e){
e=dom.event_object(e);return e.keyCode||e.which;};event.button=function(e){e=dom.event_object(e);return e.button||e.which;};event.is_left_button=function(e){return dom.button(e)<2}
event.is_right_button=function(e){return dom.button(e)==2};event.mouse_coordinates=function(e){var x=0;var y=0;e=dom.event_object(e);x=e.pageX||(e.clientX+document.body.scrollLeft+document.documentElement.scrollLeft)
y=e.pageY||(e.clientY+document.body.scrollTop+document.documentElement.scrollTop);return[x,y];};});dom.has_css_class=function(classname){return{initialize:oo.ctor(function(args){
this.className=classname;})};};});"com.spencertipping.ja::style".create_namespace();using("com.spencertipping.ja::style","com.spencertipping.ja::hash","com.spencertipping.ja::types","com.spencertipping.ja::string",
function(style,hash,types,string){style.parse_css=function(s){var props=s.split(/;\s*/);var result={};for(var i=0,l=props.length;i<l;++i){var prop=props[i].split(/:\s*/)
result[string.css_to_js(prop[0])]=prop[1];}return result;};style.create=function(){var result={};for(var i=0,l=arguments.length;i<l;++i)if(types.is_string(arguments[i]))hash.merge_in_place(result,style.parse_css(arguments[i]))
else hash.merge_in_place(result,arguments[i]);return result;};style.reset=function(element){for(var k in element.style)try{element.style[k]&&(element.style[k]='')}catch(e){}}
style.merge=function(element,new_style){for(var k in new_style)element.style[k]=new_style[k];};style.replace=function(element,new_style){style.reset(element);style.merge(element,new_style)
};style.color=style.color_255=function(r,g,b){return'rgb('+r+','+g+','+b+')'};style.colorf=style.color_1=function(r,g,b){return'rgb('+Math.round(r*255)+','+Math.round(g*255)+','+Math.round(b*255)+')'}
style.colora=function(c){return'rgb('+Math.round(c[0]*255)+','+Math.round(c[1]*255)+','+Math.round(c[2]*255)+')'};style.mix_colors=function(c1,c2,f){var one_minus_f=1.0-f
return[one_minus_f*c1[0]+f*c2[0],one_minus_f*c1[1]+f*c2[1],one_minus_f*c1[2]+f*c2[2]];};});"com.spencertipping.ja::state".create_namespace();using("com.spencertipping.ja::state","com.spencertipping.ja::ml","com.spencertipping.ja::oo","com.spencertipping.ja::hash",
"com.spencertipping.ja::require",function(state,ml,oo,hash,require){state.has_states=function(){var states=Array.prototype.slice.call(arguments);require.is_true(states.length>0,"has_states: At least one state must be provided.")
return oo.create_extension(hash.union(ml.provides_event("state_change"),{initialize:oo.ctor(function(args){this.state=args.initial_state||states[0];this.possible_states=states
}),become:function(state){require.contains(states,state,"state.has_states#become: You cannot change into an invalid state.");this.alert_state_change_listeners(state,this.state,this)
this.state=state;},current_state:function(){return this.state;}}));};});"com.spencertipping.ja::timing".create_namespace();using("com.spencertipping.ja::timing","com.spencertipping.ja::fa",function(timing,fa){
timing.run=timing.invoke=timing.call=function(what,when){return window.setTimeout(what,when)};timing.run_asap=timing.asap=function(what){return window.setTimeout(what,0)}
timing.cancel=timing.stop=function(t){return window.clearTimeout(t)};timing.repeat=function(what,freq){return window.setInterval(what,freq)};timing.kill=function(t){return window.clearInterval(t)}
timing.interpolate=function(what,delay,steps){var interpolation_object={start_time:new Date().getTime(),delay:delay,what:what,abort:false};interpolation_object.delay_function=fa.bind(function(finished){
this.what((new Date().getTime()-this.start_time)/this.delay);if(this.abort)timing.kill(this.repeater);if(new Date().getTime()>=this.start_time+this.delay){this.what(1.0)
timing.kill(this.repeater);}},interpolation_object);interpolation_object.cancel=fa.bind(function(){this.abort=true;},interpolation_object);interpolation_object.repeater=timing.repeat(interpolation_object.delay_function,delay/steps)
return interpolation_object;};var half_wave_shift=Math.PI/2.0;timing.interpolate.smooth=function(f){return function(x){f((Math.sin(x*Math.PI-half_wave_shift)+1.0)*0.5)}}
timing.interpolate.fast_stop=function(f){return function(x){f(Math.sin(x*half_wave_shift))}};timing.interpolate.fast_start=function(f){return function(x){f(Math.sin((x-1.0)*half_wave_shift)+1.0)}}
timing.interpolate.linear=function(f){return f};});"com.spencertipping.ja::ajax".create_namespace();using("com.spencertipping.ja::ajax","com.spencertipping.ja::oo","com.spencertipping.ja::ml","com.spencertipping.ja::require",
"com.spencertipping.ja::types",function(ajax,oo,ml,require,types){ajax.xmlhttprequest_generator=oo.create_constructor(function(){try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}
try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}return new XMLHttpRequest();});ajax.request=oo.create_class(ajax.xmlhttprequest_generator,ml.provides_event("success"),ml.provides_event("failure"),
ml.provides_event("state_change"),oo.create_extension({initialize:oo.ctor(function(args){this.url=args.url;this.method=args.method||"GET";this.encoding=args.encoding||"application/x-www-form-urlencoded"
this.username=args.username||null;this.password=args.password||null;this.async=types.is_undefined(args.async)?true:args.async;this.postdata=args.postdata||null;this.headers=args.headers||{}
}),submit:function(args){require.is_true(args.url||this.url,"ajax.request#submit: You must provide a URL.");var headers=args.headers||this.headers;this.open(args.method||this.method,args.url,types.is_undefined(args.async)?this.async:args.async,
args.username||this.username,args.password||this.password);this.setRequestHeader("Content-Type",args.encoding||this.encoding);for(var k in headers)this.setRequestHeader(k,headers[k])
this.onreadystatechange=this.alert_state_change_listeners;return this;}}));});using("com.spencertipping.ja::test","com.spencertipping.ja::fa",function(test,fa){test.add("fa :: pluralize :: add_one",function(){
var add_one=function(x){return x+1};var add_one_plural=fa.pluralize(add_one);return test.assert.equal(add_one(5),6)||test.assert.equal(add_one_plural(5),6)||test.assert.equiv(add_one_plural(5,6),[6,7])||
test.assert.equiv(add_one_plural(1,3,5,7,9),[2,4,6,8,10]);});test.add("fa :: pluralize :: split",function(){var split=function(s){return s.split(".")};var split_plural=fa.pluralize(split)
return test.assert.equiv(split("foo.bar.bif"),["foo","bar","bif"])||test.assert.equiv(split_plural("foo.bar.bif"),["foo","bar","bif"])||test.assert.equiv(split_plural("foo.bar","foo.bif"),[["foo","bar"],["foo","bif"]])
});test.add("fa :: left_fold :: addition",function(){var add_two=function(x,y){return x+y};var add_two_fold=fa.left_fold(add_two);return test.assert.equal(add_two(3,4),7)||
test.assert.equal(add_two_fold(3,4),7)||test.assert.equal(add_two_fold(3,4,5),12)||test.assert.equal(add_two_fold(1,2,3,4,5),15);});test.add("fa :: left_fold :: subtraction",function(){
var sub_two=function(x,y){return x-y};var sub_two_fold=fa.left_fold(sub_two);return test.assert.equal(sub_two(5,4),1)||test.assert.equal(sub_two_fold(5,4,1),0)||
test.assert.equal(sub_two_fold(5,4,3,2,1),-5);});});using("com.spencertipping.ja::test","com.spencertipping.ja::oo","com.spencertipping.ja::require","com.spencertipping.ja::fa",
function(test,oo,require,fa){var f1=function(){return 1};var f2=function(){return 2};var f3=function(){return 3};var ret=function(x){return x+this.x};var add_x=function(){return this.s+="x"}
var add_y=function(){return this.s+="y"};var add_z=function(){return this.s+="z"};var add=function(x){return this.s+=x};test.add("oo :: inherit :: default inheritance",function(){
var b={fun1:f1};var c={fun2:f2,fun3:f3,fun_ret:ret};var b_c=oo.inherit(new Object(),b,c);b_c.x=10;return test.assert.equal(b_c.fun1(),f1(),"f1 not installed")||test.assert.equal(b_c.fun2(),f2(),"f2 not installed")||
test.assert.equal(b_c.fun3(),f3(),"f3 not installed")||test.assert.equal(b_c.fun_ret(5),15,"this binding inactive for default inheritance");});test.add("oo :: inherit :: replace with no parent member",function(){
var b={fun1:f1,fun2:f2};var c={fun3:oo.replace(f3),ret:oo.replace(ret)};var b_c=oo.inherit(new Object(),b,c);b_c.x=14;return test.assert.equal(b_c.fun1(),f1(),"f1 not installed")||
test.assert.equal(b_c.fun2(),f2(),"f2 not installed")||test.assert.equal(b_c.fun3(),f3(),"f3 not installed")||test.assert.equal(b_c.ret(6),20,"this binding inactive for replace w/o parent member")
});test.add("oo :: inherit :: replace with parent member",function(){var b={fun1:f1,fun2:f2};var c={fun1:oo.replace(f3)};var d={fun1:oo.replace(ret)};var bcd=oo.inherit(new Object(),b,c,d)
bcd.x=40;return test.assert.equal(bcd.fun2(),f2(),"f2 not installed")||test.assert.equal(bcd.fun1(7),47,"this binding inactive for replace w/ parent member");})
test.add("oo :: inherit :: before",function(){var b={f:add_x,g:add_y};var c={f:oo.before(add_z),g:oo.before(add_x)};var d={f:oo.before(add_y)};var bcd=oo.inherit(new Object(),b,c,d)
bcd.s="";return test.assert.equal(bcd.f(),"yzx")||test.assert.equal(bcd.f(),"yzxyzx")||test.assert.equal(bcd.g(),"yzxyzxxy")||test.assert.equal(bcd.s,"yzxyzxxy")
});test.add("oo :: inherit :: after",function(){var b={f:add_x,g:add_y};var c={f:oo.after(add)};var d={g:oo.after(add)};var bcd=oo.inherit(new Object(),b,c,d);bcd.s=""
return test.assert.equal(bcd.f(),"xx")||test.assert.equal(bcd.g(),"xxyxxy");});test.add("oo :: inherit :: after_blind",function(){var b={f:add_x,g:add_y};var c={f:oo.after_blind(add_z),g:oo.after_blind(add)}
var d={f:oo.after_blind(add_y)};var bcd=oo.inherit(new Object(),b,c,d);bcd.s="";return test.assert.equal(bcd.f(),"xzy")||test.assert.equal(bcd.f(),"xzyxzy")||test.assert.equal(bcd.g("a"),"xzyxzyya")||
test.assert.equal(bcd.g("q"),"xzyxzyyayq");});test.add("oo :: inherit :: around",function(){var b={f:add_x,g:add_y,add:add};var c={f:oo.around(function(base_function,x){base_function();base_function();return this.add(x);})}
var d={f:oo.around(function(base_function,x){base_function("q");return base_function(x);})};var bcd=oo.inherit(new Object(),b,c,d);bcd.s="";return test.assert.equal(bcd.f("a"),"xxqxxa",bcd)||
test.assert.equal(bcd.f("b"),"xxqxxaxxqxxb")||test.assert.equal(bcd.g(),"xxqxxaxxqxxby");});test.add("oo :: create_object :: inherit and initialize",function(){var b={x:add_x,initialize:oo.ctor(function(args){this.s=args.s})}
var e1={x:oo.after_blind(add_y)};var o=oo.create_object(new Object(),[b,e1],[{s:"abcdef"}]);return test.assert.equal(o.s,"abcdef")||test.assert.equal(o.x(),"abcdefxy")||
test.assert.equal(o.x(),"abcdefxyxy");});test.add("oo :: create_object :: DOM native",function(){var b=document.createElement("p");var e1={add_some_text:function(s){this.appendChild(document.createTextNode(s))}}
var e2={get_children:function(){return this.childNodes}};var e3={initialize:oo.ctor(function(args){this.add_some_text(args.initial_text||"no initial")})};var o=oo.create_object(b,[e1,e2,e3],[{initial_text:"foobar"}])
return test.assert.equal(o.get_children().length,1)||o.add_some_text("foo")||test.assert.equal(o.get_children().length,2)||test.assert.equal(o.get_children()[0].nodeValue,"foobar")||
test.assert.equal(o.get_children()[1].nodeValue,"foo");});test.add("oo :: create_class :: inherit and initialize",function(){var base_class=oo.create_constructor(function(){return new Object()})
var e1=oo.create_extension({initialize:oo.ctor(function(args){this.x=args.x+1}),foo:function(t){return this.x+=t}});var e2=oo.create_extension({initialize:oo.ctor(function(args){this.y=args.y||0})})
var e3=oo.create_extension({get_y:function(){return this.y}});var c1=oo.create_class(base_class,[e1,e2,e3]);var c2=oo.create_class(base_class,e1,e2,e3);var i1a=c1({x:10})
var i1b=c1({x:50,y:50});var i2a=c2({x:10});var i2b=c2({x:50,y:50});return test.assert.equal(i1a.x,11)||test.assert.equal(i1a.y,0)||test.assert.equal(i1b.x,51)||test.assert.equal(i1b.y,50)||
test.assert.equal(i1a.foo(5),16)||test.assert.equal(i2a.foo(5),16)||test.assert.equal(i1a.x,i2a.x)||test.assert.equal(i1a.y,i2a.y)||test.assert.equal(i1b.x,i2b.x)||test.assert.equal(i1b.y,i2b.y)||
test.assert(oo.types_equal(c1,c2),"Class RTTI not equal")||test.assert(oo.types_equal(i1a,i1b),"Instance RTTI not equal")||test.assert(oo.types_equal(i1a,i2a),"Instance RTTI not equal (2)")||test.assert.equal(i1a.rtti.classes[e1.class_rtti.uid],e1,"i1a RTTI not complete")
});test.add("oo :: create_class :: DOM native, oo.transform",function(){var base_class=oo.create_constructor(function(){return document.createElement("p")});var e1=oo.create_extension({add_children:fa.pluralize(function(c){this.appendChild(c)}),add_text:function(t){this.add_children(document.createTextNode(t))}})
var e2=oo.create_extension({add_text:oo.transform(fa.pluralize)});var e3=oo.create_extension({initialize:oo.ctor(function(args){this.add_text(args.initial_text," et cetera")})})
var c=oo.create_class(base_class,e1,e2,e3);var i1=c({initial_text:"Some text"});return test.assert.equal(i1.childNodes.length,2)||test.assert.equal(i1.childNodes[0].nodeValue,"Some text")||
test.assert.equal(i1.childNodes[1].nodeValue," et cetera");});test.add("oo :: create_class :: double construction",function(){var constructor_invocation_count=0
var c1=oo.create_class(oo.create_constructor(Object),oo.create_extension({initialize:oo.ctor(function(args){++constructor_invocation_count})}));var c2=oo.create_class(c1,oo.create_extension({initialize:oo.ctor(function(args){this.x=args.x||"no x"})}))
c2({x:10});return test.assert.equal(constructor_invocation_count,1,"Base constructors are doubly invoked.");});});using("com.spencertipping.ja::test","com.spencertipping.ja::oo","com.spencertipping.ja::ml",function(test,oo,ml){
test.add("ml :: event_listener_server :: interface, trigger",function(){var medium_count=0;var well_done_count=0;var c=oo.create_class(oo.create_constructor(Object),ml.provides_event("medium"),ml.provides_event("well_done"))
var i=c();i.add_medium_listener(function(x){medium_count+=x});i.add_well_done_listener(function(x){well_done_count+=x});i.alert_medium_listeners(10);i.alert_well_done_listeners(100)
i.remove_medium_listener(i.get_medium_listeners()[0]);i.alert_medium_listeners(-5);i.alert_well_done_listeners(50);i.remove_well_done_listener(i.get_well_done_listeners()[0])
i.alert_well_done_listeners(100);return test.assert.equal(medium_count,10)||test.assert.equal(well_done_count,150)||test.assert.equal(i.get_medium_listeners().length,0)||
test.assert.equal(i.get_well_done_listeners().length,0);});test.add("ml :: eventful accessors",function(){var got_setter_event=false;var got_getter_event=false;var i=oo.create_class(oo.create_constructor(Object),ml.has_eventful_attribute("x"),oo.create_extension({initialize:oo.ctor(function(args){this.x=args.x})}))({x:0})
i.set_x(10);i.add_x_changed_listener(function(new_x){got_setter_event=got_setter_event||new_x});i.add_x_retrieved_listener(function(){got_getter_event=got_getter_event||true})
i.set_x(50);return test.assert.equal(got_getter_event,false)||test.assert.equal(i.get_x(),50)||test.assert.equal(got_setter_event,50)||test.assert.equal(got_getter_event,true)
});});using("com.spencertipping.ja::test","com.spencertipping.ja::array",function(test,array){test.add("array :: flatten",function(){return test.assert.equiv(array.flatten([1,2,3]),[1,2,3])||
test.assert.equiv(array.flatten([1,[2,3]]),[1,2,3])||test.assert.equiv(array.flatten([]),[])||test.assert.equiv(array.flatten([[[1,2]],3]),[1,2,3])||test.assert.equiv(array.flatten([[[[[1]]]]]),[1])||
test.assert.equiv(array.flatten([[1,2,3],[[4]],[5,[6,7],[8,9]]]),[1,2,3,4,5,6,7,8,9]);});}); 
