package
{
	import flash.display.*;
	import flash.events.*;//for event handling
	import flash.net.Socket;//Sockets
	import flash.utils.*;
	import flash.external.ExternalInterface;
	import flash.system.*;
	import com.adobe.serialization.json.*;//as3corelib JSON support
	public class DisplayWindow extends Sprite
	{
		// Public Properties:
		public var attention:uint;
		public var meditation:uint;
		public var blink:uint;
		public var poorSignal:uint;

		public var myTimer:Timer;
		public var jsTimer:Timer;
		public var timeCount:uint;
		public var hasStarted:Boolean;

		// Private Properties:
		private var thinkGearSocket:Socket;
		public function DisplayWindow()
		{
			Security.allowDomain("*");

			var self = this;

			hasStarted = false;
			//To run the ThinkGear software without waiting for the JS, uncomment the line below
			//startThinkGearSocket();

			//Before the application tries to connect to the ThinkGearSocket, make sure JS is available
			waitForJs();
		}

		private function startThinkGearSocket()
		{
			if (! hasStarted)
			{
				hasStarted = true;
				log("Preparing ThinkGear...");
				thinkGearSocket = new Socket();
				thinkGearSocket.addEventListener(ProgressEvent.SOCKET_DATA,dataHandler);
				thinkGearSocket.addEventListener(ProgressEvent.PROGRESS,progressHandler);
				thinkGearSocket.connect("127.0.0.1",13854);
				if (thinkGearSocket.connected)
				{
					log("ThinkGear connected. Configuring...");
				}
				else
				{
					log("ThinkGear not connected. Configuring anyway...");
				}
				var configuration:Object = new Object();
				configuration["enableRawOutput"] = false;
				configuration["format"] = "Json";
				thinkGearSocket.writeUTFBytes(JSON.encode(configuration));
			}
			else
			{
				log("thinkGearSocket has already started");
			}
		}

		// Protected Methods:;
		private function progressHandler(e:ProgressEvent)
		{
			if (thinkGearSocket.connected)
			{
				log("ThinkGear connected. ProgressEvent occurred.");
			}
			else
			{
				log("ThinkGear not connected. ProgressEvent occurred.");
			}
		}
		private function dataHandler(e:ProgressEvent)
		{
			if (thinkGearSocket.connected)
			{
				log("ThinkGear connected. Receiving data.");
			}
			else
			{
				log("ThinkGear not connected. Receiving data.");
			}
			var packetString:String = thinkGearSocket.readUTFBytes(thinkGearSocket.bytesAvailable);
			if ((packetString == null))
			{
				log("packetString is NULL");
			}
			thinkGearSocket.flush();
			log("ThinkGearSocket flushed");

			var packets:Array = packetString.split(/\r/);
			log(("Packets length: " + packets.length));
			var data:Object;//temporary data
			for each (var packet:String in packets)
			{//iterate through each element
				if ((packet != ""))
				{//sometimes the line is blank so skip the line
					try
					{
						log("Packet: "+packet);
						data = JSON.decode(packet);
						//decode the data to an array
						if (data["poorSignalLevel"] != null)
						{//checking to see if the ''poorSignalLevel' key exists
							poorSignal = data["poorSignalLevel"];
							if ((poorSignal == 0))
							{
								attention = data["eSense"]["attention"];//assigning data to variables
								meditation = data["eSense"]["meditation"];
								blink = data["blinkStrength"];
								//log("Attention: " + attention);//output attention data to debug
							}
							else
							{
								if ((poorSignal == 200))
								{
									attention = 0;
									meditation = 0;
									blink = 0;
									if (!data["eSense"])
										poorSignal = 250;
								}
							}
						}
						label1.text = "Attention: " + attention.toString() + "\nMeditation: " + meditation.toString() + "\nPoor Signal: " + poorSignal.toString() + "\nblinkStrength: " + blink.toString();
						sendDataToJavaScript(poorSignal,attention,meditation,blink);
					}
					catch (jError:JSONParseError)
					{
						log("there was a JSONParseError: " + packet);
						// restart a connection at first error :(
						hasStarted = false;
						thinkGearSocket.close();
						startThinkGearSocket();
						sendDataToJavaScript(250, 0, 0, 0);
						return;
					}

				} else log("empty packet");
				data = null;

			}/*for each*/
		}/*function dataHandler*/
		/**
		 * iconLevel is the poor signal value
		 * attentionLevel is the attention value
		 * meditationLevel is the meditation value
		 * There may be some need to check the types of these values, because they are not all
		 * being passed to the Javascript, from what I can tell
		 */
		public function sendDataToJavaScript(iconLevel:uint,attentionLevel:uint,meditationLevel:uint,blinkStrength:uint)
		{
			if (ExternalInterface.available)
			{
				ExternalInterface.call("MindWave.setSignalValue",iconLevel);
				ExternalInterface.call("MindWave.setAttentionLevel",attentionLevel);
				ExternalInterface.call("MindWave.setMeditationLevel",meditationLevel);
				ExternalInterface.call("MindWave.setBlinkStrength",blinkStrength);
			}
			else
			{
				log("ExternalInterface is not available to send data to JS");
			}
		}
		public function checkJs(event:TimerEvent)
		{
			log("Checking javascript...");
			if (ExternalInterface.available)
			{
				var jsReady:Boolean = ExternalInterface.call("isReady");
				if (jsReady)
				{
					jsTimer.stop();
					startThinkGearSocket();
				}
				else
				{
					log("JS is not Ready");
				}
			} else {
				log("No JS interface...");
			}
		}
		public function checkJsStopped(event:TimerEvent)
		{
			log("Javascript connection was not established");
		}
		private function waitForJs()
		{
			jsTimer = new Timer(1000,100);
			jsTimer.addEventListener(TimerEvent.TIMER,checkJs);
			jsTimer.addEventListener(TimerEvent.TIMER_COMPLETE,checkJsStopped);
			jsTimer.start();
		}

		private function receivedFromJavaScript(value:String):void
		{
			log((("JavaScript says: " + value) + "\n"));
		}
		private function checkJavaScriptReady():Boolean
		{
			var isReady:Boolean = false;
			if (ExternalInterface.available)
			{
				isReady = ExternalInterface.call("isReady");
			}
			return isReady;
		}
		private function log(message:String)
		{
			trace(message);
			label2.text = message;
			if (ExternalInterface.available)
			{
				ExternalInterface.call("console.log",message);
			}
		}
	}
}

package
{
	import flash.display.*;
	import flash.events.*;//for event handling
	import flash.net.Socket;//Sockets
	import flash.utils.*;
	import flash.external.ExternalInterface;
	import flash.system.*;
	import com.adobe.serialization.json.*;//as3corelib JSON support
	public class DisplayWindow extends Sprite
	{
		// Public Properties:
		public var attention:uint;
		public var meditation:uint;
		public var blink:uint;
		public var poorSignal:uint;

		public var myTimer:Timer;
		public var jsTimer:Timer;
		public var timeCount:uint;
		public var hasStarted:Boolean;

		// Private Properties:
		private var thinkGearSocket:Socket;
		public function DisplayWindow()
		{
			Security.allowDomain("*");

			var self = this;

			hasStarted = false;
			//To run the ThinkGear software without waiting for the JS, uncomment the line below
			//startThinkGearSocket();

			//Before the application tries to connect to the ThinkGearSocket, make sure JS is available
			waitForJs();
		}

		private function startThinkGearSocket()
		{
			if (! hasStarted)
			{
				hasStarted = true;
				log("Preparing ThinkGear...");
				thinkGearSocket = new Socket();
				thinkGearSocket.addEventListener(ProgressEvent.SOCKET_DATA,dataHandler);
				thinkGearSocket.addEventListener(ProgressEvent.PROGRESS,progressHandler);
				thinkGearSocket.connect("127.0.0.1",13854);
				if (thinkGearSocket.connected)
				{
					log("ThinkGear connected. Configuring...");
				}
				else
				{
					log("ThinkGear not connected. Configuring anyway...");
				}
				var configuration:Object = new Object();
				configuration["enableRawOutput"] = false;
				configuration["format"] = "Json";
				thinkGearSocket.writeUTFBytes(JSON.encode(configuration));
			}
			else
			{
				log("thinkGearSocket has already started");
			}
		}

		// Protected Methods:;
		private function progressHandler(e:ProgressEvent)
		{
			if (thinkGearSocket.connected)
			{
				log("ThinkGear connected. ProgressEvent occurred.");
			}
			else
			{
				log("ThinkGear not connected. ProgressEvent occurred.");
			}
		}
		private function dataHandler(e:ProgressEvent)
		{
			if (thinkGearSocket.connected)
			{
				log("ThinkGear connected. Receiving data.");
			}
			else
			{
				log("ThinkGear not connected. Receiving data.");
			}
			var packetString:String = thinkGearSocket.readUTFBytes(thinkGearSocket.bytesAvailable);
			if ((packetString == null))
			{
				log("packetString is NULL");
			}
			thinkGearSocket.flush();
			log("ThinkGearSocket flushed");

			var packets:Array = packetString.split(/\r/);
			log(("Packets length: " + packets.length));
			var data:Object;//temporary data
			for each (var packet:String in packets)
			{//iterate through each element
				if ((packet != ""))
				{//sometimes the line is blank so skip the line
					try
					{
						log("Packet: "+packet);
						data = JSON.decode(packet);
						//decode the data to an array
						if (data["poorSignalLevel"] != null)
						{//checking to see if the ''poorSignalLevel' key exists
							poorSignal = data["poorSignalLevel"];
							if ((poorSignal == 0))
							{
								attention = data["eSense"]["attention"];//assigning data to variables
								meditation = data["eSense"]["meditation"];
								blink = data["blinkStrength"];
								//log("Attention: " + attention);//output attention data to debug
							}
							else
							{
								if ((poorSignal == 200))
								{
									attention = 0;
									meditation = 0;
									blink = 0;
									if (!data["eSense"])
										poorSignal = 250;
								}
							}
						}
						label1.text = "Attention: " + attention.toString() + "\nMeditation: " + meditation.toString() + "\nPoor Signal: " + poorSignal.toString() + "\nblinkStrength: " + blink.toString();
						sendDataToJavaScript(poorSignal,attention,meditation,blink);
					}
					catch (jError:JSONParseError)
					{
						log("there was a JSONParseError: " + packet);
						// restart a connection at first error :(
						hasStarted = false;
						thinkGearSocket.close();
						startThinkGearSocket();
						sendDataToJavaScript(250, 0, 0, 0);
						return;
					}

				} else log("empty packet");
				data = null;

			}/*for each*/
		}/*function dataHandler*/
		/**
		 * iconLevel is the poor signal value
		 * attentionLevel is the attention value
		 * meditationLevel is the meditation value
		 * There may be some need to check the types of these values, because they are not all
		 * being passed to the Javascript, from what I can tell
		 */
		public function sendDataToJavaScript(iconLevel:uint,attentionLevel:uint,meditationLevel:uint,blinkStrength:uint)
		{
			if (ExternalInterface.available)
			{
				ExternalInterface.call("MindWave.setSignalValue",iconLevel);
				ExternalInterface.call("MindWave.setAttentionLevel",attentionLevel);
				ExternalInterface.call("MindWave.setMeditationLevel",meditationLevel);
				if (blinkStrength > 0) ExternalInterface.call("MindWave.setBlinkStrength",blinkStrength);
			}
			else
			{
				log("ExternalInterface is not available to send data to JS");
			}
		}
		public function checkJs(event:TimerEvent)
		{
			log("Checking javascript...");
			if (ExternalInterface.available)
			{
				var jsReady:Boolean = ExternalInterface.call("isReady");
				if (jsReady)
				{
					jsTimer.stop();
					startThinkGearSocket();
				}
				else
				{
					log("JS is not Ready");
				}
			} else {
				log("No JS interface...");
			}
		}
		public function checkJsStopped(event:TimerEvent)
		{
			log("Javascript connection was not established");
		}
		private function waitForJs()
		{
			jsTimer = new Timer(1000,100);
			jsTimer.addEventListener(TimerEvent.TIMER,checkJs);
			jsTimer.addEventListener(TimerEvent.TIMER_COMPLETE,checkJsStopped);
			jsTimer.start();
		}

		private function receivedFromJavaScript(value:String):void
		{
			log((("JavaScript says: " + value) + "\n"));
		}
		private function checkJavaScriptReady():Boolean
		{
			var isReady:Boolean = false;
			if (ExternalInterface.available)
			{
				isReady = ExternalInterface.call("isReady");
			}
			return isReady;
		}
		private function log(message:String)
		{
			trace(message);
			label2.text = message;
			if (ExternalInterface.available)
			{
				ExternalInterface.call("console.log",message);
			}
		}
	}
}

send blink if > 0

flash: send blink if > 0


/*
* Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/

package com.snowplowanalytics.snowplow.tracker
{
	import com.snowplowanalytics.snowplow.tracker.emitter.Emitter;
	import com.snowplowanalytics.snowplow.tracker.payload.IPayload;
	import com.snowplowanalytics.snowplow.tracker.payload.SchemaPayload;
	import com.snowplowanalytics.snowplow.tracker.payload.TrackerPayload;
	import com.snowplowanalytics.snowplow.tracker.util.Preconditions;

	import flash.display.Stage;
	import flash.external.ExternalInterface;
	import flash.net.LocalConnection;
	import flash.net.SharedObject;
	import flash.system.Capabilities;

	public class Tracker
	{
		private var base64Encoded:Boolean = true;
		private var emitter:Emitter;
		private var platform:String;
		private var appId:String;
		private var namespace:String;
		private var trackerVersion:String;
		private var subject:Subject;
		private var stage:Stage;

		private var playerType:String;
		private var playerVersion:String;
		private var isDebugger:Boolean;
		private var hasLocalStorage:Boolean;
		private var hasScriptAccess:Boolean;

		/**
		 * @param emitter Emitter to which events will be sent
		 * @param subject Subject to be tracked
		 * @param namespace Identifier for the Tracker instance
		 * @param appId Application ID
		 * @param stage The flash stage object.  used for adding stage info to payload.
		 * @param base64Encoded Whether JSONs in the payload should be base-64 encoded
		 */
		function Tracker(emitter:Emitter, subject:Subject, namespace:String, appId:String, stage:Stage = null, base64Encoded:Boolean = true) {
				this.emitter = emitter;
				this.appId = appId;
				this.base64Encoded = base64Encoded;
				this.namespace = namespace;
				this.subject = subject;
				this.trackerVersion = Version.TRACKER;
				this.platform = DevicePlatform.DESKTOP;
				this.stage = stage;

				this.playerType = Capabilities.playerType;
				this.playerVersion = Capabilities.version;
				this.isDebugger = Capabilities.isDebugger;
				try
				{
					SharedObject.getLocal("test");
					this.hasLocalStorage = true;
				}
				catch (e:Error)
				{
					this.hasLocalStorage = false;
				}
				this.hasScriptAccess = ExternalInterface.available;
			}

		/**
		 * @param payload Payload builder
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 * @return A completed Payload
		 */
		protected function completePayload(payload:IPayload,
										   context:Array,
										   timestamp:Number):IPayload {

				payload.add(Parameter.PLATFORM, this.platform);
				payload.add(Parameter.APPID, this.appId);
				payload.add(Parameter.NAMESPACE, this.namespace);
				payload.add(Parameter.TRACKER_VERSION, this.trackerVersion);
				payload.add(Parameter.EID, Util.getEventId());

				// If timestamp is set to 0, generate one
				payload.add(Parameter.TIMESTAMP,
					(timestamp == 0 ? Util.getTimestamp() : String(timestamp)));

				// Add flash information
				if (context == null) {
					context = [];
				}

				var flashData:TrackerPayload = new TrackerPayload();
				flashData.add(Parameter.FLASH_PLAYER_TYPE, playerType);
				flashData.add(Parameter.FLASH_VERSION, playerVersion);
				flashData.add(Parameter.FLASH_IS_DEBUGGER, isDebugger);
				flashData.add(Parameter.FLASH_HAS_LOCAL_STORAGE, hasLocalStorage);
				flashData.add(Parameter.FLASH_HAS_SCRIPT_ACCESS, hasScriptAccess);
				if (stage != null) {
					flashData.add(Parameter.FLASH_STAGE_SIZE, stage.stageWidth + "x" + stage.stageHeight);
				}

				var flashPayload:SchemaPayload = new SchemaPayload();
				flashPayload.setSchema(Constants.SCHEMA_FLASH);
				flashPayload.setData(flashData.getMap());

				context.push(flashPayload);

				// Encodes context data
				if (context != null && context.length > 0) {
					var envelope:SchemaPayload = new SchemaPayload();
					envelope.setSchema(Constants.SCHEMA_CONTEXTS);

					// We can do better here, rather than re-iterate through the list
					var contextDataList:Array = [];
					for each(var schemaPayload:SchemaPayload in context) {
						contextDataList.push(schemaPayload.getMap());
					}

					envelope.setData(contextDataList);
					payload.addMap(envelope.getMap(), this.base64Encoded, Parameter.CONTEXT_ENCODED, Parameter.CONTEXT);
				}

				if (this.subject != null) {
					payload.addMap(Util.copyObject(subject.getSubject(), true));
				}

				return payload;
			}

		public function setPlatform(platform:String):void {
			this.platform = platform;
		}

		public function getPlatform():String {
			return this.platform;
		}

		protected function setTrackerVersion(version:String):void {
			this.trackerVersion = version;
		}

		private function addTrackerPayload(payload:IPayload):void {
			this.emitter.addToBuffer(payload);
		}

		public function setSubject(subject:Subject):void {
			this.subject = subject;
		}

		public function getSubject():Subject {
			return this.subject;
		}

		/**
		 * @param pageUrl URL of the viewed page
		 * @param pageTitle Title of the viewed page
		 * @param referrer Referrer of the page
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackPageView(pageUrl:String, pageTitle:String, referrer:String, context:Array = null, timestamp:Number = 0):void
		{
			// Precondition checks
			Preconditions.checkNotNull(pageUrl);
			Preconditions.checkArgument(!Util.isNullOrEmpty(pageUrl), "pageUrl cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(pageTitle), "pageTitle cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(referrer), "referrer cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_PAGE_VIEW);
			payload.add(Parameter.PAGE_URL, pageUrl);
			payload.add(Parameter.PAGE_TITLE, pageTitle);
			payload.add(Parameter.PAGE_REFR, referrer);

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 * @param category Category of the event
		 * @param action The event itself
		 * @param label Refer to the object the action is performed on
		 * @param property Property associated with either the action or the object
		 * @param value A value associated with the user action
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackStructuredEvent(category:String,
			action:String,
			label:String,
			property:String,
			value:int,
			context:Array = null,
			timestamp:Number = 0):void
		{
			// Precondition checks
			Preconditions.checkNotNull(label);
			Preconditions.checkNotNull(property);
			Preconditions.checkArgument(!Util.isNullOrEmpty(label), "label cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(property), "property cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(category), "category cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(action), "action cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_STRUCTURED);
			payload.add(Parameter.SE_CATEGORY, category);
			payload.add(Parameter.SE_ACTION, action);
			payload.add(Parameter.SE_LABEL, label);
			payload.add(Parameter.SE_PROPERTY, property);
			payload.add(Parameter.SE_VALUE, String(value));

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 *
		 * @param eventData The properties of the event. Has two field:
		 *                   A "data" field containing the event properties and
		 *                   A "schema" field identifying the schema against which the data is validated
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackUnstructuredEvent(eventData:SchemaPayload, context:Array = null,
			timestamp:Number = 0):void
		{
			var payload:IPayload = new TrackerPayload();
			var envelope:SchemaPayload = new SchemaPayload();

			envelope.setSchema(Constants.SCHEMA_UNSTRUCT_EVENT);
			envelope.setData(eventData.getMap());

			payload.add(Parameter.EVENT, Constants.EVENT_UNSTRUCTURED);
			payload.addMap(envelope.getMap());

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 * This is an internal method called by track_ecommerce_transaction. It is not for public use.
		 * @param order_id Order ID
		 * @param sku Item SKU
		 * @param price Item price
		 * @param quantity Item quantity
		 * @param name Item name
		 * @param category Item category
		 * @param currency The currency the price is expressed in
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		protected function trackEcommerceTransactionItem(order_id:String, sku:String, price:Number,
			quantity:int, name:String, category:String,
			currency:String, context:Array,
			timestamp:Number):void
		{
			// Precondition checks
			Preconditions.checkNotNull(name);
			Preconditions.checkNotNull(category);
			Preconditions.checkNotNull(currency);
			Preconditions.checkArgument(!Util.isNullOrEmpty(order_id), "order_id cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(sku), "sku cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(name), "name cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(category), "category cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(currency), "currency cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_ECOMM_ITEM);
			payload.add(Parameter.TI_ITEM_ID, order_id);
			payload.add(Parameter.TI_ITEM_SKU, sku);
			payload.add(Parameter.TI_ITEM_NAME, name);
			payload.add(Parameter.TI_ITEM_CATEGORY, category);
			payload.add(Parameter.TI_ITEM_PRICE, String(price));
			payload.add(Parameter.TI_ITEM_QUANTITY, String(quantity));
			payload.add(Parameter.TI_ITEM_CURRENCY, currency);

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 * @param order_id ID of the eCommerce transaction
		 * @param total_value Total transaction value
		 * @param affiliation Transaction affiliation
		 * @param tax_value Transaction tax value
		 * @param shipping Delivery cost charged
		 * @param city Delivery address city
		 * @param state Delivery address state
		 * @param country Delivery address country
		 * @param currency The currency the price is expressed in
		 * @param items The items in the transaction
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackEcommerceTransaction(order_id:String, total_value:Number, affiliation:String,
			tax_value:Number, shipping:Number, city:String,
			state:String, country:String, currency:String,
			items:Array, context:Array = null,
			timestamp:Number = 0):void
		{
			// Precondition checks
			Preconditions.checkNotNull(affiliation);
			Preconditions.checkNotNull(city);
			Preconditions.checkNotNull(state);
			Preconditions.checkNotNull(country);
			Preconditions.checkNotNull(currency);
			Preconditions.checkArgument(!Util.isNullOrEmpty(order_id), "order_id cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(affiliation), "affiliation cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(city), "city cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(state), "state cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(country), "country cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(currency), "currency cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_ECOMM);
			payload.add(Parameter.TR_ID, order_id);
			payload.add(Parameter.TR_TOTAL, String(total_value));
			payload.add(Parameter.TR_AFFILIATION, affiliation);
			payload.add(Parameter.TR_TAX, String(tax_value));
			payload.add(Parameter.TR_SHIPPING, String(shipping));
			payload.add(Parameter.TR_CITY, city);
			payload.add(Parameter.TR_STATE, state);
			payload.add(Parameter.TR_COUNTRY, country);
			payload.add(Parameter.TR_CURRENCY, currency);

			completePayload(payload, context, timestamp);

			for each(var item:TransactionItem in items) {
				trackEcommerceTransactionItem(
					String(item.get(Parameter.TI_ITEM_ID)),
					String(item.get(Parameter.TI_ITEM_SKU)),
					Number(item.get(Parameter.TI_ITEM_PRICE)),
					parseInt(item.get(Parameter.TI_ITEM_QUANTITY)),
					String(item.get(Parameter.TI_ITEM_NAME)),
					String(item.get(Parameter.TI_ITEM_CATEGORY)),
					String(item.get(Parameter.TI_ITEM_CURRENCY)),
					item.get(Parameter.CONTEXT),
					timestamp);
			}

			addTrackerPayload(payload);
		}

		/**
		 * @param name The name of the screen view event
		 * @param id Screen view ID
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackScreenView(name:String, id:String, context:Array,
			timestamp:Number):void {
				Preconditions.checkArgument(name != null || id != null);
				var trackerPayload:TrackerPayload = new TrackerPayload();

				trackerPayload.add(Parameter.SV_NAME, name);
				trackerPayload.add(Parameter.SV_ID, id);

				var payload:SchemaPayload = new SchemaPayload();
				payload.setSchema(Constants.SCHEMA_SCREEN_VIEW);
				payload.setData(trackerPayload);

				trackUnstructuredEvent(payload, context, timestamp);
			}
	}
}

/*
* Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/

package com.snowplowanalytics.snowplow.tracker
{
	import com.snowplowanalytics.snowplow.tracker.emitter.Emitter;
	import com.snowplowanalytics.snowplow.tracker.payload.IPayload;
	import com.snowplowanalytics.snowplow.tracker.payload.SchemaPayload;
	import com.snowplowanalytics.snowplow.tracker.payload.TrackerPayload;
	import com.snowplowanalytics.snowplow.tracker.util.Preconditions;

	import flash.display.Stage;
	import flash.external.ExternalInterface;
	import flash.net.LocalConnection;
	import flash.net.SharedObject;
	import flash.system.Capabilities;

	public class Tracker
	{
		private var base64Encoded:Boolean = true;
		private var emitter:Emitter;
		private var platform:String;
		private var appId:String;
		private var namespace:String;
		private var trackerVersion:String;
		private var subject:Subject;
		private var stage:Stage;

		private var playerType:String;
		private var playerVersion:String;
		private var isDebugger:Boolean;
		private var hasLocalStorage:Boolean;
		private var hasScriptAccess:Boolean;

		/**
		 * @param emitter Emitter to which events will be sent
		 * @param subject Subject to be tracked
		 * @param namespace Identifier for the Tracker instance
		 * @param appId Application ID
		 * @param stage The flash stage object.  used for adding stage info to payload.
		 * @param base64Encoded Whether JSONs in the payload should be base-64 encoded
		 */
		function Tracker(emitter:Emitter, subject:Subject, namespace:String, appId:String, stage:Stage = null, base64Encoded:Boolean = true) {
				this.emitter = emitter;
				this.appId = appId;
				this.base64Encoded = base64Encoded;
				this.namespace = namespace;
				this.subject = subject;
				this.trackerVersion = Version.TRACKER;
				this.platform = DevicePlatform.DESKTOP;
				this.stage = stage;

				this.playerType = Capabilities.playerType;
				this.playerVersion = Capabilities.version;
				this.isDebugger = Capabilities.isDebugger;

				try
				{
					SharedObject.getLocal("test");
					this.hasLocalStorage = true;
				}
				catch (e:Error)
				{
					this.hasLocalStorage = false;
				}
				this.hasScriptAccess = ExternalInterface.available;
			}

		/**
		 * @param payload Payload builder
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 * @return A completed Payload
		 */
		protected function completePayload(payload:IPayload,
										   context:Array,
										   timestamp:Number):IPayload {

				payload.add(Parameter.PLATFORM, this.platform);
				payload.add(Parameter.APPID, this.appId);
				payload.add(Parameter.NAMESPACE, this.namespace);
				payload.add(Parameter.TRACKER_VERSION, this.trackerVersion);
				payload.add(Parameter.EID, Util.getEventId());

				// If timestamp is set to 0, generate one
				payload.add(Parameter.TIMESTAMP,
					(timestamp == 0 ? Util.getTimestamp() : String(timestamp)));

				// Add flash information
				if (context == null) {
					context = [];
				}

				var flashData:TrackerPayload = new TrackerPayload();
				flashData.add(Parameter.FLASH_PLAYER_TYPE, playerType);
				flashData.add(Parameter.FLASH_VERSION, playerVersion);
				flashData.add(Parameter.FLASH_IS_DEBUGGER, isDebugger);
				flashData.add(Parameter.FLASH_HAS_LOCAL_STORAGE, hasLocalStorage);
				flashData.add(Parameter.FLASH_HAS_SCRIPT_ACCESS, hasScriptAccess);
				if (stage != null) {
					flashData.add(Parameter.FLASH_STAGE_SIZE, { "width": stage.stageWidth, "height": stage.stageHeight});
				}

				var flashPayload:SchemaPayload = new SchemaPayload();
				flashPayload.setSchema(Constants.SCHEMA_FLASH);
				flashPayload.setData(flashData.getMap());

				context.push(flashPayload);

				// Encodes context data
				if (context != null && context.length > 0) {
					var envelope:SchemaPayload = new SchemaPayload();
					envelope.setSchema(Constants.SCHEMA_CONTEXTS);

					// We can do better here, rather than re-iterate through the list
					var contextDataList:Array = [];
					for each(var schemaPayload:SchemaPayload in context) {
						contextDataList.push(schemaPayload.getMap());
					}

					envelope.setData(contextDataList);
					payload.addMap(envelope.getMap(), this.base64Encoded, Parameter.CONTEXT_ENCODED, Parameter.CONTEXT);
				}

				if (this.subject != null) {
					payload.addMap(Util.copyObject(subject.getSubject(), true));
				}

				return payload;
			}

		public function setPlatform(platform:String):void {
			this.platform = platform;
		}

		public function getPlatform():String {
			return this.platform;
		}

		protected function setTrackerVersion(version:String):void {
			this.trackerVersion = version;
		}

		private function addTrackerPayload(payload:IPayload):void {
			this.emitter.addToBuffer(payload);
		}

		public function setSubject(subject:Subject):void {
			this.subject = subject;
		}

		public function getSubject():Subject {
			return this.subject;
		}

		/**
		 * @param pageUrl URL of the viewed page
		 * @param pageTitle Title of the viewed page
		 * @param referrer Referrer of the page
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackPageView(pageUrl:String, pageTitle:String, referrer:String, context:Array = null, timestamp:Number = 0):void
		{
			// Precondition checks
			Preconditions.checkNotNull(pageUrl);
			Preconditions.checkArgument(!Util.isNullOrEmpty(pageUrl), "pageUrl cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(pageTitle), "pageTitle cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(referrer), "referrer cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_PAGE_VIEW);
			payload.add(Parameter.PAGE_URL, pageUrl);
			payload.add(Parameter.PAGE_TITLE, pageTitle);
			payload.add(Parameter.PAGE_REFR, referrer);

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 * @param category Category of the event
		 * @param action The event itself
		 * @param label Refer to the object the action is performed on
		 * @param property Property associated with either the action or the object
		 * @param value A value associated with the user action
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackStructuredEvent(category:String,
			action:String,
			label:String,
			property:String,
			value:int,
			context:Array = null,
			timestamp:Number = 0):void
		{
			// Precondition checks
			Preconditions.checkNotNull(label);
			Preconditions.checkNotNull(property);
			Preconditions.checkArgument(!Util.isNullOrEmpty(label), "label cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(property), "property cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(category), "category cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(action), "action cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_STRUCTURED);
			payload.add(Parameter.SE_CATEGORY, category);
			payload.add(Parameter.SE_ACTION, action);
			payload.add(Parameter.SE_LABEL, label);
			payload.add(Parameter.SE_PROPERTY, property);
			payload.add(Parameter.SE_VALUE, String(value));

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 *
		 * @param eventData The properties of the event. Has two field:
		 *                   A "data" field containing the event properties and
		 *                   A "schema" field identifying the schema against which the data is validated
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackUnstructuredEvent(eventData:SchemaPayload, context:Array = null,
			timestamp:Number = 0):void
		{
			var payload:IPayload = new TrackerPayload();
			var envelope:SchemaPayload = new SchemaPayload();

			envelope.setSchema(Constants.SCHEMA_UNSTRUCT_EVENT);
			envelope.setData(eventData.getMap());

			payload.add(Parameter.EVENT, Constants.EVENT_UNSTRUCTURED);
			payload.addMap(envelope.getMap());

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 * This is an internal method called by track_ecommerce_transaction. It is not for public use.
		 * @param order_id Order ID
		 * @param sku Item SKU
		 * @param price Item price
		 * @param quantity Item quantity
		 * @param name Item name
		 * @param category Item category
		 * @param currency The currency the price is expressed in
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		protected function trackEcommerceTransactionItem(order_id:String, sku:String, price:Number,
			quantity:int, name:String, category:String,
			currency:String, context:Array,
			timestamp:Number):void
		{
			// Precondition checks
			Preconditions.checkNotNull(name);
			Preconditions.checkNotNull(category);
			Preconditions.checkNotNull(currency);
			Preconditions.checkArgument(!Util.isNullOrEmpty(order_id), "order_id cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(sku), "sku cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(name), "name cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(category), "category cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(currency), "currency cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_ECOMM_ITEM);
			payload.add(Parameter.TI_ITEM_ID, order_id);
			payload.add(Parameter.TI_ITEM_SKU, sku);
			payload.add(Parameter.TI_ITEM_NAME, name);
			payload.add(Parameter.TI_ITEM_CATEGORY, category);
			payload.add(Parameter.TI_ITEM_PRICE, String(price));
			payload.add(Parameter.TI_ITEM_QUANTITY, String(quantity));
			payload.add(Parameter.TI_ITEM_CURRENCY, currency);

			completePayload(payload, context, timestamp);

			addTrackerPayload(payload);
		}

		/**
		 * @param order_id ID of the eCommerce transaction
		 * @param total_value Total transaction value
		 * @param affiliation Transaction affiliation
		 * @param tax_value Transaction tax value
		 * @param shipping Delivery cost charged
		 * @param city Delivery address city
		 * @param state Delivery address state
		 * @param country Delivery address country
		 * @param currency The currency the price is expressed in
		 * @param items The items in the transaction
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackEcommerceTransaction(order_id:String, total_value:Number, affiliation:String,
			tax_value:Number, shipping:Number, city:String,
			state:String, country:String, currency:String,
			items:Array, context:Array = null,
			timestamp:Number = 0):void
		{
			// Precondition checks
			Preconditions.checkNotNull(affiliation);
			Preconditions.checkNotNull(city);
			Preconditions.checkNotNull(state);
			Preconditions.checkNotNull(country);
			Preconditions.checkNotNull(currency);
			Preconditions.checkArgument(!Util.isNullOrEmpty(order_id), "order_id cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(affiliation), "affiliation cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(city), "city cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(state), "state cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(country), "country cannot be empty");
			Preconditions.checkArgument(!Util.isNullOrEmpty(currency), "currency cannot be empty");

			var payload:IPayload = new TrackerPayload();
			payload.add(Parameter.EVENT, Constants.EVENT_ECOMM);
			payload.add(Parameter.TR_ID, order_id);
			payload.add(Parameter.TR_TOTAL, String(total_value));
			payload.add(Parameter.TR_AFFILIATION, affiliation);
			payload.add(Parameter.TR_TAX, String(tax_value));
			payload.add(Parameter.TR_SHIPPING, String(shipping));
			payload.add(Parameter.TR_CITY, city);
			payload.add(Parameter.TR_STATE, state);
			payload.add(Parameter.TR_COUNTRY, country);
			payload.add(Parameter.TR_CURRENCY, currency);

			completePayload(payload, context, timestamp);

			for each(var item:TransactionItem in items) {
				trackEcommerceTransactionItem(
					String(item.get(Parameter.TI_ITEM_ID)),
					String(item.get(Parameter.TI_ITEM_SKU)),
					Number(item.get(Parameter.TI_ITEM_PRICE)),
					parseInt(item.get(Parameter.TI_ITEM_QUANTITY)),
					String(item.get(Parameter.TI_ITEM_NAME)),
					String(item.get(Parameter.TI_ITEM_CATEGORY)),
					String(item.get(Parameter.TI_ITEM_CURRENCY)),
					item.get(Parameter.CONTEXT),
					timestamp);
			}

			addTrackerPayload(payload);
		}

		/**
		 * @param name The name of the screen view event
		 * @param id Screen view ID
		 * @param context Custom context for the event
		 * @param timestamp Optional user-provided timestamp for the event
		 */
		public function trackScreenView(name:String, id:String, context:Array,
			timestamp:Number):void {
				Preconditions.checkArgument(name != null || id != null);
				var trackerPayload:TrackerPayload = new TrackerPayload();

				trackerPayload.add(Parameter.SV_NAME, name);
				trackerPayload.add(Parameter.SV_ID, id);

				var payload:SchemaPayload = new SchemaPayload();
				payload.setSchema(Constants.SCHEMA_SCREEN_VIEW);
				payload.setData(trackerPayload);

				trackUnstructuredEvent(payload, context, timestamp);
			}
	}
}

fix format of FLASH_STAGE_SIZE parameter


import mx.transitions.easing.*;
import com.mosesSupposes.fuse.*;

class menuColouridiomes extends MovieClip

	{
		public var cat, es, en ,fr:MovieClip;
		public var arrayLang_arr:Array = new Array ("cat", "es", "en", "fr");

		function menuColourIdiomes ():Void

		{

		this.onRollOver = this.mOver;
		this.onRollOut = this.mOut;
		this.onRelease =this.mOver;

		}

		private function mOver()

		{
			var i:Number;

				for (var i = 0; i < arrayLang_arr.length; i++)
				{
	                		arrayLang_arr[i].colorTo("#95C60D", 0.3, "easeOutCirc");
	                	]

		}

		private function mOut()

		{
			var i:Number;

				for (var i = 0; i < arrayLang_arr.length; i++)
				{
			                arrayLang_arr[i].colorTo("#010101", 0.3, "easeInCirc");
	                	}

		}

	}

import mx.transitions.easing.*;
import com.mosesSupposes.fuse.*;

class menuColouridiomes extends MovieClip

	{
		public var cat, es, en ,fr:MovieClip;
		public var arrayLang_arr:Array = new Array ("cat", "es", "en", "fr");

	public function menuColourIdiomes ()
		{

		this.onRollOver = this.mOver;
		this.onRollOut = this.mOut;
		this.onRelease =this.mOver;

		}

		private function mOver()
		{
			var i:Number;

				for (var i = 0; i < arrayLang_arr.length; i++)
				{
	                		arrayLang_arr[i].colorTo("#95C60D", 0.3, "easeOutCirc");
	                	]

		}

		private function mOut()
		{
			var i:Number;

				for (var i = 0; i < arrayLang_arr.length; i++)
				{
			                arrayLang_arr[i].colorTo("#010101", 0.3, "easeInCirc");
	                	}

		}

	}

Update menuColourIdiomes.as

Update menuColourIdiomes.as


////////////////////////////////////////////////////////////////////////////////
//
//  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 spark.skins.mobile
{
import flash.display.DisplayObject;
import flash.display.Graphics;

import mx.core.DPIClassification;
import mx.core.mx_internal;

import spark.skins.mobile.assets.TransparentNavigationButton_down;
import spark.skins.mobile.assets.TransparentNavigationButton_up;
import spark.skins.mobile.supportClasses.ActionBarButtonSkinBase;
import spark.skins.mobile.supportClasses.MobileSkin;
import spark.skins.mobile320.assets.TransparentNavigationButton_down;
import spark.skins.mobile320.assets.TransparentNavigationButton_up;
import spark.skins.mobile480.assets.TransparentNavigationButton_down;
import spark.skins.mobile480.assets.TransparentNavigationButton_up;
import spark.skins.mobile640.assets.TransparentNavigationButton_down;
import spark.skins.mobile640.assets.TransparentNavigationButton_up;

use namespace mx_internal;

/**
 *  The default skin class for buttons in the navigation area of the Spark ActionBar component
 *  in mobile applications.
 *
 *  @langversion 3.0
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class TransparentNavigationButtonSkin extends ActionBarButtonSkinBase
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     */
    public function TransparentNavigationButtonSkin()
    {
        super();

        switch (applicationDPI)
        {
			case DPIClassification.DPI_640:
			{
				upBorderSkin = spark.skins.mobile640.assets.TransparentActionButton_up;
				downBorderSkin = spark.skins.mobile640.assets.TransparentActionButton_down;

				break;
			}
			case DPIClassification.DPI_480:
			{
				upBorderSkin = spark.skins.mobile480.assets.TransparentActionButton_up;
				downBorderSkin = spark.skins.mobile480.assets.TransparentActionButton_down;

				break;
			}
            case DPIClassification.DPI_320:
            {
                upBorderSkin = spark.skins.mobile320.assets.TransparentNavigationButton_up;
                downBorderSkin = spark.skins.mobile320.assets.TransparentNavigationButton_down;

                break;
            }
            default:
            {
                upBorderSkin = spark.skins.mobile.assets.TransparentNavigationButton_up;
                downBorderSkin = spark.skins.mobile.assets.TransparentNavigationButton_down;

                break;
            }
        }
    }

    override mx_internal function layoutBorder(unscaledWidth:Number, unscaledHeight:Number):void
    {
        // trailing vertical separator is outside the right bounds of the button
        setElementSize(border, unscaledWidth + layoutBorderSize, unscaledHeight);
        setElementPosition(border, 0, 0);
    }
}
}

////////////////////////////////////////////////////////////////////////////////
//
//  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 spark.skins.android4
{
import flash.display.DisplayObject;
import flash.display.Graphics;

import mx.core.DPIClassification;
import mx.core.mx_internal;

import spark.skins.mobile.assets.TransparentNavigationButton_down;
import spark.skins.mobile.assets.TransparentNavigationButton_up;
import spark.skins.mobile.supportClasses.ActionBarButtonSkinBase;
import spark.skins.mobile.supportClasses.MobileSkin;
import spark.skins.mobile320.assets.TransparentNavigationButton_down;
import spark.skins.mobile320.assets.TransparentNavigationButton_up;
import spark.skins.mobile480.assets.TransparentNavigationButton_down;
import spark.skins.mobile480.assets.TransparentNavigationButton_up;
import spark.skins.mobile640.assets.TransparentNavigationButton_down;
import spark.skins.mobile640.assets.TransparentNavigationButton_up;

use namespace mx_internal;

/**
 *  The default skin class for buttons in the navigation area of the Spark ActionBar component
 *  in mobile applications.
 *
 *  @langversion 3.0
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class TransparentNavigationButtonSkin extends ActionBarButtonSkinBase
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     */
    public function TransparentNavigationButtonSkin()
    {
        super();

        switch (applicationDPI)
        {
			case DPIClassification.DPI_640:
			{
				upBorderSkin = spark.skins.mobile640.assets.TransparentActionButton_up;
				downBorderSkin = spark.skins.mobile640.assets.TransparentActionButton_down;

				break;
			}
			case DPIClassification.DPI_480:
			{
				upBorderSkin = spark.skins.mobile480.assets.TransparentActionButton_up;
				downBorderSkin = spark.skins.mobile480.assets.TransparentActionButton_down;

				break;
			}
            case DPIClassification.DPI_320:
            {
                upBorderSkin = spark.skins.mobile320.assets.TransparentNavigationButton_up;
                downBorderSkin = spark.skins.mobile320.assets.TransparentNavigationButton_down;

                break;
            }
            default:
            {
                upBorderSkin = spark.skins.mobile.assets.TransparentNavigationButton_up;
                downBorderSkin = spark.skins.mobile.assets.TransparentNavigationButton_down;

                break;
            }
        }
    }

    override mx_internal function layoutBorder(unscaledWidth:Number, unscaledHeight:Number):void
    {
        // trailing vertical separator is outside the right bounds of the button
        setElementSize(border, unscaledWidth + layoutBorderSize, unscaledHeight);
        setElementPosition(border, 0, 0);
    }
}
}

Move to correct package

Move to correct package


////////////////////////////////////////////////////////////////////////////////
//
//  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.effects
{

import flash.display.DisplayObject;
import flash.geom.Rectangle;

import org.apache.flex.core.IDocument;
import org.apache.flex.core.IUIBase;

/**
 *  Helper class for Wipe effects.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 */
public class PlatformWiper
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function PlatformWiper()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

	/**
	 *  @private
	 *  The target.
	 */
	private var _target:IUIBase;

    /**
     *  The object that will be clipped.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function set target(value:IUIBase):void
    {
        _target = value;
        if (value == null)
            DisplayObject(_target).scrollRect = null;
    }

    /**
     *  The visible rectangle.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function set visibleRect(value:Rectangle):void
    {
        DisplayObject(_target).scrollRect = value;
    }
}

}

////////////////////////////////////////////////////////////////////////////////
//
//  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.effects
{

import flash.display.DisplayObject;
import flash.geom.Rectangle;

import org.apache.flex.core.IDocument;
import org.apache.flex.core.IUIBase;

/**
 *  Helper class for Wipe effects.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 */
public class PlatformWiper
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function PlatformWiper()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

	/**
	 *  @private
	 *  The target.
	 */
	private var _target:IUIBase;

    /**
     *  The object that will be clipped.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function set target(value:IUIBase):void
    {
        if (value == null)
            DisplayObject(_target).scrollRect = null;
        _target = value;
    }

    /**
     *  The visible rectangle.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function set visibleRect(value:Rectangle):void
    {
        DisplayObject(_target).scrollRect = value;
    }
}

}

fix platform wiper

fix platform wiper


package dolly {
import dolly.core.dolly_internal;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertNotNull;

use namespace dolly_internal;

public class ClonerTest {

	private var classMarkedAsCloneable:ClassMarkedAsCloneable;
	private var classWithSomeCloneableFields:ClassWithSomeCloneableFields;
	private var classMarkedAsCloneableType:Type;
	private var classWithSomeCloneableFieldsType:Type;

	[Before]
	public function before():void {
		classMarkedAsCloneable = new ClassMarkedAsCloneable();
		classMarkedAsCloneable.property1 = "value 1";
		classMarkedAsCloneable.property2 = "value 2";
		classMarkedAsCloneable.property3 = "value 3";
		classMarkedAsCloneable.writableField = "value 4";

		classWithSomeCloneableFields = new ClassWithSomeCloneableFields();
		classWithSomeCloneableFieldsType = Type.forInstance(classWithSomeCloneableFields);
	}

	[After]
	public function after():void {
		classMarkedAsCloneable = null;
		classWithSomeCloneableFields = null;
		classMarkedAsCloneableType = null;
		classWithSomeCloneableFieldsType = null;
	}

	[Test]
	public function testGetCloneableFields():void {
		var cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(classMarkedAsCloneableType);

		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);

		cloneableFields = Cloner.getCloneableFieldsForType(classWithSomeCloneableFieldsType);

		assertNotNull(cloneableFields);
		assertEquals(3, cloneableFields.length);
	}

	[Test]
	public function testCloneClassLevelMetadata():void {
		const clone1:ClassMarkedAsCloneable = Cloner.clone(classMarkedAsCloneable) as ClassMarkedAsCloneable;

		assertNotNull(clone1);
		assertNotNull(clone1.property1);
		assertEquals(clone1.property1, classMarkedAsCloneable.property1);
		assertNotNull(clone1.property2);
		assertEquals(clone1.property2, classMarkedAsCloneable.property2);
		assertNotNull(clone1.property3);
		assertEquals(clone1.property3, classMarkedAsCloneable.property3);
		assertNotNull(clone1.writableField);
		assertEquals(clone1.writableField, classMarkedAsCloneable.writableField);
	}
}
}

package dolly {
import dolly.core.dolly_internal;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertNull;

use namespace dolly_internal;

public class ClonerTest {

	private var classMarkedAsCloneable:ClassMarkedAsCloneable;
	private var classWithSomeCloneableFields:ClassWithSomeCloneableFields;
	private var classMarkedAsCloneableType:Type;
	private var classWithSomeCloneableFieldsType:Type;

	[Before]
	public function before():void {
		classMarkedAsCloneable = new ClassMarkedAsCloneable();
		classMarkedAsCloneable.property1 = "value 1";
		classMarkedAsCloneable.property2 = "value 2";
		classMarkedAsCloneable.property3 = "value 3";
		classMarkedAsCloneable.writableField = "value 4";

		classWithSomeCloneableFields = new ClassWithSomeCloneableFields();
		classWithSomeCloneableFields.property1 = "value 1";
		classWithSomeCloneableFields.property2 = "value 2";
		classWithSomeCloneableFields.property3 = "value 3";
		classWithSomeCloneableFields.writableField = "value 4";

		classMarkedAsCloneableType = Type.forInstance(classMarkedAsCloneable);
		classWithSomeCloneableFieldsType = Type.forInstance(classWithSomeCloneableFields);
	}

	[After]
	public function after():void {
		classMarkedAsCloneable = null;
		classWithSomeCloneableFields = null;
		classMarkedAsCloneableType = null;
		classWithSomeCloneableFieldsType = null;
	}

	[Test]
	public function testGetCloneableFields():void {
		var cloneableFields:Vector.<Field> = Cloner.getCloneableFieldsForType(classMarkedAsCloneableType);

		assertNotNull(cloneableFields);
		assertEquals(4, cloneableFields.length);

		cloneableFields = Cloner.getCloneableFieldsForType(classWithSomeCloneableFieldsType);

		assertNotNull(cloneableFields);
		assertEquals(3, cloneableFields.length);
	}

	[Test]
	public function testCloneWithClassLevelMetadata():void {
		const clone1:ClassMarkedAsCloneable = Cloner.clone(classMarkedAsCloneable) as ClassMarkedAsCloneable;

		assertNotNull(clone1);
		assertNotNull(clone1.property1);
		assertEquals(clone1.property1, classMarkedAsCloneable.property1);
		assertNotNull(clone1.property2);
		assertEquals(clone1.property2, classMarkedAsCloneable.property2);
		assertNotNull(clone1.property3);
		assertEquals(clone1.property3, classMarkedAsCloneable.property3);
		assertNotNull(clone1.writableField);
		assertEquals(clone1.writableField, classMarkedAsCloneable.writableField);
	}

	public function testCloneWithPropertyLevelMetadata():void {
		const clone2:ClassWithSomeCloneableFields = Cloner.clone(
				classWithSomeCloneableFields
		) as ClassWithSomeCloneableFields;

		assertNotNull(clone2);
		assertNull(clone2.property1);
		assertNotNull(clone2.property2);
		assertEquals(clone2.property2, classWithSomeCloneableFields.property2);
		assertNotNull(clone2.property3);
		assertEquals(clone2.property3, classWithSomeCloneableFields.property3);
		assertNotNull(clone2.writableField);
		assertEquals(clone2.writableField, classWithSomeCloneableFields.writableField);
	}
}
}

Add test method for cloning by using property-level metadata tags.


////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008-2013 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 com.esri.builder.controllers.supportClasses
{

import com.esri.builder.model.WidgetType;
import com.esri.builder.model.WidgetTypeRegistryModel;
import com.esri.builder.supportClasses.FileUtil;
import com.esri.builder.supportClasses.LogUtil;
import com.esri.builder.views.BuilderAlert;

import flash.events.EventDispatcher;
import flash.filesystem.File;
import flash.utils.Dictionary;

import mx.logging.ILogger;
import mx.logging.Log;
import mx.resources.ResourceManager;

public class StartupWidgetTypeLoader extends EventDispatcher
{
    private static const LOG:ILogger = LogUtil.createLogger(StartupWidgetTypeLoader);

    private var widgetTypeArr:Array = [];
    private var pendingLoaders:Array;

    public function loadWidgetTypes():void
    {
        if (Log.isInfo())
        {
            LOG.info('Loading modules...');
        }

        var moduleFiles:Array = getModuleFiles(WellKnownDirectories.getInstance().bundledModules)
            .concat(getModuleFiles(WellKnownDirectories.getInstance().customModules));

        var swfFileAndXMLFileMaps:Array = mapFilenameToModuleSWFAndXMLFiles(moduleFiles);

        var processedFileNames:Array = [];
        var loaders:Array = [];

        for each (var moduleFile:File in moduleFiles)
        {
            var fileName:String = FileUtil.getFileName(moduleFile);

            if (Log.isDebug())
            {
                LOG.debug('loading module {0}', fileName);
            }

            if (processedFileNames.indexOf(fileName) == -1)
            {
                processedFileNames.push(fileName);
                loaders.push(new WidgetTypeLoader(swfFileAndXMLFileMaps[0][fileName],
                                                  swfFileAndXMLFileMaps[1][fileName]));
            }
        }

        pendingLoaders = loaders;
        for each (var loader:WidgetTypeLoader in loaders)
        {
            loader.addEventListener(WidgetTypeLoaderEvent.LOAD_COMPLETE, loader_loadCompleteHandler);
            loader.addEventListener(WidgetTypeLoaderEvent.LOAD_ERROR, loader_loadErrorHandler);
            loader.load();
        }

        checkIfWidgetTypeLoadersComplete();
    }

    private function mapFilenameToModuleSWFAndXMLFiles(moduleFiles:Array):Array
    {
        var uniqueFileNameToSWF:Dictionary = new Dictionary();
        var uniqueFileNameToXML:Dictionary = new Dictionary();

        for each (var file:File in moduleFiles)
        {
            if (file.extension == "swf")
            {
                uniqueFileNameToSWF[FileUtil.getFileName(file)] = file;
            }
            else if (file.extension == "xml")
            {
                uniqueFileNameToXML[FileUtil.getFileName(file)] = file;
            }
        }

        return [ uniqueFileNameToSWF, uniqueFileNameToXML ];
    }

    private function getModuleFiles(directory:File):Array
    {
        var moduleFiles:Array = [];

        if (directory.isDirectory)
        {
            const files:Array = directory.getDirectoryListing();

            for each (var file:File in files)
            {
                if (file.isDirectory)
                {
                    moduleFiles = moduleFiles.concat(getModuleFiles(file));
                }
                else if (isModuleFile(file))
                {
                    moduleFiles.push(file);
                }
            }
        }

        return moduleFiles;
    }

    private function isModuleFile(file:File):Boolean
    {
        const moduleFileName:RegExp = /^.*Module\.(swf|xml)$/;
        return !file.isDirectory && (moduleFileName.test(file.name));
    }

    private function checkIfWidgetTypeLoadersComplete():void
    {
        if (pendingLoaders.length === 0)
        {
            sortAndAssignWidgetTypes();
        }
    }

    private function markModuleAsLoaded(loader:WidgetTypeLoader):void
    {
        var loaderIndex:int = pendingLoaders.indexOf(loader);
        if (loaderIndex > -1)
        {
            pendingLoaders.splice(loaderIndex, 1);
        }
    }

    private function sortAndAssignWidgetTypes():void
    {
        if (Log.isInfo())
        {
            LOG.info('All modules resolved');
        }

        var widgetTypes:Array = widgetTypeArr.filter(widgetTypeFilter);
        for each (var widgetType:WidgetType in widgetTypes)
        {
            WidgetTypeRegistryModel.getInstance().widgetTypeRegistry.addWidgetType(widgetType);
        }

        var layoutWidgetTypes:Array = widgetTypeArr.filter(layoutWidgetTypeFilter);
        for each (var layoutWidgetType:WidgetType in layoutWidgetTypes)
        {
            WidgetTypeRegistryModel.getInstance().layoutWidgetTypeRegistry.addWidgetType(layoutWidgetType);
        }

        function widgetTypeFilter(item:WidgetType, index:int, source:Array):Boolean
        {
            return item.isManaged;
        }
        function layoutWidgetTypeFilter(item:WidgetType, index:int, source:Array):Boolean
        {
            return !item.isManaged;
        }

        WidgetTypeRegistryModel.getInstance().widgetTypeRegistry.sort();
        WidgetTypeRegistryModel.getInstance().layoutWidgetTypeRegistry.sort();

        dispatchEvent(new WidgetTypeLoaderEvent(WidgetTypeLoaderEvent.LOAD_TYPES_COMPLETE));
    }

    private function loader_loadCompleteHandler(event:WidgetTypeLoaderEvent):void
    {
        var loader:WidgetTypeLoader = event.currentTarget as WidgetTypeLoader;
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_COMPLETE, loader_loadCompleteHandler);
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_ERROR, loader_loadErrorHandler);

        var widgetType:WidgetType = event.widgetType;

        if (Log.isDebug())
        {
            LOG.debug('Module {0} is resolved', widgetType.name);
        }

        widgetTypeArr.push(widgetType);
        markModuleAsLoaded(loader);
        checkIfWidgetTypeLoadersComplete();
    }

    private function loader_loadErrorHandler(event:WidgetTypeLoaderEvent):void
    {
        var loader:WidgetTypeLoader = event.currentTarget as WidgetTypeLoader;
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_COMPLETE, loader_loadCompleteHandler);
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_ERROR, loader_loadErrorHandler);

        var errorMessage:String = ResourceManager.getInstance().getString('BuilderStrings',
                                                                          'importWidgetProcess.couldNotLoadCustomWidgets',
                                                                          [ loader.name ]);

        if (Log.isDebug())
        {
            LOG.debug(errorMessage);
        }

        BuilderAlert.show(errorMessage,
                          ResourceManager.getInstance().getString('BuilderStrings', 'error'));
        markModuleAsLoaded(loader);
        checkIfWidgetTypeLoadersComplete();
    }
}
}

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008-2013 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 com.esri.builder.controllers.supportClasses
{

import com.esri.builder.model.WidgetType;
import com.esri.builder.model.WidgetTypeRegistryModel;
import com.esri.builder.supportClasses.FileUtil;
import com.esri.builder.supportClasses.LogUtil;
import com.esri.builder.views.BuilderAlert;

import flash.events.EventDispatcher;
import flash.filesystem.File;
import flash.utils.Dictionary;

import mx.logging.ILogger;
import mx.logging.Log;
import mx.resources.ResourceManager;

public class StartupWidgetTypeLoader extends EventDispatcher
{
    private static const LOG:ILogger = LogUtil.createLogger(StartupWidgetTypeLoader);

    private var widgetTypeArr:Array = [];
    private var pendingLoaders:Array;

    public function loadWidgetTypes():void
    {
        if (Log.isInfo())
        {
            LOG.info('Loading modules...');
        }

        var moduleFiles:Array = getModuleFiles(WellKnownDirectories.getInstance().bundledModules)
            .concat(getModuleFiles(WellKnownDirectories.getInstance().customModules));

        var swfFileAndXMLFileMaps:Array = mapFilenameToModuleSWFAndXMLFiles(moduleFiles);

        var processedFileNames:Array = [];
        var loaders:Array = [];

        for each (var moduleFile:File in moduleFiles)
        {
            var fileName:String = FileUtil.getFileName(moduleFile);

            if (Log.isDebug())
            {
                LOG.debug('loading module {0}', fileName);
            }

            if (processedFileNames.indexOf(fileName) == -1)
            {
                processedFileNames.push(fileName);
                loaders.push(new WidgetTypeLoader(swfFileAndXMLFileMaps[0][fileName],
                                                  swfFileAndXMLFileMaps[1][fileName]));
            }
        }

        pendingLoaders = loaders;
        for each (var loader:WidgetTypeLoader in loaders)
        {
            loader.addEventListener(WidgetTypeLoaderEvent.LOAD_COMPLETE, loader_loadCompleteHandler);
            loader.addEventListener(WidgetTypeLoaderEvent.LOAD_ERROR, loader_loadErrorHandler);
            loader.load();
        }

        checkIfWidgetTypeLoadersComplete();
    }

    private function mapFilenameToModuleSWFAndXMLFiles(moduleFiles:Array):Array
    {
        var uniqueFileNameToSWF:Dictionary = new Dictionary();
        var uniqueFileNameToXML:Dictionary = new Dictionary();

        for each (var file:File in moduleFiles)
        {
            if (file.extension == "swf")
            {
                uniqueFileNameToSWF[FileUtil.getFileName(file)] = file;
            }
            else if (file.extension == "xml")
            {
                uniqueFileNameToXML[FileUtil.getFileName(file)] = file;
            }
        }

        return [ uniqueFileNameToSWF, uniqueFileNameToXML ];
    }

    private function getModuleFiles(directory:File):Array
    {
        var moduleFiles:Array = [];

        if (directory.isDirectory)
        {
            const files:Array = directory.getDirectoryListing();

            for each (var file:File in files)
            {
                if (file.isDirectory)
                {
                    moduleFiles = moduleFiles.concat(getModuleFiles(file));
                }
                else if (isModuleFile(file))
                {
                    moduleFiles.push(file);
                }
            }
        }

        return moduleFiles;
    }

    private function isModuleFile(file:File):Boolean
    {
        const moduleFileName:RegExp = /^.*Module\.(swf|xml)$/;
        return !file.isDirectory && (moduleFileName.test(file.name));
    }

    private function checkIfWidgetTypeLoadersComplete():void
    {
        if (pendingLoaders.length === 0)
        {
            sortAndAssignWidgetTypes();
        }
    }

    private function markModuleAsLoaded(loader:WidgetTypeLoader):void
    {
        var loaderIndex:int = pendingLoaders.indexOf(loader);
        if (loaderIndex > -1)
        {
            pendingLoaders.splice(loaderIndex, 1);
        }
    }

    private function sortAndAssignWidgetTypes():void
    {
        if (Log.isInfo())
        {
            LOG.info('All modules resolved');
        }

        for each (var widgetType:WidgetType in widgetTypeArr)
        {
            if (widgetType.isManaged)
            {
                WidgetTypeRegistryModel.getInstance().widgetTypeRegistry.addWidgetType(widgetType);
            }
            else
            {
                WidgetTypeRegistryModel.getInstance().layoutWidgetTypeRegistry.addWidgetType(widgetType);
            }
        }

        WidgetTypeRegistryModel.getInstance().widgetTypeRegistry.sort();
        WidgetTypeRegistryModel.getInstance().layoutWidgetTypeRegistry.sort();

        dispatchEvent(new WidgetTypeLoaderEvent(WidgetTypeLoaderEvent.LOAD_TYPES_COMPLETE));
    }

    private function loader_loadCompleteHandler(event:WidgetTypeLoaderEvent):void
    {
        var loader:WidgetTypeLoader = event.currentTarget as WidgetTypeLoader;
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_COMPLETE, loader_loadCompleteHandler);
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_ERROR, loader_loadErrorHandler);

        var widgetType:WidgetType = event.widgetType;

        if (Log.isDebug())
        {
            LOG.debug('Module {0} is resolved', widgetType.name);
        }

        widgetTypeArr.push(widgetType);
        markModuleAsLoaded(loader);
        checkIfWidgetTypeLoadersComplete();
    }

    private function loader_loadErrorHandler(event:WidgetTypeLoaderEvent):void
    {
        var loader:WidgetTypeLoader = event.currentTarget as WidgetTypeLoader;
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_COMPLETE, loader_loadCompleteHandler);
        loader.removeEventListener(WidgetTypeLoaderEvent.LOAD_ERROR, loader_loadErrorHandler);

        var errorMessage:String = ResourceManager.getInstance().getString('BuilderStrings',
                                                                          'importWidgetProcess.couldNotLoadCustomWidgets',
                                                                          [ loader.name ]);

        if (Log.isDebug())
        {
            LOG.debug(errorMessage);
        }

        BuilderAlert.show(errorMessage,
                          ResourceManager.getInstance().getString('BuilderStrings', 'error'));
        markModuleAsLoaded(loader);
        checkIfWidgetTypeLoadersComplete();
    }
}
}

Clean code for registering widgets at startup.


//
// Flump - Copyright 2012 Three Rings Design

package flump.display {

import flump.mold.MovieMold;

import starling.core.Starling;
import starling.display.DisplayObject;
import starling.display.Sprite;
import starling.events.Event;

public class Movie extends Sprite
{
    public static const FRAMERATE :Number = 30;

    public function Movie (src :MovieMold, idToDisplayObject :Function) {
        name = src.libraryItem;
        _ticker = new Ticker(advanceTime);
        var frames :int = 0;
        const flipbook :Boolean = src.flipbook;
        if (src.flipbook) {
            _layers = new Vector.<Layer>(1, true);
            _layers[0] = new Layer(this, src.layers[0], idToDisplayObject, /*flipbook=*/true);
            frames = src.layers[0].frames;
        } else {
            _layers = new Vector.<Layer>(src.layers.length, true);
            for (var ii :int = 0; ii < _layers.length; ii++) {
                _layers[ii] = new Layer(this, src.layers[ii], idToDisplayObject, /*flipbook=*/false);
                frames = Math.max(src.layers[ii].frames, frames);
            }
        }
        _duration = frames / FRAMERATE;
        goto(0, true, false);
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
        addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
    }

    protected function advanceTime (dt :Number) :void {
        if (!_playing) return;

        _playTime += dt;
        if (_playTime > _duration) _playTime = _playTime % _duration;
        var newFrame :int = int(_playTime * FRAMERATE);
        const overDuration :Boolean = dt >= _duration;
        // If the update crosses or goes to the stopFrame, go to the stop frame, stop the movie and
        // clear it
        if (_stopFrame != NO_FRAME &&
            ((newFrame >= _stopFrame && (_frame < _stopFrame || newFrame < _frame)) || overDuration)) {
            _playing = false
            newFrame = _stopFrame;
            _stopFrame = NO_FRAME;
        }
        goto(newFrame, false, overDuration);

    }

    protected function goto (newFrame :int, fromSkip :Boolean, overDuration :Boolean) :void {
        if (_goingToFrame) {
            _pendingFrame = newFrame;
            return;
        }
        _goingToFrame = true;
        const differentFrame :Boolean = newFrame != _frame;
        const wrapped :Boolean = newFrame < _frame;
        if (differentFrame) {
            if (wrapped) {
                for each (var layer :Layer in _layers) {
                    layer.changedKeyframe = true;
                    layer.keyframeIdx = 0;
                }
            }
            for each (layer in _layers) layer.drawFrame(newFrame);
        }

        // Update the frame before firing, so if firing changes the frame, it sticks.
        const oldFrame :int = _frame;
        _frame = newFrame;
        if (fromSkip) {
            // TODO [self fireLabelsFrom:newFrame to:newFrame];
            _playTime = newFrame/FRAMERATE;
        } else if (overDuration) {
            //[self fireLabelsFrom:oldFrame + 1 to:[_labels count] - 1];
            //[self fireLabelsFrom:0 to:_frame];
        } else if (differentFrame) {
            if (wrapped) {
                //[self fireLabelsFrom:oldFrame + 1 to:[_labels count] - 1];
                //[self fireLabelsFrom:0 to:_frame];
            } else {
                //[self fireLabelsFrom:oldFrame + 1 to:_frame];
            }
        }
        _goingToFrame = false;
        if (_pendingFrame != NO_FRAME) {
            newFrame = _pendingFrame;
            _pendingFrame = NO_FRAME;
            goto(newFrame, true, false);
        }

    }

    protected function addedToStage (..._) :void { Starling.juggler.add(_ticker); }

    protected function removedFromStage (..._) :void { Starling.juggler.add(_ticker); }

    protected var _goingToFrame :Boolean;
    protected var _pendingFrame :int = NO_FRAME;
    protected var _frame :int = NO_FRAME, _stopFrame :int = NO_FRAME;
    protected var _playing :Boolean = true;
    protected var _playTime :Number, _duration :Number;
    protected var _layers :Vector.<Layer>;
    protected var _ticker :Ticker;

    private static const NO_FRAME :int = -1;
}
}
import flump.display.Movie;
import flump.mold.KeyframeMold;
import flump.mold.LayerMold;

import starling.display.DisplayObject;
import starling.display.Sprite;

class Layer {
    public var keyframeIdx :int ;// The index of the last keyframe drawn in drawFrame
    public var layerIdx :int;// This layer's index in the movie
    public var keyframes :Vector.<KeyframeMold>;
    // Only created if there are multiple items on this layer. If it does exist, the appropriate display is swapped in at keyframe changes. If it doesn't, the display is only added to the parent on layer creation
    public var displays :Vector.<DisplayObject>;// <SPDisplayObject*>
    public var movie :Movie; // The movie this layer belongs to
    // If the keyframe has changed since the last drawFrame
    public var changedKeyframe :Boolean;

    public function Layer (movie :Movie, src :LayerMold, idToDisplayObject :Function,
            flipbook :Boolean) {
        keyframes = src.keyframes;
        this.movie = movie;
        var lastItem :String;
        for (var ii :int = 0; ii < keyframes.length && lastItem == null; ii++) {
            lastItem = keyframes[ii].libraryItem;
        }
        if (!flipbook && lastItem == null) movie.addChild(new Sprite());// Label only layer
        else {
            var multipleItems :Boolean = flipbook;
            for (ii = 0; ii < keyframes.length && !multipleItems; ii++) {
                multipleItems = keyframes[ii].libraryItem != lastItem;
            }
            if (!multipleItems) movie.addChild(idToDisplayObject(lastItem));
            else {
                displays = new Vector.<DisplayObject>();
                for each (var kf :KeyframeMold in keyframes) {
                    var display :DisplayObject = kf.id == null ? new Sprite() : idToDisplayObject(kf.id);
                    displays.push(display);
                    display.name = src.name;
                }
                movie.addChild(displays[0]);
            }
        }
        layerIdx = movie.numChildren - 1;
        movie.getChildAt(layerIdx).name = src.name;
    }

    public function drawFrame (frame :int) :void {
        while (keyframeIdx < keyframes.length - 1 && keyframes[keyframeIdx + 1].index <= frame) {
            keyframeIdx++;
            changedKeyframe = true;
        }
        // We've got multiple items. Swap in the one for this kf
        if (changedKeyframe && displays != null) {
            movie.removeChildAt(layerIdx);
            movie.addChildAt(displays[keyframeIdx], layerIdx);
        }
        changedKeyframe = false;

        const kf :KeyframeMold = keyframes[keyframeIdx];
        const layer :DisplayObject = movie.getChildAt(layerIdx);
        if (keyframeIdx == keyframes.length - 1 || kf.index == frame) {
            layer.x = kf.x;
            layer.y = kf.y;
            layer.scaleX = kf.scaleX;
            layer.scaleY = kf.scaleY;
            layer.rotation = kf.rotation;
            layer.alpha = kf.alpha;
        } else {
            var interped :Number = (frame - kf.index)/kf.duration;
            var ease :Number = kf.ease;
            if (ease != 0) {
                var t :Number;
                if (ease < 0) {
                    // Ease in
                    var inv :Number = 1 - interped;
                    t = 1 - inv*inv;
                    ease = -ease;
                } else {
                    // Ease out
                    t = interped*interped;
                }
                interped = ease*t + (1 - ease)*interped;
            }

            const nextKf :KeyframeMold = keyframes[keyframeIdx + 1];
            layer.x = kf.x + (nextKf.x - kf.x) * interped;
            layer.y = kf.y + (nextKf.y - kf.y) * interped;
            layer.scaleX = kf.scaleX + (nextKf.scaleX - kf.scaleX) * interped;
            layer.scaleY = kf.scaleY + (nextKf.scaleY - kf.scaleY) * interped;
            layer.rotation = kf.rotation + (nextKf.rotation - kf.rotation) * interped;
            layer.alpha = kf.alpha + (nextKf.alpha - kf.alpha) * interped;
        }

        layer.pivotX = kf.pivotX;
        layer.pivotY = kf.pivotY;
        layer.visible = kf.visible;
    }
}

import starling.animation.IAnimatable;

class Ticker implements IAnimatable {
    public function Ticker (callback :Function) {
        _callback = callback;
    }

    public function get isComplete () :Boolean { return false; }

    public function advanceTime (time :Number) :void { _callback(time); }

    protected var _callback :Function;
}

//
// Flump - Copyright 2012 Three Rings Design

package flump.display {

import flump.mold.MovieMold;

import starling.core.Starling;
import starling.display.DisplayObject;
import starling.display.Sprite;
import starling.events.Event;

public class Movie extends Sprite
{
    public static const FRAMERATE :Number = 30;

    public function Movie (src :MovieMold, idToDisplayObject :Function) {
        name = src.libraryItem;
        _ticker = new Ticker(advanceTime);
        const flipbook :Boolean = src.flipbook;
        if (src.flipbook) {
            _layers = new Vector.<Layer>(1, true);
            _layers[0] = new Layer(this, src.layers[0], idToDisplayObject, /*flipbook=*/true);
            _frames = src.layers[0].frames;
        } else {
            _layers = new Vector.<Layer>(src.layers.length, true);
            for (var ii :int = 0; ii < _layers.length; ii++) {
                _layers[ii] = new Layer(this, src.layers[ii], idToDisplayObject, /*flipbook=*/false);
                _frames = Math.max(src.layers[ii].frames, _frames);
            }
        }
        _duration = _frames / FRAMERATE;
        goto(0, true, false);
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
        addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
    }

    public function frames () :int {
        return _frames;
    }

    protected function advanceTime (dt :Number) :void {
        if (!_playing) return;

        _playTime += dt;
        var actualPlaytime :Number = _playTime;
        if (_playTime > _duration) _playTime = _playTime % _duration;
        var newFrame :int = int(_playTime * FRAMERATE);
        const overDuration :Boolean = dt >= _duration;
        // If the update crosses or goes to the stopFrame, go to the stop frame, stop the movie and
        // clear it
        if (_stopFrame != NO_FRAME) {
            // how many frames remain to the stopframe?
            var framesRemaining :int =
                (_frame <= _stopFrame ? _stopFrame - _frame : _frames - _frame + _stopFrame);
            var framesElapsed :int = int(actualPlaytime * FRAMERATE) - _frame;
            if (framesElapsed >= framesRemaining) {
                _playing = false;
                newFrame = _stopFrame;
                _stopFrame = NO_FRAME;
            }
        }
        goto(newFrame, false, overDuration);
    }

    protected function goto (newFrame :int, fromSkip :Boolean, overDuration :Boolean) :void {
        if (_goingToFrame) {
            _pendingFrame = newFrame;
            return;
        }
        _goingToFrame = true;
        const differentFrame :Boolean = newFrame != _frame;
        const wrapped :Boolean = newFrame < _frame;
        if (differentFrame) {
            if (wrapped) {
                for each (var layer :Layer in _layers) {
                    layer.changedKeyframe = true;
                    layer.keyframeIdx = 0;
                }
            }
            for each (layer in _layers) layer.drawFrame(newFrame);
        }

        // Update the frame before firing, so if firing changes the frame, it sticks.
        const oldFrame :int = _frame;
        _frame = newFrame;
        if (fromSkip) {
            // TODO [self fireLabelsFrom:newFrame to:newFrame];
            _playTime = newFrame/FRAMERATE;
        } else if (overDuration) {
            //[self fireLabelsFrom:oldFrame + 1 to:[_labels count] - 1];
            //[self fireLabelsFrom:0 to:_frame];
        } else if (differentFrame) {
            if (wrapped) {
                //[self fireLabelsFrom:oldFrame + 1 to:[_labels count] - 1];
                //[self fireLabelsFrom:0 to:_frame];
            } else {
                //[self fireLabelsFrom:oldFrame + 1 to:_frame];
            }
        }
        _goingToFrame = false;
        if (_pendingFrame != NO_FRAME) {
            newFrame = _pendingFrame;
            _pendingFrame = NO_FRAME;
            goto(newFrame, true, false);
        }

    }

    protected function addedToStage (..._) :void { Starling.juggler.add(_ticker); }

    protected function removedFromStage (..._) :void { Starling.juggler.add(_ticker); }

    protected var _goingToFrame :Boolean;
    protected var _pendingFrame :int = NO_FRAME;
    protected var _frame :int = NO_FRAME, _stopFrame :int = NO_FRAME;
    protected var _playing :Boolean = true;
    protected var _playTime :Number, _duration :Number;
    protected var _layers :Vector.<Layer>;
    protected var _ticker :Ticker;
    protected var _frames :int;

    private static const NO_FRAME :int = -1;
}
}
import flump.display.Movie;
import flump.mold.KeyframeMold;
import flump.mold.LayerMold;

import starling.display.DisplayObject;
import starling.display.Sprite;

class Layer {
    public var keyframeIdx :int ;// The index of the last keyframe drawn in drawFrame
    public var layerIdx :int;// This layer's index in the movie
    public var keyframes :Vector.<KeyframeMold>;
    // Only created if there are multiple items on this layer. If it does exist, the appropriate display is swapped in at keyframe changes. If it doesn't, the display is only added to the parent on layer creation
    public var displays :Vector.<DisplayObject>;// <SPDisplayObject*>
    public var movie :Movie; // The movie this layer belongs to
    // If the keyframe has changed since the last drawFrame
    public var changedKeyframe :Boolean;

    public function Layer (movie :Movie, src :LayerMold, idToDisplayObject :Function,
            flipbook :Boolean) {
        keyframes = src.keyframes;
        this.movie = movie;
        var lastItem :String;
        for (var ii :int = 0; ii < keyframes.length && lastItem == null; ii++) {
            lastItem = keyframes[ii].libraryItem;
        }
        if (!flipbook && lastItem == null) movie.addChild(new Sprite());// Label only layer
        else {
            var multipleItems :Boolean = flipbook;
            for (ii = 0; ii < keyframes.length && !multipleItems; ii++) {
                multipleItems = keyframes[ii].libraryItem != lastItem;
            }
            if (!multipleItems) movie.addChild(idToDisplayObject(lastItem));
            else {
                displays = new Vector.<DisplayObject>();
                for each (var kf :KeyframeMold in keyframes) {
                    var display :DisplayObject = kf.id == null ? new Sprite() : idToDisplayObject(kf.id);
                    displays.push(display);
                    display.name = src.name;
                }
                movie.addChild(displays[0]);
            }
        }
        layerIdx = movie.numChildren - 1;
        movie.getChildAt(layerIdx).name = src.name;
    }

    public function drawFrame (frame :int) :void {
        while (keyframeIdx < keyframes.length - 1 && keyframes[keyframeIdx + 1].index <= frame) {
            keyframeIdx++;
            changedKeyframe = true;
        }
        // We've got multiple items. Swap in the one for this kf
        if (changedKeyframe && displays != null) {
            movie.removeChildAt(layerIdx);
            movie.addChildAt(displays[keyframeIdx], layerIdx);
        }
        changedKeyframe = false;

        const kf :KeyframeMold = keyframes[keyframeIdx];
        const layer :DisplayObject = movie.getChildAt(layerIdx);
        if (keyframeIdx == keyframes.length - 1 || kf.index == frame) {
            layer.x = kf.x;
            layer.y = kf.y;
            layer.scaleX = kf.scaleX;
            layer.scaleY = kf.scaleY;
            layer.rotation = kf.rotation;
            layer.alpha = kf.alpha;
        } else {
            var interped :Number = (frame - kf.index)/kf.duration;
            var ease :Number = kf.ease;
            if (ease != 0) {
                var t :Number;
                if (ease < 0) {
                    // Ease in
                    var inv :Number = 1 - interped;
                    t = 1 - inv*inv;
                    ease = -ease;
                } else {
                    // Ease out
                    t = interped*interped;
                }
                interped = ease*t + (1 - ease)*interped;
            }

            const nextKf :KeyframeMold = keyframes[keyframeIdx + 1];
            layer.x = kf.x + (nextKf.x - kf.x) * interped;
            layer.y = kf.y + (nextKf.y - kf.y) * interped;
            layer.scaleX = kf.scaleX + (nextKf.scaleX - kf.scaleX) * interped;
            layer.scaleY = kf.scaleY + (nextKf.scaleY - kf.scaleY) * interped;
            layer.rotation = kf.rotation + (nextKf.rotation - kf.rotation) * interped;
            layer.alpha = kf.alpha + (nextKf.alpha - kf.alpha) * interped;
        }

        layer.pivotX = kf.pivotX;
        layer.pivotY = kf.pivotY;
        layer.visible = kf.visible;
    }
}

import starling.animation.IAnimatable;

class Ticker implements IAnimatable {
    public function Ticker (callback :Function) {
        _callback = callback;
    }

    public function get isComplete () :Boolean { return false; }

    public function advanceTime (time :Number) :void { _callback(time); }

    protected var _callback :Function;
}

Fix _stopFrame logic

Fix _stopFrame logic