forked from: forked from: JSON Tests

by jax forked from forked from: JSON Tests (diff: 3)
♥0 | Line 1888 | Modified 2013-09-25 23:22:15 | MIT License
play

ActionScript3 source code

/**
 * Copyright jax ( http://wonderfl.net/user/jax )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/qWGH
 */

// forked from skyboy's forked from: JSON Tests
// forked from skyboy's JSON Tests
package {
    import flash.display.*
    import flash.desktop.*;
    import flash.events.*;
    import flash.net.*;
    import flash.system.*;
    import flash.text.*;
    import flash.ui.*;
    import flash.utils.*;
    [SWF(width='465', height='465', backgroundColor='#333333', frameRate='60')]
    public class FlashTest extends Sprite {
        private const linebreak:String = Capabilities.os.toLowerCase().indexOf("windows") > -1 ? '\r\n' : Capabilities.os.toLowerCase().indexOf("linux") > -1 ? '\n' : '\r';
        public static const WIDTH:Number = 465;
        public static const HEIGHT:Number = 465;
        public static const hw:Number = WIDTH / 2;
        public static const hy:Number = HEIGHT / 2;
        private var logger:TextField;

        public function FlashTest() {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP;
            
            var bg:Sprite = new Sprite;
            bg.graphics.beginFill(0xFFFFFF);
            bg.graphics.drawRoundRect(0, 0, WIDTH, HEIGHT, 30);
            bg.graphics.endFill();
            addChild(bg);
            
            logger = new TextField();
            logger.autoSize = TextFieldAutoSize.LEFT;
            if (FONT_LIST.indexOf("Monaco")) logger.defaultTextFormat = new TextFormat("Monaco");
            else logger.defaultTextFormat = new TextFormat("_typewriter", 13);
            logger.mouseEnabled = false;
            addChild(logger);
            var a:SimpleButton = createButton("Save");
            addChild(a).x = WIDTH - 100;
            a.y = HEIGHT - 50;
            a.addEventListener(MouseEvent.CLICK, saveFile);
       
            a = createButton("Copy");
            addChild(a).x = WIDTH - 100;
            a.y = HEIGHT - 105;
            a.addEventListener(MouseEvent.CLICK, copyLogger);
            Wonderfl.disable_capture();
            if (stage) onAS(null); else addEventListener(Event.ADDED_TO_STAGE, onAS);
        }
        private function onAS(evt:Event):void {
            removeEventListener(Event.ADDED_TO_STAGE, onAS);
            log("                                     Click to test.");
            addEventListener(MouseEvent.CLICK, onCC);
        }
        private function copyLogger(e:MouseEvent):void {
            stopEvent(e);
            Clipboard.generalClipboard.setData(ClipboardFormats.TEXT_FORMAT, logger.text.replace(/\n/g, linebreak), false);
        }
        private function stopEvent(e:Event):void {
            e.stopImmediatePropagation();
            e.stopPropagation();
            e.preventDefault();
        }
        
        final protected function createButton(text:String = null):SimpleButton {
            var b:Sprite = new Sprite;
            var c:Graphics = b.graphics;
            c.beginFill(0x666666);
            c.drawRoundRect(0, 0, 100, 50, 30);
            c.endFill();
            if (text) {
                var d:TextField = new TextField;
                d.y = 3;
                d.width = 100;
                d.height = 50;
                d.defaultTextFormat = new TextFormat('Georgia', 30, 0xFFFFFF, false, false, false, null, null, "center");
                d.autoSize = "center";
                d.appendText(text);
                b.addChild(d);
            }
            var a:SimpleButton = new SimpleButton(b, b, b, b);
            return a;
        }
        
        private function onCC(e:MouseEvent):void {
            if (json) {
                setVersionString();
                log("\nParsing...");
                log("JSON Length:", numberDelimiter2(json.length, ",", 3, 0), '\n');
                jsonobj = skyJSON.decode(json);
                var a:* = jsonobj;
                var Ado:String = json;
                if (this.JSON) Ado = this.JSON.stringify(a); 
                json = Ado;
                start = getTimer();
                addEventListener(Event.ENTER_FRAME, skyboy_AS3JSON);
            } else {
                var b:URLRequest = new URLRequest("http://jauboux.op.lab.zslide.net/static/flashSyncData.php?v=1380118456&lang=en_US");
                var c:URLLoader = new URLLoader();
                c.addEventListener(SecurityErrorEvent.SECURITY_ERROR, trace);
                c.addEventListener(IOErrorEvent.IO_ERROR, trace);
                c.addEventListener(Event.COMPLETE, loadUserComplete);
                c.addEventListener(ProgressEvent.PROGRESS, onProgress);
                c.load(b);
                setVersionString();
                log("\nLoading...");
                try{this.JSON = getDefinitionByName("JSON");}catch(e:*){}
            }
        }
        private var json:String, JSON:Object;
        private var start:int, inputName:String, jsonobj:*;
        private function skyboy_AS3JSON(e:Event):void {
            removeEventListener(e.type, skyboy_AS3JSON);
            addEventListener(e.type, skyboyAS3JSON);
            var q:int, a:String = json;
            try {
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.decode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.decode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.decode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.decode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.decode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("skyboy v1(AS3) \t", e.name + "(" + e.errorID + "):", e.message, '\n'); 
            }
        }
        private function skyboyAS3JSON(e:Event):void {
            removeEventListener(e.type, skyboyAS3JSON);
            addEventListener(e.type, Adobe_nativeJSON);
            var q:int, a:String = json;
            try {
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.decode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.decode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.decode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.decode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.decode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("skyboy v2(AS3) \t", e.name + "(" + e.errorID + "):", e.message, '\n'); 
            }
        }
        private function Adobe_nativeJSON(e:Event):void {
            removeEventListener(e.type, Adobe_nativeJSON);
            //addEventListener(e.type, blooddycryptoJSON);
            addEventListener(e.type, JSONParsersEnd);
            var q:int, a:String = json, i:int;
            try {
                var JSON:Object = getDefinitionByName("JSON");
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.parse(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.parse(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.parse(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.parse(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.parse(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("Adobe Native JSON \t", e.name + "(" + e.errorID + "):", e.message);
                while (++i < 5) log("Adobe Native JSON \t", 0);
                log('');
            }
        }/*
        private function blooddycryptoJSON(e:Event):void {
            removeEventListener(e.type, blooddycryptoJSON);
            addEventListener(e.type, brokenfunctionJSON);
            var q:int, a:String = json;
            try {
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.decode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.decode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.decode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.decode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.decode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("blooddy.crypto \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function brokenfunctionJSON(e:Event):void {
            removeEventListener(e.type, brokenfunctionJSON);
            addEventListener(e.type, vegasSerializerJSON);
            var q:int, a:String = json;
            try {
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.decodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.decodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.decodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.decodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.decodeJson(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("actionJson \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function vegasSerializerJSON(e:Event):void {
            removeEventListener(e.type, vegasSerializerJSON);
            addEventListener(e.type, comserializationJSON);
            var q:int, a:String = json;
            try {
                var J:JSONSerializer = new JSONSerializer();
                log("vegas \t", ((q = getTimer()), J.deserialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.deserialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.deserialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.deserialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.deserialize(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("vegas \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function comserializationJSON(e:Event):void {
            removeEventListener(e.type, comserializationJSON);
            addEventListener(e.type, AdobeActionScriptJSON);
            var q:int, a:String = json;
            try {
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.deserialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.deserialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.deserialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.deserialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.deserialize(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("ekameleon JSON \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function AdobeActionScriptJSON(e:Event):void {
            removeEventListener(e.type, AdobeActionScriptJSON);
            addEventListener(e.type, JSONParsersEnd);
            var q:int, a:String = json;
            try {
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.decode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.decode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.decode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.decode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.decode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("as3corelib \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }//*/
        private function skyboy_AS3JSON2(e:Event):void {
            removeEventListener(e.type, skyboy_AS3JSON2);
            addEventListener(e.type, skyboyAS3JSON2);
            var q:int, a:* = jsonobj;
            try {
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.encode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.encode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.encode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.encode(a), getTimer() - q));
                log("skyboy v1(AS3) \t", ((q = getTimer()), skyJSON.encode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("skyboy v1(AS3) \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function skyboyAS3JSON2(e:Event):void {
            removeEventListener(e.type, skyboyAS3JSON2);
            addEventListener(e.type, Adobe_nativeJSON2);
            var q:int, a:* = jsonobj;
            try {
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.encode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.encode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.encode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.encode(a), getTimer() - q));
                log("skyboy v2(AS3) \t", ((q = getTimer()), sJSON.encode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("skyboy v2(AS3) \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function Adobe_nativeJSON2(e:Event):void {
            removeEventListener(e.type, Adobe_nativeJSON2);
            //addEventListener(e.type, blooddycryptoJSON2);
            addEventListener(e.type, JSONParsersEnd2);
            var q:int, a:* = jsonobj, i:int;
            try {
                var JSON:Object = getDefinitionByName("JSON");
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.stringify(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.stringify(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.stringify(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.stringify(a), getTimer() - q));++i
                log("Adobe Native JSON \t", ((q = getTimer()), JSON.stringify(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("Adobe Native JSON \t", e.name + "(" + e.errorID + "):", e.message);
                while (++i < 5) log("Adobe Native JSON \t", 0);
                log('');
            }
        }/*
        private function blooddycryptoJSON2(e:Event):void {
            removeEventListener(e.type, blooddycryptoJSON2);
            addEventListener(e.type, brokenfunctionJSON2);
            var q:int, a:* = jsonobj;
            try {
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.encode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.encode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.encode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.encode(a), getTimer() - q));
                log("blooddy.crypto \t", ((q = getTimer()), by.blooddy.crypto.serialization.JSON.encode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("blooddy.crypto \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function brokenfunctionJSON2(e:Event):void {
            removeEventListener(e.type, brokenfunctionJSON2);
            addEventListener(e.type, vegasSerializerJSON2);
            var q:int, a:* = jsonobj;
            try {
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.encodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.encodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.encodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.encodeJson(a), getTimer() - q));
                log("actionJson \t", ((q = getTimer()), com.brokenfunction.json.encodeJson(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("actionJson \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function vegasSerializerJSON2(e:Event):void {
            removeEventListener(e.type, vegasSerializerJSON2);
            addEventListener(e.type, comserializationJSON2);
            var q:int, a:* = jsonobj;
            try {
                var J:JSONSerializer = new JSONSerializer();
                log("vegas \t", ((q = getTimer()), J.serialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.serialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.serialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.serialize(a), getTimer() - q));
                log("vegas \t", ((q = getTimer()), J.serialize(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("vegas \r", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function comserializationJSON2(e:Event):void {
            removeEventListener(e.type, comserializationJSON2);
            addEventListener(e.type, AdobeActionScriptJSON2);
            var q:int, a:* = jsonobj;
            try {
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.serialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.serialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.serialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.serialize(a), getTimer() - q));
                log("ekameleon JSON \t", ((q = getTimer()), com.serialization.json.JSON.serialize(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("ekameleon JSON \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }
        private function AdobeActionScriptJSON2(e:Event):void {
            removeEventListener(e.type, AdobeActionScriptJSON2);
            addEventListener(e.type, JSONParsersEnd2);
            var q:int, a:* = jsonobj;
            try {
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.encode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.encode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.encode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.encode(a), getTimer() - q));
                log("as3corelib \t", ((q = getTimer()), com.adobe.serialization.json.JSON.encode(a), getTimer() - q), '\n');
            } catch (e:Error) {
                log("as3corelib \t", e.name + "(" + e.errorID + "):", e.message, '\n');
            }
        }//*/
        private function JSONParsersEnd(e:Event):void {
            removeEventListener(e.type, JSONParsersEnd);
            addEventListener(e.type, skyboy_AS3JSON2);
            log("\nEncoding...");
        }
        private function JSONParsersEnd2(e:Event):void {
            removeEventListener(e.type, JSONParsersEnd2);
            log("\nTotal time:", getTimer() - start);
            log("Input:", inputName);
            Wonderfl.capture(stage);
        }
        private function loadUserComplete(e:Event):void {
            var a:String = String(e.target.data).valueOf();
            /*
            json = a;
            inputName = "Kongregate badge list";
            //*/
            //*
            json = "[" + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "]";
            inputName = "Kongregate badge list Array (x10)";
            //*/
            /*
            a = "[" + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "," + a + "]";
            json = "{'listA1':" + a + ", 'lsatA2':" + a + "}";
            inputName = "Kongregate badge list Array Object (listx10 Arrayx2)";
            //*/
            /*
            json = "[" + a + "," + a + "]";
            inputName = "Kongregate badge list Array (x2)";
            //*/
            setTimeout(function():void{onCC(null)}, 4000)
        }
        private var b:int
        private function onProgress(e:ProgressEvent):void {
            var a:Number = (e.bytesLoaded / e.bytesTotal);
            if (int(a * 10) != b) {
                b = a * 10;
                log(int(a*100) + "% loaded...");
            }
        }
        private function log(...args):void {
            logger.appendText(args.join(" ") + "\n");
            logger.scrollV = logger.numLines;
        }
        private function setVersionString():void {
            logger.text = "  ";
            logger.appendText((Capabilities.supports64BitProcesses ? "64" : Capabilities.supports32BitProcesses ? "32" : "16") + " bit ");
            logger.appendText(Capabilities.os + " ");
            logger.appendText(Capabilities.cpuArchitecture + " ");
            logger.appendText(Capabilities.version.split(",").join(".").split(" ")[1] + " ");
            logger.appendText(Capabilities.isDebugger ? "Debug " : "Release ");
            logger.appendText(Capabilities.playerType);
            logger.appendText("\n");
        }
        
        private function dup(a:String, b:int):String {
            var r:String = "";
            while (b--) {
                r += a;
            }
            return r;
        }

        private var bytes:ByteArray;
        private const file:FileReference = new FileReference();
        
        private function saveFile(e:MouseEvent):void {
            try {
                var a:String;
                try {
                    a = file.name;
                } catch (b:*) {
                    a = "file.swf";
                }
                bytes = loaderInfo.bytes;
                file.save(bytes, a);
            } catch (er:Error) {
                //log(e)
            }
            e.stopImmediatePropagation();
            e.stopPropagation();
            e.preventDefault();
        }
public function numberDelimiter2(num:Number, delimiter:String = ",", charGroup:uint = 3, decimalPrecision:int = 2):String {
    var d:String = num.toFixed(decimalPrecision);
    if (int(charGroup == 0) | charGroup >> 31) return d;
    var n:int = int(num < 0), len:int = d.length - n - (int(decimalPrecision > 0) * (decimalPrecision + 1));;
    if (len <= charGroup) return d;
    if (len % charGroup) {
        var c:int = n + len % charGroup, o:String = d.substring(0, c);
        while (~(((len -= charGroup) >> 31))) {
            o = o + delimiter + d.substring(c, c += charGroup);
        }
        return o + d.substring(c);
    }
    var count:int = n + charGroup, out:String = d.substring(0, count);
    while (len -= charGroup) {
        out = out + delimiter + d.substring(count, count += charGroup);
    }
    return out + d.substring(count);
}
    }
}
    import flash.text.Font;
internal const FONT_LIST:Array = Font.enumerateFonts(true);
// original can be found here: https://github.com/skyboy/AS3-Utilities/blob/master/skyboy/serialization/JSON.as
import flash.utils.ByteArray;
    import flash.utils.getQualifiedClassName;
    import flash.utils.Dictionary;
class skyJSON {
        public function skyJSON() {
            throw new Error("This class has no instance methods.")
        }
        private static const preArrs:Vector.<Array> = new Vector.<Array>();
        private static const preObjs:Vector.<Object> = new Vector.<Object>();
        private static const strArr:ByteArray = new ByteArray(); strArr.length = 0xFFFF;
        private static const strArrE:ByteArray = new ByteArray(); strArrE.length = 0xFFFF;
        private static var i:int;
        
        public static const errorID:int = 0x4A534F4E;
        
        public static function decode(data:String):* {
            if (data == null) {
                return null;
            }
            data = data.valueOf();
            var e:int = data.length;
            if (e == 0) return null;
            var temp:int, objs:int = -preObjs.length;
            while ((temp = data.indexOf("}", temp + 1)) !== -1) ++objs;
            if (objs > 0) {
                preObjs.length = objs;
                while (objs-- > 0) preObjs[objs] = new Object;
            }
            objs = temp = 0;
            while ((temp = data.indexOf("]", temp + 1)) !== -1) ++objs;
            preArrs.length = objs;
            while (objs-- > 0) preArrs[objs] = new Array(e);
            var c:int = data.charCodeAt(i = 0);
            if (isSpace(c)) {
                do {
                    c = data.charCodeAt(++i);
                } while (isSpace(c) && i != e);
            }
            var rtn:*;
            if (isObject(c)) {
                rtn = handleObject(data, e);
            } else if (isArray(c)) {
                rtn = handleArray(data, e);
            } else if (isString(c)) {
                rtn = handleString(data, e);
            } else if (isNumber(c)) {
                rtn = handleNumber2(data, e);
            } else if (isLit(c)) {
                return handleLit(data, e);
            }
            if (rtn === undefined) error(data, i);
            return rtn;
        }
        public static function parse(data:String):* {
            return decode(data);
        }
        public static function get index():int {
            return i;
        }
        
        
        private static function tryToJSON(data:*):String {
            try {
                return data.toJSON() as String;
            } catch (e:ArgumentError) {
                if (e.errorID != 1063) throw e;
            }
            return null;
        }
        private static function encode2(data:*):void {
            var ret:ByteArray = strArrE, c:String;
            if (data == null) {
                ret.writeUTFBytes("null");
                return;
            }
            if ("toJSON" in data) if (data.toJSON is Function) {
                c = tryToJSON(data);
                if (c != null) {
                    handleStringE2(c, ret);
                    return;
                }
            }
            if (data is Function) ret.writeUTFBytes("null");
            else if (data is String) {
                handleStringE2(data, ret, false);
            } else if (data is Number) {
                if ((data * 0) != 0) data = 0;
                ret.writeUTFBytes(String(data));
            } else if (data is Boolean) {
                ret.writeUTFBytes(String(data));
            } else if (data is Date) {
                ret.writeUTFBytes(String(data.getTime()));
            } else if (data is Array || getQualifiedClassName(data).indexOf("__AS3__.vec::Vector.<") == 0) {
                var i:int, e:int = data.length - 1;
                ret.writeByte(0x5B); // [
                if (e > 0) {
                    if (e & 1) encode2(data[i++]), ret.writeByte(0x2C); // ,
                    e >>>= 1;
                    while (e--) {
                        encode2(data[i++]);
                        ret.writeByte(0x2C); // ,
                        encode2(data[i++]);
                        ret.writeByte(0x2C); // ,
                    }
                    encode2(data[i]);
                } else if (!e) {
                    encode2(data[i]);
                }
                ret.writeByte(0x5D); // ]
            } else if (data is Dictionary) {
                ret.writeByte(0x7B); // {
                for (var b:* in data) {
                    if (b is String) handleStringE2(b, ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is Number) handleStringE2(String(b), ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is Date) handleStringE2(String(b.getTime()), ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is XML) handleStringE2(b.toXMLString(), ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is Boolean) handleStringE2(String(b), ret), encode2(data[b]), ret.writeByte(0x2C);
                }
                if (b !== undefined) ret.position--;
                ret.writeByte(0x7D); // }
            } else if (data is XML) {
                handleStringE2(data.toXMLString(), ret, false);
            } else if (data is Object) {
                ret.writeByte(0x7B); // {
                for (c in data) {
                    handleStringE2(c, ret), encode2(data[c]), ret.writeByte(0x2C);
                }
                if (c != null) ret.position--;
                ret.writeByte(0x7D); // }
            } else ret.writeUTFBytes("null");
        }
        public static function encode(data:*):String {
            if (data == null) return "null";
            var ret:ByteArray = strArrE, c:String;
            ret.position = 0;
            if ("toJSON" in data) if (data.toJSON is Function) {
                c = tryToJSON(data);
                if (c != null) return handleStringE(c, false);
            }
            if (data is Function) return "null";
            if (data is String) {
                handleStringE2(data, ret, false);
            } else if (data is Number) {
                if ((data * 0) != 0) data = 0;
                ret.writeUTFBytes(String(data));
            } else if (data is Boolean) {
                ret.writeUTFBytes(String(data));
            } else if (data is Date) {
                ret.writeUTFBytes(String(data.getTime()));
            } else if (data is Array || getQualifiedClassName(data).indexOf("__AS3__.vec::Vector.<") == 0) {
                var i:int, e:int = data.length - 1;
                ret.writeByte(0x5B); // [
                if (e > 0) {
                    if (e & 1) encode2(data[i++]), ret.writeByte(0x2C); // ,
                    e >>>= 1;
                    while (e--) {
                        encode2(data[i++]);
                        ret.writeByte(0x2C); // ,
                        encode2(data[i++]);
                        ret.writeByte(0x2C); // ,
                    }
                    encode2(data[i]);
                } else if (!e) {
                    encode2(data[i]);
                }
                ret.writeByte(0x5D); // ]
            } else if (data is Dictionary) {
                ret.writeByte(0x7B); // {
                for (var b:* in data) {
                    if (b is String) handleStringE2(b, ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is Number) handleStringE2(String(b), ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is Date) handleStringE2(String(b.getTime()), ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is XML) handleStringE2(b.toXMLString(), ret), encode2(data[b]), ret.writeByte(0x2C);
                    else if (b is Boolean) handleStringE2(String(b), ret), encode2(data[b]), ret.writeByte(0x2C);
                }
                if (b !== undefined) ret.position--;
                ret.writeByte(0x7D); // }
            } else if (data is XML) {
                handleStringE2(data.toXMLString(), ret, false);
            } else if (data is Object) {
                ret.writeByte(0x7B); // {
                for (c in data) {
                    handleStringE2(c, ret), encode2(data[c]), ret.writeByte(0x2C);
                }
                if (c != null) ret.position--;
                ret.writeByte(0x7D); // }
            } else return "null";
            i = ret.position;
            ret.position = 0;
            c = ret.readUTFBytes(i);
            ret.length = 0;
            return c;
        }
        public static function stringify(data:*):String {
            return encode(data);
        }
        public static function toJSON(data:* = null):String {
            return encode(data);
        }
        
        private static function isSpace(i:int):Boolean {
            return Boolean(int(i == 0x20) | int(i == 0x09));
        }
        private static function isString(i:int):Boolean {
            return Boolean(int(i == 0x22) | int(i == 0x27));
        }
        private static function isObject(i:int):Boolean {
            return i == 0x7B;
        }
        private static function isArray(i:int):Boolean {
            return i == 0x5B;
        }
        private static function isNumber(i:int):Boolean {
            return Boolean(int(i == 0x2D) | int(i == 0x2E) | (int(i > 0x2F) & int(i < 0x3A)) | int(i == 0x2B));
        }
        private static function isNumeric(i:int):Boolean {
            return Boolean(int(i > 0x2F) & int(i < 0x3A));
        }
        private static function isLit(i:int):Boolean {
            i |= 0x20;
            return Boolean(int(i == 0x74) | int(i == 0x66) | int(i == 0x6E));
        }
        
        private static function min(a:Number, b:Number):Number {
            var c:int = int(a < b);
            return (c * a) + ((1 - c) * b); // fast a < b ? a : b;
        }
        private static function handleStringE(data:String, colon:Boolean = true):String {
            var rtn:ByteArray = strArr, inx:int, c:int, i:int;
            var e:int = data.length, t:int;
            if (e == 0) return "";
            rtn.length = min(e * 5 + 3, 0xFFFFFF);
            rtn[inx++] = 0x22;
            while (i != e) {
                c = data.charCodeAt(i++);
                if (int(c < 32) | int(c > 127)) {
                    if (c > 0xFFFF) c = 0xFFFF;
                    rtn[inx++] = 0x5C;
                    rtn[inx++] = 0x75;
                    t = ((c & 0xF000) >> 12) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    t = ((c & 0xF00) >> 8) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    t = ((c & 0xF0) >> 4) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    t = (c & 15) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    continue;
                } else if (int(c == 0x22) | int(c == 0x5C)) {
                    rtn[inx++] = 0x5C;
                    rtn[inx++] = c;
                    continue;
                }
                rtn[inx++] = c;
            }
            rtn[inx++] = 0x22;
            if (colon) rtn[inx++] = 0x3A;
            rtn.position = 0;
            data = rtn.readUTFBytes(inx);
            return data;
        }
        private static function handleStringE2(data:String, rtn:ByteArray, colon:Boolean = true):void {
            if (!rtn) return;
            var inx:int = rtn.position, c:int, i:int;
            var e:int = data.length, t:int;
            if (e == 0) return;
            rtn.length = inx + min(e * 5 + 3, 0xFFFFFF);
            rtn[inx++] = 0x22;
            while (i != e) {
                c = data.charCodeAt(i++);
                if (int(c < 32) | int(c > 127)) {
                    if (c > 0xFFFF) c = 0xFFFF;
                    rtn[inx++] = 0x5C;
                    rtn[inx++] = 0x75;
                    t = ((c & 0xF000) >> 12) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    t = ((c & 0xF00) >> 8) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    t = ((c & 0xF0) >> 4) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    t = (c & 15) + 0x30;
                    t += 7 * int(t > 0x39);
                    rtn[inx++] = t;
                    continue;
                } else if (int(c == 0x22) | int(c == 0x5C)) {
                    rtn[inx++] = 0x5C;
                    rtn[inx++] = c;
                    continue;
                }
                rtn[inx++] = c;
            }
            rtn[inx++] = 0x22;
            if (colon) rtn[inx++] = 0x3A;
            rtn.position = inx;
        }
        private static function handleString(data:String, e:int):String {
            var rtn:ByteArray = strArr, inx:int, t:int, a:int = i;
            var iN:Boolean, c:int, end:int = data.charCodeAt(i), p:int;
            rtn.length = e;
            while (a != e) {
                c = data.charCodeAt(++a);
                if (c == 0x5C) {
                    c = data.charCodeAt(++a);
                    t = 0;
                    switch (c) {
                    case 0x72:
                        c = 13;
                        break;
                    case 0x6E:
                        c = 10;
                        break;
                    case 0x74:
                        c = 9;
                        break;
                    case 0x66:
                        c = 12;
                        break;
                    case 0x62:
                        c = 8;
                        break;
                    case 0x75:
                        p = data.charCodeAt(++a) - 0x30;
                        if (p > 9) {
                            p -= 7;
                            if (p > 15) {
                                p -= 0x20;
                            }
                        }
                        if (p < 0 || p > 15) {
                            error(data, a, "Expected 0-F");
                        }
                        t = p << 4;
                    case 0x30:case 0x31:case 0x32:case 0x33:
                    case 0x34:case 0x35:case 0x36:case 0x37:
                        if (c == 0x75) {
                            p = data.charCodeAt(++a) - 0x30;
                        } else {
                            t = (c == 0x30 ? data.charCodeAt(++a) : c) - 0x30;
                            if (t > 7) {
                                if (c != 0x30) {
                                    break;
                                }
                                c = 0;
                                --a;
                                break;
                            }
                            p = data.charCodeAt(++a) - 0x30;
                            if (p > 7) {
                                --a;
                                if (c != 0x30) {
                                    break;
                                }
                                c = 0;
                                --a;
                                break;
                            }
                            c = (t << 3) | p;
                            break;
                        }
                        if (p > 9) {
                            p -= 7;
                            if (p > 15) {
                                p -= 0x20;
                            }
                        }
                        if (p < 0 || p > 15) {
                            error(data, a, "Expected 0-F");
                        }
                        t = (t | p) << 4;
                    case 0x78:
                        p = data.charCodeAt(++a) - 0x30;
                        if (p > 9) {
                            p -= 7;
                            if (p > 15) {
                                p -= 0x20;
                            }
                        }
                        if (p < 0 || p > 15) {
                            error(data, a, "Expected 0-F");
                        }
                        t = (t | p) << 4;
                        p = data.charCodeAt(++a) - 0x30;
                        if (p > 9) {
                            p -= 7;
                            if (p > 15) {
                                p -= 0x20;
                            }
                        }
                        if (p < 0 || p > 15) {
                            error(data, a, "Expected 0-F");
                        }
                        c = t | p;
                        break;
                    }
                    rtn[inx++] = c;
                    continue;
                } else if (c == end) {
                    break;
                }
                rtn[inx++] = c;
            }
            i = a;
            rtn.position = 0;
            return rtn.readUTFBytes(inx);
        }
        private static function handleNumber2(data:String, e:int):Number {
            var a:int = i, c:int = data.charCodeAt(a), r:Number = 0, t:int = 1;
            var n:Boolean;
            if (isSpace(c)) {
                do {
                    c = data.charCodeAt(++a);
                } while (isSpace(c) && i != e);
            }
            if (c == 0x2D) {
                c = data.charCodeAt(++a);
                n = true;
            } else if (c == 0x2B) {
                c = data.charCodeAt(++a);
            }
            if (isNumeric(c)) {
                r = c - 0x30;
                while (a != e) {
                    c = data.charCodeAt(++a);
                    if (isNumeric(c)) {
                        r = (r * 10) + (c - 0x30);
                    }
                }
            }
            if (c == 0x2E) {
                while (a != e) {
                    c = data.charCodeAt(++a);
                    if (isNumeric(c)) {
                        r += (c - 0x30) / (t *= 10);
                    }
                }
            }
            if (a != e) {
                if (isSpace(c)) {
                    do {
                        c = data.charCodeAt(++i);
                    } while (isSpace(c) && a < e);
                }
                if (a != e) {
                    error(data, a, "Expected 0-9 or .");
                }
            }
            return n ? r * -1.0 : r;
        }
        private static function handleNumber(data:String, e:int):Number {
            var a:int = i, c:int = data.charCodeAt(a), r:Number = 0, t:int = 1;
            var n:Boolean;
            if (isSpace(c)) {
                do {
                    c = data.charCodeAt(++a);
                } while (isSpace(c));
            }
            if (c == 0x2D) {
                c = data.charCodeAt(++a);
                n = true;
            } else if (c == 0x2B) {
                c = data.charCodeAt(++a);
            }
            if (isNumeric(c)) {
                r = c - 0x30;
                while (a != e) {
                    c = data.charCodeAt(++a);
                    if (isNumeric(c)) {
                        r = (r * 10) + (c - 0x30);
                        continue;
                    } else if (int(isSpace(c)) | int(c == 0x2C) | int(c == 0x5D) | int(c == 0x7D)) {
                        i = a - 1;
                        return n ? r * -1.0 : r;
                    }
                    break;
                }
            }
            if (c == 0x2E) {
                while (a != e) {
                    c = data.charCodeAt(++a);
                    if (isNumeric(c)) {
                        r += (c - 0x30) / (t *= 10);
                        continue;
                    } else if (int(isSpace(c)) | int(c == 0x2C) | int(c == 0x5D) | int(c == 0x7D)) {
                        i = a - 1;
                        return n ? r * -1.0 : r;
                    }
                    break;
                }
            }
            error(data, a, "Expected 0-9 or .");
            return NaN;
        }
        private static function handleLit(data:String, e:int):* {
            var a:int = data.charCodeAt(i++) | 0x20, b:int = data.charCodeAt(i++) | 0x20;
            var c:int = data.charCodeAt(i++) | 0x20, d:int = data.charCodeAt(i) | 0x20;
            if (a == 0x6E) {
                if (b == 0x75) {
                    if (c == 0x6C) {
                        if (d == 0x6C) {
                            return null;
                        }
                        error(data, i-1, "Expected 'l' after nul.");
                    }
                    error(data, i-2, "Expected 'l' after nu.");
                }
                error(data, i-3, "Expected 'u' after n.");
            } else if (a == 0x74) {
                if (b == 0x72) {
                    if (c == 0x75) {
                        if (d == 0x65) {
                            return true
                        }
                        error(data, i-1, "Expected 'e' after tur.");
                    }
                    error(data, i-2, "Expected 'r' after tu.");
                }
                error(data, i-3, "Expected 'u' after t.");
            } else if (a == 0x66) {
                if (b == 0x61) {
                    if (c == 0x6C) {
                        if (d == 0x73) {
                            if ((data.charCodeAt(++i) | 0x20) == 0x65) {
                                return false;
                            }
                            error(data, i-1, "Expected 'e' after fals.");
                        }
                        error(data, i-1, "Expected 's' after fal.");
                    }
                    error(data, i-2, "Expected 'l' after fa.");
                }
                error(data, i-3, "Expected 'a' after f.");
            }
        }
        private static function handleArray(data:String, e:int):Array {
            var rtn:Array = preArrs.pop(), c:int, inx:int, p:Boolean = true;
            while (i != e) {
                c = data.charCodeAt(++i);
                if (isSpace(c)) {
                    continue;
                } else if (c == 0x5D) {
                    break;
                } else if (p) {
                    p = false;
                    if (isObject(c)) {
                        rtn[inx++] = handleObject(data, e);
                        continue;
                    } else if (isArray(c)) {
                        rtn[inx++] = handleArray(data, e);
                        continue;
                    } else if (isString(c)) {
                        rtn[inx++] = handleString(data, e);
                        continue;
                    } else if (isNumber(c)) {
                        rtn[inx++] = handleNumber(data, e);
                        continue;
                    } else if (isLit(c)) {
                        rtn[inx++] = handleLit(data, e);
                        continue;
                    }
                    error(data, i);
                } else if (c == 0x2C) {
                    p = true;
                    continue;
                }
                error(data, i, "Expected , or ]");
            }
            rtn.length = inx;
            return rtn;
        }
        private static function handleObject(data:String, e:int):Object {
            var rtn:Object = preObjs.pop(), c:int, inx:String, p:Boolean = true;
            while (i != e) {
                c = data.charCodeAt(++i);
                if (isSpace(c)) {
                    continue;
                } else if (c == 0x7D) {
                    break;
                } else if (p) {
                    p = false;
                    if (isString(c)) {
                        inx = handleString(data, e);
                    } else {
                        // handle number?
                        error(data, i, "Expected \" or '");
                    }
                    c = data.charCodeAt(++i);
                    if (isSpace(c)) {
                        do {
                            c = data.charCodeAt(++i);
                        } while (isSpace(c) && i != e);
                    }
                    if (c == 0x3A) {
                        c = data.charCodeAt(++i);
                        if (isSpace(c)) {
                            do {
                                c = data.charCodeAt(++i);
                            } while (isSpace(c) && i != e);
                        }
                        if (isString(c)) {
                            rtn[inx] = handleString(data, e);
                            continue;
                        } else if (isNumber(c)) {
                            rtn[inx] = handleNumber(data, e);
                            continue;
                        } else if (isArray(c)) {
                            rtn[inx] = handleArray(data, e);
                            continue;
                        } else  if (isLit(c)) {
                            rtn[inx] = handleLit(data, e);
                            continue;
                        } else if (isObject(c)) {
                            rtn[inx] = handleObject(data, e);
                            continue;
                        }
                        error(data, i);
                    }
                    error(data, i, "Expected :");
                } else if (c == 0x2C) {
                    p = true;
                    continue;
                }
                error(data, i, "Expected , or }");
            }
            return rtn;
        }
        private static function error(data:String, i:int, e:String = null):void {
            throw new Error("Malformed JSON at char: " + i + ", " + data.charAt(i) + (e ? ". " + e : '.'), errorID);
        }
    }
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.utils.getQualifiedClassName;
import flash.utils.Dictionary;
final internal class sJSON {
    private static var instance:sJSON;
    public function sJSON() {
        if (instance) throw new Error("This class has no instance methods.");
        instance = this;
        strArr.length = 0xFFFF; strArr.endian = Endian.BIG_ENDIAN;
        var i:int = 0x10000;
        while (i--) {
            encRL[i] = (0x30303030 | ((i & 0xF000) << 12) | ((i & 0xF00) << 8) | ((i & 0xF0) << 4) | (i & 0xF)) +
            (((int((i & 0xF000) > 0x9000) * 0x7000) << 12) |
            ((int((i & 0xF00) > 0x900) * 0x700) << 8) |
            ((int((i & 0xF0) > 0x90) * 0x70) << 4) |
            ((int((i & 0xF) > 0x9) * 0x7)));
        }
        i = 0x7F;
        while (i-- > 0x20) {
            encRL[i] = i;
        }
        encRLs[0x08] = 0x5C62;
        encRLs[0x0C] = 0x5C66;
        encRLs[0x0A] = 0x5C6E;
        encRLs[0x0D] = 0x5C72;
        encRLs[0x09] = 0x5C74;
        encRLs[0x22] = 0x5C22;
        encRLs[0x5C] = 0x5C5C;
        i = 0x80;
        while (i--) {
            encD[i] = i;
        }
        encD[0x62] = 8;
        encD[0x66] = 12;
        encD[0x6E] = 10;
        encD[0x72] = 13;
        encD[0x74] = 9;
        encMap[Vector.<int>]     = new eVI(this);
        encMap[Vector.<uint>]     = new eVU(this);
        encMap[Vector.<Number>] = new eVN(this);
        encMap[Vector.<*>]         = new eVO(this);
        encMap[Array]             = new eA(this);
        encMap[String]             = new eS(this);
        encMap['string']         = encMap[String];
        encMap[XML]             = new eX(this);
        encMap['xml']             = encMap[XML];// XMLList is of type xml and not subclass of XML
        encMap[XMLList]         = new eXL(this);
        encMap[Date]             = new eDT(this);
        encMap[Number]             = new eN(this);
        encMap['number']         = encMap[Number];
        encMap[Dictionary]         = new eD(this);
        encMap[RegExp]            = new eRE(this);
        encMap[ByteArray]        = new eBA(this);
        encMap[Object]             = new eO(this);
        encMap[Boolean]         = new eB(this);
        encMap['boolean']         = encMap[Boolean];
        encMap['object']         = new eO2(this);// nulls are of type object
        encMap['undefined']     = encMap['object'];
        i = pow10.length;
        while (i--) pow10[i] = Math.pow(10, i);
    }
    //{ STATE
    private var containsSlash:int;
    private const strArr:ByteArray = new ByteArray();
    private const encRL:Vector.<int> = new Vector.<int>(0x10000, true);
    private const encRLs:Vector.<int> = new Vector.<int>(0x5D, true);
    private const encD:Vector.<int> = new Vector.<int>(0x80, true);
    private const encMap:Dictionary = new Dictionary();
    private const pow10:Vector.<Number> = new Vector.<Number>(309, true);
    private var i:int;
    //}
    //{ DEBUGVALS
    public static function get index():int {
        return instance.i;
    }
    public static const errorID:int = 0x4A534F4E;
    //}
    //{ ENCODING
    private function tryToJSON(data:*):String {
        try {
            return data.toJSON() as String;
        } catch (e:ArgumentError) {
            if (e.errorID != 1063) throw e;
        }
        return null;
    }
    private function encode(data:Object):String {
        if (data == null) return "null";
        var ret:ByteArray = strArr, c:String, enc:Vector.<int> = encRL;
        ret.position = 0;
        if ("toJSON" in data) if (data.toJSON is Function) {
            c = tryToJSON(data);
            if (c !== null) return c;
        }
        var f:F = encMap[typeof data];
        f.f(data, ret, enc, encMap);
        i = ret.position;
        ret.position = 0;
        c = ret.readUTFBytes(i);
        ret.length = 0;
        return c;
    }
    public static function encode(data:*):String {
        return instance.encode(data);
    }
    public static function stringify(data:*):String {
        return instance.encode(data);
    }
    public static function toJSON(data:* = null):String {
        return instance.encode(data);
    }
    //{ TYPES
    sky function encodeArry(arr:Array, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        var e:int = arr.length - 1;
        rtn.writeByte(0x5B); // [
        if (e >= 0) {
            for (i = 0; i < e; ++i) {
                el = arr[i];
                f = map[typeof el];
                f.f(el, rtn, enc, map);
                rtn.writeByte(0x2C); // ,
            }
            el = arr[i];
            f = map[typeof el];
            f.f(el, rtn, enc, map);
        }
        rtn.writeByte(0x5D);// ]
        var i:int, f:F, el:*;
    }
    sky function encodeVecO(arr:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void { // * because vector can be of any type other than number/int/uint and no two vector 'types' are compatible
        if (arr is Vector.<Boolean>) {
            sky::encodeVecB(arr, rtn);
            return;
        } else if (arr is Vector.<String>) {
            sky::encodeVecS(arr, rtn, enc);
            return;
        }
        var e:int = arr.length - 1;
        rtn.writeByte(0x5B); // [
        if (e >= 0) {
            for (i = 0; i < e; ++i) {
                el = arr[i];
                f = map[typeof el];
                f.f(el, rtn, enc, map);
                rtn.writeByte(0x2C); // ,
            }
            el = arr[i];
            f = map[typeof el];
            f.f(el, rtn, enc, map);
        }
        rtn.writeByte(0x5D);// ]
        return;
        var i:int, f:F, el:*;
    }
    sky function encodeVecN(a:Vector.<Number>, rtn:ByteArray):void {
        var e:int = a.length - 1;
        rtn.writeByte(0x5B); // [
        if (e >= 0) {
            for (i = 0; i < e; ++i) {
                sky::encodeNumber(a[i], rtn);
                rtn.writeByte(0x2C); // ,
            }
            sky::encodeNumber(a[i], rtn);
        }
        rtn.writeByte(0x5D);// ]
        return;
        var i:int;
    }
    sky function encodeVecU(a:Vector.<uint>, rtn:ByteArray):void {
        var e:int = a.length - 1;
        rtn.writeByte(0x5B); // [
        if (e >= 0) {
            for (i = 0; i < e; ++i) {
                rtn.writeUTFBytes(String(a[i]));
                rtn.writeByte(0x2C); // ,
            }
            rtn.writeUTFBytes(String(a[i]));
        }
        rtn.writeByte(0x5D);// ]
        return;
        var i:int;
    }
    sky function encodeVecI(a:Vector.<int>, rtn:ByteArray):void {
        var e:int = a.length - 1;
        rtn.writeByte(0x5B); // [
        if (e >= 0) {
            for (i = 0; i < e; ++i) {
                rtn.writeUTFBytes(String(a[i]));
                rtn.writeByte(0x2C); // ,
            }
            rtn.writeUTFBytes(String(a[i]));
        }
        rtn.writeByte(0x5D);// ]
        return;
        var i:int;
    }
    sky function encodeVecB(a:Vector.<Boolean>, rtn:ByteArray):void {
        var e:int = a.length - 1;
        rtn.writeByte(0x5B); // [
        if (e >= 0) {
            for (i = 0; i < e; ++i) {
                if (a[i]) { // Boolean vectors can technically contain null (last test: FP11.1) due to poor Adobe coding.
                    rtn.writeInt(0x74727565); // true
                    rtn.writeByte(0x2C); // ,
                } else {
                    rtn.writeShort(0x6661); // fa
                    rtn.writeInt(0x6C73652C); // lse,
                }
            }
            if (a[i]) rtn.writeInt(0x74727565); // true
            else rtn.writeByte(0x66), rtn.writeInt(0x616C7365); // f, alse
        }
        rtn.writeByte(0x5D);// ]
        return;
        var i:int;
    }
    sky function encodeVecS(a:Vector.<String>, rtn:ByteArray, enc:Vector.<int>):void {
        var e:int = a.length - 1;
        rtn.writeByte(0x5B); // [
        if (e >= 0) {
            for (i = 0; i < e; ++i) {
                b = a[i] as String;
                if (b !== null) sky::encodeString(String(a[i] as String), rtn, enc);
                else rtn.writeInt(0x6E756C6C);
                rtn.writeByte(0x2C);
            }
            b = a[i];
            if (b !== null) sky::encodeString(String(a[i] as String), rtn, enc);
            else rtn.writeInt(0x6E756C6C);
        }
        rtn.writeByte(0x5D);// ]
        return;
        var b:String, i:int;
    }
    sky function encodeBool(a:Boolean, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        if (a) {
            rtn.writeInt(0x74727565); // true
            return;
        }
        rtn.writeByte(0x66); // f
        rtn.writeInt(0x616C7365); // alse
    }
    sky function encodeDate(a:Date, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        rtn.writeByte(0x22);// "
        rtn.writeUTFBytes(String(a));
        rtn.writeByte(0x22);// "
    }
    sky function encodeDict(dic:Dictionary, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        rtn.writeByte(0x7B);// {
        var a:uint = rtn.position;
        for (b in dic) {
            if (b is String) {e = dic[b];
                sky::encodeString(b, rtn, enc, true);
                f = map[typeof e];
                f.f(e, rtn, enc, map);
                rtn.writeByte(0x2C);
            } else if (b is Number) {e = dic[b];
                sky::encodeString(String(b), rtn, enc, true);
                f = map[typeof e];
                f.f(e, rtn, enc, map);
                rtn.writeByte(0x2C);
            } else if (b is Date) {e = dic[b];
                sky::encodeString(String(b), rtn, enc, true);
                f = map[typeof e];
                f.f(e, rtn, enc, map);
                rtn.writeByte(0x2C);
            } else if (b is XML) {e = dic[b];
                sky::encodeString((b as XML).toXMLString(), rtn, enc, true);
                f = map[typeof e];
                f.f(e, rtn, enc, map);
                rtn.writeByte(0x2C);
            } else if (b is XMLList) {e = dic[b];
                sky::encodeString((b as XMLList).toXMLString(), rtn, enc, true);
                f = map[typeof e];
                f.f(e, rtn, enc, map);
                rtn.writeByte(0x2C);
            } else if (b is Boolean) {e = dic[b];
                sky::encodeString(String(b), rtn, enc, true);
                f = map[typeof e];
                f.f(e, rtn, enc, map);
                rtn.writeByte(0x2C);
            }
        }
        if (rtn.position !== a) rtn.position--;
        rtn.writeByte(0x7D);// }
        return;
        var b:*, e:Object, f:F;
    }
    sky function encodeObject(a:Object, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        if ("toJSON" in a) if (a.toJSON is Function) {
            c = tryToJSON(a);
            if (c !== null) {
                rtn.writeUTFBytes(c);
                return;
            }
        }
        rtn.writeByte(0x7B);// {
        var c:String;
        for (c in a) {
            sky::encodeString(c, rtn, enc, true);
            e = a[c];
            f = map[typeof e];
            f.f(e, rtn, enc, map);
            rtn.writeByte(0x2C);
        }
        if (c !== null) rtn.position--;
        rtn.writeByte(0x7D);// }
        return;
        var e:Object, f:F;
    }
    sky function encodeObj2(a:Object, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        if (!a) {
            rtn.writeInt(0x6E756C6C);
            return;
        }
        var f:F = map[a.constructor];
        if (Boolean(f)) {
            f.f(a, rtn, enc, map);
            return;
        }
        sky::encodeObject(a, rtn, enc, map);
    }
    sky function encodeXML(a:XML, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        sky::encodeString(a.toXMLString(), rtn, enc);
    }
    sky function encodeXMLL(a:XMLList, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        sky::encodeString(a.toXMLString(), rtn, enc);
    }
    sky function encodeNumber(e:Number, rtn:ByteArray):void {
        if ((e * 0) !== 0) {
            rtn.writeInt(0x6E756C6C);
            return;
        }
        rtn.writeUTFBytes(String(e));
    }
    sky function encodeString(data:String, rtn:ByteArray, enc:Vector.<int>, colon:Boolean = false):void {
        var i:int, e:int = data.length;
        rtn.writeByte(0x22);// "
        for (; i !== e; ++i) {
            c = data.charCodeAt(i);
            if (int(c >= 0x20) & int(c <= 0x7E)) {// highest is 0x7E. common case
                if (int(c === 0x22) | int(c === 0x5C)) rtn.writeShort(encRLs[c]);
                else rtn.writeByte(c);
            } else {
                if (int(c === 0x0A) | int(c === 0x0C) | int(c === 0x0D) | int(c === 0x09) | int(c === 0x08)) {
                    rtn.writeShort(encRLs[c]);
                } else {
                    c = enc[c];
                    rtn.writeShort(0x5C75); // \u
                    rtn.writeInt(c);
                }
            }
        }
        rtn.writeByte(0x22); // "
        if (colon) rtn.writeByte(0x3A);// :
        return;
        var c:int = 0;
    }
    sky function encodeRegEx(data:RegExp, rtn:ByteArray, enc:Vector.<int>):void {
        rtn.writeByte(0x22);// "
        var a:int = rtn.position;
        sky::encodeString(data.source, rtn, enc);
        var i:int = rtn.position - 1;
        rtn.position = a;
        rtn.writeByte(0x2F);// /
        rtn.position = i;
        rtn.writeByte(0x2F);// /
        if (data.global) rtn.writeByte(0x67);// g
        if (data.ignoreCase) rtn.writeByte(0x69);// i
        if (data.multiline) rtn.writeByte(0x6D);// m
        if (data.dotall) rtn.writeByte(0x73);// s
        if (data.extended) rtn.writeByte(0x78);// x
        rtn.writeByte(0x22);// "
    }
    sky function encodeByteArray(data:ByteArray, rtn:ByteArray, enc:Vector.<int>):void {
        var i:int, e:int = data.length;
        rtn.writeByte(0x22);// "
        for (; i !== e; ++i) {
            c = data[i];
            if (int(c >= 0x20) & int(c <= 0x7E)) {// highest is 0x7E. common case
                if (int(c === 0x22) | int(c === 0x5C)) rtn.writeShort(encRLs[c]);
                else rtn.writeByte(c);
            } else {
                if (int(c === 0x0A) | int(c === 0x0C) | int(c === 0x0D) | int(c === 0x09) | int(c === 0x08)) {
                    rtn.writeShort(encRLs[c]);
                } else {
                    c = enc[c];
                    rtn.writeShort(0x5C75); // \u
                    rtn.writeInt(c);
                }
            }
        }
        rtn.writeByte(0x22);// "
        return;
        var c:int = 0;
    }
    //}
    //}
    //{ DECODING
    private function decode(data:String):* {
        if (!data) return null;
        var e:int = data.length;
        var a:int, c:int = data.charCodeAt(a), temp:int;
        while ((int(c === 0x20) | int(c === 0x09) | int(c === 10) | int(c === 13))) {
            c = data.charCodeAt(++a);
        }
        var rtn:*;
        i = a;
        temp = data.indexOf('\\') + 1
        containsSlash = temp;
        if (c === 0x7B) {
            rtn = handleObject(data, e);
        } else if (c === 0x5B) {
            rtn = handleArray(data, e, data.charCodeAt(a + 1));
        } else if ((int(c === 0x22) | int(c === 0x27))) {
            rtn = '"';
            if (c === 0x27) rtn = "'";
            ++a;
            if (temp) {
                rtn = handleString(data, e, data.charCodeAt(a), c);
            } else rtn = data.substring(a, data.indexOf(rtn, a));
        } else if ((int(c === 0x2D) | int(c === 0x2E) | (int(c > 0x2F) & int(c < 0x3A)) | int(c === 0x2B))) {
            rtn = handleNumber2(data, e);
        } else if ((int(c === 0x74) | int(c === 0x66) | int(c === 0x6E))) {
            rtn = handleLit(data, e, a);
        } else error(data, i);
        return rtn;
    }
    public static function decode(data:String):* {
        return instance.decode(data);
    }
    public static function parse(data:String):* {
        return instance.decode(data);
    }
    //{ TYPES
    private function handleString(data:String, e:int, c:int, end:int):String { // additional arguments to provide speed boosts
        var a:int = i+1; // passed in 'c' is first character of string. 'end' is teminator (" or ')
        if (c == end) { // fastpath: empty string
            i = a;
            return '';
        }
        var t:int = data.charCodeAt(a + 1), inx:int = int(c != 0x5C);
        if (inx & int(t == end)) { // fastpath: single character string
            i = a + 1;
            return String.fromCharCode(c);
        }
        var p:int = containsSlash, p1:int, p2:int, temp:String = '"';
        if (end === 0x27) temp = "'";
        if (int(Boolean(p)) & int(a > p)) p = data.indexOf('\\', a) + 1, containsSlash = p;
        p1 = data.indexOf(temp, a);
        if ((int(!p) | int(p > p1)) & int(Boolean(p1 + 1))) {
            i = p1;
            return data.substring(a, p1);
        }
        var rtn:ByteArray = strArr;
        if (inx & int(c < 0x80)) rtn[0] = c, c = t, ++a;
        var enc:Vector.<int> = encD;
        rtn.position = 0;
        const low:int = 0x7F, u:int = 0x75, x:int = 0x78, slash:int = 0x5C;
        const two:int = 2, seven:int = 7, nine:int = 9, space:int = 0x20, tt:int = 22;
        while (a < e) {
            if (c === slash) {
                c = data.charCodeAt(++a);
                if (c > low) return handleMBString(data, e, c, rtn, inx, a, end);
                c = enc[c];
                if (c === u) {
                    t = data.charCodeAt(++a) - 0x30;
                    t -= (seven & -int(t > nine)) | (space & -int(t > tt));
                    p1 = data.charCodeAt(++a) - 0x30;
                    p1 -= (seven & -int(p1 > nine)) | (space & -int(p1 > tt));
                    p2 = data.charCodeAt(++a) - 0x30;
                    p2 -= (seven & -int(p2 > nine)) | (space & -int(p2 > tt));
                    p = data.charCodeAt(++a) - 0x30;
                    p -= (seven & -int(p > nine)) | (space & -int(p > tt));
                    if (uint(t | p1 | p2 | p) > 15) { // comparing with uint instead of int means the <0 check is combined
                        error(data, a - 6, "Expected 0-F after \\u", 6);
                    }
                    rtn.position = inx;
                    // 0xE08080 | ((i & 0xF000) << 4) | ((i & 0xFC0) << 2) | (i & 0x3F)
                    /*p1 = (p1 << two) | (p2 >> two);
                    p = ((p2 << two) | p) & 0x3F;
                    rtn.writeInt(((0xE0 | t) << 24) | ((0x80 | p1) << 16) | ((0x80 | p) << 8));
                    //*/
                    if (!(p1 | (t | (p2 & 8)))) {
                        ++inx, rtn.writeByte(p|(p2<<4));
                        c = data.charCodeAt(++a);
                        continue;
                    } else {
                        p |= (p2 << 4) | (p1 << 8);
                        rtn.writeInt((0xE08080 | (t << 16) | ((p & 0xFC0) << 2) | (p & 0x3F)) << 8);
                        inx += 3;
                        c = data.charCodeAt(++a);
                        continue;
                    }
                } else if (c === x) {
                    t = data.charCodeAt(++a) - 0x30;
                    t -= (seven & -int(t > nine)) | (space & -int(t > tt));
                    p = data.charCodeAt(++a) - 0x30;
                    p -= (seven & -int(p > nine)) | (space & -int(p > tt));
                    if (uint(t | p) > 15) { // comparing with uint instead of int means the <0 check is combined
                        error(data, a - 4, "Expected 0-F after \\x", 4);
                    }
                    c = (t << 4) | p;
                    rtn.position = inx;
                    rtn.writeShort(((0xC0 | ((c >> 6) & 0x1F)) << 8) | (0x80 | (c & 0x3F)));
                    ++inx;
                    ++inx;
                    c = data.charCodeAt(++a);
                    continue;
                }
            } else if (c === end) {
                i = a;
                rtn.position = 0;
                return rtn.readUTFBytes(inx);
            } else if (c > low) {
                return handleMBString(data, e, c, rtn, inx, a, end);
            }
            rtn[inx] = c;
            ++inx;
            c = data.charCodeAt(++a);
        }
        error(data, i, "Unterminated String.", 1);
        return null; // not reached
    }
    private function handleMBString(data:String, e:int, c:int, rtn:ByteArray, inx:int, a:int, end:int):String { // the much slower method capable of handling multi-byte characters
        var t:int, p:int, p1:int, p2:int;
        var enc:Vector.<int> = encD;
        rtn.position = inx;
        while (a < e) {
            c = data.charCodeAt(++a);
            if (c === 0x5C) {
                if (c < 0x80) {
                    c = enc[data.charCodeAt(++a)];
                    if (c === 0x75) {
                        t = data.charCodeAt(++a) - 0x30;
                        t -= (-int(t > 9) & 7) | (-int(t > 22) & 0x20);
                        p1 = data.charCodeAt(++a) - 0x30;
                        p1 -= (-int(p1 > 9) & 7) | (-int(p1 > 22) & 0x20);
                        p2 = data.charCodeAt(++a) - 0x30;
                        p2 -= (-int(p2 > 9) & 7) | (-int(p2 > 22) & 0x20);
                        p = data.charCodeAt(++a) - 0x30;
                        p -= (-int(p > 9) & 7) | (-int(p > 22) & 0x20);
                        if (uint(t | p1 | p2 | p) > 15) { // comparing with uint instead of int means the <0 check is combined
                            error(data, a - 6, "Expected 0-F after \\u", 6);
                        }
                        c = ((((((t << 4) | p1) << 4) | p2) << 4) | p);
                    } else if (c === 0x78) {
                        t = data.charCodeAt(++a) - 0x30;
                        t -= (-int(t > 9) & 7) | (-int(t > 22) & 0x20);
                        p = data.charCodeAt(++a) - 0x30;
                        p -= (-int(p > 9) & 7) | (-int(p > 22) & 0x20);
                        if (uint(t | p) > 15) { // comparing with uint instead of int means the <0 check is combined
                            error(data, a - 4, "Expected 0-F after \\x", 4);
                        }
                        c = (t << 4) | p;
                    }
                }
            } else if (c === end) {
                i = a;
                inx = rtn.position;
                rtn.position = 0;
                return rtn.readUTFBytes(inx);
            }
            c = 0xF0000000 | ((c & 0x1C0000) << 6) | 0x800000 | ((c & 0x3F000) << 4) | 0x8000 | ((c & 0xFC0) << 2) | 0x80 | (c & 0x3F);
            rtn.writeInt(c);
        }
        error(data, i, "Unterminated String.", 1);
        return null;
    }
    private function handleNumber2(data:String, e:int):Number {
        var a:int = i, c:int = data.charCodeAt(a), r:Number = 0, t:Number = 1;
        var n:Number = 1, ex:int, exn:int, d:int = 3;
        if (c == 0x2D) {
            c = data.charCodeAt(++a);
            n = -1;
        } else if (c == 0x2B) {
            c = data.charCodeAt(++a);
        }
        if ((int(c > 0x2F) & int(c < 0x3A))) {
            r = c - 0x30;
            while (int(a < e) & (int(int(c = int(data.charCodeAt(++a))) > 0x2F) & int(c < 0x3A))) {
                r = (r * 10) + (c - 0x30);
            }
        }
        if (c == 0x2E) {
            while (int(a < e) & (int(int(c = int(data.charCodeAt(++a))) > 0x2F) & int(c < 0x3A))) {
                r += (c - 0x30) / (t *= 10);
            }
        }
        if ((c | 0x20) == 0x65) {
            c = data.charCodeAt(++a);
            if (c == 0x2D) {
                exn = 1;
                c = data.charCodeAt(++a);
            } else if (c == 0x2B) c = data.charCodeAt(++a);
            while (int(c > 0x2F) & int(c < 0x3A) & int(Boolean(d--))) {
                ex = (ex * 10) + (c - 0x30);
                c = data.charCodeAt(++a);
            }
            t = 10;
            while (int(c > 0x2F) & int(c < 0x3A)) ex = 400, c = data.charCodeAt(++a); // consume the remainder
            if (exn) {
                if (ex < 325) while (ex) {
                    r /= ((ex & 1) * t + (~ex & 1));
                    ex >>>= 1;
                    t *= t;
                    r /= ((ex & 1) * t + (~ex & 1));
                    ex >>>= 1;
                    t *= t;
                } else r = 0; // >= 325 for negative exponents results in 0
            } else {
                if (ex < 309) while (ex) {
                    r *= ((ex & 1) * t + (~ex & 1));
                    ex >>>= 1;
                    t *= t;
                    r *= ((ex & 1) * t + (~ex & 1));
                    ex >>>= 1;
                    t *= t;
                } else r = Infinity; // >= 309 for positive exponents results in Infinity
            }
        }
        if (a < e) {
            while ((int(c == 0x20) | int(c == 0x09) | int(c == 10) | int(c == 13))) c = data.charCodeAt(++a);
            if (a < e) {
                error(data, a);
            }
        }
        return n * r;
    }
    private function handleFNumber(data:String, e:int, a:int, c:int, r:Number, n:int):Number { // original method
        if ((int(c > 0x2F) & int(c < 0x3A))) {
            do {
                r *= 10;
                c -= 48;
                r += c;
            } while (int((c = int(data.charCodeAt(++a))) > 0x2F) & int(c < 0x3A));
            if (int(c === 0x20) | int(c === 0x09) | int(c === 10) | int(c === 13) | int(c === 0x2C) | int((c | 0x20) === 0x7D)) {
                i = a - 1;
                return n * r;
            }
        }
        var t:int = 3, ex:int, exn:int, d:Number = 10;
        if (c === 0x2E) { // inaccurate after 16 digits
            while (int((c = int(data.charCodeAt(++a))) > 0x2F) & int(c < 0x3A)) {
                c -= 0x30;
                r += c / d;
                d *= 10;
            }
            if (int(c === 0x20) | int(c === 0x09) | int(c === 10) | int(c === 13) | int(c === 0x2C) | int((c | 0x20) === 0x7D)) {
                i = a - 1;
                return n * r;
            }
        }
        if ((c | 0x20) === 0x65) { // inaccurate at extremes (+-200 ish)
            c = data.charCodeAt(++a);
            if (c === 0x2D) {
                exn = 1;
                c = data.charCodeAt(++a);
            } else if (c === 0x2B) c = data.charCodeAt(++a);
            while (c === 0x30) c = data.charCodeAt(++a); // consume leading 0s
            while (int(c > 0x2F) & int(c < 0x3A) & int(Boolean(t--))) { // limit the number of digits gathered for exponent to 3.
                ex *= 10;
                c -= 0x30;
                ex += c;
                c = data.charCodeAt(++a);
            }
            if (int(c > 0x2F) & int(c < 0x3A)) {
                ++t; // mark that we have gone over 3 digits (excluding leading 0s); this value is too great
                do {
                    c = data.charCodeAt(++a); // consume the remainder.
                } while (int(c > 0x2F) & int(c < 0x3A));
            }
            if (exn) {
                if (int(ex < 325) & t) {
                    if (ex > 307)
                        t = ex - 307, ex -= t, r /= pow10[t];
                    r /= pow10[ex];
                } else r = 0; // >= 325 for negative exponents results in 0
            } else {
                if (int(ex < 309) & t) {
                    r *= pow10[ex];
                } else r = Infinity; // >= 309 for positive exponents results in Infinity
            }
            if (int(c === 0x20) | int(c === 0x09) | int(c === 10) | int(c === 13) | int(c === 0x2C) | int((c | 0x20) === 0x7D)) {
                i = a - 1;
                return n * r;
            }
        }
        if (a > e) {
            i = e;
            return n * r;
        }
        error(data, a);
        return NaN; // not reached
    }
    private function handleNumber(data:String, e:int):Number { // fast int-first method
        var a:int = i, c:int = data.charCodeAt(a), r:uint, n:int = 1, C:int;
        if (c === 0x2D) {
            c = data.charCodeAt(++a);
            n = -1;
        } else if (c === 0x2B) {
            c = data.charCodeAt(++a);
        }
        if ((int(c > 0x2F) & int(c < 0x3A))) {
            r = c - 0x30;
            while (Boolean(int((c = int(data.charCodeAt(++a))) > 0x2F) & int(c < 0x3A) & int(C < 9))) {
                r *= 10;
                c -= 48;
                r += c;
                ++C;
            }
            if (int(c === 0x20) | int(c === 0x09) | int(c === 10) | int(c === 13) | int(c === 0x2C) | int((c | 0x20) === 0x7D)) {
                i = a - 1;
                return n * r;
            }
            if (C >= 9) return handleFNumber(data, e, a, c, r, n);
        }
        if (c === 0x2E) return handleFNumber(data, e, a, c, r, n);
        if ((c | 0x20) === 0x65) return handleFNumber(data, e, a, c, r, n);
        if (a > e) {
            i = e;
            return n * r;
        }
        error(data, a);
        return NaN; // not reached
    }
    private function handleLit(data:String, e:int, q:int):* {
        var a:int = data.charCodeAt(q++), b:int = data.charCodeAt(q++);
        var c:int = data.charCodeAt(q++), d:int = data.charCodeAt(q);
        i = q;
        if (int(a === 0x74) & int(b === 0x72) & int(c === 0x75) & int(d === 0x65)) return true
        else if (int(a === 0x6E) & int(b === 0x75) & int(c === 0x6C) & int(d === 0x6C)) return null;
        else if (a === 0x66) {
            if (int(b === 0x61) & int(c === 0x6C) & int(d === 0x73) & int(data.charCodeAt(++i) === 0x65)) return false;
            error(data, --i, "Expected 'false'", 4);
        } else {
            if (a === 0x74) error(data, i, "Expected 'true'", 3);
            error(data, i, "Expected 'null'", 3);
        }
    }
    private function handleArray(data:String, e:int, c:int):Array {
        var a:int = i + 1;
        if (c === 0x5D) {
            i = a;
            return []; // short circuit
        }
        var inx:int, p:Boolean = true, rtn:Array = [0];
        while (a < e) {
            while ((int(c === 0x20) | int(c === 0x09) | int(c === 10) | int(c === 13))) {
                c = data.charCodeAt(++a);
            }
            if (c === 0x5D) {
                c = int(p);
                if (c & int(Boolean(inx))) error(data, a, "Expected value.", 1);
                c = 1 - c;
                rtn.length = inx + c;
                i = a;
                return rtn;
            } else if (p) {
                p = false;
                i = a;
                if ((int(c === 0x22) | int(c === 0x27))) {
                    rtn[inx] = handleString(data, e, data.charCodeAt(a + 1), c);
                    a = i;
                } else if ((int(c === 0x2D) | int(c === 0x2E) | (int(c > 0x2F) & int(c < 0x3A)) | int(c === 0x2B))) {
                    rtn[inx] = handleNumber(data, e);
                    a = i;
                } else if (c === 0x7B) {
                    rtn[inx] = handleObject(data, e);
                    a = i;
                } else if (c === 0x5B) {
                    rtn[inx] = handleArray(data, e, data.charCodeAt(a + 1));
                    a = i;
                } else if ((int(c === 0x74) | int(c === 0x66) | int(c === 0x6E))) {
                    rtn[inx] = handleLit(data, e, a);
                    a = i;
                } else error(data, a, "Expected value.", 1);
            } else if ((inx += int(p = (c === 0x2C)),p)) void;
            else error(data, a, "Expected , or ]");
            c = data.charCodeAt(++a);
        }
        error(data, i, "Unterminated Array.", 1);
        return null; // not reached
    }
    private function handleObject(data:String, e:int):Object {
        var c:int, a:int = i, rtn:Object = new Object;
        c = data.charCodeAt(++a);
        if (c === 0x7D) {
            i = a;
            return rtn;
        }
        var p:Boolean = true;
        while (a < e) {
            while ((int(c == 0x20) | int(c == 0x09) | int(c == 10) | int(c == 13))) {
                c = data.charCodeAt(++a);
            }
            if (c === 0x7D) {
                if (int(p) & int(Boolean(inx))) error(data, a, "Expected value.", 1)
                i = a;
                return rtn;
            } else if (p) {
                p = false;
                if ((int(c === 0x22) | int(c === 0x27))) {
                    i = a;
                    inx = handleString(data, e, data.charCodeAt(a + 1), c);
                    a = i;
                     do {
                        c = data.charCodeAt(++a);
                    } while ((int(c == 0x20) | int(c == 0x09) | int(c == 10) | int(c == 13)));
                    if (c === 0x3A) {
                        do {
                            c = data.charCodeAt(++a);
                        } while ((int(c == 0x20) | int(c == 0x09) | int(c == 10) | int(c == 13))); // wish i could omit these
                        i = a;
                        if ((int(c === 0x22) | int(c === 0x27))) {
                            rtn[inx] = handleString(data, e, data.charCodeAt(a + 1), c);
                            a = i;
                        } else if ((int(c === 0x2D) | int(c === 0x2E) | (int(c > 0x2F) & int(c < 0x3A)) | int(c === 0x2B))) {
                            rtn[inx] = handleNumber(data, e);
                            a = i;
                        } else if (c === 0x5B) {
                            rtn[inx] = handleArray(data, e, data.charCodeAt(a + 1));
                            a = i;
                        } else if (c === 0x7B) {
                            rtn[inx] = handleObject(data, e);
                            a = i;
                        } else if ((int(c === 0x74) | int(c === 0x66) | int(c === 0x6E))) {
                            rtn[inx] = handleLit(data, e, a);
                            a = i;
                        } else error(data, a, "Expected value.", 1);
                    } else error(data, a, "Expected :");
                } else error(data, a, "Expected \" or '");
            } else if ((p = (c === 0x2C))) void;
            else error(data, a, "Expected , or }");
            c = data.charCodeAt(++a);
        }
        error(data, a, "Unterminated Object.", 1);
        return null;// not reached
        var inx:String;
    }
    private function error(data:String, i:int, e:String = null, l:int = 0):void {
        if (l) {
            if (l > 1) {
                throw new Error("Malformed JSON at: " + i + ", '" + data.substr(i, l) + (e ? "'. " + e : "'."), errorID);
            } else {
                throw new Error("Malformed JSON at: " + i + ", '" + data.charAt(i) + (e ? "'. " + e : "'."), errorID);
            }
        } else {
            throw new Error("Malformed JSON at char: " + i + ", '" + data.charAt(i) + (e ? "'. " + e : "'."), errorID);
        }
    }
    //}
    //}
}
//{
import flash.utils.ByteArray;
import flash.utils.Dictionary;
internal namespace sky = "skyboy.serialization::sJSON";
internal interface F {
    function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void;
}
internal class E implements F {
    protected var j:sJSON;
    public function E($j:sJSON):void {
        j = $j;
    }
    public function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        
    }
}
internal class eA extends E {
    public function eA(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeArry(data, rtn, enc, map);
    }
}
internal class eVO extends E {
    public function eVO(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeVecO(data, rtn, enc, map);
    }
}
internal class eVN extends E {
    public function eVN(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeVecN(data, rtn);
    }
}
internal class eVU extends E {
    public function eVU(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeVecU(data, rtn);
    }
}
internal class eVI extends E {
    public function eVI(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeVecI(data, rtn);
    }
}
internal class eB extends E {
    public function eB(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeBool(data, rtn, enc, map);
    }
}
internal class eDT extends E {
    public function eDT(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeDate(data, rtn, enc, map);
    }
}
internal class eD extends E {
    public function eD(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeDict(data, rtn, enc, map);
    }
}
internal class eO extends E {
    public function eO(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeObject(data, rtn, enc, map);
    }
}
internal class eO2 extends E {
    public function eO2(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeObj2(data, rtn, enc, map);
    }
}
internal class eX extends E {
    public function eX(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        if (data is XMLList) j.sky::encodeXMLL(data, rtn, enc, map);
        else j.sky::encodeXML(data, rtn, enc, map);
    }
}
internal class eXL extends E {
    public function eXL(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeXMLL(data, rtn, enc, map);
    }
}
internal class eN extends E {
    public function eN(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeNumber(data, rtn);
    }
}
internal class eS extends E {
    public function eS(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeString(data, rtn, enc);
    }
}
internal class eRE extends E {
    public function eRE(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeRegEx(data, rtn, enc);
    }
}
internal class eBA extends E {
    public function eBA(j:sJSON):void {
        super(j);
    }
    public override function f(data:*, rtn:ByteArray, enc:Vector.<int>, map:Dictionary):void {
        j.sky::encodeByteArray(data, rtn, enc);
    }
}
new sJSON();
//}