package com.kaltura.kdpfl.model.vo
{
	import com.kaltura.kdpfl.plugin.IMidrollSequencePlugin;

	[Bindable]
	/**
	 * Class SequenceVO holds parameters related to the KDP sequence mechanism.
	 * @author Hila
	 *
	 */
	public class SequenceVO
	{
		/**
		 *Flag signifying whether we are currently playing in a sequence (pre or post)
		 */
		public var isInSequence : Boolean;
		/**
		 * Array containing refereces to the PluginCode-s of the sequence plugins in the post sequence
		 */
		public var postSequenceArr : Array;
		/**
		 * Array containing references to the PluginCode files of the sequence plugins in the pre-sequence
		 */
		public var preSequenceArr : Array;

		/**
		 * Index of the current position in the pre sequence array, initially set to -1.
		 */
		public var preCurrentIndex : int = -1;
		/**
		 *Index of the current position in the post sequence array, initially set to -1.
		 */
		public var postCurrentIndex : int = -1;

		/**
		 * The original MediaVO for the main entry . Saved once in the bginning of the pre-sequence (or post-sequence)
		 */
		public var mainMediaVO : MediaVO;
		/**
		 *The time remaining to the ad playing in the MediaPlayer
		 */
		public var timeRemaining : Number;
		/**
		 *Property signifying whether the sequencePlugin lined up to play can be skipped;
		 */
		public var isAdSkip : Boolean = false;
		/**
		 * Property signifying whether the sequencePlugin lined up to play has loaded.
		 */
		public var isAdLoaded : Boolean = false;
		/**
		 * Flag indicating whether the post sequence is complete
		 */
		public var postSequenceComplete : Boolean = false;
		/**
		 * Flag indicating whether the pre-sequence is complete
		 */
		public var preSequenceComplete : Boolean = false;
		/**
		 * Number of pre-sequence ads.
		 */
		public var preSequenceCount : Number = 0;
		/**
		 * Number of post-sequence ads.
		 */
		public var postSequenceCount : Number = 0;

		//New Midroll-related properties - 12.22.2010

		/**
		 * Array containing references to the PluginCode files of the sequence plugins in the midroll sequence
		 */
		public var midrollArr : Array;
		/**
		 * Index of the current position in the midroll sequence array, initially set to -1.
		 */
		public var midCurrentIndex : int = -1;

		/**
		 * Property containing the current midroll plugin playing in the player. The running assumptions are:
		 * a. There is only 1 midroll plugin playing at a given time
		 * b. The only way that this midroll is of interest to us is if it's playing in the KDP MediaPlayer.
		 */
		public var activeMidrollPlugin : IMidrollSequencePlugin;
		/**
		 * New parameter allowing an ISequencePluin to set the metadata values of the ad that is currently playing.
		 * Added for analytics use.
		 */
		public var activePluginMetadata : AdMetadataVO;
		/**
		 * In case we want to ignore prerolls, for example, when starting the media from the middle with "mediaProxy.mediaPlayFrom"
		 */
		public var skipPrerolls:Boolean = false;
	}
}

package com.kaltura.kdpfl.model.vo
{
	import com.kaltura.kdpfl.plugin.IMidrollSequencePlugin;

	[Bindable]
	/**
	 * Class SequenceVO holds parameters related to the KDP sequence mechanism.
	 * @author Hila
	 *
	 */
	public class SequenceVO
	{
		/**
		 *Flag signifying whether we are currently playing in a sequence (pre or post)
		 */
		public var isInSequence : Boolean;
		/**
		 * Array containing refereces to the PluginCode-s of the sequence plugins in the post sequence
		 */
		public var postSequenceArr : Array;
		/**
		 * Array containing references to the PluginCode files of the sequence plugins in the pre-sequence
		 */
		public var preSequenceArr : Array;

		/**
		 * Index of the current position in the pre sequence array, initially set to -1.
		 */
		public var preCurrentIndex : int = -1;
		/**
		 *Index of the current position in the post sequence array, initially set to -1.
		 */
		public var postCurrentIndex : int = -1;

		/**
		 * The original MediaVO for the main entry . Saved once in the bginning of the pre-sequence (or post-sequence)
		 */
		public var mainMediaVO : MediaVO;
		/**
		 *The time remaining to the ad playing in the MediaPlayer
		 */
		public var timeRemaining : Number;
		/**
		 *Property signifying whether the sequencePlugin lined up to play can be skipped;
		 */
		public var isAdSkip : Boolean = false;
		/**
		 * Property signifying whether the sequencePlugin lined up to play has loaded.
		 */
		public var isAdLoaded : Boolean = false;
		/**
		 * Flag indicating whether the post sequence is complete
		 */
		public var postSequenceComplete : Boolean = false;
		/**
		 * Flag indicating whether the pre-sequence is complete
		 */
		public var preSequenceComplete : Boolean = false;
		/**
		 * Number of pre-sequence ads.
		 */
		public var preSequenceCount : Number = 0;
		/**
		 * Number of post-sequence ads.
		 */
		public var postSequenceCount : Number = 0;

		//New Midroll-related properties - 12.22.2010

		/**
		 * Array containing references to the PluginCode files of the sequence plugins in the midroll sequence
		 */
		public var midrollArr : Array;
		/**
		 * Index of the current position in the midroll sequence array, initially set to -1.
		 */
		public var midCurrentIndex : int = -1;

		/**
		 * Property containing the current midroll plugin playing in the player. The running assumptions are:
		 * a. There is only 1 midroll plugin playing at a given time
		 * b. The only way that this midroll is of interest to us is if it's playing in the KDP MediaPlayer.
		 */
		public var activeMidrollPlugin : IMidrollSequencePlugin;
		/**
		 * New parameter allowing an ISequencePluin to set the metadata values of the ad that is currently playing.
		 * Added for analytics use.
		 */
		public var activePluginMetadata : AdMetadataVO;
		/**
		 * In case we want to ignore prerolls, for example, when starting the media from the middle with "mediaProxy.mediaPlayFrom"
		 */
		public var skipPrerolls:Boolean = false;
		/**
		 * hodls the time remaining until skip ad will be available
		 */
		public var skipOffsetRemaining:int;
	}
}

add "skipOffsetRemaining" parameter to sequenceVo


package aerys.minko.render.material.phong
{
	import aerys.minko.render.DataBindingsProxy;
	import aerys.minko.render.Effect;
	import aerys.minko.render.RenderTarget;
	import aerys.minko.render.resource.texture.CubeTextureResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.scene.data.LightDataProvider;
	import aerys.minko.scene.node.light.AmbientLight;
	import aerys.minko.scene.node.light.DirectionalLight;
	import aerys.minko.scene.node.light.PointLight;
	import aerys.minko.type.enum.ShadowMappingQuality;
	import aerys.minko.type.enum.ShadowMappingType;

	public class PhongEffect extends Effect
	{
        private var _singlePassShader   : Shader;
        private var _baseShader         : Shader;

		public function PhongEffect(singlePassShader    : Shader    = null,
                                    baseShader          : Shader    = null)
		{
            super();

            _singlePassShader = singlePassShader || new PhongSinglePassShader(null, 0);
            _baseShader = baseShader || new PhongBaseShader(null, .5);
		}

        override protected function initializePasses(sceneBindings	: DataBindingsProxy,
                                                     meshBindings	: DataBindingsProxy) : Vector.<Shader>
        {
            var passes : Vector.<Shader>    = super.initializePasses(sceneBindings, meshBindings);

            for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
            {
                if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
                {
                    var lightType			: uint	= getLightProperty(sceneBindings, lightId, 'type');
                    var shadowMappingType 	: uint	= getLightProperty(
                        sceneBindings, lightId, 'shadowCastingType'
                    );

                    switch (shadowMappingType)
                    {
                        case ShadowMappingType.PCF:
                            if (lightType == PointLight.LIGHT_TYPE)
                                pushCubeShadowMappingPass(sceneBindings, lightId, passes);
                            else
                                pushPCFShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.DUAL_PARABOLOID:
                            pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.VARIANCE:
                            pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.EXPONENTIAL:
                            pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                    }
                }
            }

            passes.push(_singlePassShader);

            return passes;
        }

        override protected function initializeFallbackPasses(sceneBindings  : DataBindingsProxy,
                                                             meshBindings   : DataBindingsProxy) : Vector.<Shader>
        {
            var passes              : Vector.<Shader>   = super.initializeFallbackPasses(sceneBindings, meshBindings);
            var discardDirectional  : Boolean           = true;

			for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
			{
                var lightType   : uint	= getLightProperty(sceneBindings, lightId, 'type');

                if (lightType != AmbientLight.LIGHT_TYPE
                    && getLightProperty(sceneBindings, lightId, 'enabled'))
                {
                    if (lightType == DirectionalLight.LIGHT_TYPE && discardDirectional)
                        discardDirectional = false;
                    else
                        passes.push(new PhongAdditionalShader(null, 0, lightId));
                }

				if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
				{
					var shadowMappingType 	: uint	= getLightProperty(
						sceneBindings, lightId, 'shadowCastingType'
					);

					switch (shadowMappingType)
					{
						case ShadowMappingType.PCF:
							if (lightType == PointLight.LIGHT_TYPE)
								pushCubeShadowMappingPass(sceneBindings, lightId, passes);
							else
								pushPCFShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.DUAL_PARABOLOID:
							pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.VARIANCE:
							pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.EXPONENTIAL:
							pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
							break ;
					}
				}
			}

            passes.push(_baseShader);

            return passes;
		}

		private function pushPCFShadowMappingPass(sceneBindings	: DataBindingsProxy,
													 lightId 		: uint,
													 passes 		: Vector.<Shader>) : void
		{
			var textureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var renderTarget	: RenderTarget		= new RenderTarget(
				textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
			);

			passes.push(new PCFShadowMapShader(lightId, lightId + 1, renderTarget));
		}

		private function pushDualParaboloidShadowMappingPass(sceneBindings	: DataBindingsProxy,
															 lightId 		: uint,
															 passes 		: Vector.<Shader>) : void
		{
			var frontTextureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapFront'
			);
			var backTextureResource	 : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapBack'
			);
			var size				 : uint				= frontTextureResource.width;
			var frontRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, frontTextureResource, 0, 0xffffffff
			);
			var backRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, backTextureResource, 0, 0xffffffff
			);

			passes.push(
				new ParaboloidShadowMapShader(lightId, true, lightId + 0.5, frontRenderTarget),
				new ParaboloidShadowMapShader(lightId, false, lightId + 1, backRenderTarget)
			);
		}

		private function pushCubeShadowMappingPass(sceneBindings	: DataBindingsProxy,
												   lightId 			: uint,
												   passes 			: Vector.<Shader>) : void
		{
			var cubeTexture	: CubeTextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var textureSize	: uint					= cubeTexture.size;

			for (var i : uint = 0; i < 6; ++i)
				passes.push(new PCFShadowMapShader(
					lightId,
					lightId + .1 * i,
					new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff),
					i
				));
		}

		private function pushVarianceShadowMappingPass(sceneBindings	: DataBindingsProxy,
													   lightId 			: uint,
													   passes 			: Vector.<Shader>) : void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget		= new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new VarianceShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new VarianceShadowMapShader(
                        lightId,
                        i,
                        lightId + .1 * i,
                        new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function pushExponentialShadowMappingPass(sceneBindings	: DataBindingsProxy,
														  lightId 		: uint,
														  passes 		: Vector.<Shader>):void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget = new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new ExponentialShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new ExponentialShadowMapShader(
						lightId,
						i,
						lightId + .1 * i,
						new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function hasShadowBlurPass(sceneBindings	: DataBindingsProxy,
							    		   lightId 			: uint) : Boolean
		{
			var quality	: uint	= getLightProperty(sceneBindings, lightId, 'shadowQuality');

			return quality > ShadowMappingQuality.HARD;
		}

		private function lightPropertyExists(sceneBindings 	: DataBindingsProxy,
											 lightId 		: uint,
											 propertyName 	: String) : Boolean
		{
			return sceneBindings.propertyExists(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}

		private function getLightProperty(sceneBindings : DataBindingsProxy,
										  lightId 		: uint,
										  propertyName 	: String) : *
		{
			return sceneBindings.getProperty(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}
	}
}

package aerys.minko.render.material.phong
{
	import aerys.minko.render.DataBindingsProxy;
	import aerys.minko.render.Effect;
	import aerys.minko.render.RenderTarget;
	import aerys.minko.render.resource.texture.CubeTextureResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.scene.data.LightDataProvider;
	import aerys.minko.scene.node.light.AmbientLight;
	import aerys.minko.scene.node.light.DirectionalLight;
	import aerys.minko.scene.node.light.PointLight;
	import aerys.minko.type.enum.ShadowMappingQuality;
	import aerys.minko.type.enum.ShadowMappingType;

    /**
     *
The PhongEffect using the Phong lighting model to render the geometry according to
     * the lighting setup of the scene. It supports an infinite number of lights/projected
     * shadows and will automatically switch between singlepass and multipass rendering
     * in order to give the best performances whenever possible.

     *
     *
Because of the Stage3D restrictions regarding the number of shader operations or
     * the number of available registers, the number of lights might be to big to allow them
     * to be rendered in a single pass. In this situation, the PhongEffect will automatically
     * fallback and use multipass rendering.

     *
     *
Multipass rendering is done as follow:

     *

     *
The "base" pass renders objects with one per-pixel directional lights with shadows,
     * the lightmap and the ambient/emissive lighting.

     *
Each "additional" pass (one per light) will render a single light with shadows and
     * blend it using additive blending.

     *

     *
     * The singlepass rendering will mimic this behavior in order to get preserve consistency.
     *
     * @author Jean-Marc Le Roux
     *
     */
	public class PhongEffect extends Effect
	{
        private var _singlePassShader   : Shader;
        private var _baseShader         : Shader;

		public function PhongEffect(singlePassShader    : Shader    = null,
                                    baseShader          : Shader    = null)
		{
            super();

            _singlePassShader = singlePassShader || new PhongSinglePassShader(null, 0);
            _baseShader = baseShader || new PhongBaseShader(null, .5);
		}

        override protected function initializePasses(sceneBindings	: DataBindingsProxy,
                                                     meshBindings	: DataBindingsProxy) : Vector.<Shader>
        {
            var passes : Vector.<Shader>    = super.initializePasses(sceneBindings, meshBindings);

            for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
            {
                if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
                {
                    var lightType			: uint	= getLightProperty(sceneBindings, lightId, 'type');
                    var shadowMappingType 	: uint	= getLightProperty(
                        sceneBindings, lightId, 'shadowCastingType'
                    );

                    switch (shadowMappingType)
                    {
                        case ShadowMappingType.PCF:
                            if (lightType == PointLight.LIGHT_TYPE)
                                pushCubeShadowMappingPass(sceneBindings, lightId, passes);
                            else
                                pushPCFShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.DUAL_PARABOLOID:
                            pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.VARIANCE:
                            pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.EXPONENTIAL:
                            pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                    }
                }
            }

            passes.push(_singlePassShader);

            return passes;
        }

        override protected function initializeFallbackPasses(sceneBindings  : DataBindingsProxy,
                                                             meshBindings   : DataBindingsProxy) : Vector.<Shader>
        {
            var passes              : Vector.<Shader>   = super.initializeFallbackPasses(sceneBindings, meshBindings);
            var discardDirectional  : Boolean           = true;

			for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
			{
                var lightType   : uint	= getLightProperty(sceneBindings, lightId, 'type');

                if (lightType != AmbientLight.LIGHT_TYPE
                    && getLightProperty(sceneBindings, lightId, 'enabled'))
                {
                    if (lightType == DirectionalLight.LIGHT_TYPE && discardDirectional)
                        discardDirectional = false;
                    else
                        passes.push(new PhongAdditionalShader(null, 0, lightId));
                }

				if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
				{
					var shadowMappingType 	: uint	= getLightProperty(
						sceneBindings, lightId, 'shadowCastingType'
					);

					switch (shadowMappingType)
					{
						case ShadowMappingType.PCF:
							if (lightType == PointLight.LIGHT_TYPE)
								pushCubeShadowMappingPass(sceneBindings, lightId, passes);
							else
								pushPCFShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.DUAL_PARABOLOID:
							pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.VARIANCE:
							pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.EXPONENTIAL:
							pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
							break ;
					}
				}
			}

            passes.push(_baseShader);

            return passes;
		}

		private function pushPCFShadowMappingPass(sceneBindings	: DataBindingsProxy,
													 lightId 		: uint,
													 passes 		: Vector.<Shader>) : void
		{
			var textureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var renderTarget	: RenderTarget		= new RenderTarget(
				textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
			);

			passes.push(new PCFShadowMapShader(lightId, lightId + 1, renderTarget));
		}

		private function pushDualParaboloidShadowMappingPass(sceneBindings	: DataBindingsProxy,
															 lightId 		: uint,
															 passes 		: Vector.<Shader>) : void
		{
			var frontTextureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapFront'
			);
			var backTextureResource	 : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapBack'
			);
			var size				 : uint				= frontTextureResource.width;
			var frontRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, frontTextureResource, 0, 0xffffffff
			);
			var backRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, backTextureResource, 0, 0xffffffff
			);

			passes.push(
				new ParaboloidShadowMapShader(lightId, true, lightId + 0.5, frontRenderTarget),
				new ParaboloidShadowMapShader(lightId, false, lightId + 1, backRenderTarget)
			);
		}

		private function pushCubeShadowMappingPass(sceneBindings	: DataBindingsProxy,
												   lightId 			: uint,
												   passes 			: Vector.<Shader>) : void
		{
			var cubeTexture	: CubeTextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var textureSize	: uint					= cubeTexture.size;

			for (var i : uint = 0; i < 6; ++i)
				passes.push(new PCFShadowMapShader(
					lightId,
					lightId + .1 * i,
					new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff),
					i
				));
		}

		private function pushVarianceShadowMappingPass(sceneBindings	: DataBindingsProxy,
													   lightId 			: uint,
													   passes 			: Vector.<Shader>) : void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget		= new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new VarianceShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new VarianceShadowMapShader(
                        lightId,
                        i,
                        lightId + .1 * i,
                        new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function pushExponentialShadowMappingPass(sceneBindings	: DataBindingsProxy,
														  lightId 		: uint,
														  passes 		: Vector.<Shader>):void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget = new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new ExponentialShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new ExponentialShadowMapShader(
						lightId,
						i,
						lightId + .1 * i,
						new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function hasShadowBlurPass(sceneBindings	: DataBindingsProxy,
							    		   lightId 			: uint) : Boolean
		{
			var quality	: uint	= getLightProperty(sceneBindings, lightId, 'shadowQuality');

			return quality > ShadowMappingQuality.HARD;
		}

		private function lightPropertyExists(sceneBindings 	: DataBindingsProxy,
											 lightId 		: uint,
											 propertyName 	: String) : Boolean
		{
			return sceneBindings.propertyExists(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}

		private function getLightProperty(sceneBindings : DataBindingsProxy,
										  lightId 		: uint,
										  propertyName 	: String) : *
		{
			return sceneBindings.getProperty(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}
	}
}

add ASDoc to explain the behavior of PhongEffect


///////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011 Esri. All Rights Reserved.
//
// Licensed 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 widgets.Geoprocessing.parameters
{

import com.esri.ags.tasks.supportClasses.LinearUnit;

import widgets.Geoprocessing.supportClasses.UnitMappingUtil;

public class LinearUnitParameter extends BaseParameter
{
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    private function linearUnitString():String
    {
        return _defaultValue.distance + ":" + UnitMappingUtil.toPrettyUnits(_defaultValue.units);
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  defaultValue
    //----------------------------------

    private var _defaultValue:LinearUnit;

    override public function get defaultValue():Object
    {
        return _defaultValue;
    }

    override public function set defaultValue(value:Object):void
    {
        _defaultValue = new LinearUnit(value.distance, value.units);
    }

    //----------------------------------
    //  type
    //----------------------------------

    override public function get type():String
    {
        return GPParameterTypes.LINEAR_UNIT;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    override public function defaultValueFromString(description:String):void
    {
        var linearUnitTokens:Array = description.split(':');
        _defaultValue = new LinearUnit(linearUnitTokens[0], UnitMappingUtil.toEsriUnits((linearUnitTokens[1])));
    }
}

}

///////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011 Esri. All Rights Reserved.
//
// Licensed 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 widgets.Geoprocessing.parameters
{

import com.esri.ags.tasks.supportClasses.LinearUnit;

import widgets.Geoprocessing.supportClasses.UnitMappingUtil;

public class LinearUnitParameter extends BaseParameter
{
    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  defaultValue
    //----------------------------------

    private var _defaultValue:LinearUnit;

    override public function get defaultValue():Object
    {
        return _defaultValue;
    }

    override public function set defaultValue(value:Object):void
    {
        _defaultValue = new LinearUnit(value.distance, value.units);
    }

    //----------------------------------
    //  type
    //----------------------------------

    override public function get type():String
    {
        return GPParameterTypes.LINEAR_UNIT;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    override public function defaultValueFromString(description:String):void
    {
        var linearUnitTokens:Array = description.split(':');
        _defaultValue = new LinearUnit(linearUnitTokens[0], UnitMappingUtil.toEsriUnits((linearUnitTokens[1])));
    }
}

}

Remove unused method.

Remove unused method.


package aerys.minko.type.loader.parser
{
	import aerys.minko.render.effect.Effect;
	import aerys.minko.type.loader.ILoader;
	import aerys.minko.type.loader.SceneLoader;
	import aerys.minko.type.loader.TextureLoader;

	import flash.net.URLRequest;

	/**
	 * ParserOptions objects provide properties and function references
	 * to customize how a LoaderGroup object will load and interpret
	 * content.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class ParserOptions
	{
		private var _loadDependencies			: Boolean	= false;
		private var _dependencyLoaderClosure	: Function	= defaultDependencyLoaderClosure;
		private var _mipmapTextures				: Boolean	= true;
		private var _meshEffect					: Effect	= null;
		private var _vertexStreamUsage			: uint		= 0;
		private var _indexStreamUsage			: uint		= 0;
		private var _parser						: Class		= null;

		public function get parser():Class
		{
			return _parser;
		}

		public function set parser(value:Class):void
		{
			_parser = value;
		}

		public function get indexStreamUsage():uint
		{
			return _indexStreamUsage;
		}

		public function set indexStreamUsage(value:uint):void
		{
			_indexStreamUsage = value;
		}

		public function get vertexStreamUsage():uint
		{
			return _vertexStreamUsage;
		}

		public function set vertexStreamUsage(value:uint):void
		{
			_vertexStreamUsage = value;
		}

		public function get effect():Effect
		{
			return _meshEffect;
		}

		public function set effect(value:Effect):void
		{
			_meshEffect = value;
		}

		public function get mipmapTextures():Boolean
		{
			return _mipmapTextures;
		}

		public function set mipmapTextures(value:Boolean):void
		{
			_mipmapTextures = value;
		}

		public function get dependencyLoaderClosure():Function
		{
			return _dependencyLoaderClosure;
		}

		public function set dependencyLoaderClosure(value:Function):void
		{
			_dependencyLoaderClosure = value;
		}

		public function get loadDependencies():Boolean
		{
			return _loadDependencies;
		}

		public function set loadDependencies(value:Boolean):void
		{
			_loadDependencies = value;
		}

		public function ParserOptions(loadDependencies			: Boolean = false,
									  dependencyLoaderClosure	: Function = null,
									  mipmapTextures			: Boolean = true,
									  meshEffect				: Effect = null,
									  vertexStreamUsage			: uint = 0,
									  indexStreamUsage			: uint = 0,
									  parser					: Class = null)
		{
			_loadDependencies			= loadDependencies;
			_dependencyLoaderClosure	= _dependencyLoaderClosure || _dependencyLoaderClosure;
			_mipmapTextures				= mipmapTextures;
			_meshEffect					= meshEffect;
			_vertexStreamUsage			= vertexStreamUsage;
			_indexStreamUsage			= indexStreamUsage;
			_parser						= parser;
		}

		private function defaultDependencyLoaderClosure(dependencyPath	: String,
														isTexture		: Boolean,
														options			: ParserOptions) : ILoader
		{
			var loader : ILoader;

			if (isTexture)
			{
				loader = new TextureLoader(true);
				loader.load(new URLRequest(dependencyPath));
			}
			else
			{
				loader = new SceneLoader(options);
				loader.load(new URLRequest(dependencyPath));
			}

			return loader;
		}
	}
}

package aerys.minko.type.loader.parser
{
	import aerys.minko.render.effect.Effect;
	import aerys.minko.type.loader.ILoader;
	import aerys.minko.type.loader.SceneLoader;
	import aerys.minko.type.loader.TextureLoader;

	import flash.net.URLRequest;

	/**
	 * ParserOptions objects provide properties and function references
	 * to customize how a LoaderGroup object will load and interpret
	 * content.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class ParserOptions
	{
		private var _loadDependencies			: Boolean	= false;
		private var _dependencyLoaderClosure	: Function	= defaultDependencyLoaderClosure;
		private var _mipmapTextures				: Boolean	= true;
		private var _meshEffect					: Effect	= null;
		private var _vertexStreamUsage			: uint		= 0;
		private var _indexStreamUsage			: uint		= 0;
		private var _parser						: Class		= null;

		public function get parser():Class
		{
			return _parser;
		}

		public function set parser(value:Class):void
		{
			_parser = value;
		}

		public function get indexStreamUsage():uint
		{
			return _indexStreamUsage;
		}

		public function set indexStreamUsage(value:uint):void
		{
			_indexStreamUsage = value;
		}

		public function get vertexStreamUsage():uint
		{
			return _vertexStreamUsage;
		}

		public function set vertexStreamUsage(value:uint):void
		{
			_vertexStreamUsage = value;
		}

		public function get effect():Effect
		{
			return _meshEffect;
		}

		public function set effect(value:Effect):void
		{
			_meshEffect = value;
		}

		public function get mipmapTextures():Boolean
		{
			return _mipmapTextures;
		}

		public function set mipmapTextures(value:Boolean):void
		{
			_mipmapTextures = value;
		}

		public function get dependencyLoaderClosure():Function
		{
			return _dependencyLoaderClosure;
		}

		public function set dependencyLoaderClosure(value:Function):void
		{
			_dependencyLoaderClosure = value;
		}

		public function get loadDependencies():Boolean
		{
			return _loadDependencies;
		}

		public function set loadDependencies(value:Boolean):void
		{
			_loadDependencies = value;
		}

		public function ParserOptions(loadDependencies			: Boolean = false,
									  dependencyLoaderClosure	: Function = null,
									  mipmapTextures			: Boolean = true,
									  meshEffect				: Effect = null,
									  vertexStreamUsage			: uint = 0,
									  indexStreamUsage			: uint = 0,
									  parser					: Class = null)
		{
			_loadDependencies			= loadDependencies;
			_dependencyLoaderClosure	= dependencyLoaderClosure || _dependencyLoaderClosure;
			_mipmapTextures				= mipmapTextures;
			_meshEffect					= meshEffect;
			_vertexStreamUsage			= vertexStreamUsage;
			_indexStreamUsage			= indexStreamUsage;
			_parser						= parser;
		}

		private function defaultDependencyLoaderClosure(dependencyPath	: String,
														isTexture		: Boolean,
														options			: ParserOptions) : ILoader
		{
			var loader : ILoader;

			if (isTexture)
			{
				loader = new TextureLoader(true);
				loader.load(new URLRequest(dependencyPath));
			}
			else
			{
				loader = new SceneLoader(options);
				loader.load(new URLRequest(dependencyPath));
			}

			return loader;
		}
	}
}

Fix a typo in ParserOptions constructor

Fix a typo in ParserOptions constructor


package org.flexunit.events
{
	import flash.events.ErrorEvent;
	import flash.events.Event;

	public class UnknownError extends Error
	{
		public function UnknownError( event:Event )
		{
			var error:Error;
			if ( event.hasOwnProperty( "error" ) ) {
				var errorGeneric:* = event[ "error" ];

				if ( errorGeneric is Error ) {
					error = errorGeneric as Error;
				} else if ( errorGeneric is ErrorEvent ) {
					var errorEvent:ErrorEvent = errorGeneric as ErrorEvent;
					error = new Error( "Top Level Error", errorEvent.errorID );
				}
			}

			super( error.message, error.errorID );
		}
	}
}

package org.flexunit.events
{
	import flash.events.ErrorEvent;
	import flash.events.Event;

	public class UnknownError extends Error
	{
		public function UnknownError( event:Event )
		{
			var error:Error;
			if ( event.hasOwnProperty( "error" ) ) {
				var errorGeneric:* = event[ "error" ];

				if ( errorGeneric is Error ) {
					error = errorGeneric as Error;
				} else if ( errorGeneric is ErrorEvent ) {
					var errorEvent:ErrorEvent = errorGeneric as ErrorEvent;
					error = new Error( "Top Level Error", Object(errorEvent).errorID );
				}
			}

			super( error.message, error.errorID );
		}
	}
}

Fix for build issue around unknown error


/*
 * FLINT PARTICLE SYSTEM
 * .....................
 *
 * Author: Richard Lord & Michael Ivanov
 * Copyright (c) Richard Lord 2008-2011
 * http://flintparticles.org
 *
 *
 * Licence Agreement
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.flintparticles.integration.away3d.v4
{
	import away3d.containers.ObjectContainer3D;
	import away3d.core.base.Object3D;
	import away3d.core.math.Vector3DUtils;

	import org.flintparticles.common.particles.Particle;
	import org.flintparticles.common.renderers.RendererBase;
	import org.flintparticles.common.utils.Maths;
	import org.flintparticles.integration.away3d.v4.utils.Convert;
	import org.flintparticles.threeD.particles.Particle3D;

	import flash.geom.Vector3D;

	/**
	 * Renders the particles in an Away3D4 scene.
	 *
	 *
To use this renderer, the particles' image properties should be
	 * Away3D v4(Molehill API based) objects, renderable in an Away3D scene. This renderer
	 * doesn't update the scene, but copies each particle's properties
	 * to its image object so next time the Away3D scene is rendered the
	 * image objects are drawn according to the state of the particle
	 * system.

	 */
	public class A3D4Renderer extends RendererBase
	{
		private var _container:ObjectContainer3D;

		/**
		 * The constructor creates an Away3D renderer for displaying the
		 * particles in an Away3D scene.
		 *
		 * @param container An Away3D object container. The particle display
		 * objects are created inside this object container.
		 */
		///Added by Michael--second param defines recycling mode
		private var _recycleParticles:Boolean=false;
		public function A3D4Renderer( container:ObjectContainer3D ,recycleParticles:Boolean=false)
		{
			super();
			_container = container;
			_recycleParticles=recycleParticles;
		}

		/**
		 * This method copies the particle's state to the associated image object.
		 *
		 *
This method is called internally by Flint and shouldn't need to be
		 * called by the user.

		 *
		 * @param particles The particles to be rendered.
		 */
		override protected function renderParticles( particles:Array ):void
		{
			for each( var p:Particle3D in particles )
			{
				renderParticle( p );
			}
		}

		protected function renderParticle( particle:Particle3D ):void
		{
			// N.B. Sprite3D is a subclass of Object3D so we don't need to treat it as a special case
			if( particle.image is Object3D )
			{
				var obj:Object3D = particle.image as Object3D;

				obj.x = particle.position.x;
				obj.y = particle.position.y;
				obj.z = particle.position.z;
				obj.scaleX = obj.scaleY = obj.scaleZ = particle.scale;

				var rotation:flash.geom.Vector3D = away3d.core.math.Vector3DUtils.quaternion2euler( Convert.QuaternionToA3D( particle.rotation ) );
				obj.rotationX = Maths.asDegrees( rotation.x );
				obj.rotationY = Maths.asDegrees( rotation.y );
				obj.rotationZ = Maths.asDegrees( rotation.z );

				if( obj.hasOwnProperty("material") )
				{
					var material:Object = obj["material"];
					if( material.hasOwnProperty( "colorTransform" ) )
					{
						material["colorTransform"] = particle.colorTransform;
					}
					else
					{
						if( material.hasOwnProperty( "color" ) )
						{
							material["color"] = particle.color & 0xFFFFFF;
						}
						if( material.hasOwnProperty( "alpha" ) )
						{
							material["alpha"] = particle.alpha;
						}
					}
				}
			}
		}

		/**
		 * This method is called when a particle is added to an emitter -
		 * usually because the emitter has just created the particle. The
		 * method adds the particle's image to the container's display list.
		 * It is called internally by Flint and need not be called by the user.
		 *
		 * @param particle The particle being added to the emitter.
		 */
		override protected function addParticle( particle:Particle ):void
		{

			if( particle.image is ObjectContainer3D )
			{
				_container.addChild( ObjectContainer3D( particle.image ) );
				renderParticle( Particle3D( particle ) );
			}
		}

		/**
		 * This method is called when a particle is removed from an emitter -
		 * usually because the particle is dying. The method removes the
		 * particle's image from the container's display list. It is called
		 * internally by Flint and need not be called by the user.
		 *
		 * @param particle The particle being removed from the emitter.
		 */
		override protected function removeParticle( particle:Particle ):void
		{
			// We can't clean up the 3d object here because the particle may not be dead.
			// We need to handle disposal elsewhere
			if( particle.image is ObjectContainer3D )
			{
				_container.removeChild( ObjectContainer3D( particle.image ) );
			}
		}
	}
}

/*
 * FLINT PARTICLE SYSTEM
 * .....................
 *
 * Author: Richard Lord & Michael Ivanov
 * Copyright (c) Richard Lord 2008-2011
 * http://flintparticles.org
 *
 *
 * Licence Agreement
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.flintparticles.integration.away3d.v4
{
	import away3d.containers.ObjectContainer3D;
	import away3d.core.base.Object3D;
	import away3d.core.math.Vector3DUtils;

	import org.flintparticles.common.particles.Particle;
	import org.flintparticles.common.renderers.RendererBase;
	import org.flintparticles.common.utils.Maths;
	import org.flintparticles.integration.away3d.v4.utils.Convert;
	import org.flintparticles.threeD.particles.Particle3D;

	import flash.geom.Vector3D;

	/**
	 * Renders the particles in an Away3D4 scene.
	 *
	 *
To use this renderer, the particles' image properties should be
	 * Away3D v4(Molehill API based) objects, renderable in an Away3D scene. This renderer
	 * doesn't update the scene, but copies each particle's properties
	 * to its image object so next time the Away3D scene is rendered the
	 * image objects are drawn according to the state of the particle
	 * system.

	 */
	public class A3D4Renderer extends RendererBase
	{
		private var _container:ObjectContainer3D;

		/**
		 * The constructor creates an Away3D renderer for displaying the
		 * particles in an Away3D scene.
		 *
		 * @param container An Away3D object container. The particle display
		 * objects are created inside this object container.
		 */
		public function A3D4Renderer( container:ObjectContainer3D )
		{
			super();
			_container = container;
		}

		/**
		 * This method copies the particle's state to the associated image object.
		 *
		 *
This method is called internally by Flint and shouldn't need to be
		 * called by the user.

		 *
		 * @param particles The particles to be rendered.
		 */
		override protected function renderParticles( particles:Array ):void
		{
			for each( var p:Particle3D in particles )
			{
				renderParticle( p );
			}
		}

		protected function renderParticle( particle:Particle3D ):void
		{
			// N.B. Sprite3D is a subclass of Object3D so we don't need to treat it as a special case
			if( particle.image is Object3D )
			{
				var obj:Object3D = particle.image as Object3D;

				obj.x = particle.position.x;
				obj.y = particle.position.y;
				obj.z = particle.position.z;
				obj.scaleX = obj.scaleY = obj.scaleZ = particle.scale;

				var rotation:flash.geom.Vector3D = away3d.core.math.Vector3DUtils.quaternion2euler( Convert.QuaternionToA3D( particle.rotation ) );
				obj.rotationX = Maths.asDegrees( rotation.x );
				obj.rotationY = Maths.asDegrees( rotation.y );
				obj.rotationZ = Maths.asDegrees( rotation.z );

				if( obj.hasOwnProperty("material") )
				{
					var material:Object = obj["material"];
					if( material.hasOwnProperty( "colorTransform" ) )
					{
						material["colorTransform"] = particle.colorTransform;
					}
					else
					{
						if( material.hasOwnProperty( "color" ) )
						{
							material["color"] = particle.color & 0xFFFFFF;
						}
						if( material.hasOwnProperty( "alpha" ) )
						{
							material["alpha"] = particle.alpha;
						}
					}
				}
			}
		}

		/**
		 * This method is called when a particle is added to an emitter -
		 * usually because the emitter has just created the particle. The
		 * method adds the particle's image to the container's display list.
		 * It is called internally by Flint and need not be called by the user.
		 *
		 * @param particle The particle being added to the emitter.
		 */
		override protected function addParticle( particle:Particle ):void
		{

			if( particle.image is ObjectContainer3D )
			{
				_container.addChild( ObjectContainer3D( particle.image ) );
				renderParticle( Particle3D( particle ) );
			}
		}

		/**
		 * This method is called when a particle is removed from an emitter -
		 * usually because the particle is dying. The method removes the
		 * particle's image from the container's display list. It is called
		 * internally by Flint and need not be called by the user.
		 *
		 * @param particle The particle being removed from the emitter.
		 */
		override protected function removeParticle( particle:Particle ):void
		{
			// We can't clean up the 3d object here because the particle may not be dead.
			// We need to handle disposal elsewhere
			if( particle.image is ObjectContainer3D )
			{
				_container.removeChild( ObjectContainer3D( particle.image ) );
			}
		}
	}
}

Remove unused local variable

Remove unused local variable


/*
 * Copyright 2008 Adobe Systems Inc., 2008 Google Inc.
 *
 * Licensed 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.
 *
 * Contributor(s):
 *   Zwetan Kjukov <zwetan@gmail.com>.
 *   Marc Alcaraz <ekameleon@gmail.com>.
 */

package
{
    import com.google.analytics.AnalyticsTracker;
    import com.google.analytics.components.FlashTracker;
    import com.google.analytics.events.AnalyticsEvent;

    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;

    /* Stub to test the AS3 API in pure ActionScript
       but compiled with mxmlc
    */
    [SWF(width="800", height="600", backgroundColor='0xffffff', frameRate='24', pageTitle='test', scriptRecursionLimit='1000', scriptTimeLimit='60')]
    public class GA_FLASH extends Sprite
    {
        private var tracker:AnalyticsTracker;

        public function GA_FLASH()
        {
            this.stage.align = StageAlign.TOP_LEFT;
            this.stage.scaleMode = StageScaleMode.NO_SCALE;

            addEventListener( Event.ADDED_TO_STAGE, onComplete );
        }

        public function onComplete( evt:Event ):void
        {
            /* note:
               here we simulate the FlashTracker component
               as if it was a Flash visual component
               by adding it to the display list
            */
            tracker = new FlashTracker();
            tracker.trackPageview( "/test" );
            tracker.addEventListener( AnalyticsEvent.READY, onAnalyticsReady );

            tracker.account = "UA-4241494-2";
            tracker.mode    = "AS3";
            tracker.visualDebug = true;
            addChild( tracker as DisplayObject );

        }

        public function onAnalyticsReady( event:AnalyticsEvent ):void
        {
            //trace( "onAnalyticsReady()" );
            var tracker:AnalyticsTracker = event.tracker;

            tracker.debug.verbose = true;
            tracker.trackPageview( "/hello/world" );

        }

    }
}

/*
 * Copyright 2008 Adobe Systems Inc., 2008 Google Inc.
 *
 * Licensed 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.
 *
 * Contributor(s):
 *   Zwetan Kjukov <zwetan@gmail.com>.
 *   Marc Alcaraz <ekameleon@gmail.com>.
 */

package
{
    import com.google.analytics.AnalyticsTracker;
    import com.google.analytics.components.FlashTracker;
    import com.google.analytics.events.AnalyticsEvent;

    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;

    /* Stub to test the AS3 API in pure ActionScript
       but compiled with mxmlc
    */
    [SWF(width="800", height="600", backgroundColor='0xffffff', frameRate='24', pageTitle='test', scriptRecursionLimit='1000', scriptTimeLimit='60')]
    public class GA_FLASH extends Sprite
    {
        private var tracker:AnalyticsTracker;

        public function GA_FLASH()
        {
            this.stage.align = StageAlign.TOP_LEFT;
            this.stage.scaleMode = StageScaleMode.NO_SCALE;

            addEventListener( Event.ADDED_TO_STAGE, onComplete );
        }

        public function onComplete( evt:Event ):void
        {
            /* note:
               here we simulate the FlashTracker component
               as if it was a Flash visual component
               by adding it to the display list
            */
            tracker = new FlashTracker();
            tracker.trackPageview( "/test" ); //test cache
            tracker.addEventListener( AnalyticsEvent.READY, onAnalyticsReady );

            tracker.account = "UA-111-222";
            tracker.mode    = "AS3";
            tracker.visualDebug = true;
            addChild( tracker as DisplayObject );

        }

        public function onAnalyticsReady( event:AnalyticsEvent ):void
        {
            //trace( "onAnalyticsReady()" );
            var tracker:AnalyticsTracker = event.tracker;

            tracker.debug.verbose = true;
            tracker.trackPageview( "/hello/world" );

        }

    }
}

clean up GA_FLASH

clean up GA_FLASH


/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed 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 {

  import flash.external.ExternalInterface;
  import flash.display.Sprite;
  import flash.display.Bitmap;
  import flash.display.BlendMode;
  import flash.display.StageScaleMode;
  import flash.display.StageAlign;
  import flash.display.BitmapData;
  import flash.display.Loader;
  import flash.events.ErrorEvent;
  import flash.events.Event;
  import flash.events.IOErrorEvent;
  import flash.events.UncaughtErrorEvent;
  import flash.text.TextField;
  import flash.system.Security;
  import flash.geom.Point;
  import flash.geom.Rectangle;
  import flash.geom.Matrix;
  import flash.geom.Matrix3D;
  import flash.geom.Vector3D;
  import flash.geom.PerspectiveProjection;
  import flash.utils.ByteArray;
  import flash.utils.Dictionary;
  import flash.utils.setTimeout;
  import flash.net.URLRequest;

  public class FlashCommon extends Sprite {

    private var imageLoadedCallback:String = null;

    public function FlashCommon() {

      // Install event handler for uncaught errors.
      loaderInfo.uncaughtErrorEvents.addEventListener(
          UncaughtErrorEvent.UNCAUGHT_ERROR, handleError);

      // Declare external interface.
      ExternalInterface.marshallExceptions = true
      ExternalInterface.addCallback('isReady', isReady);
      ExternalInterface.addCallback('createLayer', createLayer);
      ExternalInterface.addCallback('destroyLayer', destroyLayer);
      ExternalInterface.addCallback('loadImage', loadImage);
      ExternalInterface.addCallback('cancelImage', cancelImage);
      ExternalInterface.addCallback('unloadImage', unloadImage);
      ExternalInterface.addCallback('createTexture', createTexture);
      ExternalInterface.addCallback('destroyTexture', destroyTexture);
      ExternalInterface.addCallback('drawCubeTiles', drawCubeTiles);
      ExternalInterface.addCallback('drawFlatTiles', drawFlatTiles);

      var callbacksObjName:String = root.loaderInfo.parameters.callbacksObjName as String;
      imageLoadedCallback = callbacksObjName + '.imageLoaded';

      Security.allowDomain("*");

      if (stage) {
        init();
      } else {
        addEventListener(Event.ADDED_TO_STAGE, init);
      }

    }

    private function handleError(event:UncaughtErrorEvent):void {
      var message:String;
      if (event.error is Error) {
        message = Error(event.error).message;
      } else if (event.error is ErrorEvent) {
        message = ErrorEvent(event.error).text;
      } else {
        message = event.error.toString();
      }
      debug('ERROR: ' + message);
    };

    private function debug(str:String):void {
      ExternalInterface.call('console.log', str);
    }

    public function isReady():Boolean {
      return true;
    }

    private function init():void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
      stage.frameRate = 60;
    }

    private function convertFov(fov:Number, thisDimension:Number, otherDimension:Number):Number {
      return 2 * Math.atan(otherDimension * Math.tan(fov / 2) / thisDimension);
    }

    private function getLayer(id:Number):Sprite {
      if (id in layerMap) {
        return layerMap[id];
      }
      return null;
    }

    public function createLayer(id: Number):void {
      if (id in layerMap) {
        debug('createLayer: ' + id + ' already exists');
        return;
      }

      var layer:Sprite = new Sprite();

      layerMap[id] = layer;
      layer.transform.perspectiveProjection = new PerspectiveProjection();
      layer.blendMode = BlendMode.LAYER;
      addChild(layer);
    }

    public function destroyLayer(id:Number):void {
      if (!(id in layerMap)) {
        debug('destroyLayer: ' + id + ' does not exist');
        return;
      }
      var layer:Sprite = layerMap[id];

      while (layer.numChildren > 0) {
        layer.removeChildAt(0);
      }
      removeChild(layer);
      delete layerMap[id];
    }

    public function drawCubeTiles(layerId:Number, width:Number, height:Number, left:Number, top:Number, alpha:Number, yaw:Number, pitch:Number, roll:Number, fov:Number, tiles:Array):void {
      var layer:Sprite = getLayer(layerId);
      if (!layer) {
        debug('drawCubeTiles: layer ' + layerId + ' does not exist');
      }

      // Remove all current children.
      while (layer.numChildren > 0) {
        layer.removeChildAt(0);
      }

      // Set viewport.
      layer.x = left;
      layer.y = top;
      layer.scrollRect = new Rectangle(0, 0, width, height);

      // Set opacity.
      layer.alpha = alpha;

      // Set fov.
      // Don't really know why this needs to be done; magic number adjusted from
      // https://github.com/fieldOfView/CuTy/blob/master/com/fieldofview/cuty/CutyScene.as#L260
      var fieldOfView:Number = convertFov(fov, 1, 500/height);
      layer.transform.perspectiveProjection.fieldOfView = fieldOfView * 180/Math.PI;

      var projectionCenter:Point = new Point(width/2, height/2);
      layer.transform.perspectiveProjection.projectionCenter = projectionCenter;

      var focalLength:Number = layer.transform.perspectiveProjection.focalLength;

      var viewportCenter:Vector3D = new Vector3D(width/2, height/2, 0);
      var focalCenter:Vector3D = new Vector3D(width/2, height/2, -focalLength);

      for each (var t:Object in tiles) {
        var texture:Sprite = textureMap[t.textureId];
        if (!texture) {
          debug('drawCubeTiles: texture ' + t.textureId + ' does not exist');
        }

        var m:Matrix3D = new Matrix3D();

        // Set the perspective depth.
        m.appendTranslation(0, 0, -focalLength);

        // Center tile in viewport.
        var offsetX:Number = width/2 - t.width/2;
        var offsetY:Number = height/2 - t.height/2;
        m.appendTranslation(offsetX, offsetY, 0);

        // Set tile offset within cube face.
        var translX:Number = t.centerX * t.levelSize - t.padLeft;
        var translY:Number = -t.centerY * t.levelSize - t.padTop;
        var translZ:Number = t.levelSize / 2;
        m.appendTranslation(translX, translY, translZ);

        // Set cube face rotation.
        m.appendRotation(-t.rotY, Vector3D.Y_AXIS, focalCenter);
        m.appendRotation(t.rotX, Vector3D.X_AXIS, focalCenter);

        // Set camera rotation.
        var rotX:Number = pitch*180/Math.PI;
        var rotY:Number = -yaw*180/Math.PI;
        var rotZ:Number = -roll*180/Math.PI;
        m.appendRotation(rotY, Vector3D.Y_AXIS, focalCenter);
        m.appendRotation(rotX, Vector3D.X_AXIS, focalCenter);
        m.appendRotation(rotZ, Vector3D.Z_AXIS, focalCenter);

        texture.transform.matrix3D = m;

        layer.addChild(texture);
      }
    }

    public function drawFlatTiles(layerId:Number, width:Number, height:Number, left:Number, top:Number, alpha:Number, x:Number, y:Number, zoomX:Number, zoomY:Number, tiles:Array):void {
      var layer:Sprite = getLayer(layerId);
      if (!layer) {
        debug('drawFlatTiles: layer ' + layerId + ' does not exist');
      }

      // Remove all current children.
      while (layer.numChildren > 0) {
        layer.removeChildAt(0);
      }

      // Set viewport.
      layer.x = left;
      layer.y = top;
      layer.scrollRect = new Rectangle(0, 0, width, height);

      // Set opacity.
      layer.alpha = alpha;

      // Determine the zoom factor.
      zoomX = width / zoomX;
      zoomY = height / zoomY;

      for each (var t:Object in tiles) {
        var texture:Sprite = textureMap[t.textureId];
        if (!texture) {
          debug('drawFlatTiles: texture ' + t.textureId + ' does not exist');
        }

        var m:Matrix3D = new Matrix3D();

        // Scale tile into correct size.
        var scaleX:Number = zoomX / t.levelWidth;
        var scaleY:Number = zoomY / t.levelHeight;
        m.appendScale(scaleX, scaleY, 1);

        // Place top left corner of tile at the center of the viewport.
        var offsetX:Number = width/2;
        var offsetY:Number = height/2;
        m.appendTranslation(offsetX, offsetY, 0);

        // Move tile into its position within the image.
        var cornerX:Number = t.centerX - t.scaleX / 2 + 0.5;
        var cornerY:Number = 0.5 - t.centerY - t.scaleY / 2;
        var posX:Number = cornerX * zoomX;
        var posY:Number = cornerY * zoomY;
        m.appendTranslation(posX, posY, 0);

        // Compensate for padding around the tile.
        m.appendTranslation(-t.padLeft, -t.padTop, 0);

        // Apply view offsets.
        var translX:Number = -x * zoomX;
        var translY:Number = -y * zoomY;
        m.appendTranslation(translX, translY, 0);

        texture.transform.matrix3D = m;

        layer.addChild(texture);
      }
    }

    private var imageMap:Dictionary = new Dictionary();
    private var textureMap:Dictionary = new Dictionary();
    private var layerMap:Dictionary = new Dictionary();

    private var nextId:Number = 1;

    public function loadImage(url:String, width:Number, height:Number, x:Number, y:Number):Number {
      var id:Number = nextId++;

      var loader:Loader = new Loader();
      imageMap[id] = loader;

      // TODO: Check if there are there other kinds of errors we can catch.
      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadSuccess);
      loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadError);

      var urlRequest:URLRequest = new URLRequest(url);
      loader.load(urlRequest);

      return id;

      function loadSuccess(e:Event):void {
        if (!imageMap[id]) {
          // Probably canceled before load was complete; ignore.
          return;
        }

        var image:Bitmap = Bitmap(loader.content);

        // Convert relative offset/size to absolute values.
        x *= image.bitmapData.width;
        y *= image.bitmapData.height;
        width *= image.bitmapData.width;
        height *= image.bitmapData.height;

        var croppedData:BitmapData = new BitmapData(width, height);
        croppedData.copyPixels(image.bitmapData, new Rectangle(x, y, width, height), new Point(0,0));

        imageMap[id] = croppedData;

        ExternalInterface.call(imageLoadedCallback, false, id);
      }

      function loadError(e:IOErrorEvent):void {
        if (!imageMap[id]) {
          // Probably canceled before load was complete; ignore.
          return;
        }
        delete imageMap[id];
        ExternalInterface.call(imageLoadedCallback, true, id);
      }
    }

    public function cancelImage(id:Number):void {
      if (!imageMap[id]) {
        debug('cancelImage: image ' + id + ' does not exist');
        return;
      }
      unloadImage(id);
    }

    public function unloadImage(id:Number):void {
      var loaderOrBitmapData:Object = imageMap[id];
      if (!loaderOrBitmapData) {
        debug('unloadImage: image ' + id + ' does not exist');
        return;
      }
      if (loaderOrBitmapData is Loader) {
        var loader:Loader = loaderOrBitmapData as Loader;
        // Calling close() after the load is complete seems to cause an error,
        // so first check that we are still loading.
        if (loader.contentLoaderInfo.bytesTotal != 0 && loader.contentLoaderInfo.bytesLoaded != loader.contentLoaderInfo.bytesTotal) {
          loader.close();
        }
      }
      delete imageMap[id];
    }

    public function createTexture(imageId:Number, width:Number, height:Number, padTop:Number, padBottom:Number, padLeft:Number, padRight:Number):Number {
      var image:BitmapData = imageMap[imageId];

      var i:Number;
      var point:Point = new Point();
      var rect:Rectangle = new Rectangle();

      // Create new bitmap for texture.
      var bitmap:BitmapData = new BitmapData(width + padLeft + padRight, height + padTop + padBottom, true, 0x00FFFFFF);

      // Resize source image if the texture has a different size.
      // TODO: it would be better to call draw() directly on the final bitmap
      // with both a matrix and a clippingRect parameter; this would both be
      // faster and allocate less memory. However, the clippingRect parameter
      // for the draw() method doesn't seem to work as documented.
      var scaled:BitmapData;
      if (width !== image.width || height !== image.height) {
        scaled = new BitmapData(width, height, true, 0x00FFFFFF);
        var mat:Matrix = new Matrix(width / image.width, 0, 0, height / image.height, 0, 0);
        scaled.draw(image, mat, null, null, null, true);
      } else {
        scaled = image;
      }

      // Draw image into texture.
      rect.x = 0;
      rect.y = 0;
      rect.width = width;
      rect.height = height;

      point.x = padLeft;
      point.y = padTop;
      bitmap.copyPixels(scaled, rect, point);

      // Draw top padding.
      for (i = 0; i <= padTop; i++) {
        rect.x = padLeft;
        rect.y = padTop;
        rect.width = width;
        rect.height = 1;

        point.x = padLeft;
        point.y = i;
        bitmap.copyPixels(bitmap, rect, point);
      }

      // Draw left padding.
      for (i = 0; i <= padLeft; i++) {
        rect.x = padLeft;
        rect.y = padTop;
        rect.width = 1;
        rect.height = height;

        point.x = i;
        point.y = padTop;
        bitmap.copyPixels(bitmap, rect, point);
      }

      // Draw bottom padding.
      for (i = 0; i <= padBottom; i++) {
        rect.x = padLeft;
        rect.y = padTop + height - 1;
        rect.width = width;
        rect.height = 1;

        point.x = padLeft;
        point.y = padTop + height + i;
        bitmap.copyPixels(bitmap, rect, point);
      }

      // Draw right padding.
      for (i = 0; i <= padRight; i++) {
        rect.x = padLeft + width - 1;
        rect.y = padTop;
        rect.width = 1;
        rect.height = height;

        point.x = padLeft + width + i;
        point.y = padTop;
        bitmap.copyPixels(bitmap, rect, point);
      }

      var texture:Sprite = new Sprite();
      texture.addChild(new Bitmap(bitmap));

      var textureId:Number = imageId;
      textureMap[textureId] = texture;

      return textureId;
    }

    public function destroyTexture(id:Number):void {
      var texture:Sprite = textureMap[id];
      if (!texture) {
        debug('destroyTexture: texture ' + id + ' does not exist');
        return;
      }
      if (texture.parent) {
        texture.parent.removeChild(texture);
      }
      delete textureMap[id];
    }
  }
}

/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed 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 {

  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.display.BlendMode;
  import flash.display.Loader;
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.ErrorEvent;
  import flash.events.Event;
  import flash.events.IOErrorEvent;
  import flash.events.UncaughtErrorEvent;
  import flash.external.ExternalInterface;
  import flash.geom.Matrix;
  import flash.geom.Matrix3D;
  import flash.geom.PerspectiveProjection;
  import flash.geom.Point;
  import flash.geom.Rectangle;
  import flash.geom.Vector3D;
  import flash.net.URLRequest;
  import flash.system.Security;
  import flash.utils.Dictionary;

  public class FlashCommon extends Sprite {

    private var imageLoadedCallback:String = null;

    public function FlashCommon() {

      // Install event handler for uncaught errors.
      loaderInfo.uncaughtErrorEvents.addEventListener(
          UncaughtErrorEvent.UNCAUGHT_ERROR, handleError);

      // Declare external interface.
      ExternalInterface.marshallExceptions = true
      ExternalInterface.addCallback('isReady', isReady);
      ExternalInterface.addCallback('createLayer', createLayer);
      ExternalInterface.addCallback('destroyLayer', destroyLayer);
      ExternalInterface.addCallback('loadImage', loadImage);
      ExternalInterface.addCallback('cancelImage', cancelImage);
      ExternalInterface.addCallback('unloadImage', unloadImage);
      ExternalInterface.addCallback('createTexture', createTexture);
      ExternalInterface.addCallback('destroyTexture', destroyTexture);
      ExternalInterface.addCallback('drawCubeTiles', drawCubeTiles);
      ExternalInterface.addCallback('drawFlatTiles', drawFlatTiles);

      var callbacksObjName:String = loaderInfo.parameters.callbacksObjName as String;
      imageLoadedCallback = callbacksObjName + '.imageLoaded';

      Security.allowDomain("*");

      if (stage) {
        init();
      } else {
        addEventListener(Event.ADDED_TO_STAGE, init);
      }

    }

    private function handleError(event:UncaughtErrorEvent):void {
      var message:String;
      if (event.error is Error) {
        message = Error(event.error).message;
      } else if (event.error is ErrorEvent) {
        message = ErrorEvent(event.error).text;
      } else {
        message = event.error.toString();
      }
      debug('ERROR: ' + message);
    };

    private function debug(str:String):void {
      ExternalInterface.call('console.log', str);
    }

    public function isReady():Boolean {
      return true;
    }

    private function init():void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
      stage.frameRate = 60;
    }

    private function convertFov(fov:Number, thisDimension:Number, otherDimension:Number):Number {
      return 2 * Math.atan(otherDimension * Math.tan(fov / 2) / thisDimension);
    }

    private function getLayer(id:Number):Sprite {
      if (id in layerMap) {
        return layerMap[id];
      }
      return null;
    }

    public function createLayer(id: Number):void {
      if (id in layerMap) {
        debug('createLayer: ' + id + ' already exists');
        return;
      }

      var layer:Sprite = new Sprite();

      layerMap[id] = layer;
      layer.transform.perspectiveProjection = new PerspectiveProjection();
      layer.blendMode = BlendMode.LAYER;
      addChild(layer);
    }

    public function destroyLayer(id:Number):void {
      if (!(id in layerMap)) {
        debug('destroyLayer: ' + id + ' does not exist');
        return;
      }
      var layer:Sprite = layerMap[id];

      while (layer.numChildren > 0) {
        layer.removeChildAt(0);
      }
      removeChild(layer);
      delete layerMap[id];
    }

    public function drawCubeTiles(layerId:Number, width:Number, height:Number, left:Number, top:Number, alpha:Number, yaw:Number, pitch:Number, roll:Number, fov:Number, tiles:Array):void {
      var layer:Sprite = getLayer(layerId);
      if (!layer) {
        debug('drawCubeTiles: layer ' + layerId + ' does not exist');
      }

      // Remove all current children.
      while (layer.numChildren > 0) {
        layer.removeChildAt(0);
      }

      // Set viewport.
      layer.x = left;
      layer.y = top;
      layer.scrollRect = new Rectangle(0, 0, width, height);

      // Set opacity.
      layer.alpha = alpha;

      // Set fov.
      // Don't really know why this needs to be done; magic number adjusted from
      // https://github.com/fieldOfView/CuTy/blob/master/com/fieldofview/cuty/CutyScene.as#L260
      var fieldOfView:Number = convertFov(fov, 1, 500/height);
      layer.transform.perspectiveProjection.fieldOfView = fieldOfView * 180/Math.PI;

      var projectionCenter:Point = new Point(width/2, height/2);
      layer.transform.perspectiveProjection.projectionCenter = projectionCenter;

      var focalLength:Number = layer.transform.perspectiveProjection.focalLength;

      var viewportCenter:Vector3D = new Vector3D(width/2, height/2, 0);
      var focalCenter:Vector3D = new Vector3D(width/2, height/2, -focalLength);

      for each (var t:Object in tiles) {
        var texture:Sprite = textureMap[t.textureId];
        if (!texture) {
          debug('drawCubeTiles: texture ' + t.textureId + ' does not exist');
        }

        var m:Matrix3D = new Matrix3D();

        // Set the perspective depth.
        m.appendTranslation(0, 0, -focalLength);

        // Center tile in viewport.
        var offsetX:Number = width/2 - t.width/2;
        var offsetY:Number = height/2 - t.height/2;
        m.appendTranslation(offsetX, offsetY, 0);

        // Set tile offset within cube face.
        var translX:Number = t.centerX * t.levelSize - t.padLeft;
        var translY:Number = -t.centerY * t.levelSize - t.padTop;
        var translZ:Number = t.levelSize / 2;
        m.appendTranslation(translX, translY, translZ);

        // Set cube face rotation.
        m.appendRotation(-t.rotY, Vector3D.Y_AXIS, focalCenter);
        m.appendRotation(t.rotX, Vector3D.X_AXIS, focalCenter);

        // Set camera rotation.
        var rotX:Number = pitch*180/Math.PI;
        var rotY:Number = -yaw*180/Math.PI;
        var rotZ:Number = -roll*180/Math.PI;
        m.appendRotation(rotY, Vector3D.Y_AXIS, focalCenter);
        m.appendRotation(rotX, Vector3D.X_AXIS, focalCenter);
        m.appendRotation(rotZ, Vector3D.Z_AXIS, focalCenter);

        texture.transform.matrix3D = m;

        layer.addChild(texture);
      }
    }

    public function drawFlatTiles(layerId:Number, width:Number, height:Number, left:Number, top:Number, alpha:Number, x:Number, y:Number, zoomX:Number, zoomY:Number, tiles:Array):void {
      var layer:Sprite = getLayer(layerId);
      if (!layer) {
        debug('drawFlatTiles: layer ' + layerId + ' does not exist');
      }

      // Remove all current children.
      while (layer.numChildren > 0) {
        layer.removeChildAt(0);
      }

      // Set viewport.
      layer.x = left;
      layer.y = top;
      layer.scrollRect = new Rectangle(0, 0, width, height);

      // Set opacity.
      layer.alpha = alpha;

      // Determine the zoom factor.
      zoomX = width / zoomX;
      zoomY = height / zoomY;

      for each (var t:Object in tiles) {
        var texture:Sprite = textureMap[t.textureId];
        if (!texture) {
          debug('drawFlatTiles: texture ' + t.textureId + ' does not exist');
        }

        var m:Matrix3D = new Matrix3D();

        // Scale tile into correct size.
        var scaleX:Number = zoomX / t.levelWidth;
        var scaleY:Number = zoomY / t.levelHeight;
        m.appendScale(scaleX, scaleY, 1);

        // Place top left corner of tile at the center of the viewport.
        var offsetX:Number = width/2;
        var offsetY:Number = height/2;
        m.appendTranslation(offsetX, offsetY, 0);

        // Move tile into its position within the image.
        var cornerX:Number = t.centerX - t.scaleX / 2 + 0.5;
        var cornerY:Number = 0.5 - t.centerY - t.scaleY / 2;
        var posX:Number = cornerX * zoomX;
        var posY:Number = cornerY * zoomY;
        m.appendTranslation(posX, posY, 0);

        // Compensate for padding around the tile.
        m.appendTranslation(-t.padLeft, -t.padTop, 0);

        // Apply view offsets.
        var translX:Number = -x * zoomX;
        var translY:Number = -y * zoomY;
        m.appendTranslation(translX, translY, 0);

        texture.transform.matrix3D = m;

        layer.addChild(texture);
      }
    }

    private var imageMap:Dictionary = new Dictionary();
    private var textureMap:Dictionary = new Dictionary();
    private var layerMap:Dictionary = new Dictionary();

    private var nextId:Number = 1;

    public function loadImage(url:String, width:Number, height:Number, x:Number, y:Number):Number {
      var id:Number = nextId++;

      var loader:Loader = new Loader();
      imageMap[id] = loader;

      // TODO: Check if there are there other kinds of errors we can catch.
      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadSuccess);
      loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadError);

      var urlRequest:URLRequest = new URLRequest(url);
      loader.load(urlRequest);

      return id;

      function loadSuccess(e:Event):void {
        if (!imageMap[id]) {
          // Probably canceled before load was complete; ignore.
          return;
        }

        var image:Bitmap = Bitmap(loader.content);

        // Convert relative offset/size to absolute values.
        x *= image.bitmapData.width;
        y *= image.bitmapData.height;
        width *= image.bitmapData.width;
        height *= image.bitmapData.height;

        var croppedData:BitmapData = new BitmapData(width, height);
        croppedData.copyPixels(image.bitmapData, new Rectangle(x, y, width, height), new Point(0,0));

        imageMap[id] = croppedData;

        ExternalInterface.call(imageLoadedCallback, false, id);
      }

      function loadError(e:IOErrorEvent):void {
        if (!imageMap[id]) {
          // Probably canceled before load was complete; ignore.
          return;
        }
        delete imageMap[id];
        ExternalInterface.call(imageLoadedCallback, true, id);
      }
    }

    public function cancelImage(id:Number):void {
      if (!imageMap[id]) {
        debug('cancelImage: image ' + id + ' does not exist');
        return;
      }
      unloadImage(id);
    }

    public function unloadImage(id:Number):void {
      var loaderOrBitmapData:Object = imageMap[id];
      if (!loaderOrBitmapData) {
        debug('unloadImage: image ' + id + ' does not exist');
        return;
      }
      if (loaderOrBitmapData is Loader) {
        var loader:Loader = loaderOrBitmapData as Loader;
        // Calling close() after the load is complete seems to cause an error,
        // so first check that we are still loading.
        if (loader.contentLoaderInfo.bytesTotal != 0 && loader.contentLoaderInfo.bytesLoaded != loader.contentLoaderInfo.bytesTotal) {
          loader.close();
        }
      }
      delete imageMap[id];
    }

    public function createTexture(imageId:Number, width:Number, height:Number, padTop:Number, padBottom:Number, padLeft:Number, padRight:Number):Number {
      var image:BitmapData = imageMap[imageId];

      var i:Number;
      var point:Point = new Point();
      var rect:Rectangle = new Rectangle();

      // Create new bitmap for texture.
      var bitmap:BitmapData = new BitmapData(width + padLeft + padRight, height + padTop + padBottom, true, 0x00FFFFFF);

      // Resize source image if the texture has a different size.
      // TODO: it would be better to call draw() directly on the final bitmap
      // with both a matrix and a clippingRect parameter; this would both be
      // faster and allocate less memory. However, the clippingRect parameter
      // for the draw() method doesn't seem to work as documented.
      var scaled:BitmapData;
      if (width !== image.width || height !== image.height) {
        scaled = new BitmapData(width, height, true, 0x00FFFFFF);
        var mat:Matrix = new Matrix(width / image.width, 0, 0, height / image.height, 0, 0);
        scaled.draw(image, mat, null, null, null, true);
      } else {
        scaled = image;
      }

      // Draw image into texture.
      rect.x = 0;
      rect.y = 0;
      rect.width = width;
      rect.height = height;

      point.x = padLeft;
      point.y = padTop;
      bitmap.copyPixels(scaled, rect, point);

      // Draw top padding.
      for (i = 0; i <= padTop; i++) {
        rect.x = padLeft;
        rect.y = padTop;
        rect.width = width;
        rect.height = 1;

        point.x = padLeft;
        point.y = i;
        bitmap.copyPixels(bitmap, rect, point);
      }

      // Draw left padding.
      for (i = 0; i <= padLeft; i++) {
        rect.x = padLeft;
        rect.y = padTop;
        rect.width = 1;
        rect.height = height;

        point.x = i;
        point.y = padTop;
        bitmap.copyPixels(bitmap, rect, point);
      }

      // Draw bottom padding.
      for (i = 0; i <= padBottom; i++) {
        rect.x = padLeft;
        rect.y = padTop + height - 1;
        rect.width = width;
        rect.height = 1;

        point.x = padLeft;
        point.y = padTop + height + i;
        bitmap.copyPixels(bitmap, rect, point);
      }

      // Draw right padding.
      for (i = 0; i <= padRight; i++) {
        rect.x = padLeft + width - 1;
        rect.y = padTop;
        rect.width = 1;
        rect.height = height;

        point.x = padLeft + width + i;
        point.y = padTop;
        bitmap.copyPixels(bitmap, rect, point);
      }

      var texture:Sprite = new Sprite();
      texture.addChild(new Bitmap(bitmap));

      var textureId:Number = imageId;
      textureMap[textureId] = texture;

      return textureId;
    }

    public function destroyTexture(id:Number):void {
      var texture:Sprite = textureMap[id];
      if (!texture) {
        debug('destroyTexture: texture ' + id + ' does not exist');
        return;
      }
      if (texture.parent) {
        texture.parent.removeChild(texture);
      }
      delete textureMap[id];
    }
  }
}

Remove unneeded imports from the Flash renderer.