package dolly {

import dolly.core.dolly_internal;
import dolly.core.metadata.MetadataName;

import org.as3commons.reflect.Accessor;
import org.as3commons.reflect.AccessorAccess;
import org.as3commons.reflect.Field;
import org.as3commons.reflect.IMetadataContainer;
import org.as3commons.reflect.Type;
import org.as3commons.reflect.Variable;

use namespace dolly_internal;

public class Copier {

	private static function getCopyableFieldsOfType(type:Type):Vector.<Field> {
		const result:Vector.<Field> = new Vector.<Field>();

		var variable:Variable;
		var accessor:Accessor;

		const isTypeCloneable:Boolean = type.hasMetadata(MetadataName.COPYABLE);
		if (isTypeCloneable) {
			for each(variable in type.variables) {
				if (!variable.isStatic) {
					result.push(variable);
				}
			}
			for each(accessor in type.accessors) {
				if (!accessor.isStatic && accessor.access == AccessorAccess.READ_WRITE) {
					result.push(accessor);
				}
			}
		} else {
			const metadataContainers:Array = type.getMetadataContainers(MetadataName.COPYABLE);
			for each(var metadataContainer:IMetadataContainer in metadataContainers) {
				if (metadataContainer is Variable) {
					variable = metadataContainer as Variable;
					if (!variable.isStatic && variable.hasMetadata(MetadataName.COPYABLE)) {
						result.push(variable);
					}
				} else if (metadataContainer is Accessor) {
					accessor = metadataContainer as Accessor;
					if (!accessor.isStatic
							&& accessor.access == AccessorAccess.READ_WRITE
							&& accessor.hasMetadata(MetadataName.COPYABLE)) {
						result.push(accessor);
					}
				}
			}
		}

		return result;
	}

	dolly_internal static function findCopyableFieldsForType(type:Type):Vector.<Field> {
		var result:Vector.<Field> = getCopyableFieldsOfType(type);

		var superType:Type;
		var superTypeCopyableFields:Vector.<Field>;

		for each(var superTypeName:String in type.extendsClasses) {
			superType = Type.forName(superTypeName);
			superTypeCopyableFields = getCopyableFieldsOfType(superType);
			if (superTypeCopyableFields.length > 0) {
				result = result.concat(superTypeCopyableFields);
			}
		}

		return result;
	}

	public static function copy(source:*):* {
		const type:Type = Type.forInstance(source);
		const copy:* = new (type.clazz)();

		const fieldsToCopy:Vector.<Field> = findCopyableFieldsForType(type);
		var name:String;
		for each(var field:Field in fieldsToCopy) {
			name = field.name;
			copy[name] = source[name];
		}

		return copy;
	}
}
}

package dolly {

import dolly.core.dolly_internal;
import dolly.core.metadata.MetadataName;

import flash.utils.Dictionary;

import org.as3commons.reflect.Accessor;
import org.as3commons.reflect.AccessorAccess;
import org.as3commons.reflect.Field;
import org.as3commons.reflect.IMetadataContainer;
import org.as3commons.reflect.Type;
import org.as3commons.reflect.Variable;

use namespace dolly_internal;

public class Copier {

	private static function getCopyableFieldsOfType(type:Type, foundFieldsMap:Dictionary):Vector.<Field> {
		const result:Vector.<Field> = new Vector.<Field>();

		var variable:Variable;
		var accessor:Accessor;

		const isTypeCloneable:Boolean = type.hasMetadata(MetadataName.COPYABLE);
		if (isTypeCloneable) {
			for each(variable in type.variables) {
				if (!foundFieldsMap[variable.name] && !variable.isStatic) {
					foundFieldsMap[variable.name] = variable;
					result.push(variable);
				}
			}
			for each(accessor in type.accessors) {
				if (!foundFieldsMap[accessor.name]
						&& !accessor.isStatic
						&& accessor.access == AccessorAccess.READ_WRITE) {
					foundFieldsMap[accessor.name] = accessor;
					result.push(accessor);
				}
			}
		} else {
			const metadataContainers:Array = type.getMetadataContainers(MetadataName.COPYABLE);
			for each(var metadataContainer:IMetadataContainer in metadataContainers) {
				if (metadataContainer is Variable) {
					variable = metadataContainer as Variable;
					if (!foundFieldsMap[variable.name]
							&& !variable.isStatic
							&& variable.hasMetadata(MetadataName.COPYABLE)) {
						foundFieldsMap[variable.name] = variable;
						result.push(variable);
					}
				} else if (metadataContainer is Accessor) {
					accessor = metadataContainer as Accessor;
					if (!foundFieldsMap[accessor.name]
							&& !accessor.isStatic
							&& accessor.access == AccessorAccess.READ_WRITE
							&& accessor.hasMetadata(MetadataName.COPYABLE)) {
						foundFieldsMap[accessor.name] = accessor;
						result.push(accessor);
					}
				}
			}
		}

		return result;
	}

	dolly_internal static function findCopyableFieldsForType(type:Type):Vector.<Field> {
		var foundFields:Dictionary = new Dictionary();
		var result:Vector.<Field> = getCopyableFieldsOfType(type, foundFields);

		var superType:Type;
		var superTypeCopyableFields:Vector.<Field>;

		for each(var superTypeName:String in type.extendsClasses) {
			superType = Type.forName(superTypeName);
			superTypeCopyableFields = getCopyableFieldsOfType(superType, foundFields);
			if (superTypeCopyableFields.length > 0) {
				result = result.concat(superTypeCopyableFields);
			}
		}

		return result;
	}

	public static function copy(source:*):* {
		const type:Type = Type.forInstance(source);
		const copy:* = new (type.clazz)();

		const fieldsToCopy:Vector.<Field> = findCopyableFieldsForType(type);
		var name:String;
		for each(var field:Field in fieldsToCopy) {
			name = field.name;
			copy[name] = source[name];
		}

		return copy;
	}
}
}

Remove duplications from founded copyable fields list.


package aerys.minko.scene.controller
{
	import aerys.minko.render.Viewport;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.KeyboardManager;
	import aerys.minko.type.MouseManager;

	import flash.display.BitmapData;
	import flash.utils.Dictionary;

	public class ScriptController extends EnterFrameController
	{
        private var _scene          : Scene;
        private var _started        : Dictionary;
		private var _lastTime		: Number;
		private var _deltaTime		: Number;
		private var _currentTarget	: ISceneNode;
		private var _viewport		: Viewport;

        protected function get scene() : Scene
        {
            return _scene;
        }

		protected function get deltaTime() : Number
		{
			return _deltaTime;
		}

		protected function get keyboard() : KeyboardManager
		{
			return _viewport.keyboardManager;
		}

		protected function get mouse() : MouseManager
		{
			return _viewport.mouseManager;
		}

		protected function get viewport() : Viewport
		{
			return _viewport;
		}

		public function ScriptController(targetType	: Class = null)
		{
			super(targetType);
		}

        override protected function targetAddedToSceneHandler(target    : ISceneNode,
                                                              scene     : Scene) : void
        {
            if (_scene && scene != _scene)
                throw new Error(
                    'The same ScriptController instance can not be used in more than one scene ' +
                    'at a time.'
                );

            _scene = scene;
        }

        override protected function targetRemovedFromSceneHandler(target    : ISceneNode,
                                                                  scene     : Scene) : void
        {
            if (numTargetsInScene == 0)
                _scene = null;
        }

		override protected function sceneEnterFrameHandler(scene		: Scene,
														   viewport		: Viewport,
														   destination	: BitmapData,
														   time			: Number) : void
		{
			_viewport = viewport;
			_deltaTime = _lastTime - time;
			_lastTime = time;

            beforeUpdate();

			var numTargets : uint = this.numTargets;

			for (var i : uint = 0; i < numTargets; ++i)
            {
                var target : ISceneNode = getTarget(i);

                if (target.scene)
                {
                    if (!_started[target])
                    {
                        _started[target] = true;
                        start(target);
                    }

    				update(target);
                }
                else if (_started[target])
                {
                    _started[target] = false;
                    stop(target);
                }
            }

            afterUpdate();
		}

        /**
         * The 'start' method is called on a script target at the first frame occuring after it
         * has been added to the scene.
         *
         * @param target
         *
         */
		protected function start(target : ISceneNode) : void
		{
			// nothing
		}

        /**
         * The 'beforeUpdate' method is called before each target is updated via the 'update'
         * method.
         *
         */
        protected function beforeUpdate() : void
        {
            // nothing
        }

		protected function update(target : ISceneNode) : void
		{
			// nothing
		}

        /**
         * The 'afterUpdate' method is called after each target has been updated via the 'update'
         * method.
         *
         */
        protected function afterUpdate() : void
        {
            // nothing
        }

        /**
         * The 'start' method is called on a script target at the first frame occuring after it
         * has been removed from the scene.
         *
         * @param target
         *
         */
		protected function stop(target : ISceneNode) : void
		{
			// nothing
		}
	}
}

package aerys.minko.scene.controller
{
	import aerys.minko.render.Viewport;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.KeyboardManager;
	import aerys.minko.type.MouseManager;

	import flash.display.BitmapData;
	import flash.utils.Dictionary;

	public class ScriptController extends EnterFrameController
	{
        private var _scene          : Scene;
        private var _started        : Dictionary;
		private var _lastTime		: Number;
		private var _deltaTime		: Number;
		private var _currentTarget	: ISceneNode;
		private var _viewport		: Viewport;

        protected function get scene() : Scene
        {
            return _scene;
        }

		protected function get deltaTime() : Number
		{
			return _deltaTime;
		}

		protected function get keyboard() : KeyboardManager
		{
			return _viewport.keyboardManager;
		}

		protected function get mouse() : MouseManager
		{
			return _viewport.mouseManager;
		}

		protected function get viewport() : Viewport
		{
			return _viewport;
		}

		public function ScriptController(targetType	: Class = null)
		{
			super(targetType);
		}

        protected function initialize() : void
        {
            _started = new Dictionary(true);
        }

        override protected function targetAddedToSceneHandler(target    : ISceneNode,
                                                              scene     : Scene) : void
        {
            if (_scene && scene != _scene)
                throw new Error(
                    'The same ScriptController instance can not be used in more than one scene ' +
                    'at a time.'
                );

            _scene = scene;
        }

        override protected function targetRemovedFromSceneHandler(target    : ISceneNode,
                                                                  scene     : Scene) : void
        {
            if (numTargetsInScene == 0)
                _scene = null;
        }

		override protected function sceneEnterFrameHandler(scene		: Scene,
														   viewport		: Viewport,
														   destination	: BitmapData,
														   time			: Number) : void
		{
			_viewport = viewport;
			_deltaTime = _lastTime - time;
			_lastTime = time;

            beforeUpdate();

			var numTargets : uint = this.numTargets;

			for (var i : uint = 0; i < numTargets; ++i)
            {
                var target : ISceneNode = getTarget(i);

                if (target.scene)
                {
                    if (!_started[target])
                    {
                        _started[target] = true;
                        start(target);
                    }

    				update(target);
                }
                else if (_started[target])
                {
                    _started[target] = false;
                    stop(target);
                }
            }

            afterUpdate();
		}

        /**
         * The 'start' method is called on a script target at the first frame occuring after it
         * has been added to the scene.
         *
         * @param target
         *
         */
		protected function start(target : ISceneNode) : void
		{
			// nothing
		}

        /**
         * The 'beforeUpdate' method is called before each target is updated via the 'update'
         * method.
         *
         */
        protected function beforeUpdate() : void
        {
            // nothing
        }

		protected function update(target : ISceneNode) : void
		{
			// nothing
		}

        /**
         * The 'afterUpdate' method is called after each target has been updated via the 'update'
         * method.
         *
         */
        protected function afterUpdate() : void
        {
            // nothing
        }

        /**
         * The 'start' method is called on a script target at the first frame occuring after it
         * has been removed from the scene.
         *
         * @param target
         *
         */
		protected function stop(target : ISceneNode) : void
		{
			// nothing
		}
	}
}

fix missing init of ScriptController._started


package logic
{
	/**
	 AGORA - an interactive and web-based argument mapping tool that stimulates reasoning,
	 reflection, critique, deliberation, and creativity in individual argument construction
	 and in collaborative or adversarial settings.
	 Copyright (C) 2011 Georgia Institute of Technology

	 This program is free software: you can redistribute it and/or modify
	 it under the terms of the GNU Affero General Public License as
	 published by the Free Software Foundation, either version 3 of the
	 License, or (at your option) any later version.

	 This program is distributed in the hope that it will be useful,
	 but WITHOUT ANY WARRANTY; without even the implied warranty of
	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	 GNU Affero General Public License for more details.

	 You should have received a copy of the GNU Affero General Public License
	 along with this program.  If not, see <http://www.gnu.org/licenses/>.

	 */
	import classes.ArgumentPanel;

	import mx.controls.Alert;

	public class ModusTollens extends ParentArg
	{
		public var andOr:String;
		private var _isExp:Boolean;

		public function ModusTollens()
		{
			_langTypes = ["If-then","Implies","Whenever","Only if","Provided that","Sufficient condition","Necessary condition"];
			dbLangTypeNames = ["ifthen","implies","whenever","onlyif","providedthat","sufficient","necessary"];
			_expLangTypes = ["Only if"];	// Expandable with both And and Or
			myname = MOD_TOL;
			_dbType = "MT";
		}

		override public function getOption(dbString:String):String{
			if(dbString.indexOf("or") >= 0)
			{
				return "or";
			}
			else if(dbString.indexOf("and") >= 0)
			{
				return "and"  ;
			}
			else
			{
				return "";
			}
		}

		override public function get dbType():String
		{

			for(var i:int=0; i<_langTypes.length; i++)
			{
				if(inference.myschemeSel.selectedType == _langTypes[i]){
					if(_langTypes[i] == "Only if" && inference.hasMultipleReasons){

						return _dbType+dbLangTypeNames[i]+andOr;
					}
					else
					{
						return _dbType+dbLangTypeNames[i];

					}
				}
			}
			return "Unset";
		}

		override public function createLinks():void
		{
			//Negate the claim if it is the first claim of the argument
			if(inference.claim.inference != null && !inference.claim.statementNegated)
			{
				Alert.show("Error: The claim should not have been a non-negative statement");
			}

			//change claim and reason from multistatement to normal
			//statement type
			if(inference.claim.multiStatement)
			{
				inference.claim.multiStatement = false;
			}
			for(var i:int=0; i < inference.reasons.length; i++)
			{
				if(inference.reasons[i].multiStatement)
				{
					inference.reasons[i].multiStatement = false;
				}
			}

			if(inference.claim.userEntered == false && inference.claim.inference == null && inference.claim.rules.length < 2)
			{
				inference.claim.input1.text = "P";
				inference.claim.makeUnEditable();
				inference.reasons[0].input1.text = "Q";
				inference.reasons[0].makeUnEditable();
			}

			if(!inference.claim.statementNegated)
			{
				inference.claim.statementNegated = true;
			}

			for(i = 0; i < inference.reasons.length; i++)
			{
				if(!inference.reasons[i].statementNegated)
				{
					inference.reasons[i].statementNegated = true;
				}
			}

			inference.implies = true;

			var	claim:ArgumentPanel = inference.claim;
			var reasons:Vector.<ArgumentPanel> = inference.reasons;
			claim.input1.forwardList.push(inference.input[0]);
			inference.input[0].forwardList.push(inference.inputs[1]);
			for(i=0; i < reasons.length; i++)
			{
				reasons[i].input1.forwardList.push(inference.input[i+1]);
				inference.input[i+1].forwardList.push(inference.inputs[0]);
			}
			inference.implies = true;
		}

		override public function correctUsage():String {
			var output:String = "";
			var reason:Vector.<ArgumentPanel> = inference.reasons;
			var claim:ArgumentPanel = inference.claim;
			var i:int;

			//Negate the reason. The reason will not be supported by other
			//arguments. If it were, the argument woud have had 'typed' true,
			//and myArg would not be pointing to a Modus Tollens Object

			switch(inference.myschemeSel.selectedType) {
				//negate reason
				case _langTypes[0]: //If-then. If both claim and reason negated
					//output += "If " + claim.positiveStmt + ", then "+ reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;

					inference.inputs[1].text = claim.positiveStmt;

					output = Language.lookup("ArgIfCap") + inference.inputs[1].text + ","
					 	+ Language.lookup("ArgThen") + inference.inputs[0].text;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[1]: // Implies
					output +=  claim.positiveStmt + Language.lookup("ArgImplies") + reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[2]: //Whenever
					output += Language.lookup("ArgWhenever") + claim.positiveStmt + ", " + reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[3]: // Only if
					var reasonStr:String = "";
					output += claim.positiveStmt + Language.lookup("ArgOnlyIf");
					for(i=0;i<reason.length-1;i++)
					{
						output += reason[i].positiveStmt + " " + andOr + " ";
						reasonStr = reasonStr + reason[i].positiveStmt + " " + andOr + " ";
					}
					reasonStr = reasonStr + reason[i].positiveStmt;
					output += reason[reason.length-1].positiveStmt;
					inference.inputs[0].text = reasonStr;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[4]: // Provided that
					output += reason[0].positiveStmt + Language.lookup("ArgProvidedThat") + claim.positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;

				case _langTypes[5]: // Sufficient condition
					output += claim.positiveStmt + Language.lookup("ArgSufficientCond") + reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[6]: // Necessary condition
					output += reason[0].positiveStmt + Language.lookup("ArgNecessaryCond") + claim.positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
			}
			return output;
		}
	}
}

package logic
{
	/**
	 AGORA - an interactive and web-based argument mapping tool that stimulates reasoning,
	 reflection, critique, deliberation, and creativity in individual argument construction
	 and in collaborative or adversarial settings.
	 Copyright (C) 2011 Georgia Institute of Technology

	 This program is free software: you can redistribute it and/or modify
	 it under the terms of the GNU Affero General Public License as
	 published by the Free Software Foundation, either version 3 of the
	 License, or (at your option) any later version.

	 This program is distributed in the hope that it will be useful,
	 but WITHOUT ANY WARRANTY; without even the implied warranty of
	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	 GNU Affero General Public License for more details.

	 You should have received a copy of the GNU Affero General Public License
	 along with this program.  If not, see <http://www.gnu.org/licenses/>.

	 */
	import classes.ArgumentPanel;
	import classes.Language;

	import mx.controls.Alert;

	public class ModusTollens extends ParentArg
	{
		public var andOr:String;
		private var _isExp:Boolean;

		public function ModusTollens()
		{
			_langTypes = ["If-then","Implies","Whenever","Only if","Provided that","Sufficient condition","Necessary condition"];
			dbLangTypeNames = ["ifthen","implies","whenever","onlyif","providedthat","sufficient","necessary"];
			_expLangTypes = ["Only if"];	// Expandable with both And and Or
			myname = MOD_TOL;
			_dbType = "MT";
		}

		override public function getOption(dbString:String):String{
			if(dbString.indexOf("or") >= 0)
			{
				return "or";
			}
			else if(dbString.indexOf("and") >= 0)
			{
				return "and"  ;
			}
			else
			{
				return "";
			}
		}

		override public function get dbType():String
		{

			for(var i:int=0; i<_langTypes.length; i++)
			{
				if(inference.myschemeSel.selectedType == _langTypes[i]){
					if(_langTypes[i] == "Only if" && inference.hasMultipleReasons){

						return _dbType+dbLangTypeNames[i]+andOr;
					}
					else
					{
						return _dbType+dbLangTypeNames[i];

					}
				}
			}
			return "Unset";
		}

		override public function createLinks():void
		{
			//Negate the claim if it is the first claim of the argument
			if(inference.claim.inference != null && !inference.claim.statementNegated)
			{
				Alert.show("Error: The claim should not have been a non-negative statement");
			}

			//change claim and reason from multistatement to normal
			//statement type
			if(inference.claim.multiStatement)
			{
				inference.claim.multiStatement = false;
			}
			for(var i:int=0; i < inference.reasons.length; i++)
			{
				if(inference.reasons[i].multiStatement)
				{
					inference.reasons[i].multiStatement = false;
				}
			}

			if(inference.claim.userEntered == false && inference.claim.inference == null && inference.claim.rules.length < 2)
			{
				inference.claim.input1.text = "P";
				inference.claim.makeUnEditable();
				inference.reasons[0].input1.text = "Q";
				inference.reasons[0].makeUnEditable();
			}

			if(!inference.claim.statementNegated)
			{
				inference.claim.statementNegated = true;
			}

			for(i = 0; i < inference.reasons.length; i++)
			{
				if(!inference.reasons[i].statementNegated)
				{
					inference.reasons[i].statementNegated = true;
				}
			}

			inference.implies = true;

			var	claim:ArgumentPanel = inference.claim;
			var reasons:Vector.<ArgumentPanel> = inference.reasons;
			claim.input1.forwardList.push(inference.input[0]);
			inference.input[0].forwardList.push(inference.inputs[1]);
			for(i=0; i < reasons.length; i++)
			{
				reasons[i].input1.forwardList.push(inference.input[i+1]);
				inference.input[i+1].forwardList.push(inference.inputs[0]);
			}
			inference.implies = true;
		}

		override public function correctUsage():String {
			var output:String = "";
			var reason:Vector.<ArgumentPanel> = inference.reasons;
			var claim:ArgumentPanel = inference.claim;
			var i:int;

			//Negate the reason. The reason will not be supported by other
			//arguments. If it were, the argument woud have had 'typed' true,
			//and myArg would not be pointing to a Modus Tollens Object

			switch(inference.myschemeSel.selectedType) {
				//negate reason
				case _langTypes[0]: //If-then. If both claim and reason negated
					//output += "If " + claim.positiveStmt + ", then "+ reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;

					inference.inputs[1].text = claim.positiveStmt;

					output = Language.lookup("ArgIfCap") + inference.inputs[1].text + ","
					 	+ Language.lookup("ArgThen") + inference.inputs[0].text;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[1]: // Implies
					output +=  claim.positiveStmt + Language.lookup("ArgImplies") + reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[2]: //Whenever
					output += Language.lookup("ArgWhenever") + claim.positiveStmt + ", " + reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[3]: // Only if
					var reasonStr:String = "";
					output += claim.positiveStmt + Language.lookup("ArgOnlyIf");
					for(i=0;i<reason.length-1;i++)
					{
						output += reason[i].positiveStmt + " " + andOr + " ";
						reasonStr = reasonStr + reason[i].positiveStmt + " " + andOr + " ";
					}
					reasonStr = reasonStr + reason[i].positiveStmt;
					output += reason[reason.length-1].positiveStmt;
					inference.inputs[0].text = reasonStr;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[4]: // Provided that
					output += reason[0].positiveStmt + Language.lookup("ArgProvidedThat") + claim.positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;

				case _langTypes[5]: // Sufficient condition
					output += claim.positiveStmt + Language.lookup("ArgSufficientCond") + reason[0].positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
				case _langTypes[6]: // Necessary condition
					output += reason[0].positiveStmt + Language.lookup("ArgNecessaryCond") + claim.positiveStmt;
					inference.inputs[0].text = reason[0].positiveStmt;
					inference.inputs[1].text = claim.positiveStmt;
					inference.inputs[0].forwardUpdate();
					inference.inputs[1].forwardUpdate();
					break;
			}
			return output;
		}
	}
}

Fix missing import

Fix missing import


/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mangui.hls.model {
    import org.mangui.hls.demux.ID3Tag;
    import org.mangui.hls.flv.FLVTag;
    import org.mangui.hls.utils.AES;
    import org.mangui.hls.utils.PTS;

    import flash.utils.ByteArray;

    /** Fragment Data. **/
    public class FragmentData {
        /** valid fragment **/
        public var valid : Boolean;
        /** fragment byte array **/
        public var bytes : ByteArray;
        /** bytes Loaded **/
        public var bytesLoaded : int;
        /** AES decryption instance **/
        public var decryptAES : AES;
        /** Start PTS of this chunk. **/
        public var pts_start : Number;
        /** computed Start PTS of this chunk. **/
        public var pts_start_computed : Number;
        /** min/max audio/video PTS/DTS of this chunk. **/
        public var pts_min_audio : Number;
        public var pts_max_audio : Number;
        public var pts_min_video : Number;
        public var pts_max_video : Number;
        public var dts_min : Number;
        /** audio/video found ? */
        public var audio_found : Boolean;
        public var video_found : Boolean;
        /** tag related stuff */
        public var metadata_tag_injected : Boolean;
        private var tags_pts_min_audio : Number;
        private var tags_pts_max_audio : Number;
        private var tags_pts_min_video : Number;
        private var tags_pts_max_video : Number;
        private var tags_audio_found : Boolean;
        private var tags_video_found : Boolean;
        public var tags : Vector.<FLVTag>;
        /* video dimension */
        public var video_width : int;
        public var video_height : int;
        /* is fragment loaded selected by autolevel algo */
        public var auto_level : Boolean;
        /* ID3 tags linked to this fragment */
        public var id3_tags : Vector.<ID3Tag>;

        /**  tag duration */
        private var audio_tag_duration : Number;
        private var video_tag_duration : Number;
        private var audio_tag_last_dts : Number;
        private var video_tag_last_dts : Number;

        /** Fragment metrics **/
        public function FragmentData() {
            this.pts_start = NaN;
            this.pts_start_computed = NaN;
            this.valid = true;
            this.video_width = 0;
            this.video_height = 0;
        };

        public function appendTags(tags : Vector.<FLVTag>) : void {
            // Audio PTS/DTS normalization + min/max computation
            for each (var tag : FLVTag in tags) {
                tag.pts = PTS.normalize(pts_start_computed, tag.pts);
                tag.dts = PTS.normalize(pts_start_computed, tag.dts);
                dts_min = Math.min(dts_min, tag.dts);
                switch( tag.type ) {
                    case FLVTag.AAC_RAW:
                    case FLVTag.AAC_HEADER:
                    case FLVTag.MP3_RAW:
                        audio_found = true;
                        tags_audio_found = true;
                        audio_tag_duration = tag.dts - audio_tag_last_dts;
                        audio_tag_last_dts = tag.dts;
                        tags_pts_min_audio = Math.min(tags_pts_min_audio, tag.pts);
                        tags_pts_max_audio = Math.max(tags_pts_max_audio, tag.pts);
                        pts_min_audio = Math.min(pts_min_audio, tag.pts);
                        pts_max_audio = Math.max(pts_max_audio, tag.pts);
                        break;
                    case FLVTag.AVC_HEADER:
                    case FLVTag.AVC_NALU:
                        video_found = true;
                        tags_video_found = true;
                        video_tag_duration = tag.dts - video_tag_last_dts;
                        video_tag_last_dts = tag.dts;
                        tags_pts_min_video = Math.min(tags_pts_min_video, tag.pts);
                        tags_pts_max_video = Math.max(tags_pts_max_video, tag.pts);
                        pts_min_video = Math.min(pts_min_video, tag.pts);
                        pts_max_video = Math.max(pts_max_video, tag.pts);
                        break;
                    case FLVTag.DISCONTINUITY:
                    case FLVTag.METADATA:
                    default:
                        break;
                }
                this.tags.push(tag);
            }
        }

        public function flushTags() : void {
            // clean-up tags
            tags = new Vector.<FLVTag>();
            tags_audio_found = tags_video_found = false;
            metadata_tag_injected = false;
            pts_min_audio = pts_min_video = dts_min = tags_pts_min_audio = tags_pts_min_video = Number.POSITIVE_INFINITY;
            pts_max_audio = pts_max_video = tags_pts_max_audio = tags_pts_max_video = Number.NEGATIVE_INFINITY;
            audio_found = video_found = tags_audio_found = tags_video_found = false;
        }

        public function shiftTags() : void {
            tags = new Vector.<FLVTag>();
            if (tags_audio_found) {
                tags_pts_min_audio = tags_pts_max_audio;
                tags_audio_found = false;
            }
            if (tags_video_found) {
                tags_pts_min_video = tags_pts_max_video;
                tags_video_found = false;
            }
        }

        public function get pts_min() : Number {
            if (audio_found) {
                return pts_min_audio;
            } else {
                return pts_min_video;
            }
        }

        public function get pts_max() : Number {
            if (audio_found) {
                return pts_max_audio;
            } else {
                return pts_max_video;
            }
        }

        public function get tag_duration() : Number {
            var duration : Number;
            if (audio_found) {
                duration = audio_tag_duration;
            } else {
                duration = video_tag_duration;
            }
            if(isNaN(duration)) {
                duration = 0;
            }
            return duration;
        }

        public function get tag_pts_min() : Number {
            if (audio_found) {
                return tags_pts_min_audio;
            } else {
                return tags_pts_min_video;
            }
        }

        public function get tag_pts_max() : Number {
            if (audio_found) {
                return tags_pts_max_audio;
            } else {
                return tags_pts_max_video;
            }
        }

        public function get tag_pts_start_offset() : Number {
            if (tags_audio_found) {
                return tags_pts_min_audio - pts_min_audio;
            } else {
                return tags_pts_min_video - pts_min_video;
            }
        }

        public function get tag_pts_end_offset() : Number {
            if (tags_audio_found) {
                return tags_pts_max_audio - pts_min_audio;
            } else {
                return tags_pts_max_video - pts_min_video;
            }
        }
    }
}

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mangui.hls.model {
    import org.mangui.hls.demux.ID3Tag;
    import org.mangui.hls.flv.FLVTag;
    import org.mangui.hls.utils.AES;
    import org.mangui.hls.utils.PTS;

    import flash.utils.ByteArray;

    /** Fragment Data. **/
    public class FragmentData {
        /** valid fragment **/
        public var valid : Boolean;
        /** fragment byte array **/
        public var bytes : ByteArray;
        /* Total bytes this Fragment _will_ have */
        public var bytesTotal: int;
        /** bytes Loaded **/
        public var bytesLoaded : int;
        /** AES decryption instance **/
        public var decryptAES : AES;
        /** Start PTS of this chunk. **/
        public var pts_start : Number;
        /** computed Start PTS of this chunk. **/
        public var pts_start_computed : Number;
        /** min/max audio/video PTS/DTS of this chunk. **/
        public var pts_min_audio : Number;
        public var pts_max_audio : Number;
        public var pts_min_video : Number;
        public var pts_max_video : Number;
        public var dts_min : Number;
        /** audio/video found ? */
        public var audio_found : Boolean;
        public var video_found : Boolean;
        /** tag related stuff */
        public var metadata_tag_injected : Boolean;
        private var tags_pts_min_audio : Number;
        private var tags_pts_max_audio : Number;
        private var tags_pts_min_video : Number;
        private var tags_pts_max_video : Number;
        private var tags_audio_found : Boolean;
        private var tags_video_found : Boolean;
        public var tags : Vector.<FLVTag>;
        /* video dimension */
        public var video_width : int;
        public var video_height : int;
        /* is fragment loaded selected by autolevel algo */
        public var auto_level : Boolean;
        /* ID3 tags linked to this fragment */
        public var id3_tags : Vector.<ID3Tag>;

        /**  tag duration */
        private var audio_tag_duration : Number;
        private var video_tag_duration : Number;
        private var audio_tag_last_dts : Number;
        private var video_tag_last_dts : Number;

        /** Fragment metrics **/
        public function FragmentData() {
            this.pts_start = NaN;
            this.pts_start_computed = NaN;
            this.valid = true;
            this.video_width = 0;
            this.video_height = 0;
        };

        public function appendTags(tags : Vector.<FLVTag>) : void {
            // Audio PTS/DTS normalization + min/max computation
            for each (var tag : FLVTag in tags) {
                tag.pts = PTS.normalize(pts_start_computed, tag.pts);
                tag.dts = PTS.normalize(pts_start_computed, tag.dts);
                dts_min = Math.min(dts_min, tag.dts);
                switch( tag.type ) {
                    case FLVTag.AAC_RAW:
                    case FLVTag.AAC_HEADER:
                    case FLVTag.MP3_RAW:
                        audio_found = true;
                        tags_audio_found = true;
                        audio_tag_duration = tag.dts - audio_tag_last_dts;
                        audio_tag_last_dts = tag.dts;
                        tags_pts_min_audio = Math.min(tags_pts_min_audio, tag.pts);
                        tags_pts_max_audio = Math.max(tags_pts_max_audio, tag.pts);
                        pts_min_audio = Math.min(pts_min_audio, tag.pts);
                        pts_max_audio = Math.max(pts_max_audio, tag.pts);
                        break;
                    case FLVTag.AVC_HEADER:
                    case FLVTag.AVC_NALU:
                        video_found = true;
                        tags_video_found = true;
                        video_tag_duration = tag.dts - video_tag_last_dts;
                        video_tag_last_dts = tag.dts;
                        tags_pts_min_video = Math.min(tags_pts_min_video, tag.pts);
                        tags_pts_max_video = Math.max(tags_pts_max_video, tag.pts);
                        pts_min_video = Math.min(pts_min_video, tag.pts);
                        pts_max_video = Math.max(pts_max_video, tag.pts);
                        break;
                    case FLVTag.DISCONTINUITY:
                    case FLVTag.METADATA:
                    default:
                        break;
                }
                this.tags.push(tag);
            }
        }

        public function flushTags() : void {
            // clean-up tags
            tags = new Vector.<FLVTag>();
            tags_audio_found = tags_video_found = false;
            metadata_tag_injected = false;
            pts_min_audio = pts_min_video = dts_min = tags_pts_min_audio = tags_pts_min_video = Number.POSITIVE_INFINITY;
            pts_max_audio = pts_max_video = tags_pts_max_audio = tags_pts_max_video = Number.NEGATIVE_INFINITY;
            audio_found = video_found = tags_audio_found = tags_video_found = false;
        }

        public function shiftTags() : void {
            tags = new Vector.<FLVTag>();
            if (tags_audio_found) {
                tags_pts_min_audio = tags_pts_max_audio;
                tags_audio_found = false;
            }
            if (tags_video_found) {
                tags_pts_min_video = tags_pts_max_video;
                tags_video_found = false;
            }
        }

        public function get pts_min() : Number {
            if (audio_found) {
                return pts_min_audio;
            } else {
                return pts_min_video;
            }
        }

        public function get pts_max() : Number {
            if (audio_found) {
                return pts_max_audio;
            } else {
                return pts_max_video;
            }
        }

        public function get tag_duration() : Number {
            var duration : Number;
            if (audio_found) {
                duration = audio_tag_duration;
            } else {
                duration = video_tag_duration;
            }
            if(isNaN(duration)) {
                duration = 0;
            }
            return duration;
        }

        public function get tag_pts_min() : Number {
            if (audio_found) {
                return tags_pts_min_audio;
            } else {
                return tags_pts_min_video;
            }
        }

        public function get tag_pts_max() : Number {
            if (audio_found) {
                return tags_pts_max_audio;
            } else {
                return tags_pts_max_video;
            }
        }

        public function get tag_pts_start_offset() : Number {
            if (tags_audio_found) {
                return tags_pts_min_audio - pts_min_audio;
            } else {
                return tags_pts_min_video - pts_min_video;
            }
        }

        public function get tag_pts_end_offset() : Number {
            if (tags_audio_found) {
                return tags_pts_max_audio - pts_min_audio;
            } else {
                return tags_pts_max_video - pts_min_video;
            }
        }
    }
}

Add bytesTotal

[Mangui.FragmentData] Add bytesTotal

Parallel of ProgressEvent.bytesTotal. Used by FragmentStream.


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.utils
{

import flash.utils.ByteArray;
import flash.utils.Dictionary;

import mx.core.IPropertyChangeNotifier;
import mx.core.IUIComponent;
import mx.core.IUID;
import mx.core.mx_internal;

use namespace mx_internal;

/**
 *  The UIDUtil class is an all-static class
 *  with methods for working with UIDs (unique identifiers) within Flex.
 *  You do not create instances of UIDUtil;
 *  instead you simply call static methods such as the
 *  UIDUtil.createUID() method.
 *
 *
Note: If you have a dynamic object that has no [Bindable] properties
 *  (which force the object to implement the IUID interface), Flex  adds an
 *  mx_internal_uid property that contains a UID to the object.
 *  To avoid having this field
 *  in your dynamic object, make it [Bindable], implement the IUID interface
 *  in the object class, or set a <coded>uid</coded> property with a value.

 *
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class UIDUtil
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Char codes for 0123456789ABCDEF
     */
	private static const ALPHA_CHAR_CODES:Array = [48, 49, 50, 51, 52, 53, 54,
		55, 56, 57, 65, 66, 67, 68, 69, 70];

    private static const DASH:int = 45;       // dash ascii
    private static const UIDBuffer:ByteArray = new ByteArray();       // static ByteArray used for UID generation to save memory allocation cost

    //--------------------------------------------------------------------------
    //
    //  Class variables
    //
    //--------------------------------------------------------------------------

    /**
     *  This Dictionary records all generated uids for all existing items.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private static var uidDictionary:Dictionary = new Dictionary(true);

    //--------------------------------------------------------------------------
    //
    //  Class methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Generates a UID (unique identifier) based on ActionScript's
     *  pseudo-random number generator and the current time.
     *
     *
The UID has the form
     *  "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
     *  where X is a hexadecimal digit (0-9, A-F).

     *
     *
This UID will not be truly globally unique; but it is the best
     *  we can do without player support for UID generation.

     *
     *  @return The newly-generated UID.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
	public static function createUID():String
    {
        UIDBuffer.position = 0;

        var i:int;
        var j:int;

        for (i = 0; i < 8; i++)
        {
            UIDBuffer.writeByte(ALPHA_CHAR_CODES[int(Math.random() * 16)]);
        }

        for (i = 0; i < 3; i++)
        {
            UIDBuffer.writeByte(DASH);
            for (j = 0; j < 4; j++)
            {
                UIDBuffer.writeByte(ALPHA_CHAR_CODES[int(Math.random() * 16)]);
            }
        }

        UIDBuffer.writeByte(DASH);

        var time:uint = new Date().getTime(); // extract last 8 digits
        var timeString:String = time.toString(16).toUpperCase();
        // 0xFFFFFFFF milliseconds ~= 3 days, so timeString may have between 1 and 8 digits, hence we need to pad with 0s to 8 digits
        for (i = 8; i > timeString.length; --i)
            UIDBuffer.writeByte(48);
        UIDBuffer.writeUTFBytes(timeString);

        for (i = 0; i < 4; i++)
        {
            UIDBuffer.writeByte(ALPHA_CHAR_CODES[int(Math.random() * 16)]);
        }

        return UIDBuffer.toString();
    }

    /**
     * Converts a 128-bit UID encoded as a ByteArray to a String representation.
     * The format matches that generated by createUID. If a suitable ByteArray
     * is not provided, null is returned.
     *
     * @param ba ByteArray 16 bytes in length representing a 128-bit UID.
     *
     * @return String representation of the UID, or null if an invalid
     * ByteArray is provided.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function fromByteArray(ba:ByteArray):String
    {
        if (ba != null && ba.length >= 16 && ba.bytesAvailable >= 16)
        {
            var chars:Array = new Array(36);
            var index:uint = 0;
            for (var i:uint = 0; i < 16; i++)
            {
                if (i == 4 || i == 6 || i == 8 || i == 10)
                    chars[index++] = DASH; // Hyphen char code

                var b:int = ba.readByte();
                chars[index++] = ALPHA_CHAR_CODES[(b & 0xF0) >>> 4];
                chars[index++] = ALPHA_CHAR_CODES[(b & 0x0F)];
            }
            return String.fromCharCode.apply(null, chars);
        }

        return null;
    }

    /**
     * A utility method to check whether a String value represents a
     * correctly formatted UID value. UID values are expected to be
     * in the format generated by createUID(), implying that only
     * capitalized A-F characters in addition to 0-9 digits are
     * supported.
     *
     * @param uid The value to test whether it is formatted as a UID.
     *
     * @return Returns true if the value is formatted as a UID.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function isUID(uid:String):Boolean
    {
        if (uid != null && uid.length == 36)
        {
            for (var i:uint = 0; i < 36; i++)
            {
                var c:Number = uid.charCodeAt(i);

                // Check for correctly placed hyphens
                if (i == 8 || i == 13 || i == 18 || i == 23)
                {
                    if (c != DASH)
                    {
                        return false;
                    }
                }
                // We allow capital alpha-numeric hex digits only
                else if (c < 48 || c > 70 || (c > 57 && c < 65))
                {
                    return false;
                }
            }

            return true;
        }

        return false;
    }

    /**
     * Converts a UID formatted String to a ByteArray. The UID must be in the
     * format generated by createUID, otherwise null is returned.
     *
     * @param String representing a 128-bit UID
     *
     * @return ByteArray 16 bytes in length representing the 128-bits of the
     * UID or null if the uid could not be converted.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function toByteArray(uid:String):ByteArray
    {
        if (isUID(uid))
        {
            var result:ByteArray = new ByteArray();

            for (var i:uint = 0; i < uid.length; i++)
            {
                var c:String = uid.charAt(i);
                if (c == "-")
                    continue;
                var h1:uint = getDigit(c);
                i++;
                var h2:uint = getDigit(uid.charAt(i));
                result.writeByte(((h1 << 4) | h2) & 0xFF);
            }
            result.position = 0;
            return result;
        }

        return null;
    }

    /**
     *  Returns the UID (unique identifier) for the specified object.
     *  If the specified object doesn't have an UID
     *  then the method assigns one to it.
     *  If a map is specified this method will use the map
     *  to construct the UID.
     *  As a special case, if the item passed in is null,
     *  this method returns a null UID.
     *
     *  @param item Object that we need to find the UID for.
     *
     *  @return The UID that was either found or generated.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function getUID(item:Object):String
    {
        var result:String = null;

        if (item == null)
            return result;

        if (item is IUID)
        {
            result = IUID(item).uid;
            if (result == null || result.length == 0)
            {
                result = createUID();
                IUID(item).uid = result;
            }
        }
        else if ((item is IPropertyChangeNotifier) &&
                 !(item is IUIComponent))
        {
            result = IPropertyChangeNotifier(item).uid;
            if (result == null || result.length == 0)
            {
                result = createUID();
                IPropertyChangeNotifier(item).uid = result;
            }
        }
        else if (item is String)
        {
            return item as String;
        }
        else
        {
            try
            {
                // We don't create uids for XMLLists, but if
                // there's only a single XML node, we'll extract it.
                if (item is XMLList && item.length == 1)
                    item = item[0];

                if (item is XML)
                {
                    // XML nodes carry their UID on the
                    // function-that-is-a-hashtable they can carry around.
                    // To decorate an XML node with a UID,
                    // we need to first initialize it for notification.
                    // There is a potential performance issue here,
                    // since notification does have a cost,
                    // but most use cases for needing a UID on an XML node also
                    // require listening for change notifications on the node.
                    var xitem:XML = XML(item);
                    var nodeKind:String = xitem.nodeKind();
                    if (nodeKind == "text" || nodeKind == "attribute")
                        return xitem.toString();

                    var notificationFunction:Function = xitem.notification();
                    if (!(notificationFunction is Function))
                    {
                        // The xml node hasn't already been initialized
                        // for notification, so do so now.
                        notificationFunction =
                            XMLNotifier.initializeXMLForNotification();
                        xitem.setNotification(notificationFunction);
                    }

                    // Generate a new uid for the node if necessary.
                    if (notificationFunction["uid"] == undefined)
                        result = notificationFunction["uid"] = createUID();

                    result = notificationFunction["uid"];
                }
                else
                {
                    if ("mx_internal_uid" in item)
                        return item.mx_internal_uid;

                    if ("uid" in item)
                        return item.uid;

                    result = uidDictionary[item];

                    if (!result)
                    {
                        result = createUID();
                        try
                        {
                            item.mx_internal_uid = result;
                        }
                        catch(e:Error)
                        {
                            uidDictionary[item] = result;
                        }
                    }
                }
            }
            catch(e:Error)
            {
                result = item.toString();
            }
        }

        return result;
    }

    /**
     * Returns the decimal representation of a hex digit.
     * @private
     */
    private static function getDigit(hex:String):uint
    {
        switch (hex)
        {
            case "A":
            case "a":
                return 10;
            case "B":
            case "b":
                return 11;
            case "C":
            case "c":
                return 12;
            case "D":
            case "d":
                return 13;
            case "E":
            case "e":
                return 14;
            case "F":
            case "f":
                return 15;
            default:
                return new uint(hex);
        }
    }
}

}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.utils
{

import flash.utils.ByteArray;
import flash.utils.Dictionary;

import mx.core.IPropertyChangeNotifier;
import mx.core.IUIComponent;
import mx.core.IUID;
import mx.core.mx_internal;

use namespace mx_internal;

/**
 *  The UIDUtil class is an all-static class
 *  with methods for working with UIDs (unique identifiers) within Flex.
 *  You do not create instances of UIDUtil;
 *  instead you simply call static methods such as the
 *  UIDUtil.createUID() method.
 *
 *
Note: If you have a dynamic object that has no [Bindable] properties
 *  (which force the object to implement the IUID interface), Flex  adds an
 *  mx_internal_uid property that contains a UID to the object.
 *  To avoid having this field
 *  in your dynamic object, make it [Bindable], implement the IUID interface
 *  in the object class, or set a <coded>uid</coded> property with a value.

 *
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class UIDUtil
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Char codes for 0123456789ABCDEF
     */
	private static const ALPHA_CHAR_CODES:Array = [48, 49, 50, 51, 52, 53, 54,
		55, 56, 57, 65, 66, 67, 68, 69, 70];

    private static const DASH:int = 45;       // dash ascii
    private static const UIDBuffer:ByteArray = new ByteArray();       // static ByteArray used for UID generation to save memory allocation cost

    //--------------------------------------------------------------------------
    //
    //  Class variables
    //
    //--------------------------------------------------------------------------

    /**
     *  This Dictionary records all generated uids for all existing items.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private static var uidDictionary:Dictionary = new Dictionary(true);

    //--------------------------------------------------------------------------
    //
    //  Class methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Generates a UID (unique identifier) based on ActionScript's
     *  pseudo-random number generator and the current time.
     *
     *
The UID has the form
     *  "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
     *  where X is a hexadecimal digit (0-9, A-F).

     *
     *
This UID will not be truly globally unique; but it is the best
     *  we can do without player support for UID generation.

     *
     *  @return The newly-generated UID.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
	public static function createUID():String
    {
        UIDBuffer.position = 0;

        var i:int;
        var j:int;

        for (i = 0; i < 8; i++)
        {
            UIDBuffer.writeByte(ALPHA_CHAR_CODES[int(Math.random() * 16)]);
        }

        for (i = 0; i < 3; i++)
        {
            UIDBuffer.writeByte(DASH);
            for (j = 0; j < 4; j++)
            {
                UIDBuffer.writeByte(ALPHA_CHAR_CODES[int(Math.random() * 16)]);
            }
        }

        UIDBuffer.writeByte(DASH);

        var time:uint = new Date().getTime(); // extract last 8 digits
        var timeString:String = time.toString(16).toUpperCase();
        // 0xFFFFFFFF milliseconds ~= 3 days, so timeString may have between 1 and 8 digits, hence we need to pad with 0s to 8 digits
        for (i = 8; i > timeString.length; i--)
            UIDBuffer.writeByte(48);
        UIDBuffer.writeUTFBytes(timeString);

        for (i = 0; i < 4; i++)
        {
            UIDBuffer.writeByte(ALPHA_CHAR_CODES[int(Math.random() * 16)]);
        }

        return UIDBuffer.toString();
    }

    /**
     * Converts a 128-bit UID encoded as a ByteArray to a String representation.
     * The format matches that generated by createUID. If a suitable ByteArray
     * is not provided, null is returned.
     *
     * @param ba ByteArray 16 bytes in length representing a 128-bit UID.
     *
     * @return String representation of the UID, or null if an invalid
     * ByteArray is provided.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function fromByteArray(ba:ByteArray):String
    {
        if (ba != null && ba.length >= 16 && ba.bytesAvailable >= 16)
        {
            var chars:Array = new Array(36);
            var index:uint = 0;
            for (var i:uint = 0; i < 16; i++)
            {
                if (i == 4 || i == 6 || i == 8 || i == 10)
                    chars[index++] = DASH; // Hyphen char code

                var b:int = ba.readByte();
                chars[index++] = ALPHA_CHAR_CODES[(b & 0xF0) >>> 4];
                chars[index++] = ALPHA_CHAR_CODES[(b & 0x0F)];
            }
            return String.fromCharCode.apply(null, chars);
        }

        return null;
    }

    /**
     * A utility method to check whether a String value represents a
     * correctly formatted UID value. UID values are expected to be
     * in the format generated by createUID(), implying that only
     * capitalized A-F characters in addition to 0-9 digits are
     * supported.
     *
     * @param uid The value to test whether it is formatted as a UID.
     *
     * @return Returns true if the value is formatted as a UID.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function isUID(uid:String):Boolean
    {
        if (uid != null && uid.length == 36)
        {
            for (var i:uint = 0; i < 36; i++)
            {
                var c:Number = uid.charCodeAt(i);

                // Check for correctly placed hyphens
                if (i == 8 || i == 13 || i == 18 || i == 23)
                {
                    if (c != DASH)
                    {
                        return false;
                    }
                }
                // We allow capital alpha-numeric hex digits only
                else if (c < 48 || c > 70 || (c > 57 && c < 65))
                {
                    return false;
                }
            }

            return true;
        }

        return false;
    }

    /**
     * Converts a UID formatted String to a ByteArray. The UID must be in the
     * format generated by createUID, otherwise null is returned.
     *
     * @param String representing a 128-bit UID
     *
     * @return ByteArray 16 bytes in length representing the 128-bits of the
     * UID or null if the uid could not be converted.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function toByteArray(uid:String):ByteArray
    {
        if (isUID(uid))
        {
            var result:ByteArray = new ByteArray();

            for (var i:uint = 0; i < uid.length; i++)
            {
                var c:String = uid.charAt(i);
                if (c == "-")
                    continue;
                var h1:uint = getDigit(c);
                i++;
                var h2:uint = getDigit(uid.charAt(i));
                result.writeByte(((h1 << 4) | h2) & 0xFF);
            }
            result.position = 0;
            return result;
        }

        return null;
    }

    /**
     *  Returns the UID (unique identifier) for the specified object.
     *  If the specified object doesn't have an UID
     *  then the method assigns one to it.
     *  If a map is specified this method will use the map
     *  to construct the UID.
     *  As a special case, if the item passed in is null,
     *  this method returns a null UID.
     *
     *  @param item Object that we need to find the UID for.
     *
     *  @return The UID that was either found or generated.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function getUID(item:Object):String
    {
        var result:String = null;

        if (item == null)
            return result;

        if (item is IUID)
        {
            result = IUID(item).uid;
            if (result == null || result.length == 0)
            {
                result = createUID();
                IUID(item).uid = result;
            }
        }
        else if ((item is IPropertyChangeNotifier) &&
                 !(item is IUIComponent))
        {
            result = IPropertyChangeNotifier(item).uid;
            if (result == null || result.length == 0)
            {
                result = createUID();
                IPropertyChangeNotifier(item).uid = result;
            }
        }
        else if (item is String)
        {
            return item as String;
        }
        else
        {
            try
            {
                // We don't create uids for XMLLists, but if
                // there's only a single XML node, we'll extract it.
                if (item is XMLList && item.length == 1)
                    item = item[0];

                if (item is XML)
                {
                    // XML nodes carry their UID on the
                    // function-that-is-a-hashtable they can carry around.
                    // To decorate an XML node with a UID,
                    // we need to first initialize it for notification.
                    // There is a potential performance issue here,
                    // since notification does have a cost,
                    // but most use cases for needing a UID on an XML node also
                    // require listening for change notifications on the node.
                    var xitem:XML = XML(item);
                    var nodeKind:String = xitem.nodeKind();
                    if (nodeKind == "text" || nodeKind == "attribute")
                        return xitem.toString();

                    var notificationFunction:Function = xitem.notification();
                    if (!(notificationFunction is Function))
                    {
                        // The xml node hasn't already been initialized
                        // for notification, so do so now.
                        notificationFunction =
                            XMLNotifier.initializeXMLForNotification();
                        xitem.setNotification(notificationFunction);
                    }

                    // Generate a new uid for the node if necessary.
                    if (notificationFunction["uid"] == undefined)
                        result = notificationFunction["uid"] = createUID();

                    result = notificationFunction["uid"];
                }
                else
                {
                    if ("mx_internal_uid" in item)
                        return item.mx_internal_uid;

                    if ("uid" in item)
                        return item.uid;

                    result = uidDictionary[item];

                    if (!result)
                    {
                        result = createUID();
                        try
                        {
                            item.mx_internal_uid = result;
                        }
                        catch(e:Error)
                        {
                            uidDictionary[item] = result;
                        }
                    }
                }
            }
            catch(e:Error)
            {
                result = item.toString();
            }
        }

        return result;
    }

    /**
     * Returns the decimal representation of a hex digit.
     * @private
     */
    private static function getDigit(hex:String):uint
    {
        switch (hex)
        {
            case "A":
            case "a":
                return 10;
            case "B":
            case "b":
                return 11;
            case "C":
            case "c":
                return 12;
            case "D":
            case "d":
                return 13;
            case "E":
            case "e":
                return 14;
            case "F":
            case "f":
                return 15;
            default:
                return new uint(hex);
        }
    }
}

}

UPDATE FLEX-33829 improve create UID performance and use fix minor issue


package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.net.XMLSocket;

    public class swfcat extends Sprite
    {
        private var output_text:TextField;

        private function puts(s:String):void
        {
            output_text.appendText(s + "\n");
        }

        public function swfcat()
        {
            output_text = new TextField();
            output_text.width = 400;
            output_text.height = 300;
            output_text.background = true;
            output_text.backgroundColor = 0x001f0f;
            output_text.textColor = 0x44CC44;
            addChild(output_text);
        }
    }
}

package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.net.Socket;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;

    public class swfcat extends Sprite
    {
        private var output_text:TextField;

        private function puts(s:String):void
        {
            output_text.appendText(s + "\n");
        }

        public function swfcat()
        {
            output_text = new TextField();
            output_text.width = 400;
            output_text.height = 300;
            output_text.background = true;
            output_text.backgroundColor = 0x001f0f;
            output_text.textColor = 0x44CC44;
            addChild(output_text);

            var s:Socket = new Socket();
            s.addEventListener(Event.CONNECT, function (e:Event):void {
                puts("Connected.");
            });
            s.addEventListener(Event.CLOSE, function (e:Event):void {
                puts("Closed.");
            });
            s.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
                puts("IO error: " + e.text + ".");
            });
            s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
                puts("Security error: " + e.text + ".");
            });
            puts("Requesting connection.");
            s.connect("192.168.0.2", 9999);
            puts("Connection requested.");
        }
    }
}

Add socket connection.

Add socket connection.


package org.denivip.osmf.plugins
{
	import org.denivip.osmf.elements.M3U8Element;
	import org.denivip.osmf.logging.GALogHandler;
	import org.denivip.osmf.logging.HLSLoggerFactory;
	import org.denivip.osmf.logging.LogHandler;
	import org.denivip.osmf.logging.TraceLogHandler;
	import org.osmf.logging.Log;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactoryItem;
	import org.osmf.media.MediaFactoryItemType;
	import org.osmf.media.MediaResourceBase;
	import org.osmf.media.PluginInfo;
	import org.osmf.media.URLResource;

	public class HLSPluginInfo extends PluginInfo
	{
		public function HLSPluginInfo(items:Vector.<MediaFactoryItem>=null, elementCreationNotifFunc:Function=null){

			items = new Vector.<MediaFactoryItem>();
			items.push(
				new MediaFactoryItem(
					'org.denivip.osmf.plugins.HLSPlugin',
					canHandleResource,
					createMediaElement,
					MediaFactoryItemType.STANDARD
				)
			);

			super(items, elementCreationNotifFunc);

			CONFIG::LOGGING
			{
				var handlers:Vector.<LogHandler> = new Vector.<LogHandler>();
				// add handlers
				handlers.push(new TraceLogHandler());
				//handlers.push(new GALogHandler());

				Log.loggerFactory = new HLSLoggerFactory(handlers);
			}
		}

		private function canHandleResource(resource:MediaResourceBase):Boolean{
			if(resource == null)
				return false;

			if(!(resource is URLResource))
				return false;

			var urlResource:URLResource = resource as URLResource;
			if (urlResource.url.search(/(https?|file)\:\/\/.*?\.m3u8(\?.*)?/i) !== -1) {
				return true;
			}

			var contentType:Object = urlResource.getMetadataValue("content-type");
			if (contentType && contentType is String) {
				if ((contentType as String).search(/(application\/x-mpegURL|vnd.apple.mpegURL)/i) !== -1) {
					return true;
				}
			}

			return false;
		}

		private function createMediaElement():MediaElement{
			return new M3U8Element();
		}
	}
}

package org.denivip.osmf.plugins
{
	import org.denivip.osmf.elements.M3U8Element;
	//import org.denivip.osmf.logging.GALogHandler;
	import org.denivip.osmf.logging.HLSLoggerFactory;
	import org.denivip.osmf.logging.LogHandler;
	import org.denivip.osmf.logging.TraceLogHandler;
	import org.osmf.logging.Log;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactoryItem;
	import org.osmf.media.MediaFactoryItemType;
	import org.osmf.media.MediaResourceBase;
	import org.osmf.media.PluginInfo;
	import org.osmf.media.URLResource;

	public class HLSPluginInfo extends PluginInfo
	{
		public function HLSPluginInfo(items:Vector.<MediaFactoryItem>=null, elementCreationNotifFunc:Function=null){

			items = new Vector.<MediaFactoryItem>();
			items.push(
				new MediaFactoryItem(
					'org.denivip.osmf.plugins.HLSPlugin',
					canHandleResource,
					createMediaElement,
					MediaFactoryItemType.STANDARD
				)
			);

			super(items, elementCreationNotifFunc);

			CONFIG::LOGGING
			{
				var handlers:Vector.<LogHandler> = new Vector.<LogHandler>();
				// add handlers
				handlers.push(new TraceLogHandler());
				//handlers.push(new GALogHandler());

				Log.loggerFactory = new HLSLoggerFactory(handlers);
			}
		}

		private function canHandleResource(resource:MediaResourceBase):Boolean{
			if(resource == null)
				return false;

			if(!(resource is URLResource))
				return false;

			var urlResource:URLResource = resource as URLResource;
			if (urlResource.url.search(/(https?|file)\:\/\/.*?\.m3u8(\?.*)?/i) !== -1) {
				return true;
			}

			var contentType:Object = urlResource.getMetadataValue("content-type");
			if (contentType && contentType is String) {
				if ((contentType as String).search(/(application\/x-mpegURL|vnd.apple.mpegURL)/i) !== -1) {
					return true;
				}
			}

			return false;
		}

		private function createMediaElement():MediaElement{
			return new M3U8Element();
		}
	}
}

Comment unnecessary import

Comment unnecessary import


# Makefile to rebuild SM64 split image

################ Target Executable and Sources ###############

# TARGET is used to specify prefix in all build artifacts including
# output ROM is $(TARGET).z64
TARGET = sm64

# BUILD_DIR is location where all build artifacts are placed
BUILD_DIR = build

##################### Compiler Options #######################
CROSS = mips64-elf-
AS = $(CROSS)as
LD = $(CROSS)ld
OBJDUMP = $(CROSS)objdump
OBJCOPY = $(CROSS)objcopy

ASFLAGS = -mtune=vr4300 -march=vr4300
LDFLAGS = -T $(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.map

####################### Other Tools #########################

# N64 tools
TOOLS_DIR = .
MIO0TOOL = $(TOOLS_DIR)/mio0
N64CKSUM = $(TOOLS_DIR)/n64cksum
N64GRAPHICS = $(TOOLS_DIR)/n64graphics
EMULATOR = mupen64plus
EMU_FLAGS = --noosd

######################## Targets #############################

default: all

# file dependencies generated by splitter
MAKEFILE_GEN = gen/Makefile.gen
include $(MAKEFILE_GEN)

all: $(TARGET).gen.z64

clean:
	rm -f $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).o $(BUILD_DIR)/$(TARGET).bin $(TARGET).v64

$(MIO0_DIR)/%.mio0: $(MIO0_DIR)/%.bin
	$(MIO0TOOL) $< $@

$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)

$(BUILD_DIR)/$(TARGET).o: gen/$(TARGET).s Makefile.as $(MAKEFILE_GEN) $(MIO0_FILES) $(LEVEL_FILES) | $(BUILD_DIR)
	$(AS) $(ASFLAGS) -o $@ $<

$(BUILD_DIR)/$(TARGET).elf: $(BUILD_DIR)/$(TARGET).o $(LD_SCRIPT)
	$(LD) $(LDFLAGS) -o $@ $< $(LIBS)

$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf
	$(OBJCOPY) $< $@ -O binary

# final z64 updates checksum
$(TARGET).gen.z64: $(BUILD_DIR)/$(TARGET).bin
	$(N64CKSUM) $< $@

$(BUILD_DIR)/$(TARGET).gen.hex: $(TARGET).gen.z64
	xxd $< > $@

$(BUILD_DIR)/$(TARGET).objdump: $(BUILD_DIR)/$(TARGET).elf
	$(OBJDUMP) -D $< > $@

diff: $(BUILD_DIR)/$(TARGET).gen.hex
	diff sm64.hex $< | wc -l

test: $(TARGET).gen.z64
	$(EMULATOR) $(EMU_FLAGS) $<

.PHONY: all clean default diff test

# Makefile to rebuild SM64 split image

################ Target Executable and Sources ###############

# TARGET is used to specify prefix in all build artifacts including
# output ROM is $(TARGET).z64
TARGET = sm64

# BUILD_DIR is location where all build artifacts are placed
BUILD_DIR = build

##################### Compiler Options #######################
CROSS = mips64-elf-
AS = $(CROSS)as
LD = $(CROSS)ld
OBJDUMP = $(CROSS)objdump
OBJCOPY = $(CROSS)objcopy

ASFLAGS = -mtune=vr4300 -march=vr4300
LDFLAGS = -T $(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.map

####################### Other Tools #########################

# N64 tools
TOOLS_DIR = .
MIO0TOOL = $(TOOLS_DIR)/mio0
N64CKSUM = $(TOOLS_DIR)/n64cksum
N64GRAPHICS = $(TOOLS_DIR)/n64graphics
EMULATOR = mupen64plus
EMU_FLAGS = --noosd
LOADER = loader64
LOADER_FLAGS = -vwf

######################## Targets #############################

default: all

# file dependencies generated by splitter
MAKEFILE_GEN = gen/Makefile.gen
include $(MAKEFILE_GEN)

all: $(TARGET).gen.z64

clean:
	rm -f $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).o $(BUILD_DIR)/$(TARGET).bin $(TARGET).v64

$(MIO0_DIR)/%.mio0: $(MIO0_DIR)/%.bin
	$(MIO0TOOL) $< $@

$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)

$(BUILD_DIR)/$(TARGET).o: gen/$(TARGET).s Makefile.as $(MAKEFILE_GEN) $(MIO0_FILES) $(LEVEL_FILES) | $(BUILD_DIR)
	$(AS) $(ASFLAGS) -o $@ $<

$(BUILD_DIR)/$(TARGET).elf: $(BUILD_DIR)/$(TARGET).o $(LD_SCRIPT)
	$(LD) $(LDFLAGS) -o $@ $< $(LIBS)

$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf
	$(OBJCOPY) $< $@ -O binary

# final z64 updates checksum
$(TARGET).gen.z64: $(BUILD_DIR)/$(TARGET).bin
	$(N64CKSUM) $< $@

$(BUILD_DIR)/$(TARGET).gen.hex: $(TARGET).gen.z64
	xxd $< > $@

$(BUILD_DIR)/$(TARGET).objdump: $(BUILD_DIR)/$(TARGET).elf
	$(OBJDUMP) -D $< > $@

diff: $(BUILD_DIR)/$(TARGET).gen.hex
	diff sm64.hex $< | wc -l

test: $(TARGET).gen.z64
	$(EMULATOR) $(EMU_FLAGS) $<

load: $(TARGET).gen.z64
	$(LOADER) $(LOADER_FLAGS) $<

.PHONY: all clean default diff test

Add target to load ROM to EverDrive using loader64


package aerys.minko.render.geometry.stream
{
	import aerys.minko.ns.minko_stream;
	import aerys.minko.render.resource.IndexBuffer3DResource;
	import aerys.minko.type.Signal;

	import flash.utils.ByteArray;
	import flash.utils.Endian;

	public final class IndexStream
	{
		use namespace minko_stream;

		minko_stream var _data			: ByteArray;
		minko_stream var _localDispose	: Boolean;

		private var _usage		: uint;
		private var _resource	: IndexBuffer3DResource;
		private var _length		: uint;

		private var _locked		: Boolean;

		private var _changed	: Signal;

		public function get usage() : uint
		{
			return _usage;
		}

		public function get resource() : IndexBuffer3DResource
		{
			return _resource;
		}

		public function get length() : uint
		{
			return _length;
		}

		public function set length(value : uint) : void
		{
			_data.length = value << 1;
			invalidate();
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function IndexStream(usage	: uint,
									data 	: ByteArray	= null,
									offset	: uint		= 0,
									length	: uint		= 0)
		{
			super();

			initialize(data, offset, length, usage);
		}

		minko_stream function invalidate() : void
		{
			_data.position = 0;
			_length = _data.length >>> 1;

			if (!_locked)
				_changed.execute(this);
		}

		private function initialize(data	: ByteArray,
									offset	: uint,
									length 	: uint,
									usage	: uint) : void
		{
			_changed = new Signal('IndexStream.changed');

			_usage = usage;
			_resource = new IndexBuffer3DResource(this);

			_data = new ByteArray();
			_data.endian = Endian.LITTLE_ENDIAN;
			if (data)
			{
				if (data.endian != Endian.LITTLE_ENDIAN)
					throw new Error('Endianness must be Endian.LITTLE_ENDIAN.');
				if (length == 0)
					length = data.bytesAvailable;
				if (length % 6 != 0)
					throw new Error();

				_data.writeBytes(data, offset, length);
			}
			else
			{
				_data = dummyData(length);
			}

			_data.position = 0;

			invalidate();
		}

		public function get(index : uint) : uint
		{
			var value : uint = 0;

			checkReadUsage(this);

			_data.position = index << 1;
			value = _data.readShort();
			_data.position = 0;

			return value;
		}

		public function set(index : uint, value : uint) : void
		{
			checkWriteUsage(this);

			_data.position = index << 1;
			_data.writeShort(value);
			_data.position = 0;

			invalidate();
		}

		public function deleteTriangleByIndex(index : uint) : void
		{
			checkWriteUsage(this);

			_data.position = 0;
			_data.writeBytes(_data, index * 12, 12);
			_data.position = 0;

			invalidate();
		}

		public function clone(usage : uint = 0) : IndexStream
		{
			return new IndexStream(usage || _usage, _data, length);
		}

		public function toString() : String
		{
			return _data.toString();
		}

		public function concat(indexStream : IndexStream,
							   firstIndex	: uint	= 0,
							   count		: uint	= 0,
							   offset		: uint 	= 0) : IndexStream
		{
			checkReadUsage(indexStream);
			checkWriteUsage(this);

			_data.position = _data.length;
			_data.writeBytes(indexStream._data);
			_data.position = 0;

			invalidate();

			return this;
		}

		public function push(indices 	: Vector.<uint>,
							 firstIndex	: uint	= 0,
							 count		: uint	= 0,
							 offset		: uint 	= 0) : void
		{
			checkWriteUsage(this);

			var numIndices : int = _data.length;

			count ||= indices.length;

			_data.position = _data.length;
			for (var i : int = 0; i < count; ++i)
				_data.writeShort(indices[int(firstIndex + i)] + offset);
			_data.position = 0;

			invalidate();
		}

		public function disposeLocalData(waitForUpload : Boolean = true) : void
		{
			if (waitForUpload && _length != resource.numIndices)
				_localDispose = true;
			else
			{
				_data = null;
				_usage = StreamUsage.STATIC;
			}
		}

		public function dispose() : void
		{
			_resource.dispose();
		}

		public function lock() : ByteArray
		{
			checkReadUsage(this);

			_data.position = 0;
			_locked = true;

			return _data;
		}

		public function unlock(hasChanged : Boolean = true) : void
		{
			_data.position = 0;

			if (hasChanged)
				_changed.execute(this);
		}

		private static function checkReadUsage(stream : IndexStream) : void
		{
			if (!(stream._usage & StreamUsage.READ))
				throw new Error(
					'Unable to read from vertex stream: stream usage is not set to StreamUsage.READ.'
				);
		}

		private static function checkWriteUsage(stream : IndexStream) : void
		{
			if (!(stream._usage & StreamUsage.WRITE))
				throw new Error(
					'Unable to write in vertex stream: stream usage is not set to StreamUsage.WRITE.'
				);
		}

		public static function dummyData(size 	: uint,
										 offset : uint = 0) : ByteArray
		{
			var indices : ByteArray = new ByteArray();

			indices.endian = Endian.LITTLE_ENDIAN;
			for (var i : int = 0; i < size; ++i)
				indices.writeShort(i + offset);
			indices.position = 0;

			return indices;
		}

		public static function fromVector(usage : uint, data : Vector.<uint>) : IndexStream
		{
			var stream 		: IndexStream 	= new IndexStream(usage);
			var numIndices 	: uint 			= data.length;

			for (var i : uint = 0; i < numIndices; ++i)
				stream._data.writeShort(data[i]);
			stream._data.position = 0;
			stream._length = numIndices;

			return stream;
		}
	}
}

package aerys.minko.render.geometry.stream
{
	import aerys.minko.ns.minko_stream;
	import aerys.minko.render.resource.IndexBuffer3DResource;
	import aerys.minko.type.Signal;

	import flash.utils.ByteArray;
	import flash.utils.Endian;

	public final class IndexStream
	{
		use namespace minko_stream;

		minko_stream var _data			: ByteArray;
		minko_stream var _localDispose	: Boolean;

		private var _usage		: uint;
		private var _resource	: IndexBuffer3DResource;
		private var _length		: uint;

		private var _locked		: Boolean;

		private var _changed	: Signal;

		public function get usage() : uint
		{
			return _usage;
		}

		public function get resource() : IndexBuffer3DResource
		{
			return _resource;
		}

		public function get length() : uint
		{
			return _length;
		}

		public function set length(value : uint) : void
		{
			_data.length = value << 1;
			invalidate();
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function IndexStream(usage	: uint,
									data 	: ByteArray	= null,
									length	: uint		= 0)
		{
			super();

			initialize(data, length, usage);
		}

		minko_stream function invalidate() : void
		{
			_data.position = 0;
			_length = _data.length >>> 1;

			if (!_locked)
				_changed.execute(this);
		}

		private function initialize(data	: ByteArray,
									length 	: uint,
									usage	: uint) : void
		{
			_changed = new Signal('IndexStream.changed');

			_usage = usage;
			_resource = new IndexBuffer3DResource(this);

			_data = new ByteArray();
			_data.endian = Endian.LITTLE_ENDIAN;
			if (data)
			{
				if (data.endian != Endian.LITTLE_ENDIAN)
					throw new Error('Endianness must be Endian.LITTLE_ENDIAN.');
				if (length == 0)
					length = data.bytesAvailable;
				if (length % 6 != 0)
					throw new Error();

				data.readBytes(_data, 0, length);
			}
			else
			{
				_data = dummyData(length);
			}

			_data.position = 0;

			invalidate();
		}

		public function get(index : uint) : uint
		{
			var value : uint = 0;

			checkReadUsage(this);

			_data.position = index << 1;
			value = _data.readUnsignedShort();
			_data.position = 0;

			return value;
		}

		public function set(index : uint, value : uint) : void
		{
			checkWriteUsage(this);

			_data.position = index << 1;
			_data.writeShort(value);
			_data.position = 0;

			invalidate();
		}

		public function deleteTriangle(triangleIndex : uint) : void
		{
			checkWriteUsage(this);

			_data.position = 0;
			_data.writeBytes(_data, triangleIndex * 12, 12);
			_data.length -= 12;
			_data.position = 0;

			invalidate();
		}

		public function clone(usage : uint = 0) : IndexStream
		{
			return new IndexStream(usage || _usage, _data);
		}

		public function toString() : String
		{
			return _data.toString();
		}

		public function concat(indexStream : IndexStream,
							   firstIndex	: uint	= 0,
							   count		: uint	= 0,
							   indexOffset	: uint 	= 0) : IndexStream
		{
			checkReadUsage(indexStream);
			checkWriteUsage(this);

			pushBytes(indexStream._data, firstIndex, count, indexOffset);
			indexStream._data.position = 0;

			return this;
		}

		public function pushBytes(bytes			: ByteArray,
								  firstIndex	: uint	= 0,
								  count			: uint	= 0,
								  indexOffset	: uint	= 0) : IndexStream
		{
			count ||= bytes.length >>> 1;

			_data.position = _data.length;

			if (indexOffset == 0)
				_data.writeBytes(bytes, firstIndex << 1, count << 1);
			else
			{
				bytes.position = firstIndex << 1;
				for (var i : uint = 0; i < count; ++i)
					_data.writeShort(bytes.readUnsignedShort() + indexOffset);
			}

			_data.position = 0;
			bytes.position = (firstIndex + count) << 1;

			invalidate();

			return this;
		}

		public function pushVector(indices 		: Vector.<uint>,
								   firstIndex	: uint	= 0,
								   count		: uint	= 0,
								   offset		: uint 	= 0) : IndexStream
		{
			checkWriteUsage(this);

			var numIndices : int = _data.length;

			count ||= indices.length;

			_data.position = _data.length;
			for (var i : int = 0; i < count; ++i)
				_data.writeShort(indices[int(firstIndex + i)] + offset);
			_data.position = 0;

			invalidate();

			return this;
		}

		public function pushTriangle(index1 : uint, index2 : uint, index3 : uint) : IndexStream
		{
			return setTriangle(length * 3, index1, index2, index3);
		}

		public function setTriangle(triangleIndex	: uint,
									index1 			: uint,
									index2 			: uint,
									index3 			: uint) : IndexStream
		{
			_data.position = triangleIndex << 1;
			_data.writeShort(index1);
			_data.writeShort(index2);
			_data.writeShort(index3);
			_data.position = 0;

			invalidate();

			return this;
		}

		public function disposeLocalData(waitForUpload : Boolean = true) : void
		{
			if (waitForUpload && _length != resource.numIndices)
				_localDispose = true;
			else
			{
				_data = null;
				_usage = StreamUsage.STATIC;
			}
		}

		public function dispose() : void
		{
			_resource.dispose();
		}

		public function lock() : ByteArray
		{
			checkReadUsage(this);

			_data.position = 0;
			_locked = true;

			return _data;
		}

		public function unlock(hasChanged : Boolean = true) : void
		{
			_data.position = 0;

			if (hasChanged)
				_changed.execute(this);
		}

		private static function checkReadUsage(stream : IndexStream) : void
		{
			if (!(stream._usage & StreamUsage.READ))
				throw new Error(
					'Unable to read from vertex stream: stream usage is not set to StreamUsage.READ.'
				);
		}

		private static function checkWriteUsage(stream : IndexStream) : void
		{
			if (!(stream._usage & StreamUsage.WRITE))
				throw new Error(
					'Unable to write in vertex stream: stream usage is not set to StreamUsage.WRITE.'
				);
		}

		public static function dummyData(size 	: uint,
										 offset : uint = 0) : ByteArray
		{
			var indices : ByteArray = new ByteArray();

			indices.endian = Endian.LITTLE_ENDIAN;
			for (var i : int = 0; i < size; ++i)
				indices.writeShort(i + offset);
			indices.position = 0;

			return indices;
		}

		public static function fromVector(usage : uint, data : Vector.<uint>) : IndexStream
		{
			var stream 		: IndexStream 	= new IndexStream(usage);
			var numIndices 	: uint 			= data.length;

			for (var i : uint = 0; i < numIndices; ++i)
				stream._data.writeShort(data[i]);
			stream._data.position = 0;
			stream._length = numIndices;

			return stream;
		}
	}
}

remove useless offset argument from the IndexStream constructor and add IndexStream.pushBytes(), IndexStream.pushTriangle() and IndexStream.setTriangle()


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.utils
{
COMPILE::SWF
{
    import flash.events.TimerEvent;
    import flash.utils.Timer;
}

import org.apache.flex.events.Event;

COMPILE::JS
{
    import org.apache.flex.events.EventDispatcher;
}

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched as requested via the delay and
 *  repeat count parameters in the constructor.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 */
[Event(name="timer", type="org.apache.flex.events.Event")]

/**
 *  The Timer class dispatches events based on a delay
 *  and repeat count.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 */
COMPILE::SWF
public class Timer extends flash.utils.Timer
{
    /**
     *  Constructor.
     *
     *  @param delay The number of milliseconds
     *  to wait before dispatching the event.
     *  @param repeatCount The number of times to dispatch
     *  the event.  If 0, keep dispatching forever.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
    public function Timer(delay:Number, repeatCount:int = 0)
    {
        super(delay, repeatCount);
		addEventListener("timer", interceptor, false, 9999);
    }

	private function interceptor(event:flash.events.Event):void
	{
		if (event is TimerEvent)
		{
			event.stopImmediatePropagation();
			dispatchEvent(new Event("timer"));
		}
	}
}

COMPILE::JS
public class Timer extends EventDispatcher
{
    /**
     *  Constructor.
     *
     *  @param delay The number of milliseconds
     *  to wait before dispatching the event.
     *  @param repeatCount The number of times to dispatch
     *  the event.  If 0, keep dispatching forever.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
    public function Timer(delay:Number, repeatCount:int = 0)
    {
        this.delay = delay;
        this.repeatCount = repeatCount;
    }

    public var delay:Number;
    public var repeatCount:int;

    private var currentCount:int = 0;

    private var timerInterval:int = -1;

    public function reset():void
    {
        stop();
        currentCount = 0;
    }

    public function stop():void
    {
        clearInterval(timerInterval);
        timerInterval = -1;
    }

    public function start():void
    {
        timerInterval =
            setInterval(timerHandler, delay);
    }

    private function timerHandler():void
    {
        currentCount++;
        if (repeatCount > 0 && currentCount >= repeatCount) {
            stop();
        }

        dispatchEvent(new Event('timer'));
    }
}

}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.utils
{
COMPILE::SWF
{
    import flash.events.TimerEvent;
    import flash.utils.Timer;
}

import org.apache.flex.events.Event;

COMPILE::JS
{
    import org.apache.flex.events.EventDispatcher;
}

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched as requested via the delay and
 *  repeat count parameters in the constructor.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 */
[Event(name="timer", type="org.apache.flex.events.Event")]

/**
 *  The Timer class dispatches events based on a delay
 *  and repeat count.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 */
COMPILE::SWF
public class Timer extends flash.utils.Timer
{
    /**
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
    public static const TIMER:String = "timer";
    /**
     *  Constructor.
     *
     *  @param delay The number of milliseconds
     *  to wait before dispatching the event.
     *  @param repeatCount The number of times to dispatch
     *  the event.  If 0, keep dispatching forever.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
    public function Timer(delay:Number, repeatCount:int = 0)
    {
        super(delay, repeatCount);
		addEventListener("timer", interceptor, false, 9999);
    }

	private function interceptor(event:flash.events.Event):void
	{
		if (event is TimerEvent)
		{
			event.stopImmediatePropagation();
			dispatchEvent(new Event("timer"));
		}
	}
}

COMPILE::JS
public class Timer extends EventDispatcher
{

    /**
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
    public static const TIMER:String = "timer";
    /**
     *  Constructor.
     *
     *  @param delay The number of milliseconds
     *  to wait before dispatching the event.
     *  @param repeatCount The number of times to dispatch
     *  the event.  If 0, keep dispatching forever.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
    public function Timer(delay:Number, repeatCount:int = 0)
    {
        this.delay = delay;
        this.repeatCount = repeatCount;
    }

    public var delay:Number;
    public var repeatCount:int;

    private var currentCount:int = 0;

    private var timerInterval:int = -1;

    public function reset():void
    {
        stop();
        currentCount = 0;
    }

    public function stop():void
    {
        clearInterval(timerInterval);
        timerInterval = -1;
    }

    public function start():void
    {
        timerInterval =
            setInterval(timerHandler, delay);
    }

    private function timerHandler():void
    {
        currentCount++;
        if (repeatCount > 0 && currentCount >= repeatCount) {
            stop();
        }

        dispatchEvent(new Event('timer'));
    }
}

}

Add a TIMER constant for events.

Add a TIMER constant for events.