////////////////////////////////////////////////////////////////////////////////
// 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 up.

Clean up.


////////////////////////////////////////////////////////////////////////////////
//
//  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.promises.enums
{

public class PromiseState
{

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

	public static const BLOCKED:PromiseState = new PromiseState("blocked");
	public static const FULFILLED:PromiseState = new PromiseState("fulfilled");
	public static const PENDING:PromiseState = new PromiseState("pending");
	public static const REJECTED:PromiseState = new PromiseState("rejected");

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

    public function PromiseState(stringValue:String) {
        this.stringValue = stringValue;
    }

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

    private var stringValue:String;

    //--------------------------------------------------------------------------
    //
    //    Methods
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //    toString
    //----------------------------------

    public function toString():String
    {
        return stringValue;
    }

}
}

Add license header

Add license header

Signed-off-by: Erik de Bruin <c195b508e6f0c57aeafdb5e96947e2b79e6a4b40@ixsoftware.nl>


package com.mangui.HLS.streaming {

    import com.mangui.HLS.*;
    import com.mangui.HLS.muxing.*;
    import com.mangui.HLS.streaming.*;
    import com.mangui.HLS.parsing.*;
    import com.mangui.HLS.utils.*;

    import flash.media.*;
    import flash.net.*;
    import flash.utils.*;

    /** Class that keeps the buffer filled. **/
    public class Buffer {
        /** Reference to the framework controller. **/
        private var _hls:HLS;
        /** The buffer with video tags. **/
        private var _buffer:Vector.<Tag>;
        /** NetConnection legacy stuff. **/
        private var _connection:NetConnection;
        /** The fragment loader. **/
        private var _loader:Loader;
        /** Store that a fragment load is in progress. **/
        private var _loading:Boolean;
        /** Interval for checking buffer and position. **/
        private var _interval:Number;
        /** Next loading fragment sequence number. **/
        /** The start position of the stream. **/
        public var PlaybackStartPosition:Number = 0;
         /** start play time **/
        private var _playback_start_time:Number;
        /** playback start PTS. **/
        private var _playback_start_pts:Number;
        /** playlist start PTS when playback started. **/
        private var _playlist_start_pts:Number;
        /** Current play position (relative position from beginning of sliding window) **/
        private var _playback_current_position:Number;
        /** buffer last PTS. **/
        private var _buffer_last_pts:Number;
         /** next buffer time. **/
        private var _buffer_next_time:Number;
         /** previous buffer time. **/
        private var _last_buffer:Number;
        /** Current playback state. **/
        private var _state:String;
        /** Netstream instance used for playing the stream. **/
        private var _stream:NetStream;
        /** The last tag that was appended to the buffer. **/
        private var _tag:Number;
        /** soundtransform object. **/
        private var _transform:SoundTransform;
        /** Reference to the video object. **/
        private var _video:Object;

        /** Create the buffer. **/
        public function Buffer(hls:HLS, loader:Loader, video:Object):void {
            _hls = hls;
            _loader = loader;
            _video = video;
            _hls.addEventListener(HLSEvent.MANIFEST,_manifestHandler);
            _connection = new NetConnection();
            _connection.connect(null);
            _transform = new SoundTransform();
            _transform.volume = 0.9;
            _setState(HLSStates.IDLE);
        };

        /** Check the bufferlength. **/
        private function _checkBuffer():void {
            var reachedend:Boolean = false;
            var buffer:Number = 0;
            // Calculate the buffer and position.
            if(_buffer.length) {
               buffer = (_buffer_last_pts - _playback_start_pts)/1000 - _stream.time;
               /** Current play time (time since beginning of playback) **/
               var playback_current_time:Number = (Math.round(_stream.time*100 + _playback_start_time*100)/100);
               var playliststartpts:Number = _loader.getPlayListStartPTS();
               var play_position:Number;
               if(playliststartpts < 0) {
                  play_position = 0;
               } else {
                  play_position = playback_current_time -(playliststartpts-_playlist_start_pts)/1000;
                }
               if(play_position != _playback_current_position || buffer !=_last_buffer) {
                  if (play_position <0) {
                     play_position = 0;
                  }
                  _playback_current_position = play_position;
                  _last_buffer = buffer;
                  _hls.dispatchEvent(new HLSEvent(HLSEvent.MEDIA_TIME,{ position:_playback_current_position, buffer:buffer, duration:_loader.getPlayListDuration()}));
               }
            }

            // Load new tags from fragment.
            if(buffer < _loader.getBufferLength() && !_loading) {
               var loadstatus:Number = _loader.loadfragment(_buffer_next_time,_buffer_last_pts,buffer,_loaderCallback,(_buffer.length == 0));
               if (loadstatus == 0) {
                  // good, new fragment being loaded
                  _loading = true;
               } else  if (loadstatus < 0) {
                  /* it means sequence number requested is smaller than any seqnum available.
                     it could happen on live playlist in 2 scenarios :
                     if bandwidth available is lower than lowest quality needed bandwidth
                     after long pause
                     => seek(offset) to force a restart of the playback session
                     we target second segment
                     */
                  Log.txt("long pause on live stream or bad network quality");
                  seek(_loader.getSegmentMaxDuration());
                  return;
               } else if(loadstatus > 0) {
                  //seqnum not available in playlist
                  if (_hls.getType() == HLSTypes.VOD) {
                     // if VOD playlist, it means we reached the end, on live playlist do nothing and wait ...
                     reachedend = true;
                  }
               }
            }
            // Append tags to buffer.
            if((_state == HLSStates.PLAYING && _stream.bufferLength < 10) ||
               (_state == HLSStates.BUFFERING && buffer > 10))
             {
                //Log.txt("appending data");
                while(_tag < _buffer.length && _stream.bufferLength < 20) {
                    try {
                        _stream.appendBytes(_buffer[_tag].data);
                    } catch (error:Error) {
                        _errorHandler(new Error(_buffer[_tag].type+": "+ error.message));
                    }
                    // Last tag done? Then append sequence end.
                    if (reachedend ==true && _tag == _buffer.length - 1) {
                        _stream.appendBytesAction(NetStreamAppendBytesAction.END_SEQUENCE);
                        _stream.appendBytes(new ByteArray());
                    }
                    _tag++;
                }
            }
            // Set playback state and complete.
            if(_stream.bufferLength < 3) {
                if(reachedend ==true) {
                    if(_stream.bufferLength == 0) {
                        _complete();
                    }
                } else if(_state == HLSStates.PLAYING) {
                    _setState(HLSStates.BUFFERING);
                }
            } else if (_state == HLSStates.BUFFERING) {
                _setState(HLSStates.PLAYING);
            }
        };

        /** The video completed playback. **/
        private function _complete():void {
            _setState(HLSStates.IDLE);
            clearInterval(_interval);
            // _stream.pause();
            _hls.dispatchEvent(new HLSEvent(HLSEvent.COMPLETE));
        };

        /** Dispatch an error to the controller. **/
        private function _errorHandler(error:Error):void {
            _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR,error.toString()));
        };

        /** Return the current playback state. **/
        public function getPosition():Number {
            return _playback_current_position;
        };

        /** Return the current playback state. **/
        public function getState():String {
            return _state;
        };

        /** Add a fragment to the buffer. **/
        private function _loaderCallback(tags:Vector.<Tag>,min_pts:Number,max_pts:Number):void {
            _buffer = _buffer.slice(_tag);
            _tag = 0;
            if (_playback_start_pts == 0) {
               _playback_start_pts = min_pts;
               _playlist_start_pts = _loader.getPlayListStartPTS();
            }
            _buffer_last_pts = max_pts;
            tags.sort(_sortTagsbyDTS);
            for each (var t:Tag in tags) {
               _buffer.push(t);
            }
            _buffer_next_time=_playback_start_time+(_buffer_last_pts-_playback_start_pts)/1000;
            Log.txt("_loaderCallback,_buffer_next_time:"+ _buffer_next_time);
            _loading = false;
        };

        /** Start streaming on manifest load. **/
        private function _manifestHandler(event:HLSEvent):void {
            if(_state == HLSStates.IDLE) {
                _stream = new NetStream(_connection);
                _video.attachNetStream(_stream);
                _stream.play(null);
                _stream.soundTransform = _transform;
                _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
                _stream.appendBytes(FLV.getHeader());
                seek(PlaybackStartPosition);
            }
        };

        /** Toggle playback. **/
        public function pause():void {
            clearInterval(_interval);
            if(_state == HLSStates.PAUSED) {
                _setState(HLSStates.BUFFERING);
                _stream.resume();
                _interval = setInterval(_checkBuffer,100);
            } else if(_state == HLSStates.PLAYING) {
                _setState(HLSStates.PAUSED);
                _stream.pause();
            }
        };

        /** Change playback state. **/
        private function _setState(state:String):void {
            if(state != _state) {
                _state = state;
                _hls.dispatchEvent(new HLSEvent(HLSEvent.STATE,_state));
            }
        };

        /** Sort the buffer by tag. **/
        private function _sortTagsbyDTS(x:Tag,y:Tag):Number {
            if(x.dts < y.dts) {
                return -1;
            } else if (x.dts > y.dts) {
                return 1;
            } else {
                if(x.type == Tag.AVC_HEADER || x.type == Tag.AAC_HEADER) {
                    return -1;
                } else if (y.type == Tag.AVC_HEADER || y.type == Tag.AAC_HEADER) {
                    return 1;
                } else {
                    if(x.type == Tag.AVC_NALU) {
                        return -1;
                    } else if (y.type == Tag.AVC_NALU) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            }
        };

        /** Start playing data in the buffer. **/
        public function seek(position:Number):void {
               _buffer = new Vector.<Tag>();
               _loader.clearLoader();
               _loading = false;
               _tag = 0;
                PlaybackStartPosition = position;
               _stream.seek(0);
               _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
               _playback_start_time = position;
               _playback_start_pts = 0;
               _buffer_next_time = _playback_start_time;
               _buffer_last_pts = 0;
               _last_buffer = 0;
               _setState(HLSStates.BUFFERING);
               clearInterval(_interval);
               _interval = setInterval(_checkBuffer,100);
        };

        /** Stop playback. **/
        public function stop():void {
            if(_stream) {
                _stream.pause();
            }
            _loading = false;
            clearInterval(_interval);
            _setState(HLSStates.IDLE);
        };

        /** Change the volume (set in the NetStream). **/
        public function volume(percent:Number):void {
            _transform.volume = percent/100;
            if(_stream) {
                _stream.soundTransform = _transform;
            }
        };

    }

}

trim trailing spaces

trim trailing spaces


package com.mangui.HLS.streaming {

    import com.mangui.HLS.*;
    import com.mangui.HLS.parsing.*;
    import com.mangui.HLS.utils.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    /** Loader for hls streaming manifests. **/
    public class Getter {

        /** Reference to the hls framework controller. **/
        private var _hls:HLS;
        /** Array with levels. **/
        private var _levels:Array = [];
        /** Object that fetches the manifest. **/
        private var _urlloader:URLLoader;
        /** Link to the M3U8 file. **/
        private var _url:String;
        /** Amount of playlists still need loading. **/
        private var _toLoad:Number;
        /** are all playlists filled ? **/
        private var _canStart:Boolean;
        /** initial reload timer **/
        private var _fragmentDuration:Number = 5000;
        /** Timeout ID for reloading live playlists. **/
        private var _timeoutID:Number;
        /** Streaming type (live, ondemand). **/
        private var _type:String;
        /** last reload manifest time **/
        private var _reload_playlists_timer:uint;

        /** Setup the loader. **/
        public function Getter(hls:HLS) {
            _hls = hls;
            _hls.addEventListener(HLSEvent.STATE,_stateHandler);
            _levels = [];
            _urlloader = new URLLoader();
            _urlloader.addEventListener(Event.COMPLETE,_loaderHandler);
            _urlloader.addEventListener(IOErrorEvent.IO_ERROR,_errorHandler);
            _urlloader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,_errorHandler);
        };

        /** Loading failed; return errors. **/
        private function _errorHandler(event:ErrorEvent):void {
            var txt:String = "Cannot load M3U8: "+event.text;
            if(event is SecurityErrorEvent) {
                txt = "Cannot load M3U8: crossdomain access denied";
            } else if (event is IOErrorEvent) {
                txt = "Cannot load M3U8: 404 not found";
            }
            _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR,txt));
        };

        /** return true if first two levels contain at least 2 fragments **/
        private function _areFirstLevelsFilled():Boolean {
           for(var i:Number = 0; (i < _levels.length) && (i < 2); i++) {
            if(_levels[i].fragments.length < 2) {
               return false;
            }
         }
         return true;
        };

        /** Return the current manifest. **/
        public function getLevels():Array {
            return _levels;
        };

        /** Return the stream type. **/
        public function getType():String {
            return _type;
        };

        /** Load the manifest file. **/
        public function load(url:String):void {
            _url = url;
            _levels = [];
            _canStart = false;
            _reload_playlists_timer = getTimer();
            _urlloader.load(new URLRequest(_url));
        };

        /** Manifest loaded; check and parse it **/
        private function _loaderHandler(event:Event):void {
            _loadManifest(String(event.target.data));
        };

        /** load a playlist **/
        private function _loadPlaylist(string:String,url:String,index:Number):void {
            if(string != null && string.length != 0) {
               var frags:Array = Manifest.getFragments(string,url);
               // set fragment and update sequence number range
               _levels[index].setFragments(frags);
               _levels[index].targetduration = Manifest.getTargetDuration(string);
               _levels[index].start_seqnum = frags[0].seqnum;
               _levels[index].end_seqnum = frags[frags.length-1].seqnum;
               _levels[index].duration = frags[frags.length-1].start + frags[frags.length-1].duration;
               _fragmentDuration = _levels[index].targetduration;
            }
            if(--_toLoad == 0) {
            // Check whether the stream is live or not finished yet
            if(Manifest.hasEndlist(string)) {
                _type = HLSTypes.VOD;
            } else {
                _type = HLSTypes.LIVE;
                var timeout:Number = Math.max(100,_reload_playlists_timer + _fragmentDuration - getTimer());
                Log.txt("Live Playlist parsing finished: reload in " + timeout + " ms");
                _timeoutID = setTimeout(_loadPlaylists,timeout);
            }
               if (!_canStart && (_canStart =_areFirstLevelsFilled())) {
                  Log.txt("first 2 levels are filled with at least 2 fragments, notify event");
                  _hls.dispatchEvent(new HLSEvent(HLSEvent.MANIFEST,_levels));
              }
            }
        };

        /** load First Level Playlist **/
        private function _loadManifest(string:String):void {
            // Check for M3U8 playlist or manifest.
            if(string.indexOf(Manifest.HEADER) == 0) {
               //1 level playlist, create unique level and parse playlist
                if(string.indexOf(Manifest.FRAGMENT) > 0) {
                    var level:Level = new Level();
                    level.url = _url;
                    _levels.push(level);
                    _toLoad = 1;
                    Log.txt("1 Level Playlist, load it");
                    _loadPlaylist(string,_url,0);
                } else if(string.indexOf(Manifest.LEVEL) > 0) {
                  //adaptative playlist, extract levels from playlist, get them and parse them
                  _levels = Manifest.extractLevels(string,_url);
                  _loadPlaylists();
                }
            } else {
                var message:String = "Manifest is not a valid M3U8 file" + _url;
                _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR,message));
            }
        };

        /** load/reload all M3U8 playlists **/
        private function _loadPlaylists():void {
            _reload_playlists_timer = getTimer();
            _toLoad = _levels.length;
            //Log.txt("HLS Playlist, with " + _toLoad + " levels");
            for(var i:Number = 0; i < _levels.length; i++) {
                new Manifest().loadPlaylist(_levels[i].url,_loadPlaylist,_errorHandler,i);
            }
        };

        /** When the framework idles out, reloading is cancelled. **/
        public function _stateHandler(event:HLSEvent):void {
            if(event.state == HLSStates.IDLE) {
                clearTimeout(_timeoutID);
            }
        };
    }
}

package com.mangui.HLS.streaming {

    import com.mangui.HLS.*;
    import com.mangui.HLS.parsing.*;
    import com.mangui.HLS.utils.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    /** Loader for hls streaming manifests. **/
    public class Getter {

        /** Reference to the hls framework controller. **/
        private var _hls:HLS;
        /** Array with levels. **/
        private var _levels:Array = [];
        /** Object that fetches the manifest. **/
        private var _urlloader:URLLoader;
        /** Link to the M3U8 file. **/
        private var _url:String;
        /** Amount of playlists still need loading. **/
        private var _toLoad:Number;
        /** are all playlists filled ? **/
        private var _canStart:Boolean;
        /** initial reload timer **/
        private var _fragmentDuration:Number = 5000;
        /** Timeout ID for reloading live playlists. **/
        private var _timeoutID:Number;
        /** Streaming type (live, ondemand). **/
        private var _type:String;
        /** last reload manifest time **/
        private var _reload_playlists_timer:uint;

        /** Setup the loader. **/
        public function Getter(hls:HLS) {
            _hls = hls;
            _hls.addEventListener(HLSEvent.STATE,_stateHandler);
            _levels = [];
            _urlloader = new URLLoader();
            _urlloader.addEventListener(Event.COMPLETE,_loaderHandler);
            _urlloader.addEventListener(IOErrorEvent.IO_ERROR,_errorHandler);
            _urlloader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,_errorHandler);
        };

        /** Loading failed; return errors. **/
        private function _errorHandler(event:ErrorEvent):void {
            var txt:String = "Cannot load M3U8: "+event.text;
            if(event is SecurityErrorEvent) {
                txt = "Cannot load M3U8: crossdomain access denied";
            } else if (event is IOErrorEvent) {
                txt = "Cannot load M3U8: 404 not found";
            }
            _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR,txt));
        };

        /** return true if first two levels contain at least 2 fragments **/
        private function _areFirstLevelsFilled():Boolean {
           for(var i:Number = 0; (i < _levels.length) && (i < 2); i++) {
            if(_levels[i].fragments.length < 2) {
               return false;
            }
         }
         return true;
        };

        /** Return the current manifest. **/
        public function getLevels():Array {
            return _levels;
        };

        /** Return the stream type. **/
        public function getType():String {
            return _type;
        };

        /** Load the manifest file. **/
        public function load(url:String):void {
            _url = url;
            _levels = [];
            _canStart = false;
            _reload_playlists_timer = getTimer();
            _urlloader.load(new URLRequest(_url));
        };

        /** Manifest loaded; check and parse it **/
        private function _loaderHandler(event:Event):void {
            _loadManifest(String(event.target.data));
        };

        /** load a playlist **/
        private function _loadPlaylist(string:String,url:String,index:Number):void {
            if(string != null && string.length != 0) {
               var frags:Array = Manifest.getFragments(string,url);
               // set fragment and update sequence number range
               _levels[index].setFragments(frags);
               _levels[index].targetduration = Manifest.getTargetDuration(string);
               _levels[index].start_seqnum = frags[0].seqnum;
               _levels[index].end_seqnum = frags[frags.length-1].seqnum;
               _levels[index].duration = frags[frags.length-1].start + frags[frags.length-1].duration;
               _fragmentDuration = 1000*_levels[index].targetduration;
            }
            if(--_toLoad == 0) {
            // Check whether the stream is live or not finished yet
            if(Manifest.hasEndlist(string)) {
                _type = HLSTypes.VOD;
            } else {
                _type = HLSTypes.LIVE;
                var timeout:Number = Math.max(100,_reload_playlists_timer + _fragmentDuration - getTimer());
                Log.txt("Live Playlist parsing finished: reload in " + timeout + " ms");
                _timeoutID = setTimeout(_loadPlaylists,timeout);
            }
               if (!_canStart && (_canStart =_areFirstLevelsFilled())) {
                  Log.txt("first 2 levels are filled with at least 2 fragments, notify event");
                  _hls.dispatchEvent(new HLSEvent(HLSEvent.MANIFEST,_levels));
              }
            }
        };

        /** load First Level Playlist **/
        private function _loadManifest(string:String):void {
            // Check for M3U8 playlist or manifest.
            if(string.indexOf(Manifest.HEADER) == 0) {
               //1 level playlist, create unique level and parse playlist
                if(string.indexOf(Manifest.FRAGMENT) > 0) {
                    var level:Level = new Level();
                    level.url = _url;
                    _levels.push(level);
                    _toLoad = 1;
                    Log.txt("1 Level Playlist, load it");
                    _loadPlaylist(string,_url,0);
                } else if(string.indexOf(Manifest.LEVEL) > 0) {
                  //adaptative playlist, extract levels from playlist, get them and parse them
                  _levels = Manifest.extractLevels(string,_url);
                  _loadPlaylists();
                }
            } else {
                var message:String = "Manifest is not a valid M3U8 file" + _url;
                _hls.dispatchEvent(new HLSEvent(HLSEvent.ERROR,message));
            }
        };

        /** load/reload all M3U8 playlists **/
        private function _loadPlaylists():void {
            _reload_playlists_timer = getTimer();
            _toLoad = _levels.length;
            //Log.txt("HLS Playlist, with " + _toLoad + " levels");
            for(var i:Number = 0; i < _levels.length; i++) {
                new Manifest().loadPlaylist(_levels[i].url,_loadPlaylist,_errorHandler,i);
            }
        };

        /** When the framework idles out, reloading is cancelled. **/
        public function _stateHandler(event:HLSEvent):void {
            if(event.state == HLSStates.IDLE) {
                clearTimeout(_timeoutID);
            }
        };
    }
}

fix playlist reloading too often ...

fix playlist reloading too often ...


////////////////////////////////////////////////////////////////////////////////
//
//  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.core
{
	import flash.system.ApplicationDomain;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	import flash.utils.getQualifiedSuperclassName;

	import org.apache.flex.events.EventDispatcher;
	import org.apache.flex.events.ValueChangeEvent;

    /**
     *  The SimpleCSSValuesImpl class implements a minimal set of
     *  CSS lookup rules that is sufficient for most applications.
     *  It does not support attribute selectors or descendant selectors
     *  or id selectors.  It will filter on a custom -flex-flash
     *  media query but not other media queries.  It can be
     *  replaced with other implementations that handle more complex
     *  selector lookups.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class SimpleCSSValuesImpl extends EventDispatcher implements IValuesImpl
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function SimpleCSSValuesImpl()
		{
			super();
		}

        private var mainClass:Object;

		private var conditionCombiners:Object;

        /**
         *  @copy org.apache.flex.core.IValuesImpl#init()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function init(mainClass:Object):void
        {
			var styleClassName:String;
			var c:Class;
			if (!values)
			{
				values = {};
	            this.mainClass = mainClass;
	            var mainClassName:String = getQualifiedClassName(mainClass);
				styleClassName = "_" + mainClassName + "_Styles";
				c = ApplicationDomain.currentDomain.getDefinition(styleClassName) as Class;
			}
			else
			{
				c = mainClass.constructor as Class;
			}
            generateCSSStyleDeclarations(c["factoryFunctions"], c["data"]);
        }

        /**
         *  Process the encoded CSS data into data structures.  Usually not called
         *  directly by application developers.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function generateCSSStyleDeclarations(factoryFunctions:Object, arr:Array):void
        {
			if (factoryFunctions == null)
				return;
			if (arr == null)
				return;

            var declarationName:String = "";
            var segmentName:String = "";
            var n:int = arr.length;
            for (var i:int = 0; i < n; i++)
            {
                var className:int = arr[i];
                if (className == CSSClass.CSSSelector)
                {
                    var selectorName:String = arr[++i];
                    segmentName = selectorName + segmentName;
                    if (declarationName != "")
                        declarationName += " ";
                    declarationName += segmentName;
                    segmentName = "";
                }
                else if (className == CSSClass.CSSCondition)
                {
					if (!conditionCombiners)
					{
						conditionCombiners = {};
						conditionCombiners["class"] = ".";
						conditionCombiners["id"] = "#";
						conditionCombiners["pseudo"] = ':';
					}
					var conditionType:String = arr[++i];
					var conditionName:String = arr[++i];
					segmentName = segmentName + conditionCombiners[conditionType] + conditionName;
                }
                else if (className == CSSClass.CSSStyleDeclaration)
                {
                    var factoryName:int = arr[++i]; // defaultFactory or factory
                    var defaultFactory:Boolean = factoryName == CSSFactory.DefaultFactory;
                    /*
                    if (defaultFactory)
                    {
                        mergedStyle = styleManager.getMergedStyleDeclaration(declarationName);
                        style = new CSSStyleDeclaration(selector, styleManager, mergedStyle == null);
                    }
                    else
                    {
                        style = styleManager.getStyleDeclaration(declarationName);
                        if (!style)
                        {
                            style = new CSSStyleDeclaration(selector, styleManager, mergedStyle == null);
                            if (factoryName == CSSFactory.Override)
                                newSelectors.push(style);
                        }
                    }
                    */
                    var mq:String = null;
                    var o:Object;
                    if (i < n - 2)
                    {
                        // peek ahead to see if there is a media query
                        if (arr[i + 1] == CSSClass.CSSMediaQuery)
                        {
                            mq = arr[i + 2];
                            i += 2;
                            declarationName = mq + "_" + declarationName;
                        }
                    }
                    var finalName:String;
                    var valuesFunction:Function;
                    var valuesObject:Object;
                    if (defaultFactory)
                    {
                        valuesFunction = factoryFunctions[declarationName];
                        valuesObject = new valuesFunction();
                    }
                    else
                    {
                        valuesFunction = factoryFunctions[declarationName];
                        valuesObject = new valuesFunction();
                    }
                    if (isValidStaticMediaQuery(mq))
                    {
                        finalName = fixNames(declarationName, mq);
                        o = values[finalName];
                        if (o == null)
                            values[finalName] = valuesObject;
                        else
                        {
                            valuesFunction.prototype = o;
                            values[finalName] = new valuesFunction();
                        }
                    }
                    declarationName = "";
                }
            }

        }

        private function isValidStaticMediaQuery(mq:String):Boolean
        {
            if (mq == null)
                return true;

            if (mq == "-flex-flash")
                return true;

            // TODO: (aharui) other media query

            return false;
        }

        private function fixNames(s:String, mq:String):String
        {
            if (mq != null)
                s = s.substr(mq.length + 1); // 1 more for the hyphen

			if (s == "")
				return "*";

            var arr:Array = s.split(" ");
            var n:int = arr.length;
            for (var i:int = 0; i < n; i++)
            {
                var segmentName:String = arr[i];
				if (segmentName.charAt(0) == "#" || segmentName.charAt(0) == ".")
					continue;

                var c:int = segmentName.lastIndexOf(".");
                if (c > -1)	// it is 0 for class selectors
                {
                    segmentName = segmentName.substr(0, c) + "::" + segmentName.substr(c + 1);
                    arr[i] = segmentName;
                }
            }
            return arr.join(" ");
        }

        /**
         *  The map of values.  The format is not documented and it is not recommended
         *  to manipulate this structure directly.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var values:Object;

        /**
         *  @copy org.apache.flex.core.IValuesImpl#getValue()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function getValue(thisObject:Object, valueName:String, state:String = null, attrs:Object = null):*
		{
            var c:int = valueName.indexOf("-");
            while (c != -1)
            {
                valueName = valueName.substr(0, c) +
                    valueName.charAt(c + 1).toUpperCase() +
                    valueName.substr(c + 2);
                c = valueName.indexOf("-");
            }

            var value:*;
			var o:Object;
			var className:String;
			var selectorName:String;

			if (thisObject is IStyleableObject)
			{
                var styleable:IStyleableObject = IStyleableObject(thisObject);
                if (styleable.style != null)
                {
                    try {
                        value = styleable.style[valueName];
                    }
                    catch (e:Error) {
                        value = undefined;
                    }
                    if (value == "inherit")
                        return getInheritingValue(thisObject, valueName, state, attrs);
                    if (value !== undefined)
                        return value;
                }
				className = styleable.className;
				if (state)
				{
					selectorName = className + ":" + state;
					o = values["." + selectorName];
					if (o)
					{
						value = o[valueName];
                        if (value == "inherit")
                            return getInheritingValue(thisObject, valueName, state, attrs);
						if (value !== undefined)
							return value;
					}
				}

				o = values["." + className];
				if (o)
				{
					value = o[valueName];
                    if (value == "inherit")
                        return getInheritingValue(thisObject, valueName, state, attrs);
					if (value !== undefined)
						return value;
				}
			}

			className = getQualifiedClassName(thisObject);
            var thisInstance:Object = thisObject;
			while (className != "Object")
			{
				if (state)
				{
					selectorName = className + ":" + state;
					o = values[selectorName];
					if (o)
					{
						value = o[valueName];
                        if (value == "inherit")
                            return getInheritingValue(thisObject, valueName, state, attrs);
						if (value !== undefined)
							return value;
					}
				}

	            o = values[className];
	            if (o)
	            {
	                value = o[valueName];
                    if (value == "inherit")
                        return getInheritingValue(thisObject, valueName, state, attrs);
	                if (value !== undefined)
	                    return value;
	            }
				className = getQualifiedSuperclassName(thisInstance);
				thisInstance = getDefinitionByName(className);
			}

            if (inheritingStyles[valueName] != null &&
                thisObject is IChild)
            {
                var parentObject:Object = IChild(thisObject).parent;
                if (parentObject)
                    return getValue(parentObject, valueName, state, attrs);
            }

            o = values["global"];
            if (o)
            {
    			value = o[valueName];
    			if (value !== undefined)
    				return value;
            }
			o = values["*"];
			if(o)
			{
				return o[valueName];
			}
			return undefined;
		}

        private function getInheritingValue(thisObject:Object, valueName:String, state:String = null, attrs:Object = null):*
        {
            var value:*;
            if (thisObject is IChild)
            {
                var parentObject:Object = IChild(thisObject).parent;
                if (parentObject)
                {
                    value = getValue(parentObject, valueName, state, attrs);
                    if (value == "inherit" || value === undefined)
                        return getInheritingValue(parentObject, valueName, state, attrs);
                    if (value !== undefined)
                        return value;
                }
            }
            return "inherit";
        }

        /**
         *  A method that stores a value to be shared with other objects.
         *  It is global, not per instance.  Fancier implementations
         *  may store shared values per-instance.
         *
         *  @param thisObject An object associated with this value.  Thiis
         *                parameter is ignored.
         *  @param valueName The name or key of the value being stored.
         *  @param The value to be stored.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function setValue(thisObject:Object, valueName:String, value:*):void
		{
            var c:int = valueName.indexOf("-");
            while (c != -1)
            {
                valueName = valueName.substr(0, c) +
                    valueName.charAt(c + 1).toUpperCase() +
                    valueName..substr(c + 2);
                c = valueName.indexOf("-");
            }
			var oldValue:Object = values[valueName];
			if (oldValue != value)
			{
				values[valueName] = value;
				dispatchEvent(new ValueChangeEvent(ValueChangeEvent.VALUE_CHANGE, false, false, oldValue, value));
			}
		}

		/**
		 *  @copy org.apache.flex.core.IValuesImpl#newInstance()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function newInstance(thisObject:Object, valueName:String, state:String = null, attrs:Object = null):*
		{
			var c:Class = getValue(thisObject, valueName, state, attrs);
			if (c)
				return new c();
			return null;
		}

        /**
         *  @copy org.apache.flex.core.IValuesImpl#getInstance()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function getInstance(valueName:String):Object
        {
            var o:Object = values["global"];
            if (o is Class)
            {
                o[valueName] = new o[valueName]();
                if (o[valueName] is IDocument)
                    o[valueName].setDocument(mainClass);
            }
            return o[valueName];
        }

        /**
         *  @copy org.apache.flex.core.IValuesImpl#convertColor()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function convertColor(value:Object):uint
        {
            if (!(value is String))
                return uint(value);

            var stringValue:String = value as String;
            if (stringValue.charAt(0) == '#')
                return uint(stringValue.substr(1));
            return uint(stringValue);
        }

        /**
         *  A map of inheriting styles
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public static var inheritingStyles:Object = {
            "color" : 1,
            "fontFamily" : 1,
            "fontSize" : 1,
            "fontStyle" : 1
        }

	}
}

class CSSClass
{
    public static const CSSSelector:int = 0;
    public static const CSSCondition:int = 1;
    public static const CSSStyleDeclaration:int = 2;
    public static const CSSMediaQuery:int = 3;
}

class CSSFactory
{
    public static const DefaultFactory:int = 0;
    public static const Factory:int = 1;
    public static const Override:int = 2;
}

class CSSDataType
{
    public static const Native:int = 0;
    public static const Definition:int = 1;
}

////////////////////////////////////////////////////////////////////////////////
//
//  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.core
{
	import flash.system.ApplicationDomain;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	import flash.utils.getQualifiedSuperclassName;

	import org.apache.flex.events.EventDispatcher;
	import org.apache.flex.events.ValueChangeEvent;

    /**
     *  The SimpleCSSValuesImpl class implements a minimal set of
     *  CSS lookup rules that is sufficient for most applications.
     *  It does not support attribute selectors or descendant selectors
     *  or id selectors.  It will filter on a custom -flex-flash
     *  media query but not other media queries.  It can be
     *  replaced with other implementations that handle more complex
     *  selector lookups.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class SimpleCSSValuesImpl extends EventDispatcher implements IValuesImpl
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function SimpleCSSValuesImpl()
		{
			super();
		}

        private var mainClass:Object;

		private var conditionCombiners:Object;

        /**
         *  @copy org.apache.flex.core.IValuesImpl#init()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function init(mainClass:Object):void
        {
			var styleClassName:String;
			var c:Class;
			if (!values)
			{
				values = {};
	            this.mainClass = mainClass;
	            var mainClassName:String = getQualifiedClassName(mainClass);
				styleClassName = "_" + mainClassName + "_Styles";
				c = ApplicationDomain.currentDomain.getDefinition(styleClassName) as Class;
			}
			else
			{
				c = mainClass.constructor as Class;
			}
            generateCSSStyleDeclarations(c["factoryFunctions"], c["data"]);
        }

        /**
         *  Process the encoded CSS data into data structures.  Usually not called
         *  directly by application developers.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function generateCSSStyleDeclarations(factoryFunctions:Object, arr:Array):void
        {
			if (factoryFunctions == null)
				return;
			if (arr == null)
				return;

            var declarationName:String = "";
            var segmentName:String = "";
            var n:int = arr.length;
            for (var i:int = 0; i < n; i++)
            {
                var className:int = arr[i];
                if (className == CSSClass.CSSSelector)
                {
                    var selectorName:String = arr[++i];
                    segmentName = selectorName + segmentName;
                    if (declarationName != "")
                        declarationName += " ";
                    declarationName += segmentName;
                    segmentName = "";
                }
                else if (className == CSSClass.CSSCondition)
                {
					if (!conditionCombiners)
					{
						conditionCombiners = {};
						conditionCombiners["class"] = ".";
						conditionCombiners["id"] = "#";
						conditionCombiners["pseudo"] = ':';
					}
					var conditionType:String = arr[++i];
					var conditionName:String = arr[++i];
					segmentName = segmentName + conditionCombiners[conditionType] + conditionName;
                }
                else if (className == CSSClass.CSSStyleDeclaration)
                {
                    var factoryName:int = arr[++i]; // defaultFactory or factory
                    var defaultFactory:Boolean = factoryName == CSSFactory.DefaultFactory;
                    /*
                    if (defaultFactory)
                    {
                        mergedStyle = styleManager.getMergedStyleDeclaration(declarationName);
                        style = new CSSStyleDeclaration(selector, styleManager, mergedStyle == null);
                    }
                    else
                    {
                        style = styleManager.getStyleDeclaration(declarationName);
                        if (!style)
                        {
                            style = new CSSStyleDeclaration(selector, styleManager, mergedStyle == null);
                            if (factoryName == CSSFactory.Override)
                                newSelectors.push(style);
                        }
                    }
                    */
                    var mq:String = null;
                    var o:Object;
                    if (i < n - 2)
                    {
                        // peek ahead to see if there is a media query
                        if (arr[i + 1] == CSSClass.CSSMediaQuery)
                        {
                            mq = arr[i + 2];
                            i += 2;
                            declarationName = mq + "_" + declarationName;
                        }
                    }
                    var finalName:String;
                    var valuesFunction:Function;
                    var valuesObject:Object;
                    if (defaultFactory)
                    {
                        valuesFunction = factoryFunctions[declarationName];
                        valuesObject = new valuesFunction();
                    }
                    else
                    {
                        valuesFunction = factoryFunctions[declarationName];
                        valuesObject = new valuesFunction();
                    }
                    if (isValidStaticMediaQuery(mq))
                    {
                        finalName = fixNames(declarationName, mq);
                        o = values[finalName];
                        if (o == null)
                            values[finalName] = valuesObject;
                        else
                        {
                            valuesFunction.prototype = o;
                            values[finalName] = new valuesFunction();
                        }
                    }
                    declarationName = "";
                }
            }

        }

        private function isValidStaticMediaQuery(mq:String):Boolean
        {
            if (mq == null)
                return true;

            if (mq == "-flex-flash")
                return true;

            // TODO: (aharui) other media query

            return false;
        }

        private function fixNames(s:String, mq:String):String
        {
            if (mq != null)
                s = s.substr(mq.length + 1); // 1 more for the hyphen

			if (s == "")
				return "*";

            var arr:Array = s.split(" ");
            var n:int = arr.length;
            for (var i:int = 0; i < n; i++)
            {
                var segmentName:String = arr[i];
				if (segmentName.charAt(0) == "#" || segmentName.charAt(0) == ".")
					continue;

                var c:int = segmentName.lastIndexOf(".");
                if (c > -1)	// it is 0 for class selectors
                {
                    segmentName = segmentName.substr(0, c) + "::" + segmentName.substr(c + 1);
                    arr[i] = segmentName;
                }
            }
            return arr.join(" ");
        }

        /**
         *  The map of values.  The format is not documented and it is not recommended
         *  to manipulate this structure directly.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var values:Object;

        /**
         *  @copy org.apache.flex.core.IValuesImpl#getValue()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function getValue(thisObject:Object, valueName:String, state:String = null, attrs:Object = null):*
		{
            var c:int = valueName.indexOf("-");
            while (c != -1)
            {
                valueName = valueName.substr(0, c) +
                    valueName.charAt(c + 1).toUpperCase() +
                    valueName.substr(c + 2);
                c = valueName.indexOf("-");
            }

            var value:*;
			var o:Object;
			var className:String;
			var selectorName:String;

			if (thisObject is IStyleableObject)
			{
                var styleable:IStyleableObject = IStyleableObject(thisObject);
                if (styleable.style != null)
                {
                    try {
                        value = styleable.style[valueName];
                    }
                    catch (e:Error) {
                        value = undefined;
                    }
                    if (value == "inherit")
                        return getInheritingValue(thisObject, valueName, state, attrs);
                    if (value !== undefined)
                        return value;
                }
				className = styleable.className;
				if (state)
				{
					selectorName = className + ":" + state;
					o = values["." + selectorName];
					if (o)
					{
						value = o[valueName];
                        if (value == "inherit")
                            return getInheritingValue(thisObject, valueName, state, attrs);
						if (value !== undefined)
							return value;
					}
				}

				o = values["." + className];
				if (o)
				{
					value = o[valueName];
                    if (value == "inherit")
                        return getInheritingValue(thisObject, valueName, state, attrs);
					if (value !== undefined)
						return value;
				}
			}

			className = getQualifiedClassName(thisObject);
            var thisInstance:Object = thisObject;
			while (className != "Object")
			{
				if (state)
				{
					selectorName = className + ":" + state;
					o = values[selectorName];
					if (o)
					{
						value = o[valueName];
                        if (value == "inherit")
                            return getInheritingValue(thisObject, valueName, state, attrs);
						if (value !== undefined)
							return value;
					}
				}

	            o = values[className];
	            if (o)
	            {
	                value = o[valueName];
                    if (value == "inherit")
                        return getInheritingValue(thisObject, valueName, state, attrs);
	                if (value !== undefined)
	                    return value;
	            }
				className = getQualifiedSuperclassName(thisInstance);
				thisInstance = getDefinitionByName(className);
			}

            if (inheritingStyles[valueName] != null &&
                thisObject is IChild)
            {
                var parentObject:Object = IChild(thisObject).parent;
                if (parentObject)
                    return getValue(parentObject, valueName, state, attrs);
            }

            o = values["global"];
            if (o)
            {
    			value = o[valueName];
    			if (value !== undefined)
    				return value;
            }
			o = values["*"];
			if(o)
			{
				return o[valueName];
			}
			return undefined;
		}

        private function getInheritingValue(thisObject:Object, valueName:String, state:String = null, attrs:Object = null):*
        {
            var value:*;
            if (thisObject is IChild)
            {
                var parentObject:Object = IChild(thisObject).parent;
                if (parentObject)
                {
                    value = getValue(parentObject, valueName, state, attrs);
                    if (value == "inherit" || value === undefined)
                        return getInheritingValue(parentObject, valueName, state, attrs);
                    if (value !== undefined)
                        return value;
                }
            }
            return "inherit";
        }

        /**
         *  A method that stores a value to be shared with other objects.
         *  It is global, not per instance.  Fancier implementations
         *  may store shared values per-instance.
         *
         *  @param thisObject An object associated with this value.  Thiis
         *                parameter is ignored.
         *  @param valueName The name or key of the value being stored.
         *  @param The value to be stored.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function setValue(thisObject:Object, valueName:String, value:*):void
		{
            var c:int = valueName.indexOf("-");
            while (c != -1)
            {
                valueName = valueName.substr(0, c) +
                    valueName.charAt(c + 1).toUpperCase() +
                    valueName..substr(c + 2);
                c = valueName.indexOf("-");
            }
			var oldValue:Object = values[valueName];
			if (oldValue != value)
			{
				values[valueName] = value;
				dispatchEvent(new ValueChangeEvent(ValueChangeEvent.VALUE_CHANGE, false, false, oldValue, value));
			}
		}

		/**
		 *  @copy org.apache.flex.core.IValuesImpl#newInstance()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function newInstance(thisObject:Object, valueName:String, state:String = null, attrs:Object = null):*
		{
			var c:Class = getValue(thisObject, valueName, state, attrs);
			if (c)
				return new c();
			return null;
		}

        /**
         *  @copy org.apache.flex.core.IValuesImpl#getInstance()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function getInstance(valueName:String):Object
        {
            var o:Object = values["global"];
            if (o is Class)
            {
                o[valueName] = new o[valueName]();
                if (o[valueName] is IDocument)
                    o[valueName].setDocument(mainClass);
            }
            return o[valueName];
        }

        /**
         *  @copy org.apache.flex.core.IValuesImpl#convertColor()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public function convertColor(value:Object):uint
        {
            if (!(value is String))
                return uint(value);

            var stringValue:String = value as String;
            if (stringValue.charAt(0) == '#')
                return uint(stringValue.substr(1));
            return uint(stringValue);
        }

        /**
         *  A map of inheriting styles
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public static var inheritingStyles:Object = {
            "color" : 1,
            "fontFamily" : 1,
            "fontSize" : 1,
            "fontStyle" : 1,
            "textAlign" : 1
        }

	}
}

class CSSClass
{
    public static const CSSSelector:int = 0;
    public static const CSSCondition:int = 1;
    public static const CSSStyleDeclaration:int = 2;
    public static const CSSMediaQuery:int = 3;
}

class CSSFactory
{
    public static const DefaultFactory:int = 0;
    public static const Factory:int = 1;
    public static const Override:int = 2;
}

class CSSDataType
{
    public static const Native:int = 0;
    public static const Definition:int = 1;
}

handle text-align

handle text-align


package com.kaltura.kdpfl.plugin.component
{
	import com.kaltura.vo.KalturaPlayableEntry;

	import mx.utils.ObjectProxy;

	[Bindable]
	/**
	 * This class represents playlist entry object
	 * @author michalr
	 *
	 */
	public class PlaylistEntryVO extends ObjectProxy
	{
		/**
		 * Kaltura entry object
		 */
		public var entry:KalturaPlayableEntry;

		public var isOver:Boolean;

		public function PlaylistEntryVO(entry:KalturaPlayableEntry)
		{
			this.entry = entry;

		}

		//////////////////////////////////////////////////////////////////////
		// the following getters are required to keep backward compatibility
		//////////////////////////////////////////////////////////////////////

		public function get name():String
		{
			return entry.name;
		}

		public function get thumbnailUrl():String
		{
			return entry.thumbnailUrl;
		}

		public function get description():String
		{
			return entry.description;
		}

		public function get duration():int
		{
			return entry.duration;
		}

		public function get rank():Number
		{
			return entry.rank;
		}

		public function get plays():int
		{
			return entry.plays;
		}

		public function get entryId():String
		{
			return entry.entryId;
		}
	}
}

package com.kaltura.kdpfl.plugin.component
{
	import com.kaltura.vo.KalturaPlayableEntry;

	import mx.utils.ObjectProxy;

	[Bindable]
	/**
	 * This class represents playlist entry object
	 * @author michalr
	 *
	 */
	public class PlaylistEntryVO extends ObjectProxy
	{
		/**
		 * Kaltura entry object
		 */
		public var entry:KalturaPlayableEntry;

		public var isOver:Boolean;

		public function PlaylistEntryVO(entry:KalturaPlayableEntry)
		{
			this.entry = entry;

		}

		//////////////////////////////////////////////////////////////////////
		// the following getters are required to keep backward compatibility
		//////////////////////////////////////////////////////////////////////

		public function get name():String
		{
			return entry.name;
		}

		public function get thumbnailUrl():String
		{
			return entry.thumbnailUrl;
		}

		public function get description():String
		{
			return entry.description;
		}

		public function get duration():int
		{
			return entry.duration;
		}

		public function get rank():Number
		{
			return entry.rank;
		}

		public function get plays():int
		{
			return entry.plays;
		}

		public function get entryId():String
		{
			return entry.entryId;
		}

		public function get tags():String{
			return entry.tags;
		}

		public function get categories():String{
			return entry.categories;
		}

		public function get createdAt():int{
			return entry.createdAt;
		}

		public function get userScreenName():String
		{
			return entry.userScreenName;
		}

	}
}

qnd: add backward compatibility to this.tags, categories, createdAt and userScreenName

git-svn-id: 3f608e5a9a704dd448217c0a64c508e7f145cfa1@86344 6b8eccd3-e8c5-4e7d-8186-e12b5326b719


package com.testfairy
{
	import flash.external.ExtensionContext;
	import flash.system.Capabilities;

	public class AirTestFairy
	{
		public static function get isSupported():Boolean
		{
			return Capabilities.manufacturer.indexOf("iOS") > -1;
		}

		public static function begin():void
		{
			traceLog("TESTFAIRY LOG");

			call("begin");
		}

		public static function pushFeedbackController():void
		{
			traceLog("TESTFAIRY LOG");

			call("pushFeedbackController");
		}

		public static function setCorrelationId(value:String):void
		{
			traceLog("TESTFAIRY LOG");

			if (value)
			{
				call("setCorrelationId", value);
			}
		}

		public static function getSessionUrl():String
		{
			traceLog("TESTFAIRY LOG");

			return call("getSessionUrl");
		}

		public static function pause():void
		{
			traceLog("TESTFAIRY LOG");

			call("pause");
		}

		public static function resume():void
		{
			traceLog("TESTFAIRY LOG");

			call("resume");
		}

		public static function takeScreenshot():void
		{
			traceLog("TESTFAIRY LOG");

			call("takeScreenshot");
		}

		public static function log(value:String):void
		{
			traceLog("TESTFAIRY LOG");

			if (value)
			{
				call("log", value);
			}
		}

		private static const EXTENSION_ID : String = "com.testfairy";

		private static var _context : ExtensionContext = ExtensionContext.createExtensionContext(EXTENSION_ID, null);

		private static function call(...args):*
		{
			if (!isSupported) return null;

			if (!_context) throw new Error("Extension context is null. Please check if extension.xml is setup correctly.");

			return _context.call.apply(_context, args);
		}

		private static function traceLog(msg:String):void
		{
			trace("Adam" + msg);
		}
	}
}

package com.testfairy
{
	import flash.external.ExtensionContext;
	import flash.system.Capabilities;

	public class AirTestFairy
	{
		public static function get isSupported():Boolean
		{
			return Capabilities.manufacturer.indexOf("iOS") > -1;
		}

		public static function begin(appToken:String):void
		{
			if (value) {
				call("begin", appToken);
			}
		}

		public static function pushFeedbackController():void
		{
			call("pushFeedbackController");
		}

		public static function setCorrelationId(value:String):void
		{
			if (value) {
				call("setCorrelationId", value);
			}
		}

		public static function getSessionUrl():String
		{
			return call("getSessionUrl");
		}

		public static function pause():void
		{
			call("pause");
		}

		public static function resume():void
		{
			call("resume");
		}

		public static function takeScreenshot():void
		{
			call("takeScreenshot");
		}

		public static function log(value:String):void
		{
			if (value) {
				call("log", value);
			}
		}

		public static function getVersion():String
		{
			return call("getVersion");
		}

		private static const EXTENSION_ID : String = "com.testfairy";

		private static var _context : ExtensionContext = ExtensionContext.createExtensionContext(EXTENSION_ID, null);

		private static function call(...args):*
		{
			if (!isSupported) return null;

			if (!_context) throw new Error("Extension context is null. Please check if extension.xml is setup correctly.");

			return _context.call.apply(_context, args);
		}

		private static function traceLog(msg:String):void
		{
		}
	}
}

Update AirTestFairy.as

Update AirTestFairy.as


package aerys.minko.type
{
	public final class Signal
	{
		private var _name			: String;

		private var _callbacks		: Vector.<Function>;
		private var _numCallbacks	: uint;

		private var _executed		: Boolean;
		private var _numAdded		: uint;
		private var _toAdd			: Vector.<Function>;
		private var _numRemoved		: uint;
		private var _toRemove		: Vector.<Function>;

		public function get numCallbacks() : uint
		{
			return _numCallbacks;
		}

		public function Signal(name : String)
		{
			_name = name;
            _callbacks = new <Function>[];
		}

		public function add(callback : Function) : void
		{
            if (_callbacks.indexOf(callback) >= 0)
                throw new Error('The same callback cannot be added twice.');

			if (_executed)
			{
				if (_toAdd)
					_toAdd.push(callback);
				else
					_toAdd = new <Function>[callback];
				++_numAdded;

				return ;
			}

			_callbacks[_numCallbacks] = callback;
			++_numCallbacks;
		}

		public function remove(callback : Function) : void
		{
			var index : int = _callbacks.indexOf(callback);

			if (index < 0)
				throw new Error('This callback does not exist.');

			if (_executed)
			{
				if (_toRemove)
					_toRemove.push(callback);
				else
					_toRemove = new <Function>[callback];
				++_numRemoved;

				return ;
			}

			--_numCallbacks;
			_callbacks[index] = _callbacks[_numCallbacks];
			_callbacks.length = _numCallbacks;
		}

		public function hasCallback(callback : Function) : Boolean
		{
			return _callbacks.indexOf(callback) >= 0;
		}

		public function execute(...params) : void
		{
			if (_numCallbacks)
			{
				_executed = true;
				for (var i : uint = 0; i < _numCallbacks; ++i)
					_callbacks[i].apply(null, params);
				_executed = false;

				for (i = 0; i < _numAdded; ++i)
					add(_toAdd[i]);
				_numAdded = 0;
				_toAdd = null;

				for (i = 0; i < _numRemoved; ++i)
					remove(_toRemove[i]);
				_numRemoved = 0;
				_toRemove = null;
			}
		}
	}
}

package aerys.minko.type
{
	public final class Signal
	{
		private var _name			: String;

		private var _callbacks		: Vector.<Function>;
		private var _numCallbacks	: uint;

		private var _executed		: Boolean;
		private var _numAdded		: uint;
		private var _toAdd			: Vector.<Function>;
		private var _numRemoved		: uint;
		private var _toRemove		: Vector.<Function>;

		public function get numCallbacks() : uint
		{
			return _numCallbacks;
		}

		public function Signal(name : String)
		{
			_name = name;
            _callbacks = new <Function>[];
		}

		public function add(callback : Function) : void
		{
            if (_callbacks.indexOf(callback) >= 0)
            {
                var removeIndex : int = _toRemove ? _toRemove.indexOf(callback) : -1;

                // if that callback is in the temp. remove list, we simply remove it from this list
                // instead of removing/adding it all over again
                if (removeIndex >= 0)
                {
                    --_numRemoved;
                    _toRemove[removeIndex] = _toRemove[_numRemoved];
                    _toRemove.length = _numRemoved;

                    return;
                }
                else
                    throw new Error('The same callback cannot be added twice.');
            }

			if (_executed)
			{
				if (_toAdd)
					_toAdd.push(callback);
				else
					_toAdd = new <Function>[callback];
				++_numAdded;

				return ;
			}

			_callbacks[_numCallbacks] = callback;
			++_numCallbacks;
		}

		public function remove(callback : Function) : void
		{
			var index : int = _callbacks.indexOf(callback);

			if (index < 0)
            {
                var addIndex : int = _toAdd ? _toAdd.indexOf(callback) : -1;

                // if that callback is in the temp. add list, we simply remove it from this list
                // instead of adding/removing it all over again
                if (addIndex)
                {
                    --_numAdded;
                    _toAdd[addIndex] = _toAdd[_numAdded];
                    _toAdd.length = _numAdded;
                }
                else
    				throw new Error('This callback does not exist.');
            }

			if (_executed)
			{
				if (_toRemove)
					_toRemove.push(callback);
				else
					_toRemove = new <Function>[callback];
				++_numRemoved;

				return ;
			}

			--_numCallbacks;
			_callbacks[index] = _callbacks[_numCallbacks];
			_callbacks.length = _numCallbacks;
		}

		public function hasCallback(callback : Function) : Boolean
		{
			return _callbacks.indexOf(callback) >= 0;
		}

		public function execute(...params) : void
		{
			if (_numCallbacks)
			{
				_executed = true;
				for (var i : uint = 0; i < _numCallbacks; ++i)
					_callbacks[i].apply(null, params);
				_executed = false;

				for (i = 0; i < _numAdded; ++i)
					add(_toAdd[i]);
				_numAdded = 0;
				_toAdd = null;

				for (i = 0; i < _numRemoved; ++i)
					remove(_toRemove[i]);
				_numRemoved = 0;
				_toRemove = null;
			}
		}
	}
}

fix Signal.add() and Signal.remove() error checks to take the tmp _toAdd/_toRemove tmp lists into account


##                                                         -*- shell-script -*-
## base.as: This file is part of build-aux.
## Copyright (C) Gostai S.A.S., 2006-2008.
##
## This software is provided "as is" without warranty of any kind,
## either expressed or implied, including but not limited to the
## implied warranties of fitness for a particular purpose.
##
## See the LICENSE file for more information.
## For comments, bug reports and feedback: http://www.urbiforge.com
##

m4_pattern_forbid([^_?URBI_])dnl

# m4_define([_m4_divert(M4SH-INIT)],   5)
m4_define([_m4_divert(URBI-INIT)],    10)

m4_defun([_URBI_ABSOLUTE_PREPARE],
[
# is_absolute PATH
# ----------------
is_absolute ()
{
  case $[1] in
    ([[\\/]]* | ?:[[\\/]]*) return 0;;
    (                    *) return 1;;
  esac
}

# absolute NAME -> ABS-NAME
# -------------------------
# Return an absolute path to NAME.
absolute ()
{
  local res
  AS_IF([is_absolute "$[1]"],
  [# Absolute paths do not need to be expanded.
   res=$[1]],
  [local dir=$(pwd)/$(dirname "$[1]")
   if test -d "$dir"; then
     res=$(cd "$dir" 2>/dev/null && pwd)/$(basename "$[1]")
   else
     fatal "absolute: not a directory: $dir"
   fi])

  # On Windows, we must make sure we have a Windows-like UNIX-friendly path (of
  # the form C:/cygwin/path/to/somewhere instead of /path/to/somewhere, notice
  # the use of forward slashes in the Windows path.  Windows *does* understand
  # paths with forward slashes).
  case $(uname -s) in
    (CYGWIN*) res=$(cygpath "$res")
  esac
  echo "$res"
}
])

m4_defun([_URBI_FIND_PROG_PREPARE],
[# find_file FILE PATH
# -------------------
# Return full path to FILE in PATH ($PATH_SEPARATOR separated),
# nothing if not found.
find_prog ()
{
  _AS_PATH_WALK([$[2]],
                [AS_IF([test -f $as_dir/$[1]],
                       [echo "$as_dir/$[1]"; break])])
}

# xfind_file PROG PATH
# --------------------
# Same as xfind_prog, but don't take "no" for an answer.
xfind_file ()
{
  local res
  res=$(find_prog "$[1]" "$[2]")
  test -n "$res" ||
    error OSFILE "cannot find $[1] in $[2]"
  echo "$res"
}

# find_prog PROG [PATH=$PATH]
# ---------------------------
# Return full path to PROG in PATH ($PATH_SEPARATOR separated),
# nothing if not found.
find_prog ()
{
  local path=$PATH
  test -z "$[2]" || path=$[2]

  _AS_PATH_WALK([$path],
                [AS_IF([AS_TEST_X([$as_dir/$[1]])],
                       [echo "$as_dir/$[1]"; break])])
}

# xfind_prog PROG [PATH=$PATH]
# ----------------------------
# Same as xfind_prog, but don't take "no" for an answer.
xfind_prog ()
{
  local path=$PATH
  test -z "$[2]" || path=$[2]
  local res
  res=$(find_prog "$[1]" "$path")
  test -n "$res" ||
    error OSFILE "cannot find executable $[1] in $path"
  echo "$res"
}

# require_thing TEST-FLAG ERROR_MESSAGE THING [HINT]
# --------------------------------------------------
require_thing ()
{
  local flag=$[1]
  local error="$[2]: $[3]"
  local thing=$[3]
  shift 3
  test $flag "$thing" ||
    fatal OSFILE "$error" "$[@]"
}

# require_dir DIR [HINT]
# ----------------------
require_dir ()
{
  require_thing -d "no such directory" "$[@]"
}

# require_file FILE [HINT]
# ------------------------
require_file ()
{
  require_thing -f "no such file" "$[@]"
}

])

m4_defun([_URBI_STDERR_PREPARE],
[
# stderr LINES
# ------------
stderr ()
{
  local i
  for i
  do
    echo >&2 "$as_me: $i"
  done
  echo >&2
}

# error EXIT MESSAGES
# -------------------
error ()
{
  local exit=$[1]
  shift
  stderr "$[@]"
  ex_exit $exit
}

# fatal MESSAGES
# --------------
fatal ()
{
  # To help the user, just make sure that she is not confused between
  # the prototypes of fatal and error: the first argument is unlikely
  # to be integer.
  case $[1] in
    (*[[!0-9]]*|'') ;;
    (*)  stderr "warning: possible confusion between fatal and error" \
                "fatal $[*]";;
  esac

  error 1 "$[@]"
}

# ex_to_string EXIT
# -----------------
# Return a decoding of EXIT status if available, nothing otherwise.
ex_to_string ()
{
  case $[1] in
     (  0) echo ' (EX_OK: successful termination)';;
     ( 64) echo ' (EX_USAGE: command line usage error)';;
     ( 65) echo ' (EX_DATAERR: data format error)';;
     ( 66) echo ' (EX_NOINPUT: cannot open input)';;
     ( 67) echo ' (EX_NOUSER: addressee unknown)';;
     ( 68) echo ' (EX_NOHOST: host name unknown)';;
     ( 69) echo ' (EX_UNAVAILABLE: service unavailable)';;
     ( 70) echo ' (EX_SOFTWARE: internal software error)';;
     ( 71) echo ' (EX_OSERR: system error (e.g., cannot fork))';;
     ( 72) echo ' (EX_OSFILE: critical OS file missing)';;
     ( 73) echo ' (EX_CANTCREAT: cannot create (user) output file)';;
     ( 74) echo ' (EX_IOERR: input/output error)';;
     ( 75) echo ' (EX_TEMPFAIL: temp failure; user is invited to retry)';;
     ( 76) echo ' (EX_PROTOCOL: remote error in protocol)';;
     ( 77) echo ' (EX_NOPERM: permission denied)';;
     ( 78) echo ' (EX_CONFIG: configuration error)';;
     (176) echo ' (EX_SKIP: skip this test with unmet dependencies)';;
     (177) echo ' (EX_HARD: hard error that cannot be saved)';;
     (242) echo ' (killed by Valgrind)';;
     (  *) if test 127 -lt $[1]; then
            echo " (SIG$(kill -l $[1] || true))"
          fi;;
  esac
}

# ex_to_int CODE
# --------------
# Decode the CODE and return the corresponding int.
ex_to_int ()
{
  case $[1] in
    (OK         |EX_OK)          echo 0;;
    (USAGE      |EX_USAGE)       echo 64;;
    (DATAERR    |EX_DATAERR)     echo 65;;
    (NOINPUT    |EX_NOINPUT)     echo 66;;
    (NOUSER     |EX_NOUSER)      echo 67;;
    (NOHOST     |EX_NOHOST)      echo 68;;
    (UNAVAILABLE|EX_UNAVAILABLE) echo 69;;
    (SOFTWARE   |EX_SOFTWARE)    echo 70;;
    (OSERR      |EX_OSERR)       echo 71;;
    (OSFILE     |EX_OSFILE)      echo 72;;
    (CANTCREAT  |EX_CANTCREAT)   echo 73;;
    (IOERR      |EX_IOERR)       echo 74;;
    (TEMPFAIL   |EX_TEMPFAIL)    echo 75;;
    (PROTOCOL   |EX_PROTOCOL)    echo 76;;
    (NOPERM     |EX_NOPERM)      echo 77;;
    (CONFIG     |EX_CONFIG)      echo 78;;

    (SKIP       |EX_SKIP)        echo 176;;
    (HARD       |EX_HARD)        echo 177;;

    (*)                          echo $[1];;
  esac
}

ex_exit ()
{
  exit $(ex_to_int $[1])
}
])

# URBI_GET_OPTIONS
# ----------------
# Generate get_options().
m4_define([URBI_GET_OPTIONS],
[# Parse command line options
get_options ()
{
  while test $[#] -ne 0; do
    case $[1] in
        (--*=*)
            opt=$(echo "$[1]" | sed -e 's/=.*//')
            val=$(echo "$[1]" | sed -e ['s/[^=]*=//'])
            shift
            set dummy "$opt" "$val" ${1+"$[@]"};
            shift
            ;;
    esac

    case $[1] in
      $@
    esac
    shift
  done
}
])

m4_defun([_URBI_PREPARE],
[
# truth TEST-ARGUMENTS...
# -----------------------
# Run "test TEST-ARGUMENTS" and echo true/false depending on the result.
truth ()
{
  if test "$[@]"; then
    echo true
  else
    echo false
  fi
}

_URBI_ABSOLUTE_PREPARE
_URBI_FIND_PROG_PREPARE
_URBI_STDERR_PREPARE

])

# URBI_PREPARE
# ------------
# Output all the M4sh possible initialization into the initialization
# diversion.
m4_defun([URBI_PREPARE],
[m4_divert_text([M4SH-INIT], [_URBI_PREPARE])dnl
URBI_RST_PREPARE()dnl
URBI_INSTRUMENT_PREPARE()dnl
URBI_CHILDREN_PREPARE()dnl
])

# URBI_INIT
# ---------
# Replaces the AS_INIT invocation.
# Must be defined via "m4_define", not "m4_defun" since it is AS_INIT
# which will set up the diversions used for "m4_defun".
m4_define([URBI_INIT],
[AS_INIT()dnl
URBI_PREPARE()
set -e
case $VERBOSE in
  (x) set -x;;
esac

: ${abs_builddir='@abs_builddir@'}
: ${abs_srcdir='@abs_srcdir@'}
: ${abs_top_builddir='@abs_top_builddir@'}
: ${abs_top_srcdir='@abs_top_srcdir@'}
: ${builddir='@builddir@'}
: ${srcdir='@srcdir@'}
: ${top_builddir='@top_builddir@'}
: ${top_srcdir='@top_srcdir@'}
])

##                                                         -*- shell-script -*-
## base.as: This file is part of build-aux.
## Copyright (C) Gostai S.A.S., 2006-2008.
##
## This software is provided "as is" without warranty of any kind,
## either expressed or implied, including but not limited to the
## implied warranties of fitness for a particular purpose.
##
## See the LICENSE file for more information.
## For comments, bug reports and feedback: http://www.urbiforge.com
##

m4_pattern_forbid([^_?URBI_])dnl

# m4_define([_m4_divert(M4SH-INIT)],   5)
m4_define([_m4_divert(URBI-INIT)],    10)

m4_defun([_URBI_ABSOLUTE_PREPARE],
[
# is_absolute PATH
# ----------------
is_absolute ()
{
  case $[1] in
    ([[\\/]]* | ?:[[\\/]]*) return 0;;
    (                    *) return 1;;
  esac
}

# absolute NAME -> ABS-NAME
# -------------------------
# Return an absolute path to NAME.
absolute ()
{
  local res
  AS_IF([is_absolute "$[1]"],
  [# Absolute paths do not need to be expanded.
   res=$[1]],
  [local dir=$(pwd)/$(dirname "$[1]")
   if test -d "$dir"; then
     res=$(cd "$dir" 2>/dev/null && pwd)/$(basename "$[1]")
   else
     fatal "absolute: not a directory: $dir"
   fi])

  # On Windows, we must make sure we have a Windows-like UNIX-friendly path (of
  # the form C:/cygwin/path/to/somewhere instead of /path/to/somewhere, notice
  # the use of forward slashes in the Windows path.  Windows *does* understand
  # paths with forward slashes).
  case $(uname -s) in
    (CYGWIN*) res=$(cygpath "$res")
  esac
  echo "$res"
}
])

m4_defun([_URBI_FIND_PROG_PREPARE],
[# find_file FILE PATH
# -------------------
# Return full path to FILE in PATH ($PATH_SEPARATOR separated),
# nothing if not found.
find_prog ()
{
  _AS_PATH_WALK([$[2]],
                [AS_IF([test -f $as_dir/$[1]],
                       [echo "$as_dir/$[1]"; break])])
}

# xfind_file PROG PATH
# --------------------
# Same as xfind_prog, but don't take "no" for an answer.
xfind_file ()
{
  local res
  res=$(find_prog "$[1]" "$[2]")
  test -n "$res" ||
    error OSFILE "cannot find $[1] in $[2]"
  echo "$res"
}

# find_prog PROG [PATH=$PATH]
# ---------------------------
# Return full path to PROG in PATH ($PATH_SEPARATOR separated),
# nothing if not found.
find_prog ()
{
  local path=$PATH
  test -z "$[2]" || path=$[2]

  _AS_PATH_WALK([$path],
                [AS_IF([AS_TEST_X([$as_dir/$[1]])],
                       [echo "$as_dir/$[1]"; break])])
}

# xfind_prog PROG [PATH=$PATH]
# ----------------------------
# Same as xfind_prog, but don't take "no" for an answer.
xfind_prog ()
{
  local path=$PATH
  test -z "$[2]" || path=$[2]
  local res
  res=$(find_prog "$[1]" "$path")
  test -n "$res" ||
    error OSFILE "cannot find executable $[1] in $path"
  echo "$res"
}

# require_thing TEST-FLAG ERROR_MESSAGE THING [HINT]
# --------------------------------------------------
require_thing ()
{
  local flag=$[1]
  local error="$[2]: $[3]"
  local thing=$[3]
  shift 3
  test $flag "$thing" ||
    error OSFILE "$error" "$[@]"
}

# require_dir DIR [HINT]
# ----------------------
require_dir ()
{
  require_thing -d "no such directory" "$[@]"
}

# require_file FILE [HINT]
# ------------------------
require_file ()
{
  require_thing -f "no such file" "$[@]"
}

])

m4_defun([_URBI_STDERR_PREPARE],
[
# stderr LINES
# ------------
stderr ()
{
  local i
  for i
  do
    echo >&2 "$as_me: $i"
  done
  echo >&2
}

# error EXIT MESSAGES
# -------------------
error ()
{
  local exit=$[1]
  shift
  stderr "$[@]"
  ex_exit $exit
}

# fatal MESSAGES
# --------------
fatal ()
{
  # To help the user, just make sure that she is not confused between
  # the prototypes of fatal and error: the first argument is unlikely
  # to be integer.
  case $[1] in
    (*[[!0-9]]*|'') ;;
    (*)  stderr "warning: possible confusion between fatal and error" \
                "fatal $[*]";;
  esac

  error 1 "$[@]"
}

# ex_to_string EXIT
# -----------------
# Return a decoding of EXIT status if available, nothing otherwise.
ex_to_string ()
{
  case $[1] in
     (  0) echo ' (EX_OK: successful termination)';;
     ( 64) echo ' (EX_USAGE: command line usage error)';;
     ( 65) echo ' (EX_DATAERR: data format error)';;
     ( 66) echo ' (EX_NOINPUT: cannot open input)';;
     ( 67) echo ' (EX_NOUSER: addressee unknown)';;
     ( 68) echo ' (EX_NOHOST: host name unknown)';;
     ( 69) echo ' (EX_UNAVAILABLE: service unavailable)';;
     ( 70) echo ' (EX_SOFTWARE: internal software error)';;
     ( 71) echo ' (EX_OSERR: system error (e.g., cannot fork))';;
     ( 72) echo ' (EX_OSFILE: critical OS file missing)';;
     ( 73) echo ' (EX_CANTCREAT: cannot create (user) output file)';;
     ( 74) echo ' (EX_IOERR: input/output error)';;
     ( 75) echo ' (EX_TEMPFAIL: temp failure; user is invited to retry)';;
     ( 76) echo ' (EX_PROTOCOL: remote error in protocol)';;
     ( 77) echo ' (EX_NOPERM: permission denied)';;
     ( 78) echo ' (EX_CONFIG: configuration error)';;
     (176) echo ' (EX_SKIP: skip this test with unmet dependencies)';;
     (177) echo ' (EX_HARD: hard error that cannot be saved)';;
     (242) echo ' (killed by Valgrind)';;
     (  *) if test 127 -lt $[1]; then
            echo " (SIG$(kill -l $[1] || true))"
          fi;;
  esac
}

# ex_to_int CODE
# --------------
# Decode the CODE and return the corresponding int.
ex_to_int ()
{
  case $[1] in
    (OK         |EX_OK)          echo 0;;
    (USAGE      |EX_USAGE)       echo 64;;
    (DATAERR    |EX_DATAERR)     echo 65;;
    (NOINPUT    |EX_NOINPUT)     echo 66;;
    (NOUSER     |EX_NOUSER)      echo 67;;
    (NOHOST     |EX_NOHOST)      echo 68;;
    (UNAVAILABLE|EX_UNAVAILABLE) echo 69;;
    (SOFTWARE   |EX_SOFTWARE)    echo 70;;
    (OSERR      |EX_OSERR)       echo 71;;
    (OSFILE     |EX_OSFILE)      echo 72;;
    (CANTCREAT  |EX_CANTCREAT)   echo 73;;
    (IOERR      |EX_IOERR)       echo 74;;
    (TEMPFAIL   |EX_TEMPFAIL)    echo 75;;
    (PROTOCOL   |EX_PROTOCOL)    echo 76;;
    (NOPERM     |EX_NOPERM)      echo 77;;
    (CONFIG     |EX_CONFIG)      echo 78;;

    (SKIP       |EX_SKIP)        echo 176;;
    (HARD       |EX_HARD)        echo 177;;

    (*)                          echo $[1];;
  esac
}

ex_exit ()
{
  exit $(ex_to_int $[1])
}
])

# URBI_GET_OPTIONS
# ----------------
# Generate get_options().
m4_define([URBI_GET_OPTIONS],
[# Parse command line options
get_options ()
{
  while test $[#] -ne 0; do
    case $[1] in
        (--*=*)
            opt=$(echo "$[1]" | sed -e 's/=.*//')
            val=$(echo "$[1]" | sed -e ['s/[^=]*=//'])
            shift
            set dummy "$opt" "$val" ${1+"$[@]"};
            shift
            ;;
    esac

    case $[1] in
      $@
    esac
    shift
  done
}
])

m4_defun([_URBI_PREPARE],
[
# truth TEST-ARGUMENTS...
# -----------------------
# Run "test TEST-ARGUMENTS" and echo true/false depending on the result.
truth ()
{
  if test "$[@]"; then
    echo true
  else
    echo false
  fi
}

_URBI_ABSOLUTE_PREPARE
_URBI_FIND_PROG_PREPARE
_URBI_STDERR_PREPARE

])

# URBI_PREPARE
# ------------
# Output all the M4sh possible initialization into the initialization
# diversion.
m4_defun([URBI_PREPARE],
[m4_divert_text([M4SH-INIT], [_URBI_PREPARE])dnl
URBI_RST_PREPARE()dnl
URBI_INSTRUMENT_PREPARE()dnl
URBI_CHILDREN_PREPARE()dnl
])

# URBI_INIT
# ---------
# Replaces the AS_INIT invocation.
# Must be defined via "m4_define", not "m4_defun" since it is AS_INIT
# which will set up the diversions used for "m4_defun".
m4_define([URBI_INIT],
[AS_INIT()dnl
URBI_PREPARE()
set -e
case $VERBOSE in
  (x) set -x;;
esac

: ${abs_builddir='@abs_builddir@'}
: ${abs_srcdir='@abs_srcdir@'}
: ${abs_top_builddir='@abs_top_builddir@'}
: ${abs_top_srcdir='@abs_top_srcdir@'}
: ${builddir='@builddir@'}
: ${srcdir='@srcdir@'}
: ${top_builddir='@top_builddir@'}
: ${top_srcdir='@top_srcdir@'}
])

Fix error vs. fatal confusion.

Fix error vs. fatal confusion.

	* build-aux/base.as: here.