diff --git a/js/Boot.hx b/js/Boot.hx
new file mode 100644
index 000000000..91ff8decd
--- /dev/null
+++ b/js/Boot.hx
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package js;
+
+class Boot {
+
+ private static function __unhtml(s : String) {
+ return s.split("&").join("&").split("<").join("<").split(">").join(">");
+ }
+
+ private static function __trace(v,i : haxe.PosInfos) {
+ untyped {
+ var msg = if( i != null ) i.fileName+":"+i.lineNumber+": " else "";
+ #if jsfl
+ msg += __string_rec(v,"");
+ fl.trace(msg);
+ #else
+ msg += __string_rec(v, "");
+ if( i != null && i.customParams != null )
+ for( v in i.customParams )
+ msg += "," + __string_rec(v, "");
+ var d;
+ if( __js__("typeof")(document) != "undefined" && (d = document.getElementById("haxe:trace")) != null )
+ d.innerHTML += __unhtml(msg)+"
";
+ else if( __js__("typeof console") != "undefined" && __js__("console").log != null )
+ __js__("console").log(msg);
+ #end
+ }
+ }
+
+ private static function __clear_trace() {
+ untyped {
+ #if jsfl
+ fl.outputPanel.clear();
+ #else
+ var d = document.getElementById("haxe:trace");
+ if( d != null )
+ d.innerHTML = "";
+ #end
+ }
+ }
+
+ static inline function isClass(o:Dynamic) : Bool {
+ return untyped __define_feature__("js.Boot.isClass", o.__name__);
+ }
+
+ static inline function isEnum(e:Dynamic) : Bool {
+ return untyped __define_feature__("js.Boot.isEnum", e.__ename__);
+ }
+
+ static inline function getClass(o:Dynamic) : Dynamic {
+ if (Std.is(o, Array))
+ return Array;
+ else {
+ var cl = untyped __define_feature__("js.Boot.getClass", o.__class__);
+ if (cl != null)
+ return cl;
+ var name = __nativeClassName(o);
+ if (name != null)
+ return __resolveNativeClass(name);
+ return null;
+ }
+ }
+
+ @:ifFeature("may_print_enum")
+ private static function __string_rec(o,s:String) {
+ untyped {
+ if( o == null )
+ return "null";
+ if( s.length >= 5 )
+ return "<...>"; // too much deep recursion
+ var t = __js__("typeof(o)");
+ if( t == "function" && (isClass(o) || isEnum(o)) )
+ t = "object";
+ switch( t ) {
+ case "object":
+ if( __js__("o instanceof Array") ) {
+ if( o.__enum__ ) {
+ if( o.length == 2 )
+ return o[0];
+ var str = o[0]+"(";
+ s += "\t";
+ for( i in 2...o.length ) {
+ if( i != 2 )
+ str += "," + __string_rec(o[i],s);
+ else
+ str += __string_rec(o[i],s);
+ }
+ return str + ")";
+ }
+ var l = o.length;
+ var i;
+ var str = "[";
+ s += "\t";
+ for( i in 0...l )
+ str += (if (i > 0) "," else "")+__string_rec(o[i],s);
+ str += "]";
+ return str;
+ }
+ var tostr;
+ try {
+ tostr = untyped o.toString;
+ } catch( e : Dynamic ) {
+ // strange error on IE
+ return "???";
+ }
+ if( tostr != null && tostr != __js__("Object.toString") && __typeof__(tostr) == "function" ) {
+ var s2 = o.toString();
+ if( s2 != "[object Object]")
+ return s2;
+ }
+ var k : String = null;
+ var str = "{\n";
+ s += "\t";
+ var hasp = (o.hasOwnProperty != null);
+ __js__("for( var k in o ) {");
+ if( hasp && !o.hasOwnProperty(k) )
+ __js__("continue");
+ if( k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__" )
+ __js__("continue");
+ if( str.length != 2 )
+ str += ", \n";
+ str += s + k + " : "+__string_rec(o[k],s);
+ __js__("}");
+ s = s.substring(1);
+ str += "\n" + s + "}";
+ return str;
+ case "function":
+ return "";
+ case "string":
+ return o;
+ default:
+ return String(o);
+ }
+ }
+ }
+
+ private static function __interfLoop(cc : Dynamic,cl : Dynamic) {
+ if( cc == null )
+ return false;
+ if( cc == cl )
+ return true;
+ var intf : Dynamic = cc.__interfaces__;
+ if( intf != null )
+ for( i in 0...intf.length ) {
+ var i : Dynamic = intf[i];
+ if( i == cl || __interfLoop(i,cl) )
+ return true;
+ }
+ return __interfLoop(cc.__super__,cl);
+ }
+
+ @:ifFeature("typed_catch") private static function __instanceof(o : Dynamic,cl : Dynamic) {
+ if( cl == null )
+ return false;
+ switch( cl ) {
+ case Int:
+ return (untyped __js__("(o|0) === o"));
+ case Float:
+ return (untyped __js__("typeof"))(o) == "number";
+ case Bool:
+ return (untyped __js__("typeof"))(o) == "boolean";
+ case String:
+ return (untyped __js__("typeof"))(o) == "string";
+ case Array:
+ return (untyped __js__("(o instanceof Array)")) && o.__enum__ == null;
+ case Dynamic:
+ return true;
+ default:
+ if( o != null ) {
+ // Check if o is an instance of a Haxe class or a native JS object
+ if( (untyped __js__("typeof"))(cl) == "function" ) {
+ if( untyped __js__("o instanceof cl") )
+ return true;
+ if( __interfLoop(getClass(o),cl) )
+ return true;
+ }
+ else if ( (untyped __js__("typeof"))(cl) == "object" && __isNativeObj(cl) ) {
+ if( untyped __js__("o instanceof cl") )
+ return true;
+ }
+ } else {
+ return false;
+ }
+ // do not use isClass/isEnum here
+ untyped __feature__("Class.*",if( cl == Class && o.__name__ != null ) return true);
+ untyped __feature__("Enum.*",if( cl == Enum && o.__ename__ != null ) return true);
+ return o.__enum__ == cl;
+ }
+ }
+
+ @:ifFeature("typed_cast") private static function __cast(o : Dynamic, t : Dynamic) {
+ if (__instanceof(o, t)) return o;
+ else throw "Cannot cast " +Std.string(o) + " to " +Std.string(t);
+ }
+
+ static var __toStr = untyped __js__("{}.toString");
+ // get native JS [[Class]]
+ static function __nativeClassName(o:Dynamic):String {
+ var name = untyped __toStr.call(o).slice(8, -1);
+ // exclude general Object and Function
+ // also exclude Math and JSON, because instanceof cannot be called on them
+ if (name == "Object" || name == "Function" || name == "Math" || name == "JSON")
+ return null;
+ return name;
+ }
+
+ // check for usable native JS object
+ static function __isNativeObj(o:Dynamic):Bool {
+ return __nativeClassName(o) != null;
+ }
+
+ // resolve native JS class (with window or global):
+ static function __resolveNativeClass(name:String) untyped {
+ if (__js__("typeof window") != "undefined")
+ return window[name];
+ else
+ return global[name];
+ }
+
+}