From 8e0b068b1d6929af82ef348a47b235dd89196c11 Mon Sep 17 00:00:00 2001
From: sostler The application can provide an implementation that automatically
- * resolves site.net to site.com before URI compares two URI objects.
- * Only the application can know and understand the context in which
- * the URI's are being used. Use the URI.resolver accessor to assign a custom resolver to
- * the URI class. Any resolver specified is global to all instances
- * of URI. URI will call this before performing URI comparisons in the
- * URI.getRelation() and URI.getCommonParent() functions.
- *
- * @see URI.getRelation
- * @see URI.getCommonParent
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public interface IURIResolver
- {
- /**
- * Implement this method to provide custom URI resolution for
- * your application.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- function resolve(uri:URI) : URI;
- }
+/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.net
+{
+ /**
+ * The URI class cannot know about DNS aliases, virtual hosts, or
+ * symbolic links that may be involved. The application can provide
+ * an implementation of this interface to resolve the URI before the
+ * URI class makes any comparisons. For example, a web host has
+ * two aliases:
+ *
+ * The application can provide an implementation that automatically
+ * resolves site.net to site.com before URI compares two URI objects.
+ * Only the application can know and understand the context in which
+ * the URI's are being used. Use the URI.resolver accessor to assign a custom resolver to
+ * the URI class. Any resolver specified is global to all instances
+ * of URI. URI will call this before performing URI comparisons in the
+ * URI.getRelation() and URI.getCommonParent() functions.
+ *
+ * @see URI.getRelation
+ * @see URI.getCommonParent
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public interface IURIResolver
+ {
+ /**
+ * Implement this method to provide custom URI resolution for
+ * your application.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ function resolve(uri:URI) : URI;
+ }
}
\ No newline at end of file
diff --git a/webcam/com/adobe/net/URI.as b/webcam/com/adobe/net/URI.as
index 8ec9acd..40e1cbc 100644
--- a/webcam/com/adobe/net/URI.as
+++ b/webcam/com/adobe/net/URI.as
@@ -1,2469 +1,2469 @@
-/*
-Adobe Systems Incorporated(r) Source Code License Agreement
-Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
-Please read this Source Code License Agreement carefully before using
-the source code.
-
-Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable copyright license, to reproduce,
-prepare derivative works of, publicly display, publicly perform, and
-distribute this source code and such derivative works in source or
-object code form without any attribution requirements.
-
-The name "Adobe Systems Incorporated" must not be used to endorse or promote products
-derived from the source code without prior written permission.
-
-You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
-against any loss, damage, claims or lawsuits, including attorney's
-fees that arise or result from your use or distribution of the source
-code.
-
-THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
-ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
-NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
-OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.net
-{
- import flash.utils.ByteArray;
-
- /**
- * This class implements functions and utilities for working with URI's
- * (Universal Resource Identifiers). For technical description of the
- * URI syntax, please see RFC 3986 at http://www.ietf.org/rfc/rfc3986.txt
- * or do a web search for "rfc 3986".
- *
- * The most important aspect of URI's to understand is that URI's
- * and URL's are not strings. URI's are complex data structures that
- * encapsulate many pieces of information. The string version of a
- * URI is the serialized representation of that data structure. This
- * string serialization is used to provide a human readable
- * representation and a means to transport the data over the network
- * where it can then be parsed back into its' component parts. URI's fall into one of three categories:
- * ' : '',
- class_name = (image != '') ? 'gritter-with-image' : 'gritter-without-image';
-
- // String replacements on the template
- tmp = this._str_replace(
- ['[[username]]', '[[text]]', '[[image]]', '[[number]]', '[[class_name]]', '[[item_class]]'],
- [user, text, image_str, this._item_count, class_name, item_class], tmp
- );
-
- this['_before_open_' + number]();
- $('#gritter-notice-wrapper').append(tmp);
-
- var item = $('#gritter-item-' + this._item_count);
-
- item.fadeIn(this.fade_in_speed, function(){
- Gritter['_after_open_' + number]($(this));
- });
-
- if(!sticky){
- this._setFadeTimer(item, number);
- }
-
- // Bind the hover/unhover states
- $(item).bind('mouseenter mouseleave', function(event){
- if(event.type == 'mouseenter'){
- if(!sticky){
- Gritter._restoreItemIfFading($(this), number);
- }
- }
- else {
- if(!sticky){
- Gritter._setFadeTimer($(this), number);
- }
- }
- Gritter._hoverState($(this), event.type);
- });
-
- return number;
-
- },
-
- /**
- * If we don't have any more gritter notifications, get rid of the wrapper using this check
- * @private
- * @param {Integer} unique_id The ID of the element that was just deleted, use it for a callback
- * @param {Object} e The jQuery element that we're going to perform the remove() action on
- */
- _countRemoveWrapper: function(unique_id, e){
-
- // Remove it then run the callback function
- e.remove();
- this['_after_close_' + unique_id](e);
-
- // Check if the wrapper is empty, if it is.. remove the wrapper
- if($('.gritter-item-wrapper').length == 0){
- $('#gritter-notice-wrapper').remove();
- }
-
- },
-
- /**
- * Fade out an element after it's been on the screen for x amount of time
- * @private
- * @param {Object} e The jQuery element to get rid of
- * @param {Integer} unique_id The id of the element to remove
- * @param {Object} params An optional list of params to set fade speeds etc.
- * @param {Boolean} unbind_events Unbind the mouseenter/mouseleave events if they click (X)
- */
- _fade: function(e, unique_id, params, unbind_events){
-
- var params = params || {},
- fade = (typeof(params.fade) != 'undefined') ? params.fade : true;
- fade_out_speed = params.speed || this.fade_out_speed;
-
- this['_before_close_' + unique_id](e);
-
- // If this is true, then we are coming from clicking the (X)
- if(unbind_events){
- e.unbind('mouseenter mouseleave');
- }
-
- // Fade it out or remove it
- if(fade){
-
- e.animate({
- opacity: 0
- }, fade_out_speed, function(){
- e.animate({ height: 0 }, 300, function(){
- Gritter._countRemoveWrapper(unique_id, e);
- })
- })
-
- }
- else {
-
- this._countRemoveWrapper(unique_id, e);
-
- }
-
- },
-
- /**
- * Perform actions based on the type of bind (mouseenter, mouseleave)
- * @private
- * @param {Object} e The jQuery element
- * @param {String} type The type of action we're performing: mouseenter or mouseleave
- */
- _hoverState: function(e, type){
-
- // Change the border styles and add the (X) close button when you hover
- if(type == 'mouseenter'){
-
- e.addClass('hover');
- var find_img = e.find('img');
-
- // Insert the close button before what element
- (find_img.length) ?
- find_img.before(this._tpl_close) :
- e.find('span').before(this._tpl_close);
-
- // Clicking (X) makes the perdy thing close
- e.find('.gritter-close').click(function(){
-
- var unique_id = e.attr('id').split('-')[2];
- Gritter.removeSpecific(unique_id, {}, e, true);
-
- });
-
- }
- // Remove the border styles and (X) close button when you mouse out
- else {
-
- e.removeClass('hover');
- e.find('.gritter-close').remove();
-
- }
-
- },
-
- /**
- * Remove a specific notification based on an ID
- * @param {Integer} unique_id The ID used to delete a specific notification
- * @param {Object} params A set of options passed in to determine how to get rid of it
- * @param {Object} e The jQuery element that we're "fading" then removing
- * @param {Boolean} unbind_events If we clicked on the (X) we set this to true to unbind mouseenter/mouseleave
- */
- removeSpecific: function(unique_id, params, e, unbind_events){
-
- if(!e){
- var e = $('#gritter-item-' + unique_id);
- }
-
- // We set the fourth param to let the _fade function know to
- // unbind the "mouseleave" event. Once you click (X) there's no going back!
- this._fade(e, unique_id, params || {}, unbind_events);
-
- },
-
- /**
- * If the item is fading out and we hover over it, restore it!
- * @private
- * @param {Object} e The HTML element to remove
- * @param {Integer} unique_id The ID of the element
- */
- _restoreItemIfFading: function(e, unique_id){
-
- clearTimeout(this['_int_id_' + unique_id]);
- e.stop().css({ opacity: '' });
-
- },
-
- /**
- * Setup the global options - only once
- * @private
- */
- _runSetup: function(){
-
- for(opt in $.gritter.options){
- this[opt] = $.gritter.options[opt];
- }
- this._is_setup = 1;
-
- },
-
- /**
- * Set the notification to fade out after a certain amount of time
- * @private
- * @param {Object} item The HTML element we're dealing with
- * @param {Integer} unique_id The ID of the element
- */
- _setFadeTimer: function(e, unique_id){
-
- var timer_str = (this._custom_timer) ? this._custom_timer : this.time;
- this['_int_id_' + unique_id] = setTimeout(function(){
- Gritter._fade(e, unique_id);
- }, timer_str);
-
- },
-
- /**
- * Bring everything to a halt
- * @param {Object} params A list of callback functions to pass when all notifications are removed
- */
- stop: function(params){
-
- // callbacks (if passed)
- var before_close = ($.isFunction(params.before_close)) ? params.before_close : function(){};
- var after_close = ($.isFunction(params.after_close)) ? params.after_close : function(){};
-
- var wrap = $('#gritter-notice-wrapper');
- before_close(wrap);
- wrap.fadeOut(function(){
- $(this).remove();
- after_close();
- });
-
- },
-
- /**
- * An extremely handy PHP function ported to JS, works well for templating
- * @private
- * @param {String/Array} search A list of things to search for
- * @param {String/Array} replace A list of things to replace the searches with
- * @return {String} sa The output
- */
- _str_replace: function(search, replace, subject, count){
-
- var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
- f = [].concat(search),
- r = [].concat(replace),
- s = subject,
- ra = r instanceof Array, sa = s instanceof Array;
- s = [].concat(s);
-
- if(count){
- this.window[count] = 0;
- }
-
- for(i = 0, sl = s.length; i < sl; i++){
-
- if(s[i] === ''){
- continue;
- }
-
- for (j = 0, fl = f.length; j < fl; j++){
-
- temp = s[i] + '';
- repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
- s[i] = (temp).split(f[j]).join(repl);
-
- if(count && s[i] !== temp){
- this.window[count] += (temp.length-s[i].length) / f[j].length;
- }
-
- }
- }
-
- return sa ? s : s[0];
-
- },
-
- /**
- * A check to make sure we have something to wrap our notices with
- * @private
- */
- _verifyWrapper: function(){
-
- if($('#gritter-notice-wrapper').length == 0){
- $('body').append(this._tpl_wrap);
- }
-
- }
-
- }
-
-})(jQuery);
+/*
+ * Gritter for jQuery
+ * http://www.boedesign.com/
+ *
+ * Copyright (c) 2009 Jordan Boesch
+ * Dual licensed under the MIT and GPL licenses.
+ *
+ * Date: December 1, 2009
+ * Version: 1.6
+ */
+
+(function($){
+
+ /**
+ * Set it up as an object under the jQuery namespace
+ */
+ $.gritter = {};
+
+ /**
+ * Set up global options that the user can over-ride
+ */
+ $.gritter.options = {
+ fade_in_speed: 'medium', // how fast notifications fade in
+ fade_out_speed: 1000, // how fast the notices fade out
+ time: 4500 // hang on the screen for...
+ }
+
+ /**
+ * Add a gritter notification to the screen
+ * @see Gritter#add();
+ */
+ $.gritter.add = function(params){
+
+ try {
+ return Gritter.add(params || {});
+ } catch(e) {
+
+ var err = 'Gritter Error: ' + e;
+ (typeof(console) != 'undefined' && console.error) ?
+ console.error(err, params) :
+ alert(err);
+
+ }
+
+ }
+
+ /**
+ * Remove a gritter notification from the screen
+ * @see Gritter#removeSpecific();
+ */
+ $.gritter.remove = function(id, params){
+ Gritter.removeSpecific(id, params || {});
+ }
+
+ /**
+ * Remove all notifications
+ * @see Gritter#stop();
+ */
+ $.gritter.removeAll = function(params){
+ Gritter.stop(params || {});
+ }
+
+ /**
+ * Big fat Gritter object
+ * @constructor (not really since it's object literal)
+ */
+ var Gritter = {
+
+ // Public - options to over-ride with $.gritter.options in "add"
+ fade_in_speed: '',
+ fade_out_speed: '',
+ time: '',
+
+ // Private - no touchy the private parts
+ _custom_timer: 0,
+ _item_count: 0,
+ _is_setup: 0,
+ _tpl_close: '',
+ _tpl_item: '',
+ _tpl_wrap: '',
+
+ /**
+ * Add a gritter notification to the screen
+ * @param {Object} params The object that contains all the options for drawing the notification
+ * @return {Integer} The specific numeric id to that gritter notification
+ */
+ add: function(params){
+
+ // We might have some issues if we don't have a title or text!
+ if(!params.title || !params.text){
+ throw 'You need to fill out the first 2 params: "title" and "text"';
+ }
+
+ // Check the options and set them once
+ if(!this._is_setup){
+ this._runSetup();
+ }
+
+ // Basics
+ var user = params.title,
+ text = params.text,
+ image = params.image || '',
+ sticky = params.sticky || false,
+ item_class = params.class_name || '',
+ time_alive = params.time || '';
+
+ this._verifyWrapper();
+
+ this._item_count++;
+ var number = this._item_count,
+ tmp = this._tpl_item;
+
+ // Assign callbacks
+ $(['before_open', 'after_open', 'before_close', 'after_close']).each(function(i, val){
+ Gritter['_' + val + '_' + number] = ($.isFunction(params[val])) ? params[val] : function(){}
+ });
+
+ // Reset
+ this._custom_timer = 0;
+
+ // A custom fade time set
+ if(time_alive){
+ this._custom_timer = time_alive;
+ }
+
+ var image_str = (image != '') ? '
' : '',
+ class_name = (image != '') ? 'gritter-with-image' : 'gritter-without-image';
+
+ // String replacements on the template
+ tmp = this._str_replace(
+ ['[[username]]', '[[text]]', '[[image]]', '[[number]]', '[[class_name]]', '[[item_class]]'],
+ [user, text, image_str, this._item_count, class_name, item_class], tmp
+ );
+
+ this['_before_open_' + number]();
+ $('#gritter-notice-wrapper').append(tmp);
+
+ var item = $('#gritter-item-' + this._item_count);
+
+ item.fadeIn(this.fade_in_speed, function(){
+ Gritter['_after_open_' + number]($(this));
+ });
+
+ if(!sticky){
+ this._setFadeTimer(item, number);
+ }
+
+ // Bind the hover/unhover states
+ $(item).bind('mouseenter mouseleave', function(event){
+ if(event.type == 'mouseenter'){
+ if(!sticky){
+ Gritter._restoreItemIfFading($(this), number);
+ }
+ }
+ else {
+ if(!sticky){
+ Gritter._setFadeTimer($(this), number);
+ }
+ }
+ Gritter._hoverState($(this), event.type);
+ });
+
+ return number;
+
+ },
+
+ /**
+ * If we don't have any more gritter notifications, get rid of the wrapper using this check
+ * @private
+ * @param {Integer} unique_id The ID of the element that was just deleted, use it for a callback
+ * @param {Object} e The jQuery element that we're going to perform the remove() action on
+ */
+ _countRemoveWrapper: function(unique_id, e){
+
+ // Remove it then run the callback function
+ e.remove();
+ this['_after_close_' + unique_id](e);
+
+ // Check if the wrapper is empty, if it is.. remove the wrapper
+ if($('.gritter-item-wrapper').length == 0){
+ $('#gritter-notice-wrapper').remove();
+ }
+
+ },
+
+ /**
+ * Fade out an element after it's been on the screen for x amount of time
+ * @private
+ * @param {Object} e The jQuery element to get rid of
+ * @param {Integer} unique_id The id of the element to remove
+ * @param {Object} params An optional list of params to set fade speeds etc.
+ * @param {Boolean} unbind_events Unbind the mouseenter/mouseleave events if they click (X)
+ */
+ _fade: function(e, unique_id, params, unbind_events){
+
+ var params = params || {},
+ fade = (typeof(params.fade) != 'undefined') ? params.fade : true;
+ fade_out_speed = params.speed || this.fade_out_speed;
+
+ this['_before_close_' + unique_id](e);
+
+ // If this is true, then we are coming from clicking the (X)
+ if(unbind_events){
+ e.unbind('mouseenter mouseleave');
+ }
+
+ // Fade it out or remove it
+ if(fade){
+
+ e.animate({
+ opacity: 0
+ }, fade_out_speed, function(){
+ e.animate({ height: 0 }, 300, function(){
+ Gritter._countRemoveWrapper(unique_id, e);
+ })
+ })
+
+ }
+ else {
+
+ this._countRemoveWrapper(unique_id, e);
+
+ }
+
+ },
+
+ /**
+ * Perform actions based on the type of bind (mouseenter, mouseleave)
+ * @private
+ * @param {Object} e The jQuery element
+ * @param {String} type The type of action we're performing: mouseenter or mouseleave
+ */
+ _hoverState: function(e, type){
+
+ // Change the border styles and add the (X) close button when you hover
+ if(type == 'mouseenter'){
+
+ e.addClass('hover');
+ var find_img = e.find('img');
+
+ // Insert the close button before what element
+ (find_img.length) ?
+ find_img.before(this._tpl_close) :
+ e.find('span').before(this._tpl_close);
+
+ // Clicking (X) makes the perdy thing close
+ e.find('.gritter-close').click(function(){
+
+ var unique_id = e.attr('id').split('-')[2];
+ Gritter.removeSpecific(unique_id, {}, e, true);
+
+ });
+
+ }
+ // Remove the border styles and (X) close button when you mouse out
+ else {
+
+ e.removeClass('hover');
+ e.find('.gritter-close').remove();
+
+ }
+
+ },
+
+ /**
+ * Remove a specific notification based on an ID
+ * @param {Integer} unique_id The ID used to delete a specific notification
+ * @param {Object} params A set of options passed in to determine how to get rid of it
+ * @param {Object} e The jQuery element that we're "fading" then removing
+ * @param {Boolean} unbind_events If we clicked on the (X) we set this to true to unbind mouseenter/mouseleave
+ */
+ removeSpecific: function(unique_id, params, e, unbind_events){
+
+ if(!e){
+ var e = $('#gritter-item-' + unique_id);
+ }
+
+ // We set the fourth param to let the _fade function know to
+ // unbind the "mouseleave" event. Once you click (X) there's no going back!
+ this._fade(e, unique_id, params || {}, unbind_events);
+
+ },
+
+ /**
+ * If the item is fading out and we hover over it, restore it!
+ * @private
+ * @param {Object} e The HTML element to remove
+ * @param {Integer} unique_id The ID of the element
+ */
+ _restoreItemIfFading: function(e, unique_id){
+
+ clearTimeout(this['_int_id_' + unique_id]);
+ e.stop().css({ opacity: '' });
+
+ },
+
+ /**
+ * Setup the global options - only once
+ * @private
+ */
+ _runSetup: function(){
+
+ for(opt in $.gritter.options){
+ this[opt] = $.gritter.options[opt];
+ }
+ this._is_setup = 1;
+
+ },
+
+ /**
+ * Set the notification to fade out after a certain amount of time
+ * @private
+ * @param {Object} item The HTML element we're dealing with
+ * @param {Integer} unique_id The ID of the element
+ */
+ _setFadeTimer: function(e, unique_id){
+
+ var timer_str = (this._custom_timer) ? this._custom_timer : this.time;
+ this['_int_id_' + unique_id] = setTimeout(function(){
+ Gritter._fade(e, unique_id);
+ }, timer_str);
+
+ },
+
+ /**
+ * Bring everything to a halt
+ * @param {Object} params A list of callback functions to pass when all notifications are removed
+ */
+ stop: function(params){
+
+ // callbacks (if passed)
+ var before_close = ($.isFunction(params.before_close)) ? params.before_close : function(){};
+ var after_close = ($.isFunction(params.after_close)) ? params.after_close : function(){};
+
+ var wrap = $('#gritter-notice-wrapper');
+ before_close(wrap);
+ wrap.fadeOut(function(){
+ $(this).remove();
+ after_close();
+ });
+
+ },
+
+ /**
+ * An extremely handy PHP function ported to JS, works well for templating
+ * @private
+ * @param {String/Array} search A list of things to search for
+ * @param {String/Array} replace A list of things to replace the searches with
+ * @return {String} sa The output
+ */
+ _str_replace: function(search, replace, subject, count){
+
+ var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
+ f = [].concat(search),
+ r = [].concat(replace),
+ s = subject,
+ ra = r instanceof Array, sa = s instanceof Array;
+ s = [].concat(s);
+
+ if(count){
+ this.window[count] = 0;
+ }
+
+ for(i = 0, sl = s.length; i < sl; i++){
+
+ if(s[i] === ''){
+ continue;
+ }
+
+ for (j = 0, fl = f.length; j < fl; j++){
+
+ temp = s[i] + '';
+ repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
+ s[i] = (temp).split(f[j]).join(repl);
+
+ if(count && s[i] !== temp){
+ this.window[count] += (temp.length-s[i].length) / f[j].length;
+ }
+
+ }
+ }
+
+ return sa ? s : s[0];
+
+ },
+
+ /**
+ * A check to make sure we have something to wrap our notices with
+ * @private
+ */
+ _verifyWrapper: function(){
+
+ if($('#gritter-notice-wrapper').length == 0){
+ $('body').append(this._tpl_wrap);
+ }
+
+ }
+
+ }
+
+})(jQuery);
diff --git a/static/jquery.datePicker.js b/static/jquery.datePicker.js
index 4bb82e0..7cc48e1 100644
--- a/static/jquery.datePicker.js
+++ b/static/jquery.datePicker.js
@@ -1,1189 +1,1189 @@
-/**
- * Copyright (c) 2008 Kelvin Luck (http://www.kelvinluck.com/)
- * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
- * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
- * .
- * $Id: jquery.datePicker.js 84 2009-08-05 17:54:35Z kelvin.luck@gmail.com $
- **/
-
-(function($){
-
- $.fn.extend({
-/**
- * Render a calendar table into any matched elements.
- *
- * @param Object s (optional) Customize your calendars.
- * @option Number month The month to render (NOTE that months are zero based). Default is today's month.
- * @option Number year The year to render. Default is today's year.
- * @option Function renderCallback A reference to a function that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Default is no callback.
- * @option Number showHeader Whether or not to show the header row, possible values are: $.dpConst.SHOW_HEADER_NONE (no header), $.dpConst.SHOW_HEADER_SHORT (first letter of each day) and $.dpConst.SHOW_HEADER_LONG (full name of each day). Default is $.dpConst.SHOW_HEADER_SHORT.
- * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class.
- * @type jQuery
- * @name renderCalendar
- * @cat plugins/datePicker
- * @author Kelvin Luck (http://www.kelvinluck.com/)
- *
- * @example $('#calendar-me').renderCalendar({month:0, year:2007});
- * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me.
- *
- * @example
- * var testCallback = function($td, thisDate, month, year)
- * {
- * if ($td.is('.current-month') && thisDate.getDay() == 4) {
- * var d = thisDate.getDate();
- * $td.bind(
- * 'click',
- * function()
- * {
- * alert('You clicked on ' + d + '/' + (Number(month)+1) + '/' + year);
- * }
- * ).addClass('thursday');
- * } else if (thisDate.getDay() == 5) {
- * $td.html('Friday the ' + $td.html() + 'th');
- * }
- * }
- * $('#calendar-me').renderCalendar({month:0, year:2007, renderCallback:testCallback});
- *
- * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me. Every Thursday in the current month has a class of "thursday" applied to it, is clickable and shows an alert when clicked. Every Friday on the calendar has the number inside replaced with text.
- **/
- renderCalendar : function(s)
- {
- var dc = function(a)
- {
- return document.createElement(a);
- };
-
- s = $.extend({}, $.fn.datePicker.defaults, s);
-
- if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {
- var headRow = $(dc('tr'));
- for (var i=Date.firstDayOfWeek; i
' : '',
- class_name = (image != '') ? 'gritter-with-image' : 'gritter-without-image';
-
- // String replacements on the template
- tmp = this._str_replace(
- ['[[username]]', '[[text]]', '[[image]]', '[[number]]', '[[class_name]]', '[[item_class]]'],
- [user, text, image_str, this._item_count, class_name, item_class], tmp
- );
-
- this['_before_open_' + number]();
- $('#gritter-notice-wrapper').append(tmp);
-
- var item = $('#gritter-item-' + this._item_count);
-
- item.fadeIn(this.fade_in_speed, function(){
- Gritter['_after_open_' + number]($(this));
- });
-
- if(!sticky){
- this._setFadeTimer(item, number);
- }
-
- // Bind the hover/unhover states
- $(item).bind('mouseenter mouseleave', function(event){
- if(event.type == 'mouseenter'){
- if(!sticky){
- Gritter._restoreItemIfFading($(this), number);
- }
- }
- else {
- if(!sticky){
- Gritter._setFadeTimer($(this), number);
- }
- }
- Gritter._hoverState($(this), event.type);
- });
-
- return number;
-
- },
-
- /**
- * If we don't have any more gritter notifications, get rid of the wrapper using this check
- * @private
- * @param {Integer} unique_id The ID of the element that was just deleted, use it for a callback
- * @param {Object} e The jQuery element that we're going to perform the remove() action on
- */
- _countRemoveWrapper: function(unique_id, e){
-
- // Remove it then run the callback function
- e.remove();
- this['_after_close_' + unique_id](e);
-
- // Check if the wrapper is empty, if it is.. remove the wrapper
- if($('.gritter-item-wrapper').length == 0){
- $('#gritter-notice-wrapper').remove();
- }
-
- },
-
- /**
- * Fade out an element after it's been on the screen for x amount of time
- * @private
- * @param {Object} e The jQuery element to get rid of
- * @param {Integer} unique_id The id of the element to remove
- * @param {Object} params An optional list of params to set fade speeds etc.
- * @param {Boolean} unbind_events Unbind the mouseenter/mouseleave events if they click (X)
- */
- _fade: function(e, unique_id, params, unbind_events){
-
- var params = params || {},
- fade = (typeof(params.fade) != 'undefined') ? params.fade : true;
- fade_out_speed = params.speed || this.fade_out_speed;
-
- this['_before_close_' + unique_id](e);
-
- // If this is true, then we are coming from clicking the (X)
- if(unbind_events){
- e.unbind('mouseenter mouseleave');
- }
-
- // Fade it out or remove it
- if(fade){
-
- e.animate({
- opacity: 0
- }, fade_out_speed, function(){
- e.animate({ height: 0 }, 300, function(){
- Gritter._countRemoveWrapper(unique_id, e);
- })
- })
-
- }
- else {
-
- this._countRemoveWrapper(unique_id, e);
-
- }
-
- },
-
- /**
- * Perform actions based on the type of bind (mouseenter, mouseleave)
- * @private
- * @param {Object} e The jQuery element
- * @param {String} type The type of action we're performing: mouseenter or mouseleave
- */
- _hoverState: function(e, type){
-
- // Change the border styles and add the (X) close button when you hover
- if(type == 'mouseenter'){
-
- e.addClass('hover');
- var find_img = e.find('img');
-
- // Insert the close button before what element
- (find_img.length) ?
- find_img.before(this._tpl_close) :
- e.find('span').before(this._tpl_close);
-
- // Clicking (X) makes the perdy thing close
- e.find('.gritter-close').click(function(){
-
- var unique_id = e.attr('id').split('-')[2];
- Gritter.removeSpecific(unique_id, {}, e, true);
-
- });
-
- }
- // Remove the border styles and (X) close button when you mouse out
- else {
-
- e.removeClass('hover');
- e.find('.gritter-close').remove();
-
- }
-
- },
-
- /**
- * Remove a specific notification based on an ID
- * @param {Integer} unique_id The ID used to delete a specific notification
- * @param {Object} params A set of options passed in to determine how to get rid of it
- * @param {Object} e The jQuery element that we're "fading" then removing
- * @param {Boolean} unbind_events If we clicked on the (X) we set this to true to unbind mouseenter/mouseleave
- */
- removeSpecific: function(unique_id, params, e, unbind_events){
-
- if(!e){
- var e = $('#gritter-item-' + unique_id);
- }
-
- // We set the fourth param to let the _fade function know to
- // unbind the "mouseleave" event. Once you click (X) there's no going back!
- this._fade(e, unique_id, params || {}, unbind_events);
-
- },
-
- /**
- * If the item is fading out and we hover over it, restore it!
- * @private
- * @param {Object} e The HTML element to remove
- * @param {Integer} unique_id The ID of the element
- */
- _restoreItemIfFading: function(e, unique_id){
-
- clearTimeout(this['_int_id_' + unique_id]);
- e.stop().css({ opacity: '' });
-
- },
-
- /**
- * Setup the global options - only once
- * @private
- */
- _runSetup: function(){
-
- for(opt in $.gritter.options){
- this[opt] = $.gritter.options[opt];
- }
- this._is_setup = 1;
-
- },
-
- /**
- * Set the notification to fade out after a certain amount of time
- * @private
- * @param {Object} item The HTML element we're dealing with
- * @param {Integer} unique_id The ID of the element
- */
- _setFadeTimer: function(e, unique_id){
-
- var timer_str = (this._custom_timer) ? this._custom_timer : this.time;
- this['_int_id_' + unique_id] = setTimeout(function(){
- Gritter._fade(e, unique_id);
- }, timer_str);
-
- },
-
- /**
- * Bring everything to a halt
- * @param {Object} params A list of callback functions to pass when all notifications are removed
- */
- stop: function(params){
-
- // callbacks (if passed)
- var before_close = ($.isFunction(params.before_close)) ? params.before_close : function(){};
- var after_close = ($.isFunction(params.after_close)) ? params.after_close : function(){};
-
- var wrap = $('#gritter-notice-wrapper');
- before_close(wrap);
- wrap.fadeOut(function(){
- $(this).remove();
- after_close();
- });
-
- },
-
- /**
- * An extremely handy PHP function ported to JS, works well for templating
- * @private
- * @param {String/Array} search A list of things to search for
- * @param {String/Array} replace A list of things to replace the searches with
- * @return {String} sa The output
- */
- _str_replace: function(search, replace, subject, count){
-
- var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
- f = [].concat(search),
- r = [].concat(replace),
- s = subject,
- ra = r instanceof Array, sa = s instanceof Array;
- s = [].concat(s);
-
- if(count){
- this.window[count] = 0;
- }
-
- for(i = 0, sl = s.length; i < sl; i++){
-
- if(s[i] === ''){
- continue;
- }
-
- for (j = 0, fl = f.length; j < fl; j++){
-
- temp = s[i] + '';
- repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
- s[i] = (temp).split(f[j]).join(repl);
-
- if(count && s[i] !== temp){
- this.window[count] += (temp.length-s[i].length) / f[j].length;
- }
-
- }
- }
-
- return sa ? s : s[0];
-
- },
-
- /**
- * A check to make sure we have something to wrap our notices with
- * @private
- */
- _verifyWrapper: function(){
-
- if($('#gritter-notice-wrapper').length == 0){
- $('body').append(this._tpl_wrap);
- }
-
- }
-
- }
-
-})(jQuery);
+/*
+ * Gritter for jQuery
+ * http://www.boedesign.com/
+ *
+ * Copyright (c) 2009 Jordan Boesch
+ * Dual licensed under the MIT and GPL licenses.
+ *
+ * Date: December 1, 2009
+ * Version: 1.6
+ */
+
+(function($){
+
+ /**
+ * Set it up as an object under the jQuery namespace
+ */
+ $.gritter = {};
+
+ /**
+ * Set up global options that the user can over-ride
+ */
+ $.gritter.options = {
+ fade_in_speed: 'medium', // how fast notifications fade in
+ fade_out_speed: 1000, // how fast the notices fade out
+ time: 6000 // hang on the screen for...
+ }
+
+ /**
+ * Add a gritter notification to the screen
+ * @see Gritter#add();
+ */
+ $.gritter.add = function(params){
+
+ try {
+ return Gritter.add(params || {});
+ } catch(e) {
+
+ var err = 'Gritter Error: ' + e;
+ (typeof(console) != 'undefined' && console.error) ?
+ console.error(err, params) :
+ alert(err);
+
+ }
+
+ }
+
+ /**
+ * Remove a gritter notification from the screen
+ * @see Gritter#removeSpecific();
+ */
+ $.gritter.remove = function(id, params){
+ Gritter.removeSpecific(id, params || {});
+ }
+
+ /**
+ * Remove all notifications
+ * @see Gritter#stop();
+ */
+ $.gritter.removeAll = function(params){
+ Gritter.stop(params || {});
+ }
+
+ /**
+ * Big fat Gritter object
+ * @constructor (not really since it's object literal)
+ */
+ var Gritter = {
+
+ // Public - options to over-ride with $.gritter.options in "add"
+ fade_in_speed: '',
+ fade_out_speed: '',
+ time: '',
+
+ // Private - no touchy the private parts
+ _custom_timer: 0,
+ _item_count: 0,
+ _is_setup: 0,
+ _tpl_close: '',
+ _tpl_item: '',
+ _tpl_wrap: '',
+
+ /**
+ * Add a gritter notification to the screen
+ * @param {Object} params The object that contains all the options for drawing the notification
+ * @return {Integer} The specific numeric id to that gritter notification
+ */
+ add: function(params){
+
+ // We might have some issues if we don't have a title or text!
+ if(!params.title || !params.text){
+ throw 'You need to fill out the first 2 params: "title" and "text"';
+ }
+
+ // Check the options and set them once
+ if(!this._is_setup){
+ this._runSetup();
+ }
+
+ // Basics
+ var user = params.title,
+ text = params.text,
+ image = params.image || '',
+ sticky = params.sticky || false,
+ item_class = params.class_name || '',
+ time_alive = params.time || '';
+
+ this._verifyWrapper();
+
+ this._item_count++;
+ var number = this._item_count,
+ tmp = this._tpl_item;
+
+ // Assign callbacks
+ $(['before_open', 'after_open', 'before_close', 'after_close']).each(function(i, val){
+ Gritter['_' + val + '_' + number] = ($.isFunction(params[val])) ? params[val] : function(){}
+ });
+
+ // Reset
+ this._custom_timer = 0;
+
+ // A custom fade time set
+ if(time_alive){
+ this._custom_timer = time_alive;
+ }
+
+ var image_str = (image != '') ? '
' : '',
+ class_name = (image != '') ? 'gritter-with-image' : 'gritter-without-image';
+
+ // String replacements on the template
+ tmp = this._str_replace(
+ ['[[username]]', '[[text]]', '[[image]]', '[[number]]', '[[class_name]]', '[[item_class]]'],
+ [user, text, image_str, this._item_count, class_name, item_class], tmp
+ );
+
+ this['_before_open_' + number]();
+ $('#gritter-notice-wrapper').append(tmp);
+
+ var item = $('#gritter-item-' + this._item_count);
+
+ item.fadeIn(this.fade_in_speed, function(){
+ Gritter['_after_open_' + number]($(this));
+ });
+
+ if(!sticky){
+ this._setFadeTimer(item, number);
+ }
+
+ // Bind the hover/unhover states
+ $(item).bind('mouseenter mouseleave', function(event){
+ if(event.type == 'mouseenter'){
+ if(!sticky){
+ Gritter._restoreItemIfFading($(this), number);
+ }
+ }
+ else {
+ if(!sticky){
+ Gritter._setFadeTimer($(this), number);
+ }
+ }
+ Gritter._hoverState($(this), event.type);
+ });
+
+ return number;
+
+ },
+
+ /**
+ * If we don't have any more gritter notifications, get rid of the wrapper using this check
+ * @private
+ * @param {Integer} unique_id The ID of the element that was just deleted, use it for a callback
+ * @param {Object} e The jQuery element that we're going to perform the remove() action on
+ */
+ _countRemoveWrapper: function(unique_id, e){
+
+ // Remove it then run the callback function
+ e.remove();
+ this['_after_close_' + unique_id](e);
+
+ // Check if the wrapper is empty, if it is.. remove the wrapper
+ if($('.gritter-item-wrapper').length == 0){
+ $('#gritter-notice-wrapper').remove();
+ }
+
+ },
+
+ /**
+ * Fade out an element after it's been on the screen for x amount of time
+ * @private
+ * @param {Object} e The jQuery element to get rid of
+ * @param {Integer} unique_id The id of the element to remove
+ * @param {Object} params An optional list of params to set fade speeds etc.
+ * @param {Boolean} unbind_events Unbind the mouseenter/mouseleave events if they click (X)
+ */
+ _fade: function(e, unique_id, params, unbind_events){
+
+ var params = params || {},
+ fade = (typeof(params.fade) != 'undefined') ? params.fade : true;
+ fade_out_speed = params.speed || this.fade_out_speed;
+
+ this['_before_close_' + unique_id](e);
+
+ // If this is true, then we are coming from clicking the (X)
+ if(unbind_events){
+ e.unbind('mouseenter mouseleave');
+ }
+
+ // Fade it out or remove it
+ if(fade){
+
+ e.animate({
+ opacity: 0
+ }, fade_out_speed, function(){
+ e.animate({ height: 0 }, 300, function(){
+ Gritter._countRemoveWrapper(unique_id, e);
+ })
+ })
+
+ }
+ else {
+
+ this._countRemoveWrapper(unique_id, e);
+
+ }
+
+ },
+
+ /**
+ * Perform actions based on the type of bind (mouseenter, mouseleave)
+ * @private
+ * @param {Object} e The jQuery element
+ * @param {String} type The type of action we're performing: mouseenter or mouseleave
+ */
+ _hoverState: function(e, type){
+
+ // Change the border styles and add the (X) close button when you hover
+ if(type == 'mouseenter'){
+
+ e.addClass('hover');
+ var find_img = e.find('img');
+
+ // Insert the close button before what element
+ (find_img.length) ?
+ find_img.before(this._tpl_close) :
+ e.find('span').before(this._tpl_close);
+
+ // Clicking (X) makes the perdy thing close
+ e.find('.gritter-close').click(function(){
+
+ var unique_id = e.attr('id').split('-')[2];
+ Gritter.removeSpecific(unique_id, {}, e, true);
+
+ });
+
+ }
+ // Remove the border styles and (X) close button when you mouse out
+ else {
+
+ e.removeClass('hover');
+ e.find('.gritter-close').remove();
+
+ }
+
+ },
+
+ /**
+ * Remove a specific notification based on an ID
+ * @param {Integer} unique_id The ID used to delete a specific notification
+ * @param {Object} params A set of options passed in to determine how to get rid of it
+ * @param {Object} e The jQuery element that we're "fading" then removing
+ * @param {Boolean} unbind_events If we clicked on the (X) we set this to true to unbind mouseenter/mouseleave
+ */
+ removeSpecific: function(unique_id, params, e, unbind_events){
+
+ if(!e){
+ var e = $('#gritter-item-' + unique_id);
+ }
+
+ // We set the fourth param to let the _fade function know to
+ // unbind the "mouseleave" event. Once you click (X) there's no going back!
+ this._fade(e, unique_id, params || {}, unbind_events);
+
+ },
+
+ /**
+ * If the item is fading out and we hover over it, restore it!
+ * @private
+ * @param {Object} e The HTML element to remove
+ * @param {Integer} unique_id The ID of the element
+ */
+ _restoreItemIfFading: function(e, unique_id){
+
+ clearTimeout(this['_int_id_' + unique_id]);
+ e.stop().css({ opacity: '' });
+
+ },
+
+ /**
+ * Setup the global options - only once
+ * @private
+ */
+ _runSetup: function(){
+
+ for(opt in $.gritter.options){
+ this[opt] = $.gritter.options[opt];
+ }
+ this._is_setup = 1;
+
+ },
+
+ /**
+ * Set the notification to fade out after a certain amount of time
+ * @private
+ * @param {Object} item The HTML element we're dealing with
+ * @param {Integer} unique_id The ID of the element
+ */
+ _setFadeTimer: function(e, unique_id){
+
+ var timer_str = (this._custom_timer) ? this._custom_timer : this.time;
+ this['_int_id_' + unique_id] = setTimeout(function(){
+ Gritter._fade(e, unique_id);
+ }, timer_str);
+
+ },
+
+ /**
+ * Bring everything to a halt
+ * @param {Object} params A list of callback functions to pass when all notifications are removed
+ */
+ stop: function(params){
+
+ // callbacks (if passed)
+ var before_close = ($.isFunction(params.before_close)) ? params.before_close : function(){};
+ var after_close = ($.isFunction(params.after_close)) ? params.after_close : function(){};
+
+ var wrap = $('#gritter-notice-wrapper');
+ before_close(wrap);
+ wrap.fadeOut(function(){
+ $(this).remove();
+ after_close();
+ });
+
+ },
+
+ /**
+ * An extremely handy PHP function ported to JS, works well for templating
+ * @private
+ * @param {String/Array} search A list of things to search for
+ * @param {String/Array} replace A list of things to replace the searches with
+ * @return {String} sa The output
+ */
+ _str_replace: function(search, replace, subject, count){
+
+ var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
+ f = [].concat(search),
+ r = [].concat(replace),
+ s = subject,
+ ra = r instanceof Array, sa = s instanceof Array;
+ s = [].concat(s);
+
+ if(count){
+ this.window[count] = 0;
+ }
+
+ for(i = 0, sl = s.length; i < sl; i++){
+
+ if(s[i] === ''){
+ continue;
+ }
+
+ for (j = 0, fl = f.length; j < fl; j++){
+
+ temp = s[i] + '';
+ repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
+ s[i] = (temp).split(f[j]).join(repl);
+
+ if(count && s[i] !== temp){
+ this.window[count] += (temp.length-s[i].length) / f[j].length;
+ }
+
+ }
+ }
+
+ return sa ? s : s[0];
+
+ },
+
+ /**
+ * A check to make sure we have something to wrap our notices with
+ * @private
+ */
+ _verifyWrapper: function(){
+
+ if($('#gritter-notice-wrapper').length == 0){
+ $('body').append(this._tpl_wrap);
+ }
+
+ }
+
+ }
+
+})(jQuery);
diff --git a/static/js/jquery.easing.min.js b/static/js/jquery.easing.min.js
index 1a7b42d..8d4e2f2 100755
--- a/static/js/jquery.easing.min.js
+++ b/static/js/jquery.easing.min.js
@@ -1,11 +1,11 @@
-/*
- * jQuery Easing v1.1 - http://gsgd.co.uk/sandbox/jquery.easing.php
- *
- * Uses the built in easing capabilities added in jQuery 1.1
- * to offer multiple easing options
- *
- * Copyright (c) 2007 George Smith
- * Licensed under the MIT License:
- * http://www.opensource.org/licenses/mit-license.php
- */
+/*
+ * jQuery Easing v1.1 - http://gsgd.co.uk/sandbox/jquery.easing.php
+ *
+ * Uses the built in easing capabilities added in jQuery 1.1
+ * to offer multiple easing options
+ *
+ * Copyright (c) 2007 George Smith
+ * Licensed under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ */
jQuery.easing={easein:function(x,t,b,c,d){return c*(t/=d)*t+b},easeinout:function(x,t,b,c,d){if(t
+ *
+ *
+ * Once you have included the style sheet that comes with the plugin, you will have to include
+ * a reference to jquery library, easing plugin(optional) and the LavaLamp(this) plugin.
+ *
+ * Use the following snippet to initialize the menu.
+ * $(function() { $(".lavaLamp").lavaLamp({ fx: "backout", speed: 700}) });
+ *
+ * Thats it. Now you should have a working lavalamp menu.
+ *
+ * @param an options object - You can specify all the options shown below as an options object param.
+ *
+ * @option fx - default is "linear"
+ * @example
+ * $(".lavaLamp").lavaLamp({ fx: "backout" });
+ * @desc Creates a menu with "backout" easing effect. You need to include the easing plugin for this to work.
+ *
+ * @option speed - default is 500 ms
+ * @example
+ * $(".lavaLamp").lavaLamp({ speed: 500 });
+ * @desc Creates a menu with an animation speed of 500 ms.
+ *
+ * @option click - no defaults
+ * @example
+ * $(".lavaLamp").lavaLamp({ click: function(event, menuItem) { return false; } });
+ * @desc You can supply a callback to be executed when the menu item is clicked.
+ * The event object and the menu-item that was clicked will be passed in as arguments.
+ */
+(function($) {
+$.fn.lavaLamp = function(o) {
+ o = $.extend({ fx: "linear", speed: 500, click: function(){} }, o || {});
+
+ return this.each(function() {
+ var me = $(this), noop = function(){},
+ $back = $('
- * http://www.site.com/
- * http://www.site.net/
- *
+ * http://www.site.com/
+ * http://www.site.net/
+ *
- *
The query and fragment parts are optional.
- * - *This class supports both non-hierarchical and hierarchical URI's
- * - *This class is intended to be used "as-is" for the vast majority - * of common URI's. However, if your application requires a custom - * URI syntax (e.g. custom query syntax or special handling of - * non-hierarchical URI's), this class can be fully subclassed. If you - * intended to subclass URI, please see the source code for complete - * documation on protected members and protected fuctions.
- * - * @langversion ActionScript 3.0 - * @playerversion Flash 9.0 - */ - public class URI - { - // Here we define which characters must be escaped for each - // URI part. The characters that must be escaped for each - // part differ depending on what would cause ambiguous parsing. - // RFC 3986 sec. 2.4 states that characters should only be - // encoded when they would conflict with subcomponent delimiters. - // We don't want to over-do the escaping. We only want to escape - // the minimum needed to prevent parsing problems. - - // space and % must be escaped in all cases. '%' is the delimiter - // for escaped characters. - public static const URImustEscape:String = " %"; - - // Baseline of what characters must be escaped - public static const URIbaselineEscape:String = URImustEscape + ":?#/@"; - - // Characters that must be escaped in the part part. - public static const URIpathEscape:String = URImustEscape + "?#"; - - // Characters that must be escaped in the query part, if setting - // the query as a whole string. If the query is set by - // name/value, URIqueryPartEscape is used instead. - public static const URIqueryEscape:String = URImustEscape + "#"; - - // This is what each name/value pair must escape "&=" as well - // so they don't conflict with the "param=value¶m2=value2" - // syntax. - public static const URIqueryPartEscape:String = URImustEscape + "#&="; - - // Non-hierarchical URI's can have query and fragment parts, but - // we also want to prevent '/' otherwise it might end up looking - // like a hierarchical URI to the parser. - public static const URInonHierEscape:String = URImustEscape + "?#/"; - - // Baseline uninitialized setting for the URI scheme. - public static const UNKNOWN_SCHEME:String = "unknown"; - - // The following bitmaps are used for performance enhanced - // character escaping. - - // Baseline characters that need to be escaped. Many parts use - // this. - protected static const URIbaselineExcludedBitmap:URIEncodingBitmap = - new URIEncodingBitmap(URIbaselineEscape); - - // Scheme escaping bitmap - protected static const URIschemeExcludedBitmap:URIEncodingBitmap = - URIbaselineExcludedBitmap; - - // User/pass escaping bitmap - protected static const URIuserpassExcludedBitmap:URIEncodingBitmap = - URIbaselineExcludedBitmap; - - // Authority escaping bitmap - protected static const URIauthorityExcludedBitmap:URIEncodingBitmap = - URIbaselineExcludedBitmap; - - // Port escaping bitmap - protected static const URIportExludedBitmap:URIEncodingBitmap = - URIbaselineExcludedBitmap; - - // Path escaping bitmap - protected static const URIpathExcludedBitmap:URIEncodingBitmap = - new URIEncodingBitmap(URIpathEscape); - - // Query (whole) escaping bitmap - protected static const URIqueryExcludedBitmap:URIEncodingBitmap = - new URIEncodingBitmap(URIqueryEscape); - - // Query (individual parts) escaping bitmap - protected static const URIqueryPartExcludedBitmap:URIEncodingBitmap = - new URIEncodingBitmap(URIqueryPartEscape); - - // Fragments are the last part in the URI. They only need to - // escape space, '#', and '%'. Turns out that is what query - // uses too. - protected static const URIfragmentExcludedBitmap:URIEncodingBitmap = - URIqueryExcludedBitmap; - - // Characters that need to be escaped in the non-hierarchical part - protected static const URInonHierexcludedBitmap:URIEncodingBitmap = - new URIEncodingBitmap(URInonHierEscape); - - // Values used by getRelation() - public static const NOT_RELATED:int = 0; - public static const CHILD:int = 1; - public static const EQUAL:int = 2; - public static const PARENT:int = 3; - - //------------------------------------------------------------------- - // protected class members - //------------------------------------------------------------------- - protected var _valid:Boolean = false; - protected var _relative:Boolean = false; - protected var _scheme:String = ""; - protected var _authority:String = ""; - protected var _username:String = ""; - protected var _password:String = ""; - protected var _port:String = ""; - protected var _path:String = ""; - protected var _query:String = ""; - protected var _fragment:String = ""; - protected var _nonHierarchical:String = ""; - protected static var _resolver:IURIResolver = null; - - - /** - * URI Constructor. If no string is given, this will initialize - * this URI object to a blank URI. - */ - public function URI(uri:String = null) : void - { - if (uri == null) - initialize(); - else - constructURI(uri); - } - - - /** - * @private - * Method that loads the URI from the given string. - */ - protected function constructURI(uri:String) : Boolean - { - if (!parseURI(uri)) - _valid = false; - - return isValid(); - } - - - /** - * @private Private initializiation. - */ - protected function initialize() : void - { - _valid = false; - _relative = false; - - _scheme = UNKNOWN_SCHEME; - _authority = ""; - _username = ""; - _password = ""; - _port = ""; - _path = ""; - _query = ""; - _fragment = ""; - - _nonHierarchical = ""; - } - - /** - * @private Accessor to explicitly set/get the hierarchical - * state of the URI. - */ - protected function set hierState(state:Boolean) : void - { - if (state) - { - // Clear the non-hierarchical data - _nonHierarchical = ""; - - // Also set the state vars while we are at it - if (_scheme == "" || _scheme == UNKNOWN_SCHEME) - _relative = true; - else - _relative = false; - - if (_authority.length == 0 && _path.length == 0) - _valid = false; - else - _valid = true; - } - else - { - // Clear the hierarchical data - _authority = ""; - _username = ""; - _password = ""; - _port = ""; - _path = ""; - - _relative = false; - - if (_scheme == "" || _scheme == UNKNOWN_SCHEME) - _valid = false; - else - _valid = true; - } - } - protected function get hierState() : Boolean - { - return (_nonHierarchical.length == 0); - } - - - /** - * @private Functions that performs some basic consistency validation. - */ - protected function validateURI() : Boolean - { - // Check the scheme - if (isAbsolute()) - { - if (_scheme.length <= 1 || _scheme == UNKNOWN_SCHEME) - { - // we probably parsed a C:\ type path or no scheme - return false; - } - else if (verifyAlpha(_scheme) == false) - return false; // Scheme contains bad characters - } - - if (hierState) - { - if (_path.search('\\') != -1) - return false; // local path - else if (isRelative() == false && _scheme == UNKNOWN_SCHEME) - return false; // It's an absolute URI, but it has a bad scheme - } - else - { - if (_nonHierarchical.search('\\') != -1) - return false; // some kind of local path - } - - // Looks like it's ok. - return true; - } - - - /** - * @private - * - * Given a URI in string format, parse that sucker into its basic - * components and assign them to this object. A URI is of the form: - *The URI specification allows for authentication - * credentials to be embedded in the URI as such:
- * - *http://user:passwd@host/path/to/file.htm
- * - *When setting this value, the string - * given is assumed to be unescaped. When retrieving this - * value, the resulting string is unescaped.
- */ - public function get username() : String - { - return URI.unescapeChars(_username); - } - public function set username(usernameStr:String) : void - { - _username = URI.fastEscapeChars(usernameStr, URI.URIuserpassExcludedBitmap); - - // Only hierarchical URI's can have a username. - this.hierState = true; - } - - - /** - * The password of the URI. Similar to username. - * @see URI.username - */ - public function get password() : String - { - return URI.unescapeChars(_password); - } - public function set password(passwordStr:String) : void - { - _password = URI.fastEscapeChars(passwordStr, - URI.URIuserpassExcludedBitmap); - - // Only hierarchical URI's can have a password. - this.hierState = true; - } - - - /** - * The host port number. Only valid for hierarchical URI's. If - * the URI is relative, this will be an empty string. URI's can - * contain the port number of the remote host: - * - *http://site.com:8080/index.htm
- */ - public function get port() : String - { - return URI.unescapeChars(_port); - } - public function set port(portStr:String) : void - { - _port = URI.escapeChars(portStr); - - // Only hierarchical URI's can have a port. - this.hierState = true; - } - - - /** - * The path portion of the URI. Only valid for hierarchical - * URI's. When setting this value, the string - * given is assumed to be unescaped. When retrieving this - * value, the resulting string is unescaped. - * - *The path portion can be in one of two formats. 1) an absolute - * path, or 2) a relative path. An absolute path starts with a - * slash ('/'), a relative path does not.
- * - *An absolute path may look like:
- *A relative path may look like:
- *Paths can be absolute or relative. Note that this not the same as - * an absolute or relative URI. An absolute URI can only have absolute - * paths. For example:
- * - *This absolute URI has an absolute path of "/path/to/file.htm".
- * - *Relative URI's can have either absolute paths or relative paths. - * All of the following relative URI's are valid:
- * - *This accessor should only be used if a custom query syntax - * is used. This URI class supports the common "param=value" - * style query syntax via the get/setQueryValue() and - * get/setQueryByMap() functions. Those functions should be used - * instead if the common syntax is being used. - * - *
The URI RFC does not specify any particular - * syntax for the query part of a URI. It is intended to allow - * any format that can be agreed upon by the two communicating hosts. - * However, most systems have standardized on the typical CGI - * format:
- * - *This class has specific support for this query syntax
- * - *This common query format is an array of name/value - * pairs with its own syntax that is different from the overall URI - * syntax. The query has its own escaping logic. For a query part - * to be properly escaped and unescaped, it must be split into its - * component parts. This accessor escapes/unescapes the entire query - * part without regard for it's component parts. This has the - * possibliity of leaving the query string in an ambiguious state in - * regards to its syntax. If the contents of the query part are - * important, it is recommended that get/setQueryValue() or - * get/setQueryByMap() are used instead.
- * - * If a different query syntax is being used, a subclass of URI - * can be created to handle that specific syntax. - * - * @see URI.getQueryValue, URI.getQueryByMap - */ - public function get query() : String - { - return URI.unescapeChars(_query); - } - public function set query(queryStr:String) : void - { - _query = URI.fastEscapeChars(queryStr, URI.URIqueryExcludedBitmap); - - // both hierarchical and non-hierarchical URI's can - // have a query. Do not set the hierState. - } - - /** - * Accessor to the raw query data. If you are using a custom query - * syntax, this accessor can be used to get and set the query part - * directly with no escaping/unescaping. This should ONLY be used - * if your application logic is handling custom query logic and - * handling the proper escaping of the query part. - */ - public function get queryRaw() : String - { - return _query; - } - public function set queryRaw(queryStr:String) : void - { - _query = queryStr; - } - - - /** - * The fragment (anchor) portion of the URI. This is valid for - * both hierarchical and non-hierarchical URI's. - */ - public function get fragment() : String - { - return URI.unescapeChars(_fragment); - } - public function set fragment(fragmentStr:String) : void - { - _fragment = URI.fastEscapeChars(fragmentStr, URIfragmentExcludedBitmap); - - // both hierarchical and non-hierarchical URI's can - // have a fragment. Do not set the hierState. - } - - - /** - * The non-hierarchical part of the URI. For example, if - * this URI object represents "mailto:somebody@company.com", - * this will contain "somebody@company.com". This is valid only - * for non-hierarchical URI's. - */ - public function get nonHierarchical() : String - { - return URI.unescapeChars(_nonHierarchical); - } - public function set nonHierarchical(nonHier:String) : void - { - _nonHierarchical = URI.fastEscapeChars(nonHier, URInonHierexcludedBitmap); - - // This is a non-hierarchical URI. - this.hierState = false; - } - - - /** - * Quick shorthand accessor to set the parts of this URI. - * The given parts are assumed to be in unescaped form. If - * the URI is non-hierarchical (e.g. mailto:) you will need - * to call SetScheme() and SetNonHierarchical(). - */ - public function setParts(schemeStr:String, authorityStr:String, - portStr:String, pathStr:String, queryStr:String, - fragmentStr:String) : void - { - this.scheme = schemeStr; - this.authority = authorityStr; - this.port = portStr; - this.path = pathStr; - this.query = queryStr; - this.fragment = fragmentStr; - - hierState = true; - } - - - /** - * URI escapes the given character string. This is similar in function - * to the global encodeURIComponent() function in ActionScript, but is - * slightly different in regards to which characters get escaped. This - * escapes the characters specified in the URIbaselineExluded set (see class - * static members). This is needed for this class to work properly. - * - *If a different set of characters need to be used for the escaping, - * you may use fastEscapeChars() and specify a custom URIEncodingBitmap - * that contains the characters your application needs escaped.
- * - *Never pass a full URI to this function. A URI can only be properly - * escaped/unescaped when split into its component parts (see RFC 3986 - * section 2.4). This is due to the fact that the URI component separators - * could be characters that would normally need to be escaped.
- * - * @param unescaped character string to be escaped. - * - * @return escaped character string - * - * @see encodeURIComponent - * @see fastEscapeChars - */ - static public function escapeChars(unescaped:String) : String - { - // This uses the excluded set by default. - return fastEscapeChars(unescaped, URI.URIbaselineExcludedBitmap); - } - - - /** - * Unescape any URI escaped characters in the given character - * string. - * - *Never pass a full URI to this function. A URI can only be properly - * escaped/unescaped when split into its component parts (see RFC 3986 - * section 2.4). This is due to the fact that the URI component separators - * could be characters that would normally need to be escaped.
- * - * @param escaped the escaped string to be unescaped. - * - * @return unescaped string. - */ - static public function unescapeChars(escaped:String /*, onlyHighASCII:Boolean = false*/) : String - { - // We can just use the default AS function. It seems to - // decode everything correctly - var unescaped:String; - unescaped = decodeURIComponent(escaped); - return unescaped; - } - - /** - * Performance focused function that escapes the given character - * string using the given URIEncodingBitmap as the rule for what - * characters need to be escaped. This function is used by this - * class and can be used externally to this class to perform - * escaping on custom character sets. - * - *Never pass a full URI to this function. A URI can only be properly - * escaped/unescaped when split into its component parts (see RFC 3986 - * section 2.4). This is due to the fact that the URI component separators - * could be characters that would normally need to be escaped.
- * - * @param unescaped the unescaped string to be escaped - * @param bitmap the set of characters that need to be escaped - * - * @return the escaped string. - */ - static public function fastEscapeChars(unescaped:String, bitmap:URIEncodingBitmap) : String - { - var escaped:String = ""; - var c:String; - var x:int, i:int; - - for (i = 0; i < unescaped.length; i++) - { - c = unescaped.charAt(i); - - x = bitmap.ShouldEscape(c); - if (x) - { - c = x.toString(16); - if (c.length == 1) - c = "0" + c; - - c = "%" + c; - c = c.toUpperCase(); - } - - escaped += c; - } - - return escaped; - } - - - /** - * Is this URI of a particular scheme type? For example, - * passing "http" to a URI object that represents the URI - * "http://site.com/" would return true. - * - * @param scheme scheme to check for - * - * @return true if this URI object is of the given type, false - * otherwise. - */ - public function isOfType(scheme:String) : Boolean - { - // Schemes are never case sensitive. Ignore case. - scheme = scheme.toLowerCase(); - return (this._scheme == scheme); - } - - - /** - * Get the value for the specified named in the query part. This - * assumes the query part of the URI is in the common - * "name1=value1&name2=value2" syntax. Do not call this function - * if you are using a custom query syntax. - * - * @param name name of the query value to get. - * - * @return the value of the query name, empty string if the - * query name does not exist. - */ - public function getQueryValue(name:String) : String - { - var map:Object; - var item:String; - var value:String; - - map = getQueryByMap(); - - for (item in map) - { - if (item == name) - { - value = map[item]; - return value; - } - } - - // Didn't find the specified key - return new String(""); - } - - - /** - * Set the given value on the given query name. If the given name - * does not exist, it will automatically add this name/value pair - * to the query. If null is passed as the value, it will remove - * the given item from the query. - * - *This automatically escapes any characters that may conflict with - * the query syntax so that they are "safe" within the query. The - * strings passed are assumed to be literal unescaped name and value.
- * - * @param name name of the query value to set - * @param value value of the query item to set. If null, this will - * force the removal of this item from the query. - */ - public function setQueryValue(name:String, value:String) : void - { - var map:Object; - - map = getQueryByMap(); - - // If the key doesn't exist yet, this will create a new pair in - // the map. If it does exist, this will overwrite the previous - // value, which is what we want. - map[name] = value; - - setQueryByMap(map); - } - - - /** - * Get the query of the URI in an Object class that allows for easy - * access to the query data via Object accessors. For example: - * - *Sometimes URI's are constructed by hand using strings outside - * this class. In those cases, it is unlikely the URI has been - * properly escaped. This function forcefully escapes this URI - * by unescaping each part and then re-escaping it. If the URI - * did not have any escaping, the first unescape will do nothing - * and then the re-escape will properly escape everything. If - * the URI was already escaped, the unescape and re-escape will - * essentally be a no-op. This provides a safe way to make sure - * a URI is in the proper escaped form.
- */ - public function forceEscape() : void - { - // The accessors for each of the members will unescape - // and then re-escape as we get and assign them. - - // Handle the parts that are common for both hierarchical - // and non-hierarchical URI's - this.scheme = this.scheme; - this.setQueryByMap(this.getQueryByMap()); - this.fragment = this.fragment; - - if (isHierarchical()) - { - this.authority = this.authority; - this.path = this.path; - this.port = this.port; - this.username = this.username; - this.password = this.password; - } - else - { - this.nonHierarchical = this.nonHierarchical; - } - } - - - /** - * Does this URI point to a resource of the given file type? - * Given a file extension (or just a file name, this will strip the - * extension), check to see if this URI points to a file of that - * type. - * - * @param extension string that contains a file extension with or - * without a dot ("html" and ".html" are both valid), or a file - * name with an extension (e.g. "index.html"). - * - * @return true if this URI points to a resource with the same file - * file extension as the extension provided, false otherwise. - */ - public function isOfFileType(extension:String) : Boolean - { - var thisExtension:String; - var index:int; - - index = extension.lastIndexOf("."); - if (index != -1) - { - // Strip the extension - extension = extension.substr(index + 1); - } - else - { - // The caller passed something without a dot in it. We - // will assume that it is just a plain extension (e.g. "html"). - // What they passed is exactly what we want - } - - thisExtension = getExtension(true); - - if (thisExtension == "") - return false; - - // Compare the extensions ignoring case - if (compareStr(thisExtension, extension, false) == 0) - return true; - else - return false; - } - - - /** - * Get the ".xyz" file extension from the filename in the URI. - * For example, if we have the following URI: - * - *This will return ".html".
- * - * @param minusDot If true, this will strip the dot from the extension. - * If true, the above example would have returned "html". - * - * @return the file extension - */ - public function getExtension(minusDot:Boolean = false) : String - { - var filename:String = getFilename(); - var extension:String; - var index:int; - - if (filename == "") - return String(""); - - index = filename.lastIndexOf("."); - - // If it doesn't have an extension, or if it is a "hidden" file, - // it doesn't have an extension. Hidden files on unix start with - // a dot (e.g. ".login"). - if (index == -1 || index == 0) - return String(""); - - extension = filename.substr(index); - - // If the caller does not want the dot, remove it. - if (minusDot && extension.charAt(0) == ".") - extension = extension.substr(1); - - return extension; - } - - /** - * Quick function to retrieve the file name off the end of a URI. - * - *For example, if the URI is:
- *this function will return "file.html".
- * - * @param minusExtension true if the file extension should be stripped - * - * @return the file name. If this URI is a directory, the return - * value will be empty string. - */ - public function getFilename(minusExtension:Boolean = false) : String - { - if (isDirectory()) - return String(""); - - var pathStr:String = this.path; - var filename:String; - var index:int; - - // Find the last path separator. - index = pathStr.lastIndexOf("/"); - - if (index != -1) - filename = pathStr.substr(index + 1); - else - filename = pathStr; - - if (minusExtension) - { - // The caller has requested that the extension be removed - index = filename.lastIndexOf("."); - - if (index != -1) - filename = filename.substr(0, index); - } - - return filename; - } - - - /** - * @private - * Helper function to compare strings. - * - * @return true if the two strings are identical, false otherwise. - */ - static protected function compareStr(str1:String, str2:String, - sensitive:Boolean = true) : Boolean - { - if (sensitive == false) - { - str1 = str1.toLowerCase(); - str2 = str2.toLowerCase(); - } - - return (str1 == str2) - } - - /** - * Based on the type of this URI (http, ftp, etc.) get - * the default port used for that protocol. This is - * just intended to be a helper function for the most - * common cases. - */ - public function getDefaultPort() : String - { - if (_scheme == "http") - return String("80"); - else if (_scheme == "ftp") - return String("21"); - else if (_scheme == "file") - return String(""); - else if (_scheme == "sftp") - return String("22"); // ssh standard port - else - { - // Don't know the port for this URI type - return String(""); - } - } - - /** - * @private - * - * This resolves the given URI if the application has a - * resolver interface defined. This function does not - * modify the passed in URI and returns a new URI. - */ - static protected function resolve(uri:URI) : URI - { - var copy:URI = new URI(); - copy.copyURI(uri); - - if (_resolver != null) - { - // A resolver class has been registered. Call it. - return _resolver.resolve(copy); - } - else - { - // No resolver. Nothing to do, but we don't - // want to reuse the one passed in. - return copy; - } - } - - /** - * Accessor to set and get the resolver object used by all URI - * objects to dynamically resolve URI's before comparison. - */ - static public function set resolver(resolver:IURIResolver) : void - { - _resolver = resolver; - } - static public function get resolver() : IURIResolver - { - return _resolver; - } - - /** - * Given another URI, return this URI object's relation to the one given. - * URI's can have 1 of 4 possible relationships. They can be unrelated, - * equal, parent, or a child of the given URI. - * - * @param uri URI to compare this URI object to. - * @param caseSensitive true if the URI comparison should be done - * taking case into account, false if the comparison should be - * performed case insensitive. - * - * @return URI.NOT_RELATED, URI.CHILD, URI.PARENT, or URI.EQUAL - */ - public function getRelation(uri:URI, caseSensitive:Boolean = true) : int - { - // Give the app a chance to resolve these URI's before we compare them. - var thisURI:URI = URI.resolve(this); - var thatURI:URI = URI.resolve(uri); - - if (thisURI.isRelative() || thatURI.isRelative()) - { - // You cannot compare relative URI's due to their lack of context. - // You could have two relative URI's that look like: - // ../../images/ - // ../../images/marketing/logo.gif - // These may appear related, but you have no overall context - // from which to make the comparison. The first URI could be - // from one site and the other URI could be from another site. - return URI.NOT_RELATED; - } - else if (thisURI.isHierarchical() == false || thatURI.isHierarchical() == false) - { - // One or both of the URI's are non-hierarchical. - if (((thisURI.isHierarchical() == false) && (thatURI.isHierarchical() == true)) || - ((thisURI.isHierarchical() == true) && (thatURI.isHierarchical() == false))) - { - // XOR. One is hierarchical and the other is - // non-hierarchical. They cannot be compared. - return URI.NOT_RELATED; - } - else - { - // They are both non-hierarchical - if (thisURI.scheme != thatURI.scheme) - return URI.NOT_RELATED; - - if (thisURI.nonHierarchical != thatURI.nonHierarchical) - return URI.NOT_RELATED; - - // The two non-hierarcical URI's are equal. - return URI.EQUAL; - } - } - - // Ok, this URI and the one we are being compared to are both - // absolute hierarchical URI's. - - if (thisURI.scheme != thatURI.scheme) - return URI.NOT_RELATED; - - if (thisURI.authority != thatURI.authority) - return URI.NOT_RELATED; - - var thisPort:String = thisURI.port; - var thatPort:String = thatURI.port; - - // Different ports are considered completely different servers. - if (thisPort == "") - thisPort = thisURI.getDefaultPort(); - if (thatPort == "") - thatPort = thatURI.getDefaultPort(); - - // Check to see if the port is the default port. - if (thisPort != thatPort) - return URI.NOT_RELATED; - - if (compareStr(thisURI.path, thatURI.path, caseSensitive)) - return URI.EQUAL; - - // Special case check. If we are here, the scheme, authority, - // and port match, and it is not a relative path, but the - // paths did not match. There is a special case where we - // could have: - // http://something.com/ - // http://something.com - // Technically, these are equal. So lets, check for this case. - var thisPath:String = thisURI.path; - var thatPath:String = thatURI.path; - - if ( (thisPath == "/" || thatPath == "/") && - (thisPath == "" || thatPath == "") ) - { - // We hit the special case. These two are equal. - return URI.EQUAL; - } - - // Ok, the paths do not match, but one path may be a parent/child - // of the other. For example, we may have: - // http://something.com/path/to/homepage/ - // http://something.com/path/to/homepage/images/logo.gif - // In this case, the first is a parent of the second (or the second - // is a child of the first, depending on which you compare to the - // other). To make this comparison, we must split the path into - // its component parts (split the string on the '/' path delimiter). - // We then compare the - var thisParts:Array, thatParts:Array; - var thisPart:String, thatPart:String; - var i:int; - - thisParts = thisPath.split("/"); - thatParts = thatPath.split("/"); - - if (thisParts.length > thatParts.length) - { - thatPart = thatParts[thatParts.length - 1]; - if (thatPart.length > 0) - { - // if the last part is not empty, the passed URI is - // not a directory. There is no way the passed URI - // can be a parent. - return URI.NOT_RELATED; - } - else - { - // Remove the empty trailing part - thatParts.pop(); - } - - // This may be a child of the one passed in - for (i = 0; i < thatParts.length; i++) - { - thisPart = thisParts[i]; - thatPart = thatParts[i]; - - if (compareStr(thisPart, thatPart, caseSensitive) == false) - return URI.NOT_RELATED; - } - - return URI.CHILD; - } - else if (thisParts.length < thatParts.length) - { - thisPart = thisParts[thisParts.length - 1]; - if (thisPart.length > 0) - { - // if the last part is not empty, this URI is not a - // directory. There is no way this object can be - // a parent. - return URI.NOT_RELATED; - } - else - { - // Remove the empty trailing part - thisParts.pop(); - } - - // This may be the parent of the one passed in - for (i = 0; i < thisParts.length; i++) - { - thisPart = thisParts[i]; - thatPart = thatParts[i]; - - if (compareStr(thisPart, thatPart, caseSensitive) == false) - return URI.NOT_RELATED; - } - - return URI.PARENT; - } - else - { - // Both URI's have the same number of path components, but - // it failed the equivelence check above. This means that - // the two URI's are not related. - return URI.NOT_RELATED; - } - - // If we got here, the scheme and authority are the same, - // but the paths pointed to two different locations that - // were in different parts of the file system tree - return URI.NOT_RELATED; - } - - /** - * Given another URI, return the common parent between this one - * and the provided URI. - * - * @param uri the other URI from which to find a common parent - * @para caseSensitive true if this operation should be done - * with case sensitive comparisons. - * - * @return the parent URI if successful, null otherwise. - */ - public function getCommonParent(uri:URI, caseSensitive:Boolean = true) : URI - { - var thisURI:URI = URI.resolve(this); - var thatURI:URI = URI.resolve(uri); - - if(!thisURI.isAbsolute() || !thatURI.isAbsolute() || - thisURI.isHierarchical() == false || - thatURI.isHierarchical() == false) - { - // Both URI's must be absolute hierarchical for this to - // make sense. - return null; - } - - var relation:int = thisURI.getRelation(thatURI); - if (relation == URI.NOT_RELATED) - { - // The given URI is not related to this one. No - // common parent. - return null; - } - - thisURI.chdir("."); - thatURI.chdir("."); - - var strBefore:String, strAfter:String; - do - { - relation = thisURI.getRelation(thatURI, caseSensitive); - if(relation == URI.EQUAL || relation == URI.PARENT) - break; - - // If strBefore and strAfter end up being the same, - // we know we are at the root of the path because - // chdir("..") is doing nothing. - strBefore = thisURI.toString(); - thisURI.chdir(".."); - strAfter = thisURI.toString(); - } - while(strBefore != strAfter); - - return thisURI; - } - - - /** - * This function is used to move around in a URI in a way similar - * to the 'cd' or 'chdir' commands on Unix. These operations are - * completely string based, using the context of the URI to - * determine the position within the path. The heuristics used - * to determine the action are based off Appendix C in RFC 2396. - * - *URI paths that end in '/' are considered paths that point to
- * directories, while paths that do not end in '/' are files. For
- * example, if you execute chdir("d") on the following URI's:
- * 1. http://something.com/a/b/c/ (directory)
- * 2. http://something.com/a/b/c (not directory)
- * you will get:
- * 1. http://something.com/a/b/c/d
- * 2. http://something.com/a/b/d
See RFC 2396, Appendix C for more info.
- * - * @param reference the URI or path to "cd" to. - * @param escape true if the passed reference string should be URI - * escaped before using it. - * - * @return true if the chdir was successful, false otherwise. - */ - public function chdir(reference:String, escape:Boolean = false) : Boolean - { - var uriReference:URI; - var ref:String = reference; - - if (escape) - ref = URI.escapeChars(reference); - - if (ref == "") - { - // NOOP - return true; - } - else if (ref.substr(0, 2) == "//") - { - // Special case. This is an absolute URI but without the scheme. - // Take the scheme from this URI and tack it on. This is - // intended to make working with chdir() a little more - // tolerant. - var final:String = this.scheme + ":" + ref; - - return constructURI(final); - } - else if (ref.charAt(0) == "?") - { - // A relative URI that is just a query part is essentially - // a "./?query". We tack on the "./" here to make the rest - // of our logic work. - ref = "./" + ref; - } - - // Parse the reference passed in as a URI. This way we - // get any query and fragments parsed out as well. - uriReference = new URI(ref); - - if (uriReference.isAbsolute() || - uriReference.isHierarchical() == false) - { - // If the URI given is a full URI, it replaces this one. - copyURI(uriReference); - return true; - } - - - var thisPath:String, thatPath:String; - var thisParts:Array, thatParts:Array; - var thisIsDir:Boolean = false, thatIsDir:Boolean = false; - var thisIsAbs:Boolean = false, thatIsAbs:Boolean = false; - var lastIsDotOperation:Boolean = false; - var curDir:String; - var i:int; - - thisPath = this.path; - thatPath = uriReference.path; - - if (thisPath.length > 0) - thisParts = thisPath.split("/"); - else - thisParts = new Array(); - - if (thatPath.length > 0) - thatParts = thatPath.split("/"); - else - thatParts = new Array(); - - if (thisParts.length > 0 && thisParts[0] == "") - { - thisIsAbs = true; - thisParts.shift(); // pop the first one off the array - } - if (thisParts.length > 0 && thisParts[thisParts.length - 1] == "") - { - thisIsDir = true; - thisParts.pop(); // pop the last one off the array - } - - if (thatParts.length > 0 && thatParts[0] == "") - { - thatIsAbs = true; - thatParts.shift(); // pop the first one off the array - } - if (thatParts.length > 0 && thatParts[thatParts.length - 1] == "") - { - thatIsDir = true; - thatParts.pop(); // pop the last one off the array - } - - if (thatIsAbs) - { - // The reference is an absolute path (starts with a slash). - // It replaces this path wholesale. - this.path = uriReference.path; - - // And it inherits the query and fragment - this.queryRaw = uriReference.queryRaw; - this.fragment = uriReference.fragment; - - return true; - } - else if (thatParts.length == 0 && uriReference.query == "") - { - // The reference must have only been a fragment. Fragments just - // get appended to whatever the current path is. We don't want - // to overwrite any query that may already exist, so this case - // only takes on the new fragment. - this.fragment = uriReference.fragment; - return true; - } - else if (thisIsDir == false && thisParts.length > 0) - { - // This path ends in a file. It goes away no matter what. - thisParts.pop(); - } - - // By default, this assumes the query and fragment of the reference - this.queryRaw = uriReference.queryRaw; - this.fragment = uriReference.fragment; - - // Append the parts of the path from the passed in reference - // to this object's path. - thisParts = thisParts.concat(thatParts); - - for(i = 0; i < thisParts.length; i++) - { - curDir = thisParts[i]; - lastIsDotOperation = false; - - if (curDir == ".") - { - thisParts.splice(i, 1); - i = i - 1; // account for removing this item - lastIsDotOperation = true; - } - else if (curDir == "..") - { - if (i >= 1) - { - if (thisParts[i - 1] == "..") - { - // If the previous is a "..", we must have skipped - // it due to this URI being relative. We can't - // collapse leading ".."s in a relative URI, so - // do nothing. - } - else - { - thisParts.splice(i - 1, 2); - i = i - 2; // move back to account for the 2 we removed - } - } - else - { - // This is the first thing in the path. - - if (isRelative()) - { - // We can't collapse leading ".."s in a relative - // path. Do noting. - } - else - { - // This is an abnormal case. We have dot-dotted up - // past the base of our "file system". This is a - // case where we had a /path/like/this.htm and were - // given a path to chdir to like this: - // ../../../../../../mydir - // Obviously, it has too many ".." and will take us - // up beyond the top of the URI. However, according - // RFC 2396 Appendix C.2, we should try to handle - // these abnormal cases appropriately. In this case, - // we will do what UNIX command lines do if you are - // at the root (/) of the filesystem and execute: - // # cd ../../../../../bin - // Which will put you in /bin. Essentially, the extra - // ".."'s will just get eaten. - - thisParts.splice(i, 1); - i = i - 1; // account for the ".." we just removed - } - } - - lastIsDotOperation = true; - } - } - - var finalPath:String = ""; - - // If the last thing in the path was a "." or "..", then this thing is a - // directory. If the last thing isn't a dot-op, then we don't want to - // blow away any information about the directory (hence the "|=" binary - // assignment). - thatIsDir = thatIsDir || lastIsDotOperation; - - // Reconstruct the path with the abs/dir info we have - finalPath = joinPath(thisParts, thisIsAbs, thatIsDir); - - // Set the path (automatically escaping it) - this.path = finalPath; - - return true; - } - - /** - * @private - * Join an array of path parts back into a URI style path string. - * This is used by the various path logic functions to recombine - * a path. This is different than the standard Array.join() - * function because we need to take into account the starting and - * ending path delimiters if this is an absolute path or a - * directory. - * - * @param parts the Array that contains strings of each path part. - * @param isAbs true if the given path is absolute - * @param isDir true if the given path is a directory - * - * @return the combined path string. - */ - protected function joinPath(parts:Array, isAbs:Boolean, isDir:Boolean) : String - { - var pathStr:String = ""; - var i:int; - - for (i = 0; i < parts.length; i++) - { - if (pathStr.length > 0) - pathStr += "/"; - - pathStr += parts[i]; - } - - // If this path is a directory, tack on the directory delimiter, - // but only if the path contains something. Adding this to an - // empty path would make it "/", which is an absolute path that - // starts at the root. - if (isDir && pathStr.length > 0) - pathStr += "/"; - - if (isAbs) - pathStr = "/" + pathStr; - - return pathStr; - } - - /** - * Given an absolute URI, make this relative URI absolute using - * the given URI as a base. This URI instance must be relative - * and the base_uri must be absolute. - * - * @param base_uri URI to use as the base from which to make - * this relative URI into an absolute URI. - * - * @return true if successful, false otherwise. - */ - public function makeAbsoluteURI(base_uri:URI) : Boolean - { - if (isAbsolute() || base_uri.isRelative()) - { - // This URI needs to be relative, and the base needs to be - // absolute otherwise we won't know what to do! - return false; - } - - // Make a copy of the base URI. We don't want to modify - // the passed URI. - var base:URI = new URI(); - base.copyURI(base_uri); - - // ChDir on the base URI. This will preserve any query - // and fragment we have. - if (base.chdir(toString()) == false) - return false; - - // It worked, so copy the base into this one - copyURI(base); - - return true; - } - - - /** - * Given a URI to use as a base from which this object should be - * relative to, convert this object into a relative URI. For example, - * if you have: - * - *uri1 will have a final value of "../some/file.html"
- * - *Note! This function is brute force. If you have two URI's - * that are completely unrelated, this will still attempt to make - * the relative URI. In that case, you will most likely get a - * relative path that looks something like:
- * - *../../../../../../some/path/to/my/file.html
- * - * @param base_uri the URI from which to make this URI relative - * - * @return true if successful, false if the base_uri and this URI - * are not related, of if error. - */ - public function makeRelativeURI(base_uri:URI, caseSensitive:Boolean = true) : Boolean - { - var base:URI = new URI(); - base.copyURI(base_uri); - - var thisParts:Array, thatParts:Array; - var finalParts:Array = new Array(); - var thisPart:String, thatPart:String, finalPath:String; - var pathStr:String = this.path; - var queryStr:String = this.queryRaw; - var fragmentStr:String = this.fragment; - var i:int; - var diff:Boolean = false; - var isDir:Boolean = false; - - if (isRelative()) - { - // We're already relative. - return true; - } - - if (base.isRelative()) - { - // The base is relative. A relative base doesn't make sense. - return false; - } - - - if ( (isOfType(base_uri.scheme) == false) || - (this.authority != base_uri.authority) ) - { - // The schemes and/or authorities are different. We can't - // make a relative path to something that is completely - // unrelated. - return false; - } - - // Record the state of this URI - isDir = isDirectory(); - - // We are based of the directory of the given URI. We need to - // make sure the URI is pointing to a directory. Changing - // directory to "." will remove any file name if the base is - // not a directory. - base.chdir("."); - - thisParts = pathStr.split("/"); - thatParts = base.path.split("/"); - - if (thisParts.length > 0 && thisParts[0] == "") - thisParts.shift(); - - if (thisParts.length > 0 && thisParts[thisParts.length - 1] == "") - { - isDir = true; - thisParts.pop(); - } - - if (thatParts.length > 0 && thatParts[0] == "") - thatParts.shift(); - if (thatParts.length > 0 && thatParts[thatParts.length - 1] == "") - thatParts.pop(); - - - // Now that we have the paths split into an array of directories, - // we can compare the two paths. We start from the left of side - // of the path and start comparing. When we either run out of - // directories (one path is longer than the other), or we find - // a directory that is different, we stop. The remaining parts - // of each path is then used to determine the relative path. For - // example, lets say we have: - // path we want to make relative: /a/b/c/d/e.txt - // path to use as base for relative: /a/b/f/ - // - // This loop will start at the left, and remove directories - // until we get a mismatch or run off the end of one of them. - // In this example, the result will be: - // c/d/e.txt - // f - // - // For every part left over in the base path, we prepend a ".." - // to the relative to get the final path: - // ../c/d/e.txt - while(thatParts.length > 0) - { - if (thisParts.length == 0) - { - // we matched all there is to match, we are done. - // This is the case where "this" object is a parent - // path of the given URI. eg: - // this.path = /a/b/ (thisParts) - // base.path = /a/b/c/d/e/ (thatParts) - break; - } - - thisPart = thisParts[0]; - thatPart = thatParts[0]; - - if (compareStr(thisPart, thatPart, caseSensitive)) - { - thisParts.shift(); - thatParts.shift(); - } - else - break; - } - - // If there are any path info left from the base URI, that means - // **this** object is above the given URI in the file tree. For - // each part left over in the given URI, we need to move up one - // directory to get where we are. - var dotdot:String = ".."; - for (i = 0; i < thatParts.length; i++) - { - finalParts.push(dotdot); - } - - // Append the parts of this URI to any dot-dot's we have - finalParts = finalParts.concat(thisParts); - - // Join the parts back into a path - finalPath = joinPath(finalParts, false /* not absolute */, isDir); - - if (finalPath.length == 0) - { - // The two URI's are exactly the same. The proper relative - // path is: - finalPath = "./"; - } - - // Set the parts of the URI, preserving the original query and - // fragment parts. - setParts("", "", "", finalPath, queryStr, fragmentStr); - - return true; - } - - /** - * Given a string, convert it to a URI. The string could be a - * full URI that is improperly escaped, a malformed URI (e.g. - * missing a protocol like "www.something.com"), a relative URI, - * or any variation there of. - * - *The intention of this function is to take anything that a - * user might manually enter as a URI/URL and try to determine what - * they mean. This function differs from the URI constructor in - * that it makes some assumptions to make it easy to import user - * entered URI data.
- * - *This function is intended to be a helper function. - * It is not all-knowning and will probably make mistakes - * when attempting to parse a string of unknown origin. If - * your applicaiton is receiving input from the user, your - * application should already have a good idea what the user - * should be entering, and your application should be - * pre-processing the user's input to make sure it is well formed - * before passing it to this function.
- * - *It is assumed that the string given to this function is - * something the user may have manually entered. Given this, - * the URI string is probably unescaped or improperly escaped. - * This function will attempt to properly escape the URI by - * using forceEscape(). The result is that a toString() call - * on a URI that was created from unknownToURI() may not match - * the input string due to the difference in escaping.
- * - * @param unknown a potental URI string that should be parsed - * and loaded into this object. - * @param defaultScheme if it is determined that the passed string - * looks like a URI, but it is missing the scheme part, this - * string will be used as the missing scheme. - * - * @return true if the given string was successfully parsed into - * a valid URI object, false otherwise. - */ - public function unknownToURI(unknown:String, defaultScheme:String = "http") : Boolean - { - var temp:String; - - if (unknown.length == 0) - { - this.initialize(); - return false; - } - - // Some users love the backslash key. Fix it. - unknown = unknown.replace(/\\/g, "/"); - - // Check for any obviously missing scheme. - if (unknown.length >= 2) - { - temp = unknown.substr(0, 2); - if (temp == "//") - unknown = defaultScheme + ":" + unknown; - } - - if (unknown.length >= 3) - { - temp = unknown.substr(0, 3); - if (temp == "://") - unknown = defaultScheme + unknown; - } - - // Try parsing it as a normal URI - var uri:URI = new URI(unknown); - - if (uri.isHierarchical() == false) - { - if (uri.scheme == UNKNOWN_SCHEME) - { - this.initialize(); - return false; - } - - // It's a non-hierarchical URI - copyURI(uri); - forceEscape(); - return true; - } - else if ((uri.scheme != UNKNOWN_SCHEME) && - (uri.scheme.length > 0)) - { - if ( (uri.authority.length > 0) || - (uri.scheme == "file") ) - { - // file://... URI - copyURI(uri); - forceEscape(); // ensure proper escaping - return true; - } - else if (uri.authority.length == 0 && uri.path.length == 0) - { - // It's is an incomplete URI (eg "http://") - - setParts(uri.scheme, "", "", "", "", ""); - return false; - } - } - else - { - // Possible relative URI. We can only detect relative URI's - // that start with "." or "..". If it starts with something - // else, the parsing is ambiguous. - var path:String = uri.path; - - if (path == ".." || path == "." || - (path.length >= 3 && path.substr(0, 3) == "../") || - (path.length >= 2 && path.substr(0, 2) == "./") ) - { - // This is a relative URI. - copyURI(uri); - forceEscape(); - return true; - } - } - - // Ok, it looks like we are just a normal URI missing the scheme. Tack - // on the scheme. - uri = new URI(defaultScheme + "://" + unknown); - - // Check to see if we are good now - if (uri.scheme.length > 0 && uri.authority.length > 0) - { - // It was just missing the scheme. - copyURI(uri); - forceEscape(); // Make sure we are properly encoded. - return true; - } - - // don't know what this is - this.initialize(); - return false; - } - - } // end URI class +/* +Adobe Systems Incorporated(r) Source Code License Agreement +Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. + +Please read this Source Code License Agreement carefully before using +the source code. + +Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable copyright license, to reproduce, +prepare derivative works of, publicly display, publicly perform, and +distribute this source code and such derivative works in source or +object code form without any attribution requirements. + +The name "Adobe Systems Incorporated" must not be used to endorse or promote products +derived from the source code without prior written permission. + +You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and +against any loss, damage, claims or lawsuits, including attorney's +fees that arise or result from your use or distribution of the source +code. + +THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT +ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF +NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.adobe.net +{ + import flash.utils.ByteArray; + + /** + * This class implements functions and utilities for working with URI's + * (Universal Resource Identifiers). For technical description of the + * URI syntax, please see RFC 3986 at http://www.ietf.org/rfc/rfc3986.txt + * or do a web search for "rfc 3986". + * + *The most important aspect of URI's to understand is that URI's + * and URL's are not strings. URI's are complex data structures that + * encapsulate many pieces of information. The string version of a + * URI is the serialized representation of that data structure. This + * string serialization is used to provide a human readable + * representation and a means to transport the data over the network + * where it can then be parsed back into its' component parts.
+ * + *URI's fall into one of three categories: + *
The query and fragment parts are optional.
+ * + *This class supports both non-hierarchical and hierarchical URI's
+ * + *This class is intended to be used "as-is" for the vast majority + * of common URI's. However, if your application requires a custom + * URI syntax (e.g. custom query syntax or special handling of + * non-hierarchical URI's), this class can be fully subclassed. If you + * intended to subclass URI, please see the source code for complete + * documation on protected members and protected fuctions.
+ * + * @langversion ActionScript 3.0 + * @playerversion Flash 9.0 + */ + public class URI + { + // Here we define which characters must be escaped for each + // URI part. The characters that must be escaped for each + // part differ depending on what would cause ambiguous parsing. + // RFC 3986 sec. 2.4 states that characters should only be + // encoded when they would conflict with subcomponent delimiters. + // We don't want to over-do the escaping. We only want to escape + // the minimum needed to prevent parsing problems. + + // space and % must be escaped in all cases. '%' is the delimiter + // for escaped characters. + public static const URImustEscape:String = " %"; + + // Baseline of what characters must be escaped + public static const URIbaselineEscape:String = URImustEscape + ":?#/@"; + + // Characters that must be escaped in the part part. + public static const URIpathEscape:String = URImustEscape + "?#"; + + // Characters that must be escaped in the query part, if setting + // the query as a whole string. If the query is set by + // name/value, URIqueryPartEscape is used instead. + public static const URIqueryEscape:String = URImustEscape + "#"; + + // This is what each name/value pair must escape "&=" as well + // so they don't conflict with the "param=value¶m2=value2" + // syntax. + public static const URIqueryPartEscape:String = URImustEscape + "#&="; + + // Non-hierarchical URI's can have query and fragment parts, but + // we also want to prevent '/' otherwise it might end up looking + // like a hierarchical URI to the parser. + public static const URInonHierEscape:String = URImustEscape + "?#/"; + + // Baseline uninitialized setting for the URI scheme. + public static const UNKNOWN_SCHEME:String = "unknown"; + + // The following bitmaps are used for performance enhanced + // character escaping. + + // Baseline characters that need to be escaped. Many parts use + // this. + protected static const URIbaselineExcludedBitmap:URIEncodingBitmap = + new URIEncodingBitmap(URIbaselineEscape); + + // Scheme escaping bitmap + protected static const URIschemeExcludedBitmap:URIEncodingBitmap = + URIbaselineExcludedBitmap; + + // User/pass escaping bitmap + protected static const URIuserpassExcludedBitmap:URIEncodingBitmap = + URIbaselineExcludedBitmap; + + // Authority escaping bitmap + protected static const URIauthorityExcludedBitmap:URIEncodingBitmap = + URIbaselineExcludedBitmap; + + // Port escaping bitmap + protected static const URIportExludedBitmap:URIEncodingBitmap = + URIbaselineExcludedBitmap; + + // Path escaping bitmap + protected static const URIpathExcludedBitmap:URIEncodingBitmap = + new URIEncodingBitmap(URIpathEscape); + + // Query (whole) escaping bitmap + protected static const URIqueryExcludedBitmap:URIEncodingBitmap = + new URIEncodingBitmap(URIqueryEscape); + + // Query (individual parts) escaping bitmap + protected static const URIqueryPartExcludedBitmap:URIEncodingBitmap = + new URIEncodingBitmap(URIqueryPartEscape); + + // Fragments are the last part in the URI. They only need to + // escape space, '#', and '%'. Turns out that is what query + // uses too. + protected static const URIfragmentExcludedBitmap:URIEncodingBitmap = + URIqueryExcludedBitmap; + + // Characters that need to be escaped in the non-hierarchical part + protected static const URInonHierexcludedBitmap:URIEncodingBitmap = + new URIEncodingBitmap(URInonHierEscape); + + // Values used by getRelation() + public static const NOT_RELATED:int = 0; + public static const CHILD:int = 1; + public static const EQUAL:int = 2; + public static const PARENT:int = 3; + + //------------------------------------------------------------------- + // protected class members + //------------------------------------------------------------------- + protected var _valid:Boolean = false; + protected var _relative:Boolean = false; + protected var _scheme:String = ""; + protected var _authority:String = ""; + protected var _username:String = ""; + protected var _password:String = ""; + protected var _port:String = ""; + protected var _path:String = ""; + protected var _query:String = ""; + protected var _fragment:String = ""; + protected var _nonHierarchical:String = ""; + protected static var _resolver:IURIResolver = null; + + + /** + * URI Constructor. If no string is given, this will initialize + * this URI object to a blank URI. + */ + public function URI(uri:String = null) : void + { + if (uri == null) + initialize(); + else + constructURI(uri); + } + + + /** + * @private + * Method that loads the URI from the given string. + */ + protected function constructURI(uri:String) : Boolean + { + if (!parseURI(uri)) + _valid = false; + + return isValid(); + } + + + /** + * @private Private initializiation. + */ + protected function initialize() : void + { + _valid = false; + _relative = false; + + _scheme = UNKNOWN_SCHEME; + _authority = ""; + _username = ""; + _password = ""; + _port = ""; + _path = ""; + _query = ""; + _fragment = ""; + + _nonHierarchical = ""; + } + + /** + * @private Accessor to explicitly set/get the hierarchical + * state of the URI. + */ + protected function set hierState(state:Boolean) : void + { + if (state) + { + // Clear the non-hierarchical data + _nonHierarchical = ""; + + // Also set the state vars while we are at it + if (_scheme == "" || _scheme == UNKNOWN_SCHEME) + _relative = true; + else + _relative = false; + + if (_authority.length == 0 && _path.length == 0) + _valid = false; + else + _valid = true; + } + else + { + // Clear the hierarchical data + _authority = ""; + _username = ""; + _password = ""; + _port = ""; + _path = ""; + + _relative = false; + + if (_scheme == "" || _scheme == UNKNOWN_SCHEME) + _valid = false; + else + _valid = true; + } + } + protected function get hierState() : Boolean + { + return (_nonHierarchical.length == 0); + } + + + /** + * @private Functions that performs some basic consistency validation. + */ + protected function validateURI() : Boolean + { + // Check the scheme + if (isAbsolute()) + { + if (_scheme.length <= 1 || _scheme == UNKNOWN_SCHEME) + { + // we probably parsed a C:\ type path or no scheme + return false; + } + else if (verifyAlpha(_scheme) == false) + return false; // Scheme contains bad characters + } + + if (hierState) + { + if (_path.search('\\') != -1) + return false; // local path + else if (isRelative() == false && _scheme == UNKNOWN_SCHEME) + return false; // It's an absolute URI, but it has a bad scheme + } + else + { + if (_nonHierarchical.search('\\') != -1) + return false; // some kind of local path + } + + // Looks like it's ok. + return true; + } + + + /** + * @private + * + * Given a URI in string format, parse that sucker into its basic + * components and assign them to this object. A URI is of the form: + *The URI specification allows for authentication + * credentials to be embedded in the URI as such:
+ * + *http://user:passwd@host/path/to/file.htm
+ * + *When setting this value, the string + * given is assumed to be unescaped. When retrieving this + * value, the resulting string is unescaped.
+ */ + public function get username() : String + { + return URI.unescapeChars(_username); + } + public function set username(usernameStr:String) : void + { + _username = URI.fastEscapeChars(usernameStr, URI.URIuserpassExcludedBitmap); + + // Only hierarchical URI's can have a username. + this.hierState = true; + } + + + /** + * The password of the URI. Similar to username. + * @see URI.username + */ + public function get password() : String + { + return URI.unescapeChars(_password); + } + public function set password(passwordStr:String) : void + { + _password = URI.fastEscapeChars(passwordStr, + URI.URIuserpassExcludedBitmap); + + // Only hierarchical URI's can have a password. + this.hierState = true; + } + + + /** + * The host port number. Only valid for hierarchical URI's. If + * the URI is relative, this will be an empty string. URI's can + * contain the port number of the remote host: + * + *http://site.com:8080/index.htm
+ */ + public function get port() : String + { + return URI.unescapeChars(_port); + } + public function set port(portStr:String) : void + { + _port = URI.escapeChars(portStr); + + // Only hierarchical URI's can have a port. + this.hierState = true; + } + + + /** + * The path portion of the URI. Only valid for hierarchical + * URI's. When setting this value, the string + * given is assumed to be unescaped. When retrieving this + * value, the resulting string is unescaped. + * + *The path portion can be in one of two formats. 1) an absolute + * path, or 2) a relative path. An absolute path starts with a + * slash ('/'), a relative path does not.
+ * + *An absolute path may look like:
+ *A relative path may look like:
+ *Paths can be absolute or relative. Note that this not the same as + * an absolute or relative URI. An absolute URI can only have absolute + * paths. For example:
+ * + *This absolute URI has an absolute path of "/path/to/file.htm".
+ * + *Relative URI's can have either absolute paths or relative paths. + * All of the following relative URI's are valid:
+ * + *This accessor should only be used if a custom query syntax + * is used. This URI class supports the common "param=value" + * style query syntax via the get/setQueryValue() and + * get/setQueryByMap() functions. Those functions should be used + * instead if the common syntax is being used. + * + *
The URI RFC does not specify any particular + * syntax for the query part of a URI. It is intended to allow + * any format that can be agreed upon by the two communicating hosts. + * However, most systems have standardized on the typical CGI + * format:
+ * + *This class has specific support for this query syntax
+ * + *This common query format is an array of name/value + * pairs with its own syntax that is different from the overall URI + * syntax. The query has its own escaping logic. For a query part + * to be properly escaped and unescaped, it must be split into its + * component parts. This accessor escapes/unescapes the entire query + * part without regard for it's component parts. This has the + * possibliity of leaving the query string in an ambiguious state in + * regards to its syntax. If the contents of the query part are + * important, it is recommended that get/setQueryValue() or + * get/setQueryByMap() are used instead.
+ * + * If a different query syntax is being used, a subclass of URI + * can be created to handle that specific syntax. + * + * @see URI.getQueryValue, URI.getQueryByMap + */ + public function get query() : String + { + return URI.unescapeChars(_query); + } + public function set query(queryStr:String) : void + { + _query = URI.fastEscapeChars(queryStr, URI.URIqueryExcludedBitmap); + + // both hierarchical and non-hierarchical URI's can + // have a query. Do not set the hierState. + } + + /** + * Accessor to the raw query data. If you are using a custom query + * syntax, this accessor can be used to get and set the query part + * directly with no escaping/unescaping. This should ONLY be used + * if your application logic is handling custom query logic and + * handling the proper escaping of the query part. + */ + public function get queryRaw() : String + { + return _query; + } + public function set queryRaw(queryStr:String) : void + { + _query = queryStr; + } + + + /** + * The fragment (anchor) portion of the URI. This is valid for + * both hierarchical and non-hierarchical URI's. + */ + public function get fragment() : String + { + return URI.unescapeChars(_fragment); + } + public function set fragment(fragmentStr:String) : void + { + _fragment = URI.fastEscapeChars(fragmentStr, URIfragmentExcludedBitmap); + + // both hierarchical and non-hierarchical URI's can + // have a fragment. Do not set the hierState. + } + + + /** + * The non-hierarchical part of the URI. For example, if + * this URI object represents "mailto:somebody@company.com", + * this will contain "somebody@company.com". This is valid only + * for non-hierarchical URI's. + */ + public function get nonHierarchical() : String + { + return URI.unescapeChars(_nonHierarchical); + } + public function set nonHierarchical(nonHier:String) : void + { + _nonHierarchical = URI.fastEscapeChars(nonHier, URInonHierexcludedBitmap); + + // This is a non-hierarchical URI. + this.hierState = false; + } + + + /** + * Quick shorthand accessor to set the parts of this URI. + * The given parts are assumed to be in unescaped form. If + * the URI is non-hierarchical (e.g. mailto:) you will need + * to call SetScheme() and SetNonHierarchical(). + */ + public function setParts(schemeStr:String, authorityStr:String, + portStr:String, pathStr:String, queryStr:String, + fragmentStr:String) : void + { + this.scheme = schemeStr; + this.authority = authorityStr; + this.port = portStr; + this.path = pathStr; + this.query = queryStr; + this.fragment = fragmentStr; + + hierState = true; + } + + + /** + * URI escapes the given character string. This is similar in function + * to the global encodeURIComponent() function in ActionScript, but is + * slightly different in regards to which characters get escaped. This + * escapes the characters specified in the URIbaselineExluded set (see class + * static members). This is needed for this class to work properly. + * + *If a different set of characters need to be used for the escaping, + * you may use fastEscapeChars() and specify a custom URIEncodingBitmap + * that contains the characters your application needs escaped.
+ * + *Never pass a full URI to this function. A URI can only be properly + * escaped/unescaped when split into its component parts (see RFC 3986 + * section 2.4). This is due to the fact that the URI component separators + * could be characters that would normally need to be escaped.
+ * + * @param unescaped character string to be escaped. + * + * @return escaped character string + * + * @see encodeURIComponent + * @see fastEscapeChars + */ + static public function escapeChars(unescaped:String) : String + { + // This uses the excluded set by default. + return fastEscapeChars(unescaped, URI.URIbaselineExcludedBitmap); + } + + + /** + * Unescape any URI escaped characters in the given character + * string. + * + *Never pass a full URI to this function. A URI can only be properly + * escaped/unescaped when split into its component parts (see RFC 3986 + * section 2.4). This is due to the fact that the URI component separators + * could be characters that would normally need to be escaped.
+ * + * @param escaped the escaped string to be unescaped. + * + * @return unescaped string. + */ + static public function unescapeChars(escaped:String /*, onlyHighASCII:Boolean = false*/) : String + { + // We can just use the default AS function. It seems to + // decode everything correctly + var unescaped:String; + unescaped = decodeURIComponent(escaped); + return unescaped; + } + + /** + * Performance focused function that escapes the given character + * string using the given URIEncodingBitmap as the rule for what + * characters need to be escaped. This function is used by this + * class and can be used externally to this class to perform + * escaping on custom character sets. + * + *Never pass a full URI to this function. A URI can only be properly + * escaped/unescaped when split into its component parts (see RFC 3986 + * section 2.4). This is due to the fact that the URI component separators + * could be characters that would normally need to be escaped.
+ * + * @param unescaped the unescaped string to be escaped + * @param bitmap the set of characters that need to be escaped + * + * @return the escaped string. + */ + static public function fastEscapeChars(unescaped:String, bitmap:URIEncodingBitmap) : String + { + var escaped:String = ""; + var c:String; + var x:int, i:int; + + for (i = 0; i < unescaped.length; i++) + { + c = unescaped.charAt(i); + + x = bitmap.ShouldEscape(c); + if (x) + { + c = x.toString(16); + if (c.length == 1) + c = "0" + c; + + c = "%" + c; + c = c.toUpperCase(); + } + + escaped += c; + } + + return escaped; + } + + + /** + * Is this URI of a particular scheme type? For example, + * passing "http" to a URI object that represents the URI + * "http://site.com/" would return true. + * + * @param scheme scheme to check for + * + * @return true if this URI object is of the given type, false + * otherwise. + */ + public function isOfType(scheme:String) : Boolean + { + // Schemes are never case sensitive. Ignore case. + scheme = scheme.toLowerCase(); + return (this._scheme == scheme); + } + + + /** + * Get the value for the specified named in the query part. This + * assumes the query part of the URI is in the common + * "name1=value1&name2=value2" syntax. Do not call this function + * if you are using a custom query syntax. + * + * @param name name of the query value to get. + * + * @return the value of the query name, empty string if the + * query name does not exist. + */ + public function getQueryValue(name:String) : String + { + var map:Object; + var item:String; + var value:String; + + map = getQueryByMap(); + + for (item in map) + { + if (item == name) + { + value = map[item]; + return value; + } + } + + // Didn't find the specified key + return new String(""); + } + + + /** + * Set the given value on the given query name. If the given name + * does not exist, it will automatically add this name/value pair + * to the query. If null is passed as the value, it will remove + * the given item from the query. + * + *This automatically escapes any characters that may conflict with + * the query syntax so that they are "safe" within the query. The + * strings passed are assumed to be literal unescaped name and value.
+ * + * @param name name of the query value to set + * @param value value of the query item to set. If null, this will + * force the removal of this item from the query. + */ + public function setQueryValue(name:String, value:String) : void + { + var map:Object; + + map = getQueryByMap(); + + // If the key doesn't exist yet, this will create a new pair in + // the map. If it does exist, this will overwrite the previous + // value, which is what we want. + map[name] = value; + + setQueryByMap(map); + } + + + /** + * Get the query of the URI in an Object class that allows for easy + * access to the query data via Object accessors. For example: + * + *Sometimes URI's are constructed by hand using strings outside + * this class. In those cases, it is unlikely the URI has been + * properly escaped. This function forcefully escapes this URI + * by unescaping each part and then re-escaping it. If the URI + * did not have any escaping, the first unescape will do nothing + * and then the re-escape will properly escape everything. If + * the URI was already escaped, the unescape and re-escape will + * essentally be a no-op. This provides a safe way to make sure + * a URI is in the proper escaped form.
+ */ + public function forceEscape() : void + { + // The accessors for each of the members will unescape + // and then re-escape as we get and assign them. + + // Handle the parts that are common for both hierarchical + // and non-hierarchical URI's + this.scheme = this.scheme; + this.setQueryByMap(this.getQueryByMap()); + this.fragment = this.fragment; + + if (isHierarchical()) + { + this.authority = this.authority; + this.path = this.path; + this.port = this.port; + this.username = this.username; + this.password = this.password; + } + else + { + this.nonHierarchical = this.nonHierarchical; + } + } + + + /** + * Does this URI point to a resource of the given file type? + * Given a file extension (or just a file name, this will strip the + * extension), check to see if this URI points to a file of that + * type. + * + * @param extension string that contains a file extension with or + * without a dot ("html" and ".html" are both valid), or a file + * name with an extension (e.g. "index.html"). + * + * @return true if this URI points to a resource with the same file + * file extension as the extension provided, false otherwise. + */ + public function isOfFileType(extension:String) : Boolean + { + var thisExtension:String; + var index:int; + + index = extension.lastIndexOf("."); + if (index != -1) + { + // Strip the extension + extension = extension.substr(index + 1); + } + else + { + // The caller passed something without a dot in it. We + // will assume that it is just a plain extension (e.g. "html"). + // What they passed is exactly what we want + } + + thisExtension = getExtension(true); + + if (thisExtension == "") + return false; + + // Compare the extensions ignoring case + if (compareStr(thisExtension, extension, false) == 0) + return true; + else + return false; + } + + + /** + * Get the ".xyz" file extension from the filename in the URI. + * For example, if we have the following URI: + * + *This will return ".html".
+ * + * @param minusDot If true, this will strip the dot from the extension. + * If true, the above example would have returned "html". + * + * @return the file extension + */ + public function getExtension(minusDot:Boolean = false) : String + { + var filename:String = getFilename(); + var extension:String; + var index:int; + + if (filename == "") + return String(""); + + index = filename.lastIndexOf("."); + + // If it doesn't have an extension, or if it is a "hidden" file, + // it doesn't have an extension. Hidden files on unix start with + // a dot (e.g. ".login"). + if (index == -1 || index == 0) + return String(""); + + extension = filename.substr(index); + + // If the caller does not want the dot, remove it. + if (minusDot && extension.charAt(0) == ".") + extension = extension.substr(1); + + return extension; + } + + /** + * Quick function to retrieve the file name off the end of a URI. + * + *For example, if the URI is:
+ *this function will return "file.html".
+ * + * @param minusExtension true if the file extension should be stripped + * + * @return the file name. If this URI is a directory, the return + * value will be empty string. + */ + public function getFilename(minusExtension:Boolean = false) : String + { + if (isDirectory()) + return String(""); + + var pathStr:String = this.path; + var filename:String; + var index:int; + + // Find the last path separator. + index = pathStr.lastIndexOf("/"); + + if (index != -1) + filename = pathStr.substr(index + 1); + else + filename = pathStr; + + if (minusExtension) + { + // The caller has requested that the extension be removed + index = filename.lastIndexOf("."); + + if (index != -1) + filename = filename.substr(0, index); + } + + return filename; + } + + + /** + * @private + * Helper function to compare strings. + * + * @return true if the two strings are identical, false otherwise. + */ + static protected function compareStr(str1:String, str2:String, + sensitive:Boolean = true) : Boolean + { + if (sensitive == false) + { + str1 = str1.toLowerCase(); + str2 = str2.toLowerCase(); + } + + return (str1 == str2) + } + + /** + * Based on the type of this URI (http, ftp, etc.) get + * the default port used for that protocol. This is + * just intended to be a helper function for the most + * common cases. + */ + public function getDefaultPort() : String + { + if (_scheme == "http") + return String("80"); + else if (_scheme == "ftp") + return String("21"); + else if (_scheme == "file") + return String(""); + else if (_scheme == "sftp") + return String("22"); // ssh standard port + else + { + // Don't know the port for this URI type + return String(""); + } + } + + /** + * @private + * + * This resolves the given URI if the application has a + * resolver interface defined. This function does not + * modify the passed in URI and returns a new URI. + */ + static protected function resolve(uri:URI) : URI + { + var copy:URI = new URI(); + copy.copyURI(uri); + + if (_resolver != null) + { + // A resolver class has been registered. Call it. + return _resolver.resolve(copy); + } + else + { + // No resolver. Nothing to do, but we don't + // want to reuse the one passed in. + return copy; + } + } + + /** + * Accessor to set and get the resolver object used by all URI + * objects to dynamically resolve URI's before comparison. + */ + static public function set resolver(resolver:IURIResolver) : void + { + _resolver = resolver; + } + static public function get resolver() : IURIResolver + { + return _resolver; + } + + /** + * Given another URI, return this URI object's relation to the one given. + * URI's can have 1 of 4 possible relationships. They can be unrelated, + * equal, parent, or a child of the given URI. + * + * @param uri URI to compare this URI object to. + * @param caseSensitive true if the URI comparison should be done + * taking case into account, false if the comparison should be + * performed case insensitive. + * + * @return URI.NOT_RELATED, URI.CHILD, URI.PARENT, or URI.EQUAL + */ + public function getRelation(uri:URI, caseSensitive:Boolean = true) : int + { + // Give the app a chance to resolve these URI's before we compare them. + var thisURI:URI = URI.resolve(this); + var thatURI:URI = URI.resolve(uri); + + if (thisURI.isRelative() || thatURI.isRelative()) + { + // You cannot compare relative URI's due to their lack of context. + // You could have two relative URI's that look like: + // ../../images/ + // ../../images/marketing/logo.gif + // These may appear related, but you have no overall context + // from which to make the comparison. The first URI could be + // from one site and the other URI could be from another site. + return URI.NOT_RELATED; + } + else if (thisURI.isHierarchical() == false || thatURI.isHierarchical() == false) + { + // One or both of the URI's are non-hierarchical. + if (((thisURI.isHierarchical() == false) && (thatURI.isHierarchical() == true)) || + ((thisURI.isHierarchical() == true) && (thatURI.isHierarchical() == false))) + { + // XOR. One is hierarchical and the other is + // non-hierarchical. They cannot be compared. + return URI.NOT_RELATED; + } + else + { + // They are both non-hierarchical + if (thisURI.scheme != thatURI.scheme) + return URI.NOT_RELATED; + + if (thisURI.nonHierarchical != thatURI.nonHierarchical) + return URI.NOT_RELATED; + + // The two non-hierarcical URI's are equal. + return URI.EQUAL; + } + } + + // Ok, this URI and the one we are being compared to are both + // absolute hierarchical URI's. + + if (thisURI.scheme != thatURI.scheme) + return URI.NOT_RELATED; + + if (thisURI.authority != thatURI.authority) + return URI.NOT_RELATED; + + var thisPort:String = thisURI.port; + var thatPort:String = thatURI.port; + + // Different ports are considered completely different servers. + if (thisPort == "") + thisPort = thisURI.getDefaultPort(); + if (thatPort == "") + thatPort = thatURI.getDefaultPort(); + + // Check to see if the port is the default port. + if (thisPort != thatPort) + return URI.NOT_RELATED; + + if (compareStr(thisURI.path, thatURI.path, caseSensitive)) + return URI.EQUAL; + + // Special case check. If we are here, the scheme, authority, + // and port match, and it is not a relative path, but the + // paths did not match. There is a special case where we + // could have: + // http://something.com/ + // http://something.com + // Technically, these are equal. So lets, check for this case. + var thisPath:String = thisURI.path; + var thatPath:String = thatURI.path; + + if ( (thisPath == "/" || thatPath == "/") && + (thisPath == "" || thatPath == "") ) + { + // We hit the special case. These two are equal. + return URI.EQUAL; + } + + // Ok, the paths do not match, but one path may be a parent/child + // of the other. For example, we may have: + // http://something.com/path/to/homepage/ + // http://something.com/path/to/homepage/images/logo.gif + // In this case, the first is a parent of the second (or the second + // is a child of the first, depending on which you compare to the + // other). To make this comparison, we must split the path into + // its component parts (split the string on the '/' path delimiter). + // We then compare the + var thisParts:Array, thatParts:Array; + var thisPart:String, thatPart:String; + var i:int; + + thisParts = thisPath.split("/"); + thatParts = thatPath.split("/"); + + if (thisParts.length > thatParts.length) + { + thatPart = thatParts[thatParts.length - 1]; + if (thatPart.length > 0) + { + // if the last part is not empty, the passed URI is + // not a directory. There is no way the passed URI + // can be a parent. + return URI.NOT_RELATED; + } + else + { + // Remove the empty trailing part + thatParts.pop(); + } + + // This may be a child of the one passed in + for (i = 0; i < thatParts.length; i++) + { + thisPart = thisParts[i]; + thatPart = thatParts[i]; + + if (compareStr(thisPart, thatPart, caseSensitive) == false) + return URI.NOT_RELATED; + } + + return URI.CHILD; + } + else if (thisParts.length < thatParts.length) + { + thisPart = thisParts[thisParts.length - 1]; + if (thisPart.length > 0) + { + // if the last part is not empty, this URI is not a + // directory. There is no way this object can be + // a parent. + return URI.NOT_RELATED; + } + else + { + // Remove the empty trailing part + thisParts.pop(); + } + + // This may be the parent of the one passed in + for (i = 0; i < thisParts.length; i++) + { + thisPart = thisParts[i]; + thatPart = thatParts[i]; + + if (compareStr(thisPart, thatPart, caseSensitive) == false) + return URI.NOT_RELATED; + } + + return URI.PARENT; + } + else + { + // Both URI's have the same number of path components, but + // it failed the equivelence check above. This means that + // the two URI's are not related. + return URI.NOT_RELATED; + } + + // If we got here, the scheme and authority are the same, + // but the paths pointed to two different locations that + // were in different parts of the file system tree + return URI.NOT_RELATED; + } + + /** + * Given another URI, return the common parent between this one + * and the provided URI. + * + * @param uri the other URI from which to find a common parent + * @para caseSensitive true if this operation should be done + * with case sensitive comparisons. + * + * @return the parent URI if successful, null otherwise. + */ + public function getCommonParent(uri:URI, caseSensitive:Boolean = true) : URI + { + var thisURI:URI = URI.resolve(this); + var thatURI:URI = URI.resolve(uri); + + if(!thisURI.isAbsolute() || !thatURI.isAbsolute() || + thisURI.isHierarchical() == false || + thatURI.isHierarchical() == false) + { + // Both URI's must be absolute hierarchical for this to + // make sense. + return null; + } + + var relation:int = thisURI.getRelation(thatURI); + if (relation == URI.NOT_RELATED) + { + // The given URI is not related to this one. No + // common parent. + return null; + } + + thisURI.chdir("."); + thatURI.chdir("."); + + var strBefore:String, strAfter:String; + do + { + relation = thisURI.getRelation(thatURI, caseSensitive); + if(relation == URI.EQUAL || relation == URI.PARENT) + break; + + // If strBefore and strAfter end up being the same, + // we know we are at the root of the path because + // chdir("..") is doing nothing. + strBefore = thisURI.toString(); + thisURI.chdir(".."); + strAfter = thisURI.toString(); + } + while(strBefore != strAfter); + + return thisURI; + } + + + /** + * This function is used to move around in a URI in a way similar + * to the 'cd' or 'chdir' commands on Unix. These operations are + * completely string based, using the context of the URI to + * determine the position within the path. The heuristics used + * to determine the action are based off Appendix C in RFC 2396. + * + *URI paths that end in '/' are considered paths that point to
+ * directories, while paths that do not end in '/' are files. For
+ * example, if you execute chdir("d") on the following URI's:
+ * 1. http://something.com/a/b/c/ (directory)
+ * 2. http://something.com/a/b/c (not directory)
+ * you will get:
+ * 1. http://something.com/a/b/c/d
+ * 2. http://something.com/a/b/d
See RFC 2396, Appendix C for more info.
+ * + * @param reference the URI or path to "cd" to. + * @param escape true if the passed reference string should be URI + * escaped before using it. + * + * @return true if the chdir was successful, false otherwise. + */ + public function chdir(reference:String, escape:Boolean = false) : Boolean + { + var uriReference:URI; + var ref:String = reference; + + if (escape) + ref = URI.escapeChars(reference); + + if (ref == "") + { + // NOOP + return true; + } + else if (ref.substr(0, 2) == "//") + { + // Special case. This is an absolute URI but without the scheme. + // Take the scheme from this URI and tack it on. This is + // intended to make working with chdir() a little more + // tolerant. + var final:String = this.scheme + ":" + ref; + + return constructURI(final); + } + else if (ref.charAt(0) == "?") + { + // A relative URI that is just a query part is essentially + // a "./?query". We tack on the "./" here to make the rest + // of our logic work. + ref = "./" + ref; + } + + // Parse the reference passed in as a URI. This way we + // get any query and fragments parsed out as well. + uriReference = new URI(ref); + + if (uriReference.isAbsolute() || + uriReference.isHierarchical() == false) + { + // If the URI given is a full URI, it replaces this one. + copyURI(uriReference); + return true; + } + + + var thisPath:String, thatPath:String; + var thisParts:Array, thatParts:Array; + var thisIsDir:Boolean = false, thatIsDir:Boolean = false; + var thisIsAbs:Boolean = false, thatIsAbs:Boolean = false; + var lastIsDotOperation:Boolean = false; + var curDir:String; + var i:int; + + thisPath = this.path; + thatPath = uriReference.path; + + if (thisPath.length > 0) + thisParts = thisPath.split("/"); + else + thisParts = new Array(); + + if (thatPath.length > 0) + thatParts = thatPath.split("/"); + else + thatParts = new Array(); + + if (thisParts.length > 0 && thisParts[0] == "") + { + thisIsAbs = true; + thisParts.shift(); // pop the first one off the array + } + if (thisParts.length > 0 && thisParts[thisParts.length - 1] == "") + { + thisIsDir = true; + thisParts.pop(); // pop the last one off the array + } + + if (thatParts.length > 0 && thatParts[0] == "") + { + thatIsAbs = true; + thatParts.shift(); // pop the first one off the array + } + if (thatParts.length > 0 && thatParts[thatParts.length - 1] == "") + { + thatIsDir = true; + thatParts.pop(); // pop the last one off the array + } + + if (thatIsAbs) + { + // The reference is an absolute path (starts with a slash). + // It replaces this path wholesale. + this.path = uriReference.path; + + // And it inherits the query and fragment + this.queryRaw = uriReference.queryRaw; + this.fragment = uriReference.fragment; + + return true; + } + else if (thatParts.length == 0 && uriReference.query == "") + { + // The reference must have only been a fragment. Fragments just + // get appended to whatever the current path is. We don't want + // to overwrite any query that may already exist, so this case + // only takes on the new fragment. + this.fragment = uriReference.fragment; + return true; + } + else if (thisIsDir == false && thisParts.length > 0) + { + // This path ends in a file. It goes away no matter what. + thisParts.pop(); + } + + // By default, this assumes the query and fragment of the reference + this.queryRaw = uriReference.queryRaw; + this.fragment = uriReference.fragment; + + // Append the parts of the path from the passed in reference + // to this object's path. + thisParts = thisParts.concat(thatParts); + + for(i = 0; i < thisParts.length; i++) + { + curDir = thisParts[i]; + lastIsDotOperation = false; + + if (curDir == ".") + { + thisParts.splice(i, 1); + i = i - 1; // account for removing this item + lastIsDotOperation = true; + } + else if (curDir == "..") + { + if (i >= 1) + { + if (thisParts[i - 1] == "..") + { + // If the previous is a "..", we must have skipped + // it due to this URI being relative. We can't + // collapse leading ".."s in a relative URI, so + // do nothing. + } + else + { + thisParts.splice(i - 1, 2); + i = i - 2; // move back to account for the 2 we removed + } + } + else + { + // This is the first thing in the path. + + if (isRelative()) + { + // We can't collapse leading ".."s in a relative + // path. Do noting. + } + else + { + // This is an abnormal case. We have dot-dotted up + // past the base of our "file system". This is a + // case where we had a /path/like/this.htm and were + // given a path to chdir to like this: + // ../../../../../../mydir + // Obviously, it has too many ".." and will take us + // up beyond the top of the URI. However, according + // RFC 2396 Appendix C.2, we should try to handle + // these abnormal cases appropriately. In this case, + // we will do what UNIX command lines do if you are + // at the root (/) of the filesystem and execute: + // # cd ../../../../../bin + // Which will put you in /bin. Essentially, the extra + // ".."'s will just get eaten. + + thisParts.splice(i, 1); + i = i - 1; // account for the ".." we just removed + } + } + + lastIsDotOperation = true; + } + } + + var finalPath:String = ""; + + // If the last thing in the path was a "." or "..", then this thing is a + // directory. If the last thing isn't a dot-op, then we don't want to + // blow away any information about the directory (hence the "|=" binary + // assignment). + thatIsDir = thatIsDir || lastIsDotOperation; + + // Reconstruct the path with the abs/dir info we have + finalPath = joinPath(thisParts, thisIsAbs, thatIsDir); + + // Set the path (automatically escaping it) + this.path = finalPath; + + return true; + } + + /** + * @private + * Join an array of path parts back into a URI style path string. + * This is used by the various path logic functions to recombine + * a path. This is different than the standard Array.join() + * function because we need to take into account the starting and + * ending path delimiters if this is an absolute path or a + * directory. + * + * @param parts the Array that contains strings of each path part. + * @param isAbs true if the given path is absolute + * @param isDir true if the given path is a directory + * + * @return the combined path string. + */ + protected function joinPath(parts:Array, isAbs:Boolean, isDir:Boolean) : String + { + var pathStr:String = ""; + var i:int; + + for (i = 0; i < parts.length; i++) + { + if (pathStr.length > 0) + pathStr += "/"; + + pathStr += parts[i]; + } + + // If this path is a directory, tack on the directory delimiter, + // but only if the path contains something. Adding this to an + // empty path would make it "/", which is an absolute path that + // starts at the root. + if (isDir && pathStr.length > 0) + pathStr += "/"; + + if (isAbs) + pathStr = "/" + pathStr; + + return pathStr; + } + + /** + * Given an absolute URI, make this relative URI absolute using + * the given URI as a base. This URI instance must be relative + * and the base_uri must be absolute. + * + * @param base_uri URI to use as the base from which to make + * this relative URI into an absolute URI. + * + * @return true if successful, false otherwise. + */ + public function makeAbsoluteURI(base_uri:URI) : Boolean + { + if (isAbsolute() || base_uri.isRelative()) + { + // This URI needs to be relative, and the base needs to be + // absolute otherwise we won't know what to do! + return false; + } + + // Make a copy of the base URI. We don't want to modify + // the passed URI. + var base:URI = new URI(); + base.copyURI(base_uri); + + // ChDir on the base URI. This will preserve any query + // and fragment we have. + if (base.chdir(toString()) == false) + return false; + + // It worked, so copy the base into this one + copyURI(base); + + return true; + } + + + /** + * Given a URI to use as a base from which this object should be + * relative to, convert this object into a relative URI. For example, + * if you have: + * + *uri1 will have a final value of "../some/file.html"
+ * + *Note! This function is brute force. If you have two URI's + * that are completely unrelated, this will still attempt to make + * the relative URI. In that case, you will most likely get a + * relative path that looks something like:
+ * + *../../../../../../some/path/to/my/file.html
+ * + * @param base_uri the URI from which to make this URI relative + * + * @return true if successful, false if the base_uri and this URI + * are not related, of if error. + */ + public function makeRelativeURI(base_uri:URI, caseSensitive:Boolean = true) : Boolean + { + var base:URI = new URI(); + base.copyURI(base_uri); + + var thisParts:Array, thatParts:Array; + var finalParts:Array = new Array(); + var thisPart:String, thatPart:String, finalPath:String; + var pathStr:String = this.path; + var queryStr:String = this.queryRaw; + var fragmentStr:String = this.fragment; + var i:int; + var diff:Boolean = false; + var isDir:Boolean = false; + + if (isRelative()) + { + // We're already relative. + return true; + } + + if (base.isRelative()) + { + // The base is relative. A relative base doesn't make sense. + return false; + } + + + if ( (isOfType(base_uri.scheme) == false) || + (this.authority != base_uri.authority) ) + { + // The schemes and/or authorities are different. We can't + // make a relative path to something that is completely + // unrelated. + return false; + } + + // Record the state of this URI + isDir = isDirectory(); + + // We are based of the directory of the given URI. We need to + // make sure the URI is pointing to a directory. Changing + // directory to "." will remove any file name if the base is + // not a directory. + base.chdir("."); + + thisParts = pathStr.split("/"); + thatParts = base.path.split("/"); + + if (thisParts.length > 0 && thisParts[0] == "") + thisParts.shift(); + + if (thisParts.length > 0 && thisParts[thisParts.length - 1] == "") + { + isDir = true; + thisParts.pop(); + } + + if (thatParts.length > 0 && thatParts[0] == "") + thatParts.shift(); + if (thatParts.length > 0 && thatParts[thatParts.length - 1] == "") + thatParts.pop(); + + + // Now that we have the paths split into an array of directories, + // we can compare the two paths. We start from the left of side + // of the path and start comparing. When we either run out of + // directories (one path is longer than the other), or we find + // a directory that is different, we stop. The remaining parts + // of each path is then used to determine the relative path. For + // example, lets say we have: + // path we want to make relative: /a/b/c/d/e.txt + // path to use as base for relative: /a/b/f/ + // + // This loop will start at the left, and remove directories + // until we get a mismatch or run off the end of one of them. + // In this example, the result will be: + // c/d/e.txt + // f + // + // For every part left over in the base path, we prepend a ".." + // to the relative to get the final path: + // ../c/d/e.txt + while(thatParts.length > 0) + { + if (thisParts.length == 0) + { + // we matched all there is to match, we are done. + // This is the case where "this" object is a parent + // path of the given URI. eg: + // this.path = /a/b/ (thisParts) + // base.path = /a/b/c/d/e/ (thatParts) + break; + } + + thisPart = thisParts[0]; + thatPart = thatParts[0]; + + if (compareStr(thisPart, thatPart, caseSensitive)) + { + thisParts.shift(); + thatParts.shift(); + } + else + break; + } + + // If there are any path info left from the base URI, that means + // **this** object is above the given URI in the file tree. For + // each part left over in the given URI, we need to move up one + // directory to get where we are. + var dotdot:String = ".."; + for (i = 0; i < thatParts.length; i++) + { + finalParts.push(dotdot); + } + + // Append the parts of this URI to any dot-dot's we have + finalParts = finalParts.concat(thisParts); + + // Join the parts back into a path + finalPath = joinPath(finalParts, false /* not absolute */, isDir); + + if (finalPath.length == 0) + { + // The two URI's are exactly the same. The proper relative + // path is: + finalPath = "./"; + } + + // Set the parts of the URI, preserving the original query and + // fragment parts. + setParts("", "", "", finalPath, queryStr, fragmentStr); + + return true; + } + + /** + * Given a string, convert it to a URI. The string could be a + * full URI that is improperly escaped, a malformed URI (e.g. + * missing a protocol like "www.something.com"), a relative URI, + * or any variation there of. + * + *The intention of this function is to take anything that a + * user might manually enter as a URI/URL and try to determine what + * they mean. This function differs from the URI constructor in + * that it makes some assumptions to make it easy to import user + * entered URI data.
+ * + *This function is intended to be a helper function. + * It is not all-knowning and will probably make mistakes + * when attempting to parse a string of unknown origin. If + * your applicaiton is receiving input from the user, your + * application should already have a good idea what the user + * should be entering, and your application should be + * pre-processing the user's input to make sure it is well formed + * before passing it to this function.
+ * + *It is assumed that the string given to this function is + * something the user may have manually entered. Given this, + * the URI string is probably unescaped or improperly escaped. + * This function will attempt to properly escape the URI by + * using forceEscape(). The result is that a toString() call + * on a URI that was created from unknownToURI() may not match + * the input string due to the difference in escaping.
+ * + * @param unknown a potental URI string that should be parsed + * and loaded into this object. + * @param defaultScheme if it is determined that the passed string + * looks like a URI, but it is missing the scheme part, this + * string will be used as the missing scheme. + * + * @return true if the given string was successfully parsed into + * a valid URI object, false otherwise. + */ + public function unknownToURI(unknown:String, defaultScheme:String = "http") : Boolean + { + var temp:String; + + if (unknown.length == 0) + { + this.initialize(); + return false; + } + + // Some users love the backslash key. Fix it. + unknown = unknown.replace(/\\/g, "/"); + + // Check for any obviously missing scheme. + if (unknown.length >= 2) + { + temp = unknown.substr(0, 2); + if (temp == "//") + unknown = defaultScheme + ":" + unknown; + } + + if (unknown.length >= 3) + { + temp = unknown.substr(0, 3); + if (temp == "://") + unknown = defaultScheme + unknown; + } + + // Try parsing it as a normal URI + var uri:URI = new URI(unknown); + + if (uri.isHierarchical() == false) + { + if (uri.scheme == UNKNOWN_SCHEME) + { + this.initialize(); + return false; + } + + // It's a non-hierarchical URI + copyURI(uri); + forceEscape(); + return true; + } + else if ((uri.scheme != UNKNOWN_SCHEME) && + (uri.scheme.length > 0)) + { + if ( (uri.authority.length > 0) || + (uri.scheme == "file") ) + { + // file://... URI + copyURI(uri); + forceEscape(); // ensure proper escaping + return true; + } + else if (uri.authority.length == 0 && uri.path.length == 0) + { + // It's is an incomplete URI (eg "http://") + + setParts(uri.scheme, "", "", "", "", ""); + return false; + } + } + else + { + // Possible relative URI. We can only detect relative URI's + // that start with "." or "..". If it starts with something + // else, the parsing is ambiguous. + var path:String = uri.path; + + if (path == ".." || path == "." || + (path.length >= 3 && path.substr(0, 3) == "../") || + (path.length >= 2 && path.substr(0, 2) == "./") ) + { + // This is a relative URI. + copyURI(uri); + forceEscape(); + return true; + } + } + + // Ok, it looks like we are just a normal URI missing the scheme. Tack + // on the scheme. + uri = new URI(defaultScheme + "://" + unknown); + + // Check to see if we are good now + if (uri.scheme.length > 0 && uri.authority.length > 0) + { + // It was just missing the scheme. + copyURI(uri); + forceEscape(); // Make sure we are properly encoded. + return true; + } + + // don't know what this is + this.initialize(); + return false; + } + + } // end URI class } // end package \ No newline at end of file diff --git a/webcam/com/adobe/net/URIEncodingBitmap.as b/webcam/com/adobe/net/URIEncodingBitmap.as index e85ac55..9c0239c 100644 --- a/webcam/com/adobe/net/URIEncodingBitmap.as +++ b/webcam/com/adobe/net/URIEncodingBitmap.as @@ -1,142 +1,142 @@ -/* - Adobe Systems Incorporated(r) Source Code License Agreement - Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. - - Please read this Source Code License Agreement carefully before using - the source code. - - Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, - no-charge, royalty-free, irrevocable copyright license, to reproduce, - prepare derivative works of, publicly display, publicly perform, and - distribute this source code and such derivative works in source or - object code form without any attribution requirements. - - The name "Adobe Systems Incorporated" must not be used to endorse or promote products - derived from the source code without prior written permission. - - You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and - against any loss, damage, claims or lawsuits, including attorney's - fees that arise or result from your use or distribution of the source - code. - - THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT - ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF - NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA - OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.adobe.net -{ - import flash.utils.ByteArray; - - /** - * This class implements an efficient lookup table for URI - * character escaping. This class is only needed if you - * create a derived class of URI to handle custom URI - * syntax. This class is used internally by URI. - * - * @langversion ActionScript 3.0 - * @playerversion Flash 9.0* - */ - public class URIEncodingBitmap extends ByteArray - { - /** - * Constructor. Creates an encoding bitmap using the given - * string of characters as the set of characters that need - * to be URI escaped. - * - * @langversion ActionScript 3.0 - * @playerversion Flash 9.0 - */ - public function URIEncodingBitmap(charsToEscape:String) : void - { - var i:int; - var data:ByteArray = new ByteArray(); - - // Initialize our 128 bits (16 bytes) to zero - for (i = 0; i < 16; i++) - this.writeByte(0); - - data.writeUTFBytes(charsToEscape); - data.position = 0; - - while (data.bytesAvailable) - { - var c:int = data.readByte(); - - if (c > 0x7f) - continue; // only escape low bytes - - var enc:int; - this.position = (c >> 3); - enc = this.readByte(); - enc |= 1 << (c & 0x7); - this.position = (c >> 3); - this.writeByte(enc); - } - } - - /** - * Based on the data table contained in this object, check - * if the given character should be escaped. - * - * @param char the character to be escaped. Only the first - * character in the string is used. Any other characters - * are ignored. - * - * @return the integer value of the raw UTF8 character. For - * example, if '%' is given, the return value is 37 (0x25). - * If the character given does not need to be escaped, the - * return value is zero. - * - * @langversion ActionScript 3.0 - * @playerversion Flash 9.0 - */ - public function ShouldEscape(char:String) : int - { - var data:ByteArray = new ByteArray(); - var c:int, mask:int; - - // write the character into a ByteArray so - // we can pull it out as a raw byte value. - data.writeUTFBytes(char); - data.position = 0; - c = data.readByte(); - - if (c & 0x80) - { - // don't escape high byte characters. It can make international - // URI's unreadable. We just want to escape characters that would - // make URI syntax ambiguous. - return 0; - } - else if ((c < 0x1f) || (c == 0x7f)) - { - // control characters must be escaped. - return c; - } - - this.position = (c >> 3); - mask = this.readByte(); - - if (mask & (1 << (c & 0x7))) - { - // we need to escape this, return the numeric value - // of the character - return c; - } - else - { - return 0; - } - } - } +/* + Adobe Systems Incorporated(r) Source Code License Agreement + Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. + + Please read this Source Code License Agreement carefully before using + the source code. + + Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, + no-charge, royalty-free, irrevocable copyright license, to reproduce, + prepare derivative works of, publicly display, publicly perform, and + distribute this source code and such derivative works in source or + object code form without any attribution requirements. + + The name "Adobe Systems Incorporated" must not be used to endorse or promote products + derived from the source code without prior written permission. + + You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and + against any loss, damage, claims or lawsuits, including attorney's + fees that arise or result from your use or distribution of the source + code. + + THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT + ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF + NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA + OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.adobe.net +{ + import flash.utils.ByteArray; + + /** + * This class implements an efficient lookup table for URI + * character escaping. This class is only needed if you + * create a derived class of URI to handle custom URI + * syntax. This class is used internally by URI. + * + * @langversion ActionScript 3.0 + * @playerversion Flash 9.0* + */ + public class URIEncodingBitmap extends ByteArray + { + /** + * Constructor. Creates an encoding bitmap using the given + * string of characters as the set of characters that need + * to be URI escaped. + * + * @langversion ActionScript 3.0 + * @playerversion Flash 9.0 + */ + public function URIEncodingBitmap(charsToEscape:String) : void + { + var i:int; + var data:ByteArray = new ByteArray(); + + // Initialize our 128 bits (16 bytes) to zero + for (i = 0; i < 16; i++) + this.writeByte(0); + + data.writeUTFBytes(charsToEscape); + data.position = 0; + + while (data.bytesAvailable) + { + var c:int = data.readByte(); + + if (c > 0x7f) + continue; // only escape low bytes + + var enc:int; + this.position = (c >> 3); + enc = this.readByte(); + enc |= 1 << (c & 0x7); + this.position = (c >> 3); + this.writeByte(enc); + } + } + + /** + * Based on the data table contained in this object, check + * if the given character should be escaped. + * + * @param char the character to be escaped. Only the first + * character in the string is used. Any other characters + * are ignored. + * + * @return the integer value of the raw UTF8 character. For + * example, if '%' is given, the return value is 37 (0x25). + * If the character given does not need to be escaped, the + * return value is zero. + * + * @langversion ActionScript 3.0 + * @playerversion Flash 9.0 + */ + public function ShouldEscape(char:String) : int + { + var data:ByteArray = new ByteArray(); + var c:int, mask:int; + + // write the character into a ByteArray so + // we can pull it out as a raw byte value. + data.writeUTFBytes(char); + data.position = 0; + c = data.readByte(); + + if (c & 0x80) + { + // don't escape high byte characters. It can make international + // URI's unreadable. We just want to escape characters that would + // make URI syntax ambiguous. + return 0; + } + else if ((c < 0x1f) || (c == 0x7f)) + { + // control characters must be escaped. + return c; + } + + this.position = (c >> 3); + mask = this.readByte(); + + if (mask & (1 << (c & 0x7))) + { + // we need to escape this, return the numeric value + // of the character + return c; + } + else + { + return 0; + } + } + } } \ No newline at end of file diff --git a/webcam/com/adobe/net/proxies/RFC2817Socket.as b/webcam/com/adobe/net/proxies/RFC2817Socket.as index 3657da4..c52ee39 100644 --- a/webcam/com/adobe/net/proxies/RFC2817Socket.as +++ b/webcam/com/adobe/net/proxies/RFC2817Socket.as @@ -1,204 +1,204 @@ -/* - Adobe Systems Incorporated(r) Source Code License Agreement - Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. - - Please read this Source Code License Agreement carefully before using - the source code. - - Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, - no-charge, royalty-free, irrevocable copyright license, to reproduce, - prepare derivative works of, publicly display, publicly perform, and - distribute this source code and such derivative works in source or - object code form without any attribution requirements. - - The name "Adobe Systems Incorporated" must not be used to endorse or promote products - derived from the source code without prior written permission. - - You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and - against any loss, damage, claims or lawsuits, including attorney's - fees that arise or result from your use or distribution of the source - code. - - THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT - ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF - NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA - OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -package com.adobe.net.proxies -{ - import flash.events.Event; - import flash.events.IOErrorEvent; - import flash.events.ProgressEvent; - import flash.net.Socket; - - /** - * This class allows TCP socket connections through HTTP proxies in accordance with - * RFC 2817: - * - * ftp://ftp.rfc-editor.org/in-notes/rfc2817.txt - * - * It can also be used to make direct connections to a destination, as well. If you - * pass the host and port into the constructor, no proxy will be used. You can also - * call connect, passing in the host and the port, and if you didn't set the proxy - * info, a direct connection will be made. A proxy is only used after you have called - * the setProxyInfo function. - * - * The connection to and negotiation with the proxy is completely hidden. All the - * same events are thrown whether you are using a proxy or not, and the data you - * receive from the target server will look exact as it would if you were connected - * to it directly rather than through a proxy. - * - * @author Christian Cantrell - * - **/ - public class RFC2817Socket - extends Socket - { - private var proxyHost:String = null; - private var host:String = null; - private var proxyPort:int = 0; - private var port:int = 0; - private var deferredEventHandlers:Object = new Object(); - private var buffer:String = new String(); - - /** - * Construct a new RFC2817Socket object. If you pass in the host and the port, - * no proxy will be used. If you want to use a proxy, instantiate with no - * arguments, call setProxyInfo, then call connect. - **/ - public function RFC2817Socket(host:String = null, port:int = 0) - { - if (host != null && port != 0) - { - super(host, port); - } - } - - /** - * Set the proxy host and port number. Your connection will only proxied if - * this function has been called. - **/ - public function setProxyInfo(host:String, port:int):void - { - this.proxyHost = host; - this.proxyPort = port; - - var deferredSocketDataHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA]; - var deferredConnectHandler:Object = this.deferredEventHandlers[Event.CONNECT]; - - if (deferredSocketDataHandler != null) - { - super.removeEventListener(ProgressEvent.SOCKET_DATA, deferredSocketDataHandler.listener, deferredSocketDataHandler.useCapture); - } - - if (deferredConnectHandler != null) - { - super.removeEventListener(Event.CONNECT, deferredConnectHandler.listener, deferredConnectHandler.useCapture); - } - } - - /** - * Connect to the specified host over the specified port. If you want your - * connection proxied, call the setProxyInfo function first. - **/ - public override function connect(host:String, port:int):void - { - if (this.proxyHost == null) - { - this.redirectConnectEvent(); - this.redirectSocketDataEvent(); - super.connect(host, port); - } - else - { - this.host = host; - this.port = port; - super.addEventListener(Event.CONNECT, this.onConnect); - super.addEventListener(ProgressEvent.SOCKET_DATA, this.onSocketData); - super.connect(this.proxyHost, this.proxyPort); - } - } - - private function onConnect(event:Event):void - { - this.writeUTFBytes("CONNECT "+this.host+":"+this.port+" HTTP/1.1\n\n"); - this.flush(); - this.redirectConnectEvent(); - } - - private function onSocketData(event:ProgressEvent):void - { - while (this.bytesAvailable != 0) - { - this.buffer += this.readUTFBytes(1); - if (this.buffer.search(/\r?\n\r?\n$/) != -1) - { - this.checkResponse(event); - break; - } - } - } - - private function checkResponse(event:ProgressEvent):void - { - var responseCode:String = this.buffer.substr(this.buffer.indexOf(" ")+1, 3); - - if (responseCode.search(/^2/) == -1) - { - var ioError:IOErrorEvent = new IOErrorEvent(IOErrorEvent.IO_ERROR); - ioError.text = "Error connecting to the proxy ["+this.proxyHost+"] on port ["+this.proxyPort+"]: " + this.buffer; - this.dispatchEvent(ioError); - } - else - { - this.redirectSocketDataEvent(); - this.dispatchEvent(new Event(Event.CONNECT)); - if (this.bytesAvailable > 0) - { - this.dispatchEvent(event); - } - } - this.buffer = null; - } - - private function redirectConnectEvent():void - { - super.removeEventListener(Event.CONNECT, onConnect); - var deferredEventHandler:Object = this.deferredEventHandlers[Event.CONNECT]; - if (deferredEventHandler != null) - { - super.addEventListener(Event.CONNECT, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference); - } - } - - private function redirectSocketDataEvent():void - { - super.removeEventListener(ProgressEvent.SOCKET_DATA, onSocketData); - var deferredEventHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA]; - if (deferredEventHandler != null) - { - super.addEventListener(ProgressEvent.SOCKET_DATA, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference); - } - } - - public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int=0.0, useWeakReference:Boolean=false):void - { - if (type == Event.CONNECT || type == ProgressEvent.SOCKET_DATA) - { - this.deferredEventHandlers[type] = {listener:listener,useCapture:useCapture, priority:priority, useWeakReference:useWeakReference}; - } - else - { - super.addEventListener(type, listener, useCapture, priority, useWeakReference); - } - } - } +/* + Adobe Systems Incorporated(r) Source Code License Agreement + Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. + + Please read this Source Code License Agreement carefully before using + the source code. + + Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, + no-charge, royalty-free, irrevocable copyright license, to reproduce, + prepare derivative works of, publicly display, publicly perform, and + distribute this source code and such derivative works in source or + object code form without any attribution requirements. + + The name "Adobe Systems Incorporated" must not be used to endorse or promote products + derived from the source code without prior written permission. + + You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and + against any loss, damage, claims or lawsuits, including attorney's + fees that arise or result from your use or distribution of the source + code. + + THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT + ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF + NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA + OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +package com.adobe.net.proxies +{ + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.events.ProgressEvent; + import flash.net.Socket; + + /** + * This class allows TCP socket connections through HTTP proxies in accordance with + * RFC 2817: + * + * ftp://ftp.rfc-editor.org/in-notes/rfc2817.txt + * + * It can also be used to make direct connections to a destination, as well. If you + * pass the host and port into the constructor, no proxy will be used. You can also + * call connect, passing in the host and the port, and if you didn't set the proxy + * info, a direct connection will be made. A proxy is only used after you have called + * the setProxyInfo function. + * + * The connection to and negotiation with the proxy is completely hidden. All the + * same events are thrown whether you are using a proxy or not, and the data you + * receive from the target server will look exact as it would if you were connected + * to it directly rather than through a proxy. + * + * @author Christian Cantrell + * + **/ + public class RFC2817Socket + extends Socket + { + private var proxyHost:String = null; + private var host:String = null; + private var proxyPort:int = 0; + private var port:int = 0; + private var deferredEventHandlers:Object = new Object(); + private var buffer:String = new String(); + + /** + * Construct a new RFC2817Socket object. If you pass in the host and the port, + * no proxy will be used. If you want to use a proxy, instantiate with no + * arguments, call setProxyInfo, then call connect. + **/ + public function RFC2817Socket(host:String = null, port:int = 0) + { + if (host != null && port != 0) + { + super(host, port); + } + } + + /** + * Set the proxy host and port number. Your connection will only proxied if + * this function has been called. + **/ + public function setProxyInfo(host:String, port:int):void + { + this.proxyHost = host; + this.proxyPort = port; + + var deferredSocketDataHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA]; + var deferredConnectHandler:Object = this.deferredEventHandlers[Event.CONNECT]; + + if (deferredSocketDataHandler != null) + { + super.removeEventListener(ProgressEvent.SOCKET_DATA, deferredSocketDataHandler.listener, deferredSocketDataHandler.useCapture); + } + + if (deferredConnectHandler != null) + { + super.removeEventListener(Event.CONNECT, deferredConnectHandler.listener, deferredConnectHandler.useCapture); + } + } + + /** + * Connect to the specified host over the specified port. If you want your + * connection proxied, call the setProxyInfo function first. + **/ + public override function connect(host:String, port:int):void + { + if (this.proxyHost == null) + { + this.redirectConnectEvent(); + this.redirectSocketDataEvent(); + super.connect(host, port); + } + else + { + this.host = host; + this.port = port; + super.addEventListener(Event.CONNECT, this.onConnect); + super.addEventListener(ProgressEvent.SOCKET_DATA, this.onSocketData); + super.connect(this.proxyHost, this.proxyPort); + } + } + + private function onConnect(event:Event):void + { + this.writeUTFBytes("CONNECT "+this.host+":"+this.port+" HTTP/1.1\n\n"); + this.flush(); + this.redirectConnectEvent(); + } + + private function onSocketData(event:ProgressEvent):void + { + while (this.bytesAvailable != 0) + { + this.buffer += this.readUTFBytes(1); + if (this.buffer.search(/\r?\n\r?\n$/) != -1) + { + this.checkResponse(event); + break; + } + } + } + + private function checkResponse(event:ProgressEvent):void + { + var responseCode:String = this.buffer.substr(this.buffer.indexOf(" ")+1, 3); + + if (responseCode.search(/^2/) == -1) + { + var ioError:IOErrorEvent = new IOErrorEvent(IOErrorEvent.IO_ERROR); + ioError.text = "Error connecting to the proxy ["+this.proxyHost+"] on port ["+this.proxyPort+"]: " + this.buffer; + this.dispatchEvent(ioError); + } + else + { + this.redirectSocketDataEvent(); + this.dispatchEvent(new Event(Event.CONNECT)); + if (this.bytesAvailable > 0) + { + this.dispatchEvent(event); + } + } + this.buffer = null; + } + + private function redirectConnectEvent():void + { + super.removeEventListener(Event.CONNECT, onConnect); + var deferredEventHandler:Object = this.deferredEventHandlers[Event.CONNECT]; + if (deferredEventHandler != null) + { + super.addEventListener(Event.CONNECT, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference); + } + } + + private function redirectSocketDataEvent():void + { + super.removeEventListener(ProgressEvent.SOCKET_DATA, onSocketData); + var deferredEventHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA]; + if (deferredEventHandler != null) + { + super.addEventListener(ProgressEvent.SOCKET_DATA, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference); + } + } + + public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int=0.0, useWeakReference:Boolean=false):void + { + if (type == Event.CONNECT || type == ProgressEvent.SOCKET_DATA) + { + this.deferredEventHandlers[type] = {listener:listener,useCapture:useCapture, priority:priority, useWeakReference:useWeakReference}; + } + else + { + super.addEventListener(type, listener, useCapture, priority, useWeakReference); + } + } + } } \ No newline at end of file diff --git a/webcam/com/adobe/serialization/json/JSON.as b/webcam/com/adobe/serialization/json/JSON.as index d43c420..1d2477e 100644 --- a/webcam/com/adobe/serialization/json/JSON.as +++ b/webcam/com/adobe/serialization/json/JSON.as @@ -1,88 +1,88 @@ -/* -Adobe Systems Incorporated(r) Source Code License Agreement -Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. - -Please read this Source Code License Agreement carefully before using -the source code. - -Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable copyright license, to reproduce, -prepare derivative works of, publicly display, publicly perform, and -distribute this source code and such derivative works in source or -object code form without any attribution requirements. - -The name "Adobe Systems Incorporated" must not be used to endorse or promote products -derived from the source code without prior written permission. - -You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and -against any loss, damage, claims or lawsuits, including attorney's -fees that arise or result from your use or distribution of the source -code. - -THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT -ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF -NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA -OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.adobe.serialization.json { - - /** - * This class provides encoding and decoding of the JSON format. - * - * Example usage: - *
- * // create a JSON string from an internal object
- * JSON.encode( myObject );
- *
- * // read a JSON string into an internal object
- * var myObject:Object = JSON.decode( jsonString );
- *
- */
- public class JSON {
-
-
- /**
- * Encodes a object into a JSON string.
- *
- * @param o The object to create a JSON string for
- * @return the JSON string representing o
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function encode( o:Object ):String {
-
- var encoder:JSONEncoder = new JSONEncoder( o );
- return encoder.getString();
-
- }
-
- /**
- * Decodes a JSON string into a native object.
- *
- * @param s The JSON string representing the object
- * @return A native object as specified by s
- * @throw JSONParseError
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function decode( s:String ):* {
-
- var decoder:JSONDecoder = new JSONDecoder( s )
- return decoder.getValue();
-
- }
-
- }
-
+/*
+Adobe Systems Incorporated(r) Source Code License Agreement
+Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+Please read this Source Code License Agreement carefully before using
+the source code.
+
+Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable copyright license, to reproduce,
+prepare derivative works of, publicly display, publicly perform, and
+distribute this source code and such derivative works in source or
+object code form without any attribution requirements.
+
+The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+derived from the source code without prior written permission.
+
+You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+against any loss, damage, claims or lawsuits, including attorney's
+fees that arise or result from your use or distribution of the source
+code.
+
+THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.serialization.json {
+
+ /**
+ * This class provides encoding and decoding of the JSON format.
+ *
+ * Example usage:
+ *
+ * // create a JSON string from an internal object
+ * JSON.encode( myObject );
+ *
+ * // read a JSON string into an internal object
+ * var myObject:Object = JSON.decode( jsonString );
+ *
+ */
+ public class JSON {
+
+
+ /**
+ * Encodes a object into a JSON string.
+ *
+ * @param o The object to create a JSON string for
+ * @return the JSON string representing o
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function encode( o:Object ):String {
+
+ var encoder:JSONEncoder = new JSONEncoder( o );
+ return encoder.getString();
+
+ }
+
+ /**
+ * Decodes a JSON string into a native object.
+ *
+ * @param s The JSON string representing the object
+ * @return A native object as specified by s
+ * @throw JSONParseError
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function decode( s:String ):* {
+
+ var decoder:JSONDecoder = new JSONDecoder( s )
+ return decoder.getValue();
+
+ }
+
+ }
+
}
\ No newline at end of file
diff --git a/webcam/com/adobe/serialization/json/JSONDecoder.as b/webcam/com/adobe/serialization/json/JSONDecoder.as
index be06317..833438d 100644
--- a/webcam/com/adobe/serialization/json/JSONDecoder.as
+++ b/webcam/com/adobe/serialization/json/JSONDecoder.as
@@ -1,218 +1,218 @@
-/*
-Adobe Systems Incorporated(r) Source Code License Agreement
-Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
-Please read this Source Code License Agreement carefully before using
-the source code.
-
-Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable copyright license, to reproduce,
-prepare derivative works of, publicly display, publicly perform, and
-distribute this source code and such derivative works in source or
-object code form without any attribution requirements.
-
-The name "Adobe Systems Incorporated" must not be used to endorse or promote products
-derived from the source code without prior written permission.
-
-You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
-against any loss, damage, claims or lawsuits, including attorney's
-fees that arise or result from your use or distribution of the source
-code.
-
-THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
-ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
-NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
-OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.serialization.json {
-
- public class JSONDecoder {
-
- /** The value that will get parsed from the JSON string */
- private var value:*;
-
- /** The tokenizer designated to read the JSON string */
- private var tokenizer:JSONTokenizer;
-
- /** The current token from the tokenizer */
- private var token:JSONToken;
-
- /**
- * Constructs a new JSONDecoder to parse a JSON string
- * into a native object.
- *
- * @param s The JSON string to be converted
- * into a native object
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function JSONDecoder( s:String ) {
-
- tokenizer = new JSONTokenizer( s );
-
- nextToken();
- value = parseValue();
- }
-
- /**
- * Gets the internal object that was created by parsing
- * the JSON string passed to the constructor.
- *
- * @return The internal object representation of the JSON
- * string that was passed to the constructor
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function getValue():* {
- return value;
- }
-
- /**
- * Returns the next token from the tokenzier reading
- * the JSON string
- */
- private function nextToken():JSONToken {
- return token = tokenizer.getNextToken();
- }
-
- /**
- * Attempt to parse an array
- */
- private function parseArray():Array {
- // create an array internally that we're going to attempt
- // to parse from the tokenizer
- var a:Array = new Array();
-
- // grab the next token from the tokenizer to move
- // past the opening [
- nextToken();
-
- // check to see if we have an empty array
- if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
- // we're done reading the array, so return it
- return a;
- }
-
- // deal with elements of the array, and use an "infinite"
- // loop because we could have any amount of elements
- while ( true ) {
- // read in the value and add it to the array
- a.push ( parseValue() );
-
- // after the value there should be a ] or a ,
- nextToken();
-
- if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
- // we're done reading the array, so return it
- return a;
- } else if ( token.type == JSONTokenType.COMMA ) {
- // move past the comma and read another value
- nextToken();
- } else {
- tokenizer.parseError( "Expecting ] or , but found " + token.value );
- }
- }
- return null;
- }
-
- /**
- * Attempt to parse an object
- */
- private function parseObject():Object {
- // create the object internally that we're going to
- // attempt to parse from the tokenizer
- var o:Object = new Object();
-
- // store the string part of an object member so
- // that we can assign it a value in the object
- var key:String
-
- // grab the next token from the tokenizer
- nextToken();
-
- // check to see if we have an empty object
- if ( token.type == JSONTokenType.RIGHT_BRACE ) {
- // we're done reading the object, so return it
- return o;
- }
-
- // deal with members of the object, and use an "infinite"
- // loop because we could have any amount of members
- while ( true ) {
-
- if ( token.type == JSONTokenType.STRING ) {
- // the string value we read is the key for the object
- key = String( token.value );
-
- // move past the string to see what's next
- nextToken();
-
- // after the string there should be a :
- if ( token.type == JSONTokenType.COLON ) {
-
- // move past the : and read/assign a value for the key
- nextToken();
- o[key] = parseValue();
-
- // move past the value to see what's next
- nextToken();
-
- // after the value there's either a } or a ,
- if ( token.type == JSONTokenType.RIGHT_BRACE ) {
- // // we're done reading the object, so return it
- return o;
-
- } else if ( token.type == JSONTokenType.COMMA ) {
- // skip past the comma and read another member
- nextToken();
- } else {
- tokenizer.parseError( "Expecting } or , but found " + token.value );
- }
- } else {
- tokenizer.parseError( "Expecting : but found " + token.value );
- }
- } else {
- tokenizer.parseError( "Expecting string but found " + token.value );
- }
- }
- return null;
- }
-
- /**
- * Attempt to parse a value
- */
- private function parseValue():Object {
-
- switch ( token.type ) {
- case JSONTokenType.LEFT_BRACE:
- return parseObject();
-
- case JSONTokenType.LEFT_BRACKET:
- return parseArray();
-
- case JSONTokenType.STRING:
- case JSONTokenType.NUMBER:
- case JSONTokenType.TRUE:
- case JSONTokenType.FALSE:
- case JSONTokenType.NULL:
- return token.value;
-
- default:
- tokenizer.parseError( "Unexpected " + token.value );
-
- }
- return null;
- }
- }
-}
+/*
+Adobe Systems Incorporated(r) Source Code License Agreement
+Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+Please read this Source Code License Agreement carefully before using
+the source code.
+
+Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable copyright license, to reproduce,
+prepare derivative works of, publicly display, publicly perform, and
+distribute this source code and such derivative works in source or
+object code form without any attribution requirements.
+
+The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+derived from the source code without prior written permission.
+
+You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+against any loss, damage, claims or lawsuits, including attorney's
+fees that arise or result from your use or distribution of the source
+code.
+
+THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.serialization.json {
+
+ public class JSONDecoder {
+
+ /** The value that will get parsed from the JSON string */
+ private var value:*;
+
+ /** The tokenizer designated to read the JSON string */
+ private var tokenizer:JSONTokenizer;
+
+ /** The current token from the tokenizer */
+ private var token:JSONToken;
+
+ /**
+ * Constructs a new JSONDecoder to parse a JSON string
+ * into a native object.
+ *
+ * @param s The JSON string to be converted
+ * into a native object
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function JSONDecoder( s:String ) {
+
+ tokenizer = new JSONTokenizer( s );
+
+ nextToken();
+ value = parseValue();
+ }
+
+ /**
+ * Gets the internal object that was created by parsing
+ * the JSON string passed to the constructor.
+ *
+ * @return The internal object representation of the JSON
+ * string that was passed to the constructor
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function getValue():* {
+ return value;
+ }
+
+ /**
+ * Returns the next token from the tokenzier reading
+ * the JSON string
+ */
+ private function nextToken():JSONToken {
+ return token = tokenizer.getNextToken();
+ }
+
+ /**
+ * Attempt to parse an array
+ */
+ private function parseArray():Array {
+ // create an array internally that we're going to attempt
+ // to parse from the tokenizer
+ var a:Array = new Array();
+
+ // grab the next token from the tokenizer to move
+ // past the opening [
+ nextToken();
+
+ // check to see if we have an empty array
+ if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
+ // we're done reading the array, so return it
+ return a;
+ }
+
+ // deal with elements of the array, and use an "infinite"
+ // loop because we could have any amount of elements
+ while ( true ) {
+ // read in the value and add it to the array
+ a.push ( parseValue() );
+
+ // after the value there should be a ] or a ,
+ nextToken();
+
+ if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
+ // we're done reading the array, so return it
+ return a;
+ } else if ( token.type == JSONTokenType.COMMA ) {
+ // move past the comma and read another value
+ nextToken();
+ } else {
+ tokenizer.parseError( "Expecting ] or , but found " + token.value );
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Attempt to parse an object
+ */
+ private function parseObject():Object {
+ // create the object internally that we're going to
+ // attempt to parse from the tokenizer
+ var o:Object = new Object();
+
+ // store the string part of an object member so
+ // that we can assign it a value in the object
+ var key:String
+
+ // grab the next token from the tokenizer
+ nextToken();
+
+ // check to see if we have an empty object
+ if ( token.type == JSONTokenType.RIGHT_BRACE ) {
+ // we're done reading the object, so return it
+ return o;
+ }
+
+ // deal with members of the object, and use an "infinite"
+ // loop because we could have any amount of members
+ while ( true ) {
+
+ if ( token.type == JSONTokenType.STRING ) {
+ // the string value we read is the key for the object
+ key = String( token.value );
+
+ // move past the string to see what's next
+ nextToken();
+
+ // after the string there should be a :
+ if ( token.type == JSONTokenType.COLON ) {
+
+ // move past the : and read/assign a value for the key
+ nextToken();
+ o[key] = parseValue();
+
+ // move past the value to see what's next
+ nextToken();
+
+ // after the value there's either a } or a ,
+ if ( token.type == JSONTokenType.RIGHT_BRACE ) {
+ // // we're done reading the object, so return it
+ return o;
+
+ } else if ( token.type == JSONTokenType.COMMA ) {
+ // skip past the comma and read another member
+ nextToken();
+ } else {
+ tokenizer.parseError( "Expecting } or , but found " + token.value );
+ }
+ } else {
+ tokenizer.parseError( "Expecting : but found " + token.value );
+ }
+ } else {
+ tokenizer.parseError( "Expecting string but found " + token.value );
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Attempt to parse a value
+ */
+ private function parseValue():Object {
+
+ switch ( token.type ) {
+ case JSONTokenType.LEFT_BRACE:
+ return parseObject();
+
+ case JSONTokenType.LEFT_BRACKET:
+ return parseArray();
+
+ case JSONTokenType.STRING:
+ case JSONTokenType.NUMBER:
+ case JSONTokenType.TRUE:
+ case JSONTokenType.FALSE:
+ case JSONTokenType.NULL:
+ return token.value;
+
+ default:
+ tokenizer.parseError( "Unexpected " + token.value );
+
+ }
+ return null;
+ }
+ }
+}
diff --git a/webcam/com/adobe/serialization/json/JSONEncoder.as b/webcam/com/adobe/serialization/json/JSONEncoder.as
index f8b195c..f371a17 100644
--- a/webcam/com/adobe/serialization/json/JSONEncoder.as
+++ b/webcam/com/adobe/serialization/json/JSONEncoder.as
@@ -1,302 +1,302 @@
-/*
-Adobe Systems Incorporated(r) Source Code License Agreement
-Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
-Please read this Source Code License Agreement carefully before using
-the source code.
-
-Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable copyright license, to reproduce,
-prepare derivative works of, publicly display, publicly perform, and
-distribute this source code and such derivative works in source or
-object code form without any attribution requirements.
-
-The name "Adobe Systems Incorporated" must not be used to endorse or promote products
-derived from the source code without prior written permission.
-
-You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
-against any loss, damage, claims or lawsuits, including attorney's
-fees that arise or result from your use or distribution of the source
-code.
-
-THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
-ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
-NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
-OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.serialization.json
-{
-
- import flash.utils.describeType;
-
- public class JSONEncoder {
-
- /** The string that is going to represent the object we're encoding */
- private var jsonString:String;
-
- /**
- * Creates a new JSONEncoder.
- *
- * @param o The object to encode as a JSON string
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function JSONEncoder( value:* ) {
- jsonString = convertToString( value );
-
- }
-
- /**
- * Gets the JSON string from the encoder.
- *
- * @return The JSON string representation of the object
- * that was passed to the constructor
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function getString():String {
- return jsonString;
- }
-
- /**
- * Converts a value to it's JSON string equivalent.
- *
- * @param value The value to convert. Could be any
- * type (object, number, array, etc)
- */
- private function convertToString( value:* ):String {
-
- // determine what value is and convert it based on it's type
- if ( value is String ) {
-
- // escape the string so it's formatted correctly
- return escapeString( value as String );
-
- } else if ( value is Number ) {
-
- // only encode numbers that finate
- return isFinite( value as Number) ? value.toString() : "null";
-
- } else if ( value is Boolean ) {
-
- // convert boolean to string easily
- return value ? "true" : "false";
-
- } else if ( value is Array ) {
-
- // call the helper method to convert an array
- return arrayToString( value as Array );
-
- } else if ( value is Object && value != null ) {
-
- // call the helper method to convert an object
- return objectToString( value );
- }
- return "null";
- }
-
- /**
- * Escapes a string accoding to the JSON specification.
- *
- * @param str The string to be escaped
- * @return The string with escaped special characters
- * according to the JSON specification
- */
- private function escapeString( str:String ):String {
- // create a string to store the string's jsonstring value
- var s:String = "";
- // current character in the string we're processing
- var ch:String;
- // store the length in a local variable to reduce lookups
- var len:Number = str.length;
-
- // loop over all of the characters in the string
- for ( var i:int = 0; i < len; i++ ) {
-
- // examine the character to determine if we have to escape it
- ch = str.charAt( i );
- switch ( ch ) {
-
- case '"': // quotation mark
- s += "\\\"";
- break;
-
- //case '/': // solidus
- // s += "\\/";
- // break;
-
- case '\\': // reverse solidus
- s += "\\\\";
- break;
-
- case '\b': // bell
- s += "\\b";
- break;
-
- case '\f': // form feed
- s += "\\f";
- break;
-
- case '\n': // newline
- s += "\\n";
- break;
-
- case '\r': // carriage return
- s += "\\r";
- break;
-
- case '\t': // horizontal tab
- s += "\\t";
- break;
-
- default: // everything else
-
- // check for a control character and escape as unicode
- if ( ch < ' ' ) {
- // get the hex digit(s) of the character (either 1 or 2 digits)
- var hexCode:String = ch.charCodeAt( 0 ).toString( 16 );
-
- // ensure that there are 4 digits by adjusting
- // the # of zeros accordingly.
- var zeroPad:String = hexCode.length == 2 ? "00" : "000";
-
- // create the unicode escape sequence with 4 hex digits
- s += "\\u" + zeroPad + hexCode;
- } else {
-
- // no need to do any special encoding, just pass-through
- s += ch;
-
- }
- } // end switch
-
- } // end for loop
-
- return "\"" + s + "\"";
- }
-
- /**
- * Converts an array to it's JSON string equivalent
- *
- * @param a The array to convert
- * @return The JSON string representation of a
- */
- private function arrayToString( a:Array ):String {
- // create a string to store the array's jsonstring value
- var s:String = "";
-
- // loop over the elements in the array and add their converted
- // values to the string
- for ( var i:int = 0; i < a.length; i++ ) {
- // when the length is 0 we're adding the first element so
- // no comma is necessary
- if ( s.length > 0 ) {
- // we've already added an element, so add the comma separator
- s += ","
- }
-
- // convert the value to a string
- s += convertToString( a[i] );
- }
-
- // KNOWN ISSUE: In ActionScript, Arrays can also be associative
- // objects and you can put anything in them, ie:
- // myArray["foo"] = "bar";
- //
- // These properties aren't picked up in the for loop above because
- // the properties don't correspond to indexes. However, we're
- // sort of out luck because the JSON specification doesn't allow
- // these types of array properties.
- //
- // So, if the array was also used as an associative object, there
- // may be some values in the array that don't get properly encoded.
- //
- // A possible solution is to instead encode the Array as an Object
- // but then it won't get decoded correctly (and won't be an
- // Array instance)
-
- // close the array and return it's string value
- return "[" + s + "]";
- }
-
- /**
- * Converts an object to it's JSON string equivalent
- *
- * @param o The object to convert
- * @return The JSON string representation of o
- */
- private function objectToString( o:Object ):String
- {
- // create a string to store the object's jsonstring value
- var s:String = "";
-
- // determine if o is a class instance or a plain object
- var classInfo:XML = describeType( o );
- if ( classInfo.@name.toString() == "Object" )
- {
- // the value of o[key] in the loop below - store this
- // as a variable so we don't have to keep looking up o[key]
- // when testing for valid values to convert
- var value:Object;
-
- // loop over the keys in the object and add their converted
- // values to the string
- for ( var key:String in o )
- {
- // assign value to a variable for quick lookup
- value = o[key];
-
- // don't add function's to the JSON string
- if ( value is Function )
- {
- // skip this key and try another
- continue;
- }
-
- // when the length is 0 we're adding the first item so
- // no comma is necessary
- if ( s.length > 0 ) {
- // we've already added an item, so add the comma separator
- s += ","
- }
-
- s += escapeString( key ) + ":" + convertToString( value );
- }
- }
- else // o is a class instance
- {
- // Loop over all of the variables and accessors in the class and
- // serialize them along with their values.
- for each ( var v:XML in classInfo..*.( name() == "variable" || name() == "accessor" ) )
- {
- // When the length is 0 we're adding the first item so
- // no comma is necessary
- if ( s.length > 0 ) {
- // We've already added an item, so add the comma separator
- s += ","
- }
-
- s += escapeString( v.@name.toString() ) + ":"
- + convertToString( o[ v.@name ] );
- }
-
- }
-
- return "{" + s + "}";
- }
-
-
- }
-
-}
+/*
+Adobe Systems Incorporated(r) Source Code License Agreement
+Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+Please read this Source Code License Agreement carefully before using
+the source code.
+
+Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable copyright license, to reproduce,
+prepare derivative works of, publicly display, publicly perform, and
+distribute this source code and such derivative works in source or
+object code form without any attribution requirements.
+
+The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+derived from the source code without prior written permission.
+
+You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+against any loss, damage, claims or lawsuits, including attorney's
+fees that arise or result from your use or distribution of the source
+code.
+
+THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.serialization.json
+{
+
+ import flash.utils.describeType;
+
+ public class JSONEncoder {
+
+ /** The string that is going to represent the object we're encoding */
+ private var jsonString:String;
+
+ /**
+ * Creates a new JSONEncoder.
+ *
+ * @param o The object to encode as a JSON string
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function JSONEncoder( value:* ) {
+ jsonString = convertToString( value );
+
+ }
+
+ /**
+ * Gets the JSON string from the encoder.
+ *
+ * @return The JSON string representation of the object
+ * that was passed to the constructor
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function getString():String {
+ return jsonString;
+ }
+
+ /**
+ * Converts a value to it's JSON string equivalent.
+ *
+ * @param value The value to convert. Could be any
+ * type (object, number, array, etc)
+ */
+ private function convertToString( value:* ):String {
+
+ // determine what value is and convert it based on it's type
+ if ( value is String ) {
+
+ // escape the string so it's formatted correctly
+ return escapeString( value as String );
+
+ } else if ( value is Number ) {
+
+ // only encode numbers that finate
+ return isFinite( value as Number) ? value.toString() : "null";
+
+ } else if ( value is Boolean ) {
+
+ // convert boolean to string easily
+ return value ? "true" : "false";
+
+ } else if ( value is Array ) {
+
+ // call the helper method to convert an array
+ return arrayToString( value as Array );
+
+ } else if ( value is Object && value != null ) {
+
+ // call the helper method to convert an object
+ return objectToString( value );
+ }
+ return "null";
+ }
+
+ /**
+ * Escapes a string accoding to the JSON specification.
+ *
+ * @param str The string to be escaped
+ * @return The string with escaped special characters
+ * according to the JSON specification
+ */
+ private function escapeString( str:String ):String {
+ // create a string to store the string's jsonstring value
+ var s:String = "";
+ // current character in the string we're processing
+ var ch:String;
+ // store the length in a local variable to reduce lookups
+ var len:Number = str.length;
+
+ // loop over all of the characters in the string
+ for ( var i:int = 0; i < len; i++ ) {
+
+ // examine the character to determine if we have to escape it
+ ch = str.charAt( i );
+ switch ( ch ) {
+
+ case '"': // quotation mark
+ s += "\\\"";
+ break;
+
+ //case '/': // solidus
+ // s += "\\/";
+ // break;
+
+ case '\\': // reverse solidus
+ s += "\\\\";
+ break;
+
+ case '\b': // bell
+ s += "\\b";
+ break;
+
+ case '\f': // form feed
+ s += "\\f";
+ break;
+
+ case '\n': // newline
+ s += "\\n";
+ break;
+
+ case '\r': // carriage return
+ s += "\\r";
+ break;
+
+ case '\t': // horizontal tab
+ s += "\\t";
+ break;
+
+ default: // everything else
+
+ // check for a control character and escape as unicode
+ if ( ch < ' ' ) {
+ // get the hex digit(s) of the character (either 1 or 2 digits)
+ var hexCode:String = ch.charCodeAt( 0 ).toString( 16 );
+
+ // ensure that there are 4 digits by adjusting
+ // the # of zeros accordingly.
+ var zeroPad:String = hexCode.length == 2 ? "00" : "000";
+
+ // create the unicode escape sequence with 4 hex digits
+ s += "\\u" + zeroPad + hexCode;
+ } else {
+
+ // no need to do any special encoding, just pass-through
+ s += ch;
+
+ }
+ } // end switch
+
+ } // end for loop
+
+ return "\"" + s + "\"";
+ }
+
+ /**
+ * Converts an array to it's JSON string equivalent
+ *
+ * @param a The array to convert
+ * @return The JSON string representation of a
+ */
+ private function arrayToString( a:Array ):String {
+ // create a string to store the array's jsonstring value
+ var s:String = "";
+
+ // loop over the elements in the array and add their converted
+ // values to the string
+ for ( var i:int = 0; i < a.length; i++ ) {
+ // when the length is 0 we're adding the first element so
+ // no comma is necessary
+ if ( s.length > 0 ) {
+ // we've already added an element, so add the comma separator
+ s += ","
+ }
+
+ // convert the value to a string
+ s += convertToString( a[i] );
+ }
+
+ // KNOWN ISSUE: In ActionScript, Arrays can also be associative
+ // objects and you can put anything in them, ie:
+ // myArray["foo"] = "bar";
+ //
+ // These properties aren't picked up in the for loop above because
+ // the properties don't correspond to indexes. However, we're
+ // sort of out luck because the JSON specification doesn't allow
+ // these types of array properties.
+ //
+ // So, if the array was also used as an associative object, there
+ // may be some values in the array that don't get properly encoded.
+ //
+ // A possible solution is to instead encode the Array as an Object
+ // but then it won't get decoded correctly (and won't be an
+ // Array instance)
+
+ // close the array and return it's string value
+ return "[" + s + "]";
+ }
+
+ /**
+ * Converts an object to it's JSON string equivalent
+ *
+ * @param o The object to convert
+ * @return The JSON string representation of o
+ */
+ private function objectToString( o:Object ):String
+ {
+ // create a string to store the object's jsonstring value
+ var s:String = "";
+
+ // determine if o is a class instance or a plain object
+ var classInfo:XML = describeType( o );
+ if ( classInfo.@name.toString() == "Object" )
+ {
+ // the value of o[key] in the loop below - store this
+ // as a variable so we don't have to keep looking up o[key]
+ // when testing for valid values to convert
+ var value:Object;
+
+ // loop over the keys in the object and add their converted
+ // values to the string
+ for ( var key:String in o )
+ {
+ // assign value to a variable for quick lookup
+ value = o[key];
+
+ // don't add function's to the JSON string
+ if ( value is Function )
+ {
+ // skip this key and try another
+ continue;
+ }
+
+ // when the length is 0 we're adding the first item so
+ // no comma is necessary
+ if ( s.length > 0 ) {
+ // we've already added an item, so add the comma separator
+ s += ","
+ }
+
+ s += escapeString( key ) + ":" + convertToString( value );
+ }
+ }
+ else // o is a class instance
+ {
+ // Loop over all of the variables and accessors in the class and
+ // serialize them along with their values.
+ for each ( var v:XML in classInfo..*.( name() == "variable" || name() == "accessor" ) )
+ {
+ // When the length is 0 we're adding the first item so
+ // no comma is necessary
+ if ( s.length > 0 ) {
+ // We've already added an item, so add the comma separator
+ s += ","
+ }
+
+ s += escapeString( v.@name.toString() ) + ":"
+ + convertToString( o[ v.@name ] );
+ }
+
+ }
+
+ return "{" + s + "}";
+ }
+
+
+ }
+
+}
diff --git a/webcam/com/adobe/serialization/json/JSONParseError.as b/webcam/com/adobe/serialization/json/JSONParseError.as
index 5042b35..b8c0ecf 100644
--- a/webcam/com/adobe/serialization/json/JSONParseError.as
+++ b/webcam/com/adobe/serialization/json/JSONParseError.as
@@ -1,90 +1,90 @@
-/*
-Adobe Systems Incorporated(r) Source Code License Agreement
-Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
-Please read this Source Code License Agreement carefully before using
-the source code.
-
-Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable copyright license, to reproduce,
-prepare derivative works of, publicly display, publicly perform, and
-distribute this source code and such derivative works in source or
-object code form without any attribution requirements.
-
-The name "Adobe Systems Incorporated" must not be used to endorse or promote products
-derived from the source code without prior written permission.
-
-You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
-against any loss, damage, claims or lawsuits, including attorney's
-fees that arise or result from your use or distribution of the source
-code.
-
-THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
-ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
-NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
-OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.serialization.json {
-
- /**
- *
- *
- */
- public class JSONParseError extends Error {
-
- /** The location in the string where the error occurred */
- private var _location:int;
-
- /** The string in which the parse error occurred */
- private var _text:String;
-
- /**
- * Constructs a new JSONParseError.
- *
- * @param message The error message that occured during parsing
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function JSONParseError( message:String = "", location:int = 0, text:String = "") {
- super( message );
- //name = "JSONParseError";
- _location = location;
- _text = text;
- }
-
- /**
- * Provides read-only access to the location variable.
- *
- * @return The location in the string where the error occurred
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function get location():int {
- return _location;
- }
-
- /**
- * Provides read-only access to the text variable.
- *
- * @return The string in which the error occurred
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function get text():String {
- return _text;
- }
- }
-
+/*
+Adobe Systems Incorporated(r) Source Code License Agreement
+Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+Please read this Source Code License Agreement carefully before using
+the source code.
+
+Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable copyright license, to reproduce,
+prepare derivative works of, publicly display, publicly perform, and
+distribute this source code and such derivative works in source or
+object code form without any attribution requirements.
+
+The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+derived from the source code without prior written permission.
+
+You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+against any loss, damage, claims or lawsuits, including attorney's
+fees that arise or result from your use or distribution of the source
+code.
+
+THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.serialization.json {
+
+ /**
+ *
+ *
+ */
+ public class JSONParseError extends Error {
+
+ /** The location in the string where the error occurred */
+ private var _location:int;
+
+ /** The string in which the parse error occurred */
+ private var _text:String;
+
+ /**
+ * Constructs a new JSONParseError.
+ *
+ * @param message The error message that occured during parsing
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function JSONParseError( message:String = "", location:int = 0, text:String = "") {
+ super( message );
+ //name = "JSONParseError";
+ _location = location;
+ _text = text;
+ }
+
+ /**
+ * Provides read-only access to the location variable.
+ *
+ * @return The location in the string where the error occurred
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function get location():int {
+ return _location;
+ }
+
+ /**
+ * Provides read-only access to the text variable.
+ *
+ * @return The string in which the error occurred
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function get text():String {
+ return _text;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/webcam/com/adobe/serialization/json/JSONToken.as b/webcam/com/adobe/serialization/json/JSONToken.as
index 54b1332..51e3714 100644
--- a/webcam/com/adobe/serialization/json/JSONToken.as
+++ b/webcam/com/adobe/serialization/json/JSONToken.as
@@ -1,107 +1,107 @@
-/*
-Adobe Systems Incorporated(r) Source Code License Agreement
-Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
-Please read this Source Code License Agreement carefully before using
-the source code.
-
-Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable copyright license, to reproduce,
-prepare derivative works of, publicly display, publicly perform, and
-distribute this source code and such derivative works in source or
-object code form without any attribution requirements.
-
-The name "Adobe Systems Incorporated" must not be used to endorse or promote products
-derived from the source code without prior written permission.
-
-You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
-against any loss, damage, claims or lawsuits, including attorney's
-fees that arise or result from your use or distribution of the source
-code.
-
-THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
-ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
-NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
-OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.serialization.json {
-
- public class JSONToken {
-
- private var _type:int;
- private var _value:Object;
-
- /**
- * Creates a new JSONToken with a specific token type and value.
- *
- * @param type The JSONTokenType of the token
- * @param value The value of the token
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function JSONToken( type:int = -1 /* JSONTokenType.UNKNOWN */, value:Object = null ) {
- _type = type;
- _value = value;
- }
-
- /**
- * Returns the type of the token.
- *
- * @see com.adobe.serialization.json.JSONTokenType
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function get type():int {
- return _type;
- }
-
- /**
- * Sets the type of the token.
- *
- * @see com.adobe.serialization.json.JSONTokenType
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function set type( value:int ):void {
- _type = value;
- }
-
- /**
- * Gets the value of the token
- *
- * @see com.adobe.serialization.json.JSONTokenType
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function get value():Object {
- return _value;
- }
-
- /**
- * Sets the value of the token
- *
- * @see com.adobe.serialization.json.JSONTokenType
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public function set value ( v:Object ):void {
- _value = v;
- }
-
- }
-
+/*
+Adobe Systems Incorporated(r) Source Code License Agreement
+Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+Please read this Source Code License Agreement carefully before using
+the source code.
+
+Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable copyright license, to reproduce,
+prepare derivative works of, publicly display, publicly perform, and
+distribute this source code and such derivative works in source or
+object code form without any attribution requirements.
+
+The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+derived from the source code without prior written permission.
+
+You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+against any loss, damage, claims or lawsuits, including attorney's
+fees that arise or result from your use or distribution of the source
+code.
+
+THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.serialization.json {
+
+ public class JSONToken {
+
+ private var _type:int;
+ private var _value:Object;
+
+ /**
+ * Creates a new JSONToken with a specific token type and value.
+ *
+ * @param type The JSONTokenType of the token
+ * @param value The value of the token
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function JSONToken( type:int = -1 /* JSONTokenType.UNKNOWN */, value:Object = null ) {
+ _type = type;
+ _value = value;
+ }
+
+ /**
+ * Returns the type of the token.
+ *
+ * @see com.adobe.serialization.json.JSONTokenType
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function get type():int {
+ return _type;
+ }
+
+ /**
+ * Sets the type of the token.
+ *
+ * @see com.adobe.serialization.json.JSONTokenType
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function set type( value:int ):void {
+ _type = value;
+ }
+
+ /**
+ * Gets the value of the token
+ *
+ * @see com.adobe.serialization.json.JSONTokenType
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function get value():Object {
+ return _value;
+ }
+
+ /**
+ * Sets the value of the token
+ *
+ * @see com.adobe.serialization.json.JSONTokenType
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function set value ( v:Object ):void {
+ _value = v;
+ }
+
+ }
+
}
\ No newline at end of file
diff --git a/webcam/com/adobe/serialization/json/JSONTokenType.as b/webcam/com/adobe/serialization/json/JSONTokenType.as
index e78173e..398a0f4 100644
--- a/webcam/com/adobe/serialization/json/JSONTokenType.as
+++ b/webcam/com/adobe/serialization/json/JSONTokenType.as
@@ -1,70 +1,70 @@
-/*
-Adobe Systems Incorporated(r) Source Code License Agreement
-Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
-Please read this Source Code License Agreement carefully before using
-the source code.
-
-Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable copyright license, to reproduce,
-prepare derivative works of, publicly display, publicly perform, and
-distribute this source code and such derivative works in source or
-object code form without any attribution requirements.
-
-The name "Adobe Systems Incorporated" must not be used to endorse or promote products
-derived from the source code without prior written permission.
-
-You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
-against any loss, damage, claims or lawsuits, including attorney's
-fees that arise or result from your use or distribution of the source
-code.
-
-THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
-ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
-NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
-OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.serialization.json {
-
- /**
- * Class containing constant values for the different types
- * of tokens in a JSON encoded string.
- */
- public class JSONTokenType {
-
- public static const UNKNOWN:int = -1;
-
- public static const COMMA:int = 0;
-
- public static const LEFT_BRACE:int = 1;
-
- public static const RIGHT_BRACE:int = 2;
-
- public static const LEFT_BRACKET:int = 3;
-
- public static const RIGHT_BRACKET:int = 4;
-
- public static const COLON:int = 6;
-
- public static const TRUE:int = 7;
-
- public static const FALSE:int = 8;
-
- public static const NULL:int = 9;
-
- public static const STRING:int = 10;
-
- public static const NUMBER:int = 11;
-
- }
-
+/*
+Adobe Systems Incorporated(r) Source Code License Agreement
+Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+Please read this Source Code License Agreement carefully before using
+the source code.
+
+Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable copyright license, to reproduce,
+prepare derivative works of, publicly display, publicly perform, and
+distribute this source code and such derivative works in source or
+object code form without any attribution requirements.
+
+The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+derived from the source code without prior written permission.
+
+You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+against any loss, damage, claims or lawsuits, including attorney's
+fees that arise or result from your use or distribution of the source
+code.
+
+THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.serialization.json {
+
+ /**
+ * Class containing constant values for the different types
+ * of tokens in a JSON encoded string.
+ */
+ public class JSONTokenType {
+
+ public static const UNKNOWN:int = -1;
+
+ public static const COMMA:int = 0;
+
+ public static const LEFT_BRACE:int = 1;
+
+ public static const RIGHT_BRACE:int = 2;
+
+ public static const LEFT_BRACKET:int = 3;
+
+ public static const RIGHT_BRACKET:int = 4;
+
+ public static const COLON:int = 6;
+
+ public static const TRUE:int = 7;
+
+ public static const FALSE:int = 8;
+
+ public static const NULL:int = 9;
+
+ public static const STRING:int = 10;
+
+ public static const NUMBER:int = 11;
+
+ }
+
}
\ No newline at end of file
diff --git a/webcam/com/adobe/serialization/json/JSONTokenizer.as b/webcam/com/adobe/serialization/json/JSONTokenizer.as
index 2516446..077414d 100644
--- a/webcam/com/adobe/serialization/json/JSONTokenizer.as
+++ b/webcam/com/adobe/serialization/json/JSONTokenizer.as
@@ -1,550 +1,550 @@
-/*
-Adobe Systems Incorporated(r) Source Code License Agreement
-Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
-Please read this Source Code License Agreement carefully before using
-the source code.
-
-Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable copyright license, to reproduce,
-prepare derivative works of, publicly display, publicly perform, and
-distribute this source code and such derivative works in source or
-object code form without any attribution requirements.
-
-The name "Adobe Systems Incorporated" must not be used to endorse or promote products
-derived from the source code without prior written permission.
-
-You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
-against any loss, damage, claims or lawsuits, including attorney's
-fees that arise or result from your use or distribution of the source
-code.
-
-THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
-ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
-NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
-OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.serialization.json {
-
- public class JSONTokenizer {
-
- /** The object that will get parsed from the JSON string */
- private var obj:Object;
-
- /** The JSON string to be parsed */
- private var jsonString:String;
-
- /** The current parsing location in the JSON string */
- private var loc:int;
-
- /** The current character in the JSON string during parsing */
- private var ch:String;
-
- /**
- * Constructs a new JSONDecoder to parse a JSON string
- * into a native object.
- *
- * @param s The JSON string to be converted
- * into a native object
- */
- public function JSONTokenizer( s:String ) {
- jsonString = s;
- loc = 0;
-
- // prime the pump by getting the first character
- nextChar();
- }
-
- /**
- * Gets the next token in the input sting and advances
- * the character to the next character after the token
- */
- public function getNextToken():JSONToken {
- var token:JSONToken = new JSONToken();
-
- // skip any whitespace / comments since the last
- // token was read
- skipIgnored();
-
- // examine the new character and see what we have...
- switch ( ch ) {
-
- case '{':
- token.type = JSONTokenType.LEFT_BRACE;
- token.value = '{';
- nextChar();
- break
-
- case '}':
- token.type = JSONTokenType.RIGHT_BRACE;
- token.value = '}';
- nextChar();
- break
-
- case '[':
- token.type = JSONTokenType.LEFT_BRACKET;
- token.value = '[';
- nextChar();
- break
-
- case ']':
- token.type = JSONTokenType.RIGHT_BRACKET;
- token.value = ']';
- nextChar();
- break
-
- case ',':
- token.type = JSONTokenType.COMMA;
- token.value = ',';
- nextChar();
- break
-
- case ':':
- token.type = JSONTokenType.COLON;
- token.value = ':';
- nextChar();
- break;
-
- case 't': // attempt to read true
- var possibleTrue:String = "t" + nextChar() + nextChar() + nextChar();
-
- if ( possibleTrue == "true" ) {
- token.type = JSONTokenType.TRUE;
- token.value = true;
- nextChar();
- } else {
- parseError( "Expecting 'true' but found " + possibleTrue );
- }
-
- break;
-
- case 'f': // attempt to read false
- var possibleFalse:String = "f" + nextChar() + nextChar() + nextChar() + nextChar();
-
- if ( possibleFalse == "false" ) {
- token.type = JSONTokenType.FALSE;
- token.value = false;
- nextChar();
- } else {
- parseError( "Expecting 'false' but found " + possibleFalse );
- }
-
- break;
-
- case 'n': // attempt to read null
-
- var possibleNull:String = "n" + nextChar() + nextChar() + nextChar();
-
- if ( possibleNull == "null" ) {
- token.type = JSONTokenType.NULL;
- token.value = null;
- nextChar();
- } else {
- parseError( "Expecting 'null' but found " + possibleNull );
- }
-
- break;
-
- case '"': // the start of a string
- token = readString();
- break;
-
- default:
- // see if we can read a number
- if ( isDigit( ch ) || ch == '-' ) {
- token = readNumber();
- } else if ( ch == '' ) {
- // check for reading past the end of the string
- return null;
- } else {
- // not sure what was in the input string - it's not
- // anything we expected
- parseError( "Unexpected " + ch + " encountered" );
- }
- }
-
- return token;
- }
-
- /**
- * Attempts to read a string from the input string. Places
- * the character location at the first character after the
- * string. It is assumed that ch is " before this method is called.
- *
- * @return the JSONToken with the string value if a string could
- * be read. Throws an error otherwise.
- */
- private function readString():JSONToken {
- // the token for the string we'll try to read
- var token:JSONToken = new JSONToken();
- token.type = JSONTokenType.STRING;
-
- // the string to store the string we'll try to read
- var string:String = "";
-
- // advance past the first "
- nextChar();
-
- while ( ch != '"' && ch != '' ) {
-
- // unescape the escape sequences in the string
- if ( ch == '\\' ) {
-
- // get the next character so we know what
- // to unescape
- nextChar();
-
- switch ( ch ) {
-
- case '"': // quotation mark
- string += '"';
- break;
-
- case '/': // solidus
- string += "/";
- break;
-
- case '\\': // reverse solidus
- string += '\\';
- break;
-
- case 'b': // bell
- string += '\b';
- break;
-
- case 'f': // form feed
- string += '\f';
- break;
-
- case 'n': // newline
- string += '\n';
- break;
-
- case 'r': // carriage return
- string += '\r';
- break;
-
- case 't': // horizontal tab
- string += '\t'
- break;
-
- case 'u':
- // convert a unicode escape sequence
- // to it's character value - expecting
- // 4 hex digits
-
- // save the characters as a string we'll convert to an int
- var hexValue:String = "";
-
- // try to find 4 hex characters
- for ( var i:int = 0; i < 4; i++ ) {
- // get the next character and determine
- // if it's a valid hex digit or not
- if ( !isHexDigit( nextChar() ) ) {
- parseError( " Excepted a hex digit, but found: " + ch );
- }
- // valid, add it to the value
- hexValue += ch;
- }
-
- // convert hexValue to an integer, and use that
- // integrer value to create a character to add
- // to our string.
- string += String.fromCharCode( parseInt( hexValue, 16 ) );
-
- break;
-
- default:
- // couldn't unescape the sequence, so just
- // pass it through
- string += '\\' + ch;
-
- }
-
- } else {
- // didn't have to unescape, so add the character to the string
- string += ch;
-
- }
-
- // move to the next character
- nextChar();
-
- }
-
- // we read past the end of the string without closing it, which
- // is a parse error
- if ( ch == '' ) {
- parseError( "Unterminated string literal" );
- }
-
- // move past the closing " in the input string
- nextChar();
-
- // attach to the string to the token so we can return it
- token.value = string;
-
- return token;
- }
-
- /**
- * Attempts to read a number from the input string. Places
- * the character location at the first character after the
- * number.
- *
- * @return The JSONToken with the number value if a number could
- * be read. Throws an error otherwise.
- */
- private function readNumber():JSONToken {
- // the token for the number we'll try to read
- var token:JSONToken = new JSONToken();
- token.type = JSONTokenType.NUMBER;
-
- // the string to accumulate the number characters
- // into that we'll convert to a number at the end
- var input:String = "";
-
- // check for a negative number
- if ( ch == '-' ) {
- input += '-';
- nextChar();
- }
-
- // the number must start with a digit
- if ( !isDigit( ch ) )
- {
- parseError( "Expecting a digit" );
- }
-
- // 0 can only be the first digit if it
- // is followed by a decimal point
- if ( ch == '0' )
- {
- input += ch;
- nextChar();
-
- // make sure no other digits come after 0
- if ( isDigit( ch ) )
- {
- parseError( "A digit cannot immediately follow 0" );
- }
- }
- else
- {
- // read numbers while we can
- while ( isDigit( ch ) ) {
- input += ch;
- nextChar();
- }
- }
-
- // check for a decimal value
- if ( ch == '.' ) {
- input += '.';
- nextChar();
-
- // after the decimal there has to be a digit
- if ( !isDigit( ch ) )
- {
- parseError( "Expecting a digit" );
- }
-
- // read more numbers to get the decimal value
- while ( isDigit( ch ) ) {
- input += ch;
- nextChar();
- }
- }
-
- // check for scientific notation
- if ( ch == 'e' || ch == 'E' )
- {
- input += "e"
- nextChar();
- // check for sign
- if ( ch == '+' || ch == '-' )
- {
- input += ch;
- nextChar();
- }
-
- // require at least one number for the exponent
- // in this case
- if ( !isDigit( ch ) )
- {
- parseError( "Scientific notation number needs exponent value" );
- }
-
- // read in the exponent
- while ( isDigit( ch ) )
- {
- input += ch;
- nextChar();
- }
- }
-
- // convert the string to a number value
- var num:Number = Number( input );
-
- if ( isFinite( num ) && !isNaN( num ) ) {
- token.value = num;
- return token;
- } else {
- parseError( "Number " + num + " is not valid!" );
- }
- return null;
- }
-
- /**
- * Reads the next character in the input
- * string and advances the character location.
- *
- * @return The next character in the input string, or
- * null if we've read past the end.
- */
- private function nextChar():String {
- return ch = jsonString.charAt( loc++ );
- }
-
- /**
- * Advances the character location past any
- * sort of white space and comments
- */
- private function skipIgnored():void {
- skipWhite();
- skipComments();
- skipWhite();
- }
-
- /**
- * Skips comments in the input string, either
- * single-line or multi-line. Advances the character
- * to the first position after the end of the comment.
- */
- private function skipComments():void {
- if ( ch == '/' ) {
- // Advance past the first / to find out what type of comment
- nextChar();
- switch ( ch ) {
- case '/': // single-line comment, read through end of line
-
- // Loop over the characters until we find
- // a newline or until there's no more characters left
- do {
- nextChar();
- } while ( ch != '\n' && ch != '' )
-
- // move past the \n
- nextChar();
-
- break;
-
- case '*': // multi-line comment, read until closing */
-
- // move past the opening *
- nextChar();
-
- // try to find a trailing */
- while ( true ) {
- if ( ch == '*' ) {
- // check to see if we have a closing /
- nextChar();
- if ( ch == '/') {
- // move past the end of the closing */
- nextChar();
- break;
- }
- } else {
- // move along, looking if the next character is a *
- nextChar();
- }
-
- // when we're here we've read past the end of
- // the string without finding a closing */, so error
- if ( ch == '' ) {
- parseError( "Multi-line comment not closed" );
- }
- }
-
- break;
-
- // Can't match a comment after a /, so it's a parsing error
- default:
- parseError( "Unexpected " + ch + " encountered (expecting '/' or '*' )" );
- }
- }
-
- }
-
-
- /**
- * Skip any whitespace in the input string and advances
- * the character to the first character after any possible
- * whitespace.
- */
- private function skipWhite():void {
-
- // As long as there are spaces in the input
- // stream, advance the current location pointer
- // past them
- while ( isWhiteSpace( ch ) ) {
- nextChar();
- }
-
- }
-
- /**
- * Determines if a character is whitespace or not.
- *
- * @return True if the character passed in is a whitespace
- * character
- */
- private function isWhiteSpace( ch:String ):Boolean {
- return ( ch == ' ' || ch == '\t' || ch == '\n' );
- }
-
- /**
- * Determines if a character is a digit [0-9].
- *
- * @return True if the character passed in is a digit
- */
- private function isDigit( ch:String ):Boolean {
- return ( ch >= '0' && ch <= '9' );
- }
-
- /**
- * Determines if a character is a digit [0-9].
- *
- * @return True if the character passed in is a digit
- */
- private function isHexDigit( ch:String ):Boolean {
- // get the uppercase value of ch so we only have
- // to compare the value between 'A' and 'F'
- var uc:String = ch.toUpperCase();
-
- // a hex digit is a digit of A-F, inclusive ( using
- // our uppercase constraint )
- return ( isDigit( ch ) || ( uc >= 'A' && uc <= 'F' ) );
- }
-
- /**
- * Raises a parsing error with a specified message, tacking
- * on the error location and the original string.
- *
- * @param message The message indicating why the error occurred
- */
- public function parseError( message:String ):void {
- throw new JSONParseError( message, loc, jsonString );
- }
- }
-
-}
+/*
+Adobe Systems Incorporated(r) Source Code License Agreement
+Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+Please read this Source Code License Agreement carefully before using
+the source code.
+
+Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable copyright license, to reproduce,
+prepare derivative works of, publicly display, publicly perform, and
+distribute this source code and such derivative works in source or
+object code form without any attribution requirements.
+
+The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+derived from the source code without prior written permission.
+
+You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+against any loss, damage, claims or lawsuits, including attorney's
+fees that arise or result from your use or distribution of the source
+code.
+
+THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.serialization.json {
+
+ public class JSONTokenizer {
+
+ /** The object that will get parsed from the JSON string */
+ private var obj:Object;
+
+ /** The JSON string to be parsed */
+ private var jsonString:String;
+
+ /** The current parsing location in the JSON string */
+ private var loc:int;
+
+ /** The current character in the JSON string during parsing */
+ private var ch:String;
+
+ /**
+ * Constructs a new JSONDecoder to parse a JSON string
+ * into a native object.
+ *
+ * @param s The JSON string to be converted
+ * into a native object
+ */
+ public function JSONTokenizer( s:String ) {
+ jsonString = s;
+ loc = 0;
+
+ // prime the pump by getting the first character
+ nextChar();
+ }
+
+ /**
+ * Gets the next token in the input sting and advances
+ * the character to the next character after the token
+ */
+ public function getNextToken():JSONToken {
+ var token:JSONToken = new JSONToken();
+
+ // skip any whitespace / comments since the last
+ // token was read
+ skipIgnored();
+
+ // examine the new character and see what we have...
+ switch ( ch ) {
+
+ case '{':
+ token.type = JSONTokenType.LEFT_BRACE;
+ token.value = '{';
+ nextChar();
+ break
+
+ case '}':
+ token.type = JSONTokenType.RIGHT_BRACE;
+ token.value = '}';
+ nextChar();
+ break
+
+ case '[':
+ token.type = JSONTokenType.LEFT_BRACKET;
+ token.value = '[';
+ nextChar();
+ break
+
+ case ']':
+ token.type = JSONTokenType.RIGHT_BRACKET;
+ token.value = ']';
+ nextChar();
+ break
+
+ case ',':
+ token.type = JSONTokenType.COMMA;
+ token.value = ',';
+ nextChar();
+ break
+
+ case ':':
+ token.type = JSONTokenType.COLON;
+ token.value = ':';
+ nextChar();
+ break;
+
+ case 't': // attempt to read true
+ var possibleTrue:String = "t" + nextChar() + nextChar() + nextChar();
+
+ if ( possibleTrue == "true" ) {
+ token.type = JSONTokenType.TRUE;
+ token.value = true;
+ nextChar();
+ } else {
+ parseError( "Expecting 'true' but found " + possibleTrue );
+ }
+
+ break;
+
+ case 'f': // attempt to read false
+ var possibleFalse:String = "f" + nextChar() + nextChar() + nextChar() + nextChar();
+
+ if ( possibleFalse == "false" ) {
+ token.type = JSONTokenType.FALSE;
+ token.value = false;
+ nextChar();
+ } else {
+ parseError( "Expecting 'false' but found " + possibleFalse );
+ }
+
+ break;
+
+ case 'n': // attempt to read null
+
+ var possibleNull:String = "n" + nextChar() + nextChar() + nextChar();
+
+ if ( possibleNull == "null" ) {
+ token.type = JSONTokenType.NULL;
+ token.value = null;
+ nextChar();
+ } else {
+ parseError( "Expecting 'null' but found " + possibleNull );
+ }
+
+ break;
+
+ case '"': // the start of a string
+ token = readString();
+ break;
+
+ default:
+ // see if we can read a number
+ if ( isDigit( ch ) || ch == '-' ) {
+ token = readNumber();
+ } else if ( ch == '' ) {
+ // check for reading past the end of the string
+ return null;
+ } else {
+ // not sure what was in the input string - it's not
+ // anything we expected
+ parseError( "Unexpected " + ch + " encountered" );
+ }
+ }
+
+ return token;
+ }
+
+ /**
+ * Attempts to read a string from the input string. Places
+ * the character location at the first character after the
+ * string. It is assumed that ch is " before this method is called.
+ *
+ * @return the JSONToken with the string value if a string could
+ * be read. Throws an error otherwise.
+ */
+ private function readString():JSONToken {
+ // the token for the string we'll try to read
+ var token:JSONToken = new JSONToken();
+ token.type = JSONTokenType.STRING;
+
+ // the string to store the string we'll try to read
+ var string:String = "";
+
+ // advance past the first "
+ nextChar();
+
+ while ( ch != '"' && ch != '' ) {
+
+ // unescape the escape sequences in the string
+ if ( ch == '\\' ) {
+
+ // get the next character so we know what
+ // to unescape
+ nextChar();
+
+ switch ( ch ) {
+
+ case '"': // quotation mark
+ string += '"';
+ break;
+
+ case '/': // solidus
+ string += "/";
+ break;
+
+ case '\\': // reverse solidus
+ string += '\\';
+ break;
+
+ case 'b': // bell
+ string += '\b';
+ break;
+
+ case 'f': // form feed
+ string += '\f';
+ break;
+
+ case 'n': // newline
+ string += '\n';
+ break;
+
+ case 'r': // carriage return
+ string += '\r';
+ break;
+
+ case 't': // horizontal tab
+ string += '\t'
+ break;
+
+ case 'u':
+ // convert a unicode escape sequence
+ // to it's character value - expecting
+ // 4 hex digits
+
+ // save the characters as a string we'll convert to an int
+ var hexValue:String = "";
+
+ // try to find 4 hex characters
+ for ( var i:int = 0; i < 4; i++ ) {
+ // get the next character and determine
+ // if it's a valid hex digit or not
+ if ( !isHexDigit( nextChar() ) ) {
+ parseError( " Excepted a hex digit, but found: " + ch );
+ }
+ // valid, add it to the value
+ hexValue += ch;
+ }
+
+ // convert hexValue to an integer, and use that
+ // integrer value to create a character to add
+ // to our string.
+ string += String.fromCharCode( parseInt( hexValue, 16 ) );
+
+ break;
+
+ default:
+ // couldn't unescape the sequence, so just
+ // pass it through
+ string += '\\' + ch;
+
+ }
+
+ } else {
+ // didn't have to unescape, so add the character to the string
+ string += ch;
+
+ }
+
+ // move to the next character
+ nextChar();
+
+ }
+
+ // we read past the end of the string without closing it, which
+ // is a parse error
+ if ( ch == '' ) {
+ parseError( "Unterminated string literal" );
+ }
+
+ // move past the closing " in the input string
+ nextChar();
+
+ // attach to the string to the token so we can return it
+ token.value = string;
+
+ return token;
+ }
+
+ /**
+ * Attempts to read a number from the input string. Places
+ * the character location at the first character after the
+ * number.
+ *
+ * @return The JSONToken with the number value if a number could
+ * be read. Throws an error otherwise.
+ */
+ private function readNumber():JSONToken {
+ // the token for the number we'll try to read
+ var token:JSONToken = new JSONToken();
+ token.type = JSONTokenType.NUMBER;
+
+ // the string to accumulate the number characters
+ // into that we'll convert to a number at the end
+ var input:String = "";
+
+ // check for a negative number
+ if ( ch == '-' ) {
+ input += '-';
+ nextChar();
+ }
+
+ // the number must start with a digit
+ if ( !isDigit( ch ) )
+ {
+ parseError( "Expecting a digit" );
+ }
+
+ // 0 can only be the first digit if it
+ // is followed by a decimal point
+ if ( ch == '0' )
+ {
+ input += ch;
+ nextChar();
+
+ // make sure no other digits come after 0
+ if ( isDigit( ch ) )
+ {
+ parseError( "A digit cannot immediately follow 0" );
+ }
+ }
+ else
+ {
+ // read numbers while we can
+ while ( isDigit( ch ) ) {
+ input += ch;
+ nextChar();
+ }
+ }
+
+ // check for a decimal value
+ if ( ch == '.' ) {
+ input += '.';
+ nextChar();
+
+ // after the decimal there has to be a digit
+ if ( !isDigit( ch ) )
+ {
+ parseError( "Expecting a digit" );
+ }
+
+ // read more numbers to get the decimal value
+ while ( isDigit( ch ) ) {
+ input += ch;
+ nextChar();
+ }
+ }
+
+ // check for scientific notation
+ if ( ch == 'e' || ch == 'E' )
+ {
+ input += "e"
+ nextChar();
+ // check for sign
+ if ( ch == '+' || ch == '-' )
+ {
+ input += ch;
+ nextChar();
+ }
+
+ // require at least one number for the exponent
+ // in this case
+ if ( !isDigit( ch ) )
+ {
+ parseError( "Scientific notation number needs exponent value" );
+ }
+
+ // read in the exponent
+ while ( isDigit( ch ) )
+ {
+ input += ch;
+ nextChar();
+ }
+ }
+
+ // convert the string to a number value
+ var num:Number = Number( input );
+
+ if ( isFinite( num ) && !isNaN( num ) ) {
+ token.value = num;
+ return token;
+ } else {
+ parseError( "Number " + num + " is not valid!" );
+ }
+ return null;
+ }
+
+ /**
+ * Reads the next character in the input
+ * string and advances the character location.
+ *
+ * @return The next character in the input string, or
+ * null if we've read past the end.
+ */
+ private function nextChar():String {
+ return ch = jsonString.charAt( loc++ );
+ }
+
+ /**
+ * Advances the character location past any
+ * sort of white space and comments
+ */
+ private function skipIgnored():void {
+ skipWhite();
+ skipComments();
+ skipWhite();
+ }
+
+ /**
+ * Skips comments in the input string, either
+ * single-line or multi-line. Advances the character
+ * to the first position after the end of the comment.
+ */
+ private function skipComments():void {
+ if ( ch == '/' ) {
+ // Advance past the first / to find out what type of comment
+ nextChar();
+ switch ( ch ) {
+ case '/': // single-line comment, read through end of line
+
+ // Loop over the characters until we find
+ // a newline or until there's no more characters left
+ do {
+ nextChar();
+ } while ( ch != '\n' && ch != '' )
+
+ // move past the \n
+ nextChar();
+
+ break;
+
+ case '*': // multi-line comment, read until closing */
+
+ // move past the opening *
+ nextChar();
+
+ // try to find a trailing */
+ while ( true ) {
+ if ( ch == '*' ) {
+ // check to see if we have a closing /
+ nextChar();
+ if ( ch == '/') {
+ // move past the end of the closing */
+ nextChar();
+ break;
+ }
+ } else {
+ // move along, looking if the next character is a *
+ nextChar();
+ }
+
+ // when we're here we've read past the end of
+ // the string without finding a closing */, so error
+ if ( ch == '' ) {
+ parseError( "Multi-line comment not closed" );
+ }
+ }
+
+ break;
+
+ // Can't match a comment after a /, so it's a parsing error
+ default:
+ parseError( "Unexpected " + ch + " encountered (expecting '/' or '*' )" );
+ }
+ }
+
+ }
+
+
+ /**
+ * Skip any whitespace in the input string and advances
+ * the character to the first character after any possible
+ * whitespace.
+ */
+ private function skipWhite():void {
+
+ // As long as there are spaces in the input
+ // stream, advance the current location pointer
+ // past them
+ while ( isWhiteSpace( ch ) ) {
+ nextChar();
+ }
+
+ }
+
+ /**
+ * Determines if a character is whitespace or not.
+ *
+ * @return True if the character passed in is a whitespace
+ * character
+ */
+ private function isWhiteSpace( ch:String ):Boolean {
+ return ( ch == ' ' || ch == '\t' || ch == '\n' );
+ }
+
+ /**
+ * Determines if a character is a digit [0-9].
+ *
+ * @return True if the character passed in is a digit
+ */
+ private function isDigit( ch:String ):Boolean {
+ return ( ch >= '0' && ch <= '9' );
+ }
+
+ /**
+ * Determines if a character is a digit [0-9].
+ *
+ * @return True if the character passed in is a digit
+ */
+ private function isHexDigit( ch:String ):Boolean {
+ // get the uppercase value of ch so we only have
+ // to compare the value between 'A' and 'F'
+ var uc:String = ch.toUpperCase();
+
+ // a hex digit is a digit of A-F, inclusive ( using
+ // our uppercase constraint )
+ return ( isDigit( ch ) || ( uc >= 'A' && uc <= 'F' ) );
+ }
+
+ /**
+ * Raises a parsing error with a specified message, tacking
+ * on the error location and the original string.
+ *
+ * @param message The message indicating why the error occurred
+ */
+ public function parseError( message:String ):void {
+ throw new JSONParseError( message, loc, jsonString );
+ }
+ }
+
+}
diff --git a/webcam/com/adobe/utils/ArrayUtil.as b/webcam/com/adobe/utils/ArrayUtil.as
index 79f499b..c535602 100644
--- a/webcam/com/adobe/utils/ArrayUtil.as
+++ b/webcam/com/adobe/utils/ArrayUtil.as
@@ -1,190 +1,190 @@
-/*
- Adobe Systems Incorporated(r) Source Code License Agreement
- Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
- Please read this Source Code License Agreement carefully before using
- the source code.
-
- Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
- no-charge, royalty-free, irrevocable copyright license, to reproduce,
- prepare derivative works of, publicly display, publicly perform, and
- distribute this source code and such derivative works in source or
- object code form without any attribution requirements.
-
- The name "Adobe Systems Incorporated" must not be used to endorse or promote products
- derived from the source code without prior written permission.
-
- You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
- against any loss, damage, claims or lawsuits, including attorney's
- fees that arise or result from your use or distribution of the source
- code.
-
- THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
- ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
- NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
- OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.utils
-{
-
- /**
- * Class that contains static utility methods for manipulating and working
- * with Arrays.
- *
- * Note that all APIs assume that they are working with well formed arrays.
- * i.e. they will only manipulate indexed values.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public class ArrayUtil
- {
-
- /**
- * Determines whether the specified array contains the specified value.
- *
- * @param arr The array that will be checked for the specified value.
- *
- * @param value The object which will be searched for within the array
- *
- * @return True if the array contains the value, False if it does not.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function arrayContainsValue(arr:Array, value:Object):Boolean
- {
- return (arr.indexOf(value) != -1);
- }
-
- /**
- * Remove all instances of the specified value from the array,
- *
- * @param arr The array from which the value will be removed
- *
- * @param value The object that will be removed from the array.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function removeValueFromArray(arr:Array, value:Object):void
- {
- var len:uint = arr.length;
-
- for(var i:Number = len; i > -1; i--)
- {
- if(arr[i] === value)
- {
- arr.splice(i, 1);
- }
- }
- }
-
- /**
- * Create a new array that only contains unique instances of objects
- * in the specified array.
- *
- * Basically, this can be used to remove duplication object instances
- * from an array
- *
- * @param arr The array which contains the values that will be used to
- * create the new array that contains no duplicate values.
- *
- * @return A new array which only contains unique items from the specified
- * array.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function createUniqueCopy(a:Array):Array
- {
- var newArray:Array = new Array();
-
- var len:Number = a.length;
- var item:Object;
-
- for (var i:uint = 0; i < len; ++i)
- {
- item = a[i];
-
- if(ArrayUtil.arrayContainsValue(newArray, item))
- {
- continue;
- }
-
- newArray.push(item);
- }
-
- return newArray;
- }
-
- /**
- * Creates a copy of the specified array.
- *
- * Note that the array returned is a new array but the items within the
- * array are not copies of the items in the original array (but rather
- * references to the same items)
- *
- * @param arr The array that will be copies
- *
- * @return A new array which contains the same items as the array passed
- * in.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function copyArray(arr:Array):Array
- {
- return arr.slice();
- }
-
- /**
- * Compares two arrays and returns a boolean indicating whether the arrays
- * contain the same values at the same indexes.
- *
- * @param arr1 The first array that will be compared to the second.
- *
- * @param arr2 The second array that will be compared to the first.
- *
- * @return True if the arrays contains the same values at the same indexes.
- False if they do not.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function arraysAreEqual(arr1:Array, arr2:Array):Boolean
- {
- if(arr1.length != arr2.length)
- {
- return false;
- }
-
- var len:Number = arr1.length;
-
- for(var i:Number = 0; i < len; i++)
- {
- if(arr1[i] !== arr2[i])
- {
- return false;
- }
- }
-
- return true;
- }
- }
-}
+/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.utils
+{
+
+ /**
+ * Class that contains static utility methods for manipulating and working
+ * with Arrays.
+ *
+ * Note that all APIs assume that they are working with well formed arrays.
+ * i.e. they will only manipulate indexed values.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public class ArrayUtil
+ {
+
+ /**
+ * Determines whether the specified array contains the specified value.
+ *
+ * @param arr The array that will be checked for the specified value.
+ *
+ * @param value The object which will be searched for within the array
+ *
+ * @return True if the array contains the value, False if it does not.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function arrayContainsValue(arr:Array, value:Object):Boolean
+ {
+ return (arr.indexOf(value) != -1);
+ }
+
+ /**
+ * Remove all instances of the specified value from the array,
+ *
+ * @param arr The array from which the value will be removed
+ *
+ * @param value The object that will be removed from the array.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function removeValueFromArray(arr:Array, value:Object):void
+ {
+ var len:uint = arr.length;
+
+ for(var i:Number = len; i > -1; i--)
+ {
+ if(arr[i] === value)
+ {
+ arr.splice(i, 1);
+ }
+ }
+ }
+
+ /**
+ * Create a new array that only contains unique instances of objects
+ * in the specified array.
+ *
+ * Basically, this can be used to remove duplication object instances
+ * from an array
+ *
+ * @param arr The array which contains the values that will be used to
+ * create the new array that contains no duplicate values.
+ *
+ * @return A new array which only contains unique items from the specified
+ * array.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function createUniqueCopy(a:Array):Array
+ {
+ var newArray:Array = new Array();
+
+ var len:Number = a.length;
+ var item:Object;
+
+ for (var i:uint = 0; i < len; ++i)
+ {
+ item = a[i];
+
+ if(ArrayUtil.arrayContainsValue(newArray, item))
+ {
+ continue;
+ }
+
+ newArray.push(item);
+ }
+
+ return newArray;
+ }
+
+ /**
+ * Creates a copy of the specified array.
+ *
+ * Note that the array returned is a new array but the items within the
+ * array are not copies of the items in the original array (but rather
+ * references to the same items)
+ *
+ * @param arr The array that will be copies
+ *
+ * @return A new array which contains the same items as the array passed
+ * in.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function copyArray(arr:Array):Array
+ {
+ return arr.slice();
+ }
+
+ /**
+ * Compares two arrays and returns a boolean indicating whether the arrays
+ * contain the same values at the same indexes.
+ *
+ * @param arr1 The first array that will be compared to the second.
+ *
+ * @param arr2 The second array that will be compared to the first.
+ *
+ * @return True if the arrays contains the same values at the same indexes.
+ False if they do not.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function arraysAreEqual(arr1:Array, arr2:Array):Boolean
+ {
+ if(arr1.length != arr2.length)
+ {
+ return false;
+ }
+
+ var len:Number = arr1.length;
+
+ for(var i:Number = 0; i < len; i++)
+ {
+ if(arr1[i] !== arr2[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/webcam/com/adobe/utils/IntUtil.as b/webcam/com/adobe/utils/IntUtil.as
index 6b677ef..591edc0 100644
--- a/webcam/com/adobe/utils/IntUtil.as
+++ b/webcam/com/adobe/utils/IntUtil.as
@@ -1,69 +1,69 @@
-
-package com.adobe.utils {
-
- import flash.utils.Endian;
-
- /**
- * Contains reusable methods for operations pertaining
- * to int values.
- */
- public class IntUtil {
-
- /**
- * Rotates x left n bits
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function rol ( x:int, n:int ):int {
- return ( x << n ) | ( x >>> ( 32 - n ) );
- }
-
- /**
- * Rotates x right n bits
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function ror ( x:int, n:int ):uint {
- var nn:int = 32 - n;
- return ( x << nn ) | ( x >>> ( 32 - nn ) );
- }
-
- /** String for quick lookup of a hex character based on index */
- private static var hexChars:String = "0123456789abcdef";
-
- /**
- * Outputs the hex value of a int, allowing the developer to specify
- * the endinaness in the process. Hex output is lowercase.
- *
- * @param n The int value to output as hex
- * @param bigEndian Flag to output the int as big or little endian
- * @return A string of length 8 corresponding to the
- * hex representation of n ( minus the leading "0x" )
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function toHex( n:int, bigEndian:Boolean = false ):String {
- var s:String = "";
-
- if ( bigEndian ) {
- for ( var i:int = 0; i < 4; i++ ) {
- s += hexChars.charAt( ( n >> ( ( 3 - i ) * 8 + 4 ) ) & 0xF )
- + hexChars.charAt( ( n >> ( ( 3 - i ) * 8 ) ) & 0xF );
- }
- } else {
- for ( var x:int = 0; x < 4; x++ ) {
- s += hexChars.charAt( ( n >> ( x * 8 + 4 ) ) & 0xF )
- + hexChars.charAt( ( n >> ( x * 8 ) ) & 0xF );
- }
- }
-
- return s;
- }
- }
-
+
+package com.adobe.utils {
+
+ import flash.utils.Endian;
+
+ /**
+ * Contains reusable methods for operations pertaining
+ * to int values.
+ */
+ public class IntUtil {
+
+ /**
+ * Rotates x left n bits
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function rol ( x:int, n:int ):int {
+ return ( x << n ) | ( x >>> ( 32 - n ) );
+ }
+
+ /**
+ * Rotates x right n bits
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function ror ( x:int, n:int ):uint {
+ var nn:int = 32 - n;
+ return ( x << nn ) | ( x >>> ( 32 - nn ) );
+ }
+
+ /** String for quick lookup of a hex character based on index */
+ private static var hexChars:String = "0123456789abcdef";
+
+ /**
+ * Outputs the hex value of a int, allowing the developer to specify
+ * the endinaness in the process. Hex output is lowercase.
+ *
+ * @param n The int value to output as hex
+ * @param bigEndian Flag to output the int as big or little endian
+ * @return A string of length 8 corresponding to the
+ * hex representation of n ( minus the leading "0x" )
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function toHex( n:int, bigEndian:Boolean = false ):String {
+ var s:String = "";
+
+ if ( bigEndian ) {
+ for ( var i:int = 0; i < 4; i++ ) {
+ s += hexChars.charAt( ( n >> ( ( 3 - i ) * 8 + 4 ) ) & 0xF )
+ + hexChars.charAt( ( n >> ( ( 3 - i ) * 8 ) ) & 0xF );
+ }
+ } else {
+ for ( var x:int = 0; x < 4; x++ ) {
+ s += hexChars.charAt( ( n >> ( x * 8 + 4 ) ) & 0xF )
+ + hexChars.charAt( ( n >> ( x * 8 ) ) & 0xF );
+ }
+ }
+
+ return s;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/webcam/com/adobe/utils/NumberFormatter.as b/webcam/com/adobe/utils/NumberFormatter.as
index 60b9667..53b2501 100644
--- a/webcam/com/adobe/utils/NumberFormatter.as
+++ b/webcam/com/adobe/utils/NumberFormatter.as
@@ -1,77 +1,77 @@
-/*
- Adobe Systems Incorporated(r) Source Code License Agreement
- Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
- Please read this Source Code License Agreement carefully before using
- the source code.
-
- Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
- no-charge, royalty-free, irrevocable copyright license, to reproduce,
- prepare derivative works of, publicly display, publicly perform, and
- distribute this source code and such derivative works in source or
- object code form without any attribution requirements.
-
- The name "Adobe Systems Incorporated" must not be used to endorse or promote products
- derived from the source code without prior written permission.
-
- You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
- against any loss, damage, claims or lawsuits, including attorney's
- fees that arise or result from your use or distribution of the source
- code.
-
- THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
- ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
- NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
- OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.utils
-{
-
- /**
- * Class that contains static utility methods for formatting Numbers
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- *
- * @see #mx.formatters.NumberFormatter
- */
- public class NumberFormatter
- {
-
- /**
- * Formats a number to include a leading zero if it is a single digit
- * between -1 and 10.
- *
- * @param n The number that will be formatted
- *
- * @return A string with single digits between -1 and 10 padded with a
- * leading zero.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
- */
- public static function addLeadingZero(n:Number):String
- {
- var out:String = String(n);
-
- if(n < 10 && n > -1)
- {
- out = "0" + out;
- }
-
- return out;
- }
-
- }
+/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.utils
+{
+
+ /**
+ * Class that contains static utility methods for formatting Numbers
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ *
+ * @see #mx.formatters.NumberFormatter
+ */
+ public class NumberFormatter
+ {
+
+ /**
+ * Formats a number to include a leading zero if it is a single digit
+ * between -1 and 10.
+ *
+ * @param n The number that will be formatted
+ *
+ * @return A string with single digits between -1 and 10 padded with a
+ * leading zero.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function addLeadingZero(n:Number):String
+ {
+ var out:String = String(n);
+
+ if(n < 10 && n > -1)
+ {
+ out = "0" + out;
+ }
+
+ return out;
+ }
+
+ }
}
\ No newline at end of file
diff --git a/webcam/com/adobe/utils/XMLUtil.as b/webcam/com/adobe/utils/XMLUtil.as
index 1a902ef..8524a0b 100644
--- a/webcam/com/adobe/utils/XMLUtil.as
+++ b/webcam/com/adobe/utils/XMLUtil.as
@@ -1,171 +1,171 @@
-/*
- Adobe Systems Incorporated(r) Source Code License Agreement
- Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
- Please read this Source Code License Agreement carefully before using
- the source code.
-
- Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
- no-charge, royalty-free, irrevocable copyright license, to reproduce,
- prepare derivative works of, publicly display, publicly perform, and
- distribute this source code and such derivative works in source or
- object code form without any attribution requirements.
-
- The name "Adobe Systems Incorporated" must not be used to endorse or promote products
- derived from the source code without prior written permission.
-
- You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
- against any loss, damage, claims or lawsuits, including attorney's
- fees that arise or result from your use or distribution of the source
- code.
-
- THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
- ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
- NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
- OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.utils
-{
-
- public class XMLUtil
- {
- /**
- * Constant representing a text node type returned from XML.nodeKind.
- *
- * @see XML.nodeKind()
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static const TEXT:String = "text";
-
- /**
- * Constant representing a comment node type returned from XML.nodeKind.
- *
- * @see XML.nodeKind()
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static const COMMENT:String = "comment";
-
- /**
- * Constant representing a processing instruction type returned from XML.nodeKind.
- *
- * @see XML.nodeKind()
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static const PROCESSING_INSTRUCTION:String = "processing-instruction";
-
- /**
- * Constant representing an attribute type returned from XML.nodeKind.
- *
- * @see XML.nodeKind()
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static const ATTRIBUTE:String = "attribute";
-
- /**
- * Constant representing a element type returned from XML.nodeKind.
- *
- * @see XML.nodeKind()
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static const ELEMENT:String = "element";
-
- /**
- * Checks whether the specified string is valid and well formed XML.
- *
- * @param data The string that is being checked to see if it is valid XML.
- *
- * @return A Boolean value indicating whether the specified string is
- * valid XML.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static function isValidXML(data:String):Boolean
- {
- var xml:XML;
-
- try
- {
- xml = new XML(data);
- }
- catch(e:Error)
- {
- return false;
- }
-
- if(xml.nodeKind() != XMLUtil.ELEMENT)
- {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns the next sibling of the specified node relative to the node's parent.
- *
- * @param x The node whose next sibling will be returned.
- *
- * @return The next sibling of the node. null if the node does not have
- * a sibling after it, or if the node has no parent.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static function getNextSibling(x:XML):XML
- {
- return XMLUtil.getSiblingByIndex(x, 1);
- }
-
- /**
- * Returns the sibling before the specified node relative to the node's parent.
- *
- * @param x The node whose sibling before it will be returned.
- *
- * @return The sibling before the node. null if the node does not have
- * a sibling before it, or if the node has no parent.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public static function getPreviousSibling(x:XML):XML
- {
- return XMLUtil.getSiblingByIndex(x, -1);
- }
-
- protected static function getSiblingByIndex(x:XML, count:int):XML
- {
- var out:XML;
-
- try
- {
- out = x.parent().children()[x.childIndex() + count];
- }
- catch(e:Error)
- {
- return null;
- }
-
- return out;
- }
- }
+/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.utils
+{
+
+ public class XMLUtil
+ {
+ /**
+ * Constant representing a text node type returned from XML.nodeKind.
+ *
+ * @see XML.nodeKind()
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static const TEXT:String = "text";
+
+ /**
+ * Constant representing a comment node type returned from XML.nodeKind.
+ *
+ * @see XML.nodeKind()
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static const COMMENT:String = "comment";
+
+ /**
+ * Constant representing a processing instruction type returned from XML.nodeKind.
+ *
+ * @see XML.nodeKind()
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static const PROCESSING_INSTRUCTION:String = "processing-instruction";
+
+ /**
+ * Constant representing an attribute type returned from XML.nodeKind.
+ *
+ * @see XML.nodeKind()
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static const ATTRIBUTE:String = "attribute";
+
+ /**
+ * Constant representing a element type returned from XML.nodeKind.
+ *
+ * @see XML.nodeKind()
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static const ELEMENT:String = "element";
+
+ /**
+ * Checks whether the specified string is valid and well formed XML.
+ *
+ * @param data The string that is being checked to see if it is valid XML.
+ *
+ * @return A Boolean value indicating whether the specified string is
+ * valid XML.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static function isValidXML(data:String):Boolean
+ {
+ var xml:XML;
+
+ try
+ {
+ xml = new XML(data);
+ }
+ catch(e:Error)
+ {
+ return false;
+ }
+
+ if(xml.nodeKind() != XMLUtil.ELEMENT)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the next sibling of the specified node relative to the node's parent.
+ *
+ * @param x The node whose next sibling will be returned.
+ *
+ * @return The next sibling of the node. null if the node does not have
+ * a sibling after it, or if the node has no parent.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static function getNextSibling(x:XML):XML
+ {
+ return XMLUtil.getSiblingByIndex(x, 1);
+ }
+
+ /**
+ * Returns the sibling before the specified node relative to the node's parent.
+ *
+ * @param x The node whose sibling before it will be returned.
+ *
+ * @return The sibling before the node. null if the node does not have
+ * a sibling before it, or if the node has no parent.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public static function getPreviousSibling(x:XML):XML
+ {
+ return XMLUtil.getSiblingByIndex(x, -1);
+ }
+
+ protected static function getSiblingByIndex(x:XML, count:int):XML
+ {
+ var out:XML;
+
+ try
+ {
+ out = x.parent().children()[x.childIndex() + count];
+ }
+ catch(e:Error)
+ {
+ return null;
+ }
+
+ return out;
+ }
+ }
}
\ No newline at end of file
diff --git a/webcam/com/adobe/webapis/ServiceBase.as b/webcam/com/adobe/webapis/ServiceBase.as
index cbd7ac8..27ffbb0 100644
--- a/webcam/com/adobe/webapis/ServiceBase.as
+++ b/webcam/com/adobe/webapis/ServiceBase.as
@@ -1,51 +1,51 @@
-/*
- Adobe Systems Incorporated(r) Source Code License Agreement
- Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
- Please read this Source Code License Agreement carefully before using
- the source code.
-
- Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
- no-charge, royalty-free, irrevocable copyright license, to reproduce,
- prepare derivative works of, publicly display, publicly perform, and
- distribute this source code and such derivative works in source or
- object code form without any attribution requirements.
-
- The name "Adobe Systems Incorporated" must not be used to endorse or promote products
- derived from the source code without prior written permission.
-
- You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
- against any loss, damage, claims or lawsuits, including attorney's
- fees that arise or result from your use or distribution of the source
- code.
-
- THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
- ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
- NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
- OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-package com.adobe.webapis
-{
- import flash.events.EventDispatcher;
-
- /**
- * Base class for remote service classes.
- */
- public class ServiceBase extends EventDispatcher
- {
- public function ServiceBase()
- {
- }
-
- }
+/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+package com.adobe.webapis
+{
+ import flash.events.EventDispatcher;
+
+ /**
+ * Base class for remote service classes.
+ */
+ public class ServiceBase extends EventDispatcher
+ {
+ public function ServiceBase()
+ {
+ }
+
+ }
}
\ No newline at end of file
diff --git a/webcam/com/adobe/webapis/URLLoaderBase.as b/webcam/com/adobe/webapis/URLLoaderBase.as
index dad2b2c..41e7b33 100644
--- a/webcam/com/adobe/webapis/URLLoaderBase.as
+++ b/webcam/com/adobe/webapis/URLLoaderBase.as
@@ -1,111 +1,111 @@
-/*
- Adobe Systems Incorporated(r) Source Code License Agreement
- Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
- Please read this Source Code License Agreement carefully before using
- the source code.
-
- Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
- no-charge, royalty-free, irrevocable copyright license, to reproduce,
- prepare derivative works of, publicly display, publicly perform, and
- distribute this source code and such derivative works in source or
- object code form without any attribution requirements.
-
- The name "Adobe Systems Incorporated" must not be used to endorse or promote products
- derived from the source code without prior written permission.
-
- You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
- against any loss, damage, claims or lawsuits, including attorney's
- fees that arise or result from your use or distribution of the source
- code.
-
- THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
- ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
- NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
- OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.webapis
-{
- import flash.events.IOErrorEvent;
- import flash.events.SecurityErrorEvent;
- import flash.events.ProgressEvent;
-
- import com.adobe.net.DynamicURLLoader;
-
- /**
- * Dispatched when data is
- * received as the download operation progresses.
- *
- * @eventType flash.events.ProgressEvent.PROGRESS
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- [Event(name="progress", type="flash.events.ProgressEvent")]
-
- /**
- * Dispatched if a call to the server results in a fatal
- * error that terminates the download.
- *
- * @eventType flash.events.IOErrorEvent.IO_ERROR
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- [Event(name="ioError", type="flash.events.IOErrorEvent")]
-
- /**
- * A securityError event occurs if a call attempts to
- * load data from a server outside the security sandbox.
- *
- * @eventType flash.events.SecurityErrorEvent.SECURITY_ERROR
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- [Event(name="securityError", type="flash.events.SecurityErrorEvent")]
-
- /**
- * Base class for services that utilize URLLoader
- * to communicate with remote APIs / Services.
- *
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- */
- public class URLLoaderBase extends ServiceBase
- {
- protected function getURLLoader():DynamicURLLoader
- {
- var loader:DynamicURLLoader = new DynamicURLLoader();
- loader.addEventListener("progress", onProgress);
- loader.addEventListener("ioError", onIOError);
- loader.addEventListener("securityError", onSecurityError);
-
- return loader;
- }
-
- private function onIOError(event:IOErrorEvent):void
- {
- dispatchEvent(event);
- }
-
- private function onSecurityError(event:SecurityErrorEvent):void
- {
- dispatchEvent(event);
- }
-
- private function onProgress(event:ProgressEvent):void
- {
- dispatchEvent(event);
- }
- }
+/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.adobe.webapis
+{
+ import flash.events.IOErrorEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.events.ProgressEvent;
+
+ import com.adobe.net.DynamicURLLoader;
+
+ /**
+ * Dispatched when data is
+ * received as the download operation progresses.
+ *
+ * @eventType flash.events.ProgressEvent.PROGRESS
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ [Event(name="progress", type="flash.events.ProgressEvent")]
+
+ /**
+ * Dispatched if a call to the server results in a fatal
+ * error that terminates the download.
+ *
+ * @eventType flash.events.IOErrorEvent.IO_ERROR
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ [Event(name="ioError", type="flash.events.IOErrorEvent")]
+
+ /**
+ * A securityError event occurs if a call attempts to
+ * load data from a server outside the security sandbox.
+ *
+ * @eventType flash.events.SecurityErrorEvent.SECURITY_ERROR
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ [Event(name="securityError", type="flash.events.SecurityErrorEvent")]
+
+ /**
+ * Base class for services that utilize URLLoader
+ * to communicate with remote APIs / Services.
+ *
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ */
+ public class URLLoaderBase extends ServiceBase
+ {
+ protected function getURLLoader():DynamicURLLoader
+ {
+ var loader:DynamicURLLoader = new DynamicURLLoader();
+ loader.addEventListener("progress", onProgress);
+ loader.addEventListener("ioError", onIOError);
+ loader.addEventListener("securityError", onSecurityError);
+
+ return loader;
+ }
+
+ private function onIOError(event:IOErrorEvent):void
+ {
+ dispatchEvent(event);
+ }
+
+ private function onSecurityError(event:SecurityErrorEvent):void
+ {
+ dispatchEvent(event);
+ }
+
+ private function onProgress(event:ProgressEvent):void
+ {
+ dispatchEvent(event);
+ }
+ }
}
\ No newline at end of file
diff --git a/webcam/com/adobe/webapis/events/ServiceEvent.as b/webcam/com/adobe/webapis/events/ServiceEvent.as
index d83ab25..5ed5737 100644
--- a/webcam/com/adobe/webapis/events/ServiceEvent.as
+++ b/webcam/com/adobe/webapis/events/ServiceEvent.as
@@ -1,78 +1,78 @@
-/*
- Adobe Systems Incorporated(r) Source Code License Agreement
- Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
-
- Please read this Source Code License Agreement carefully before using
- the source code.
-
- Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
- no-charge, royalty-free, irrevocable copyright license, to reproduce,
- prepare derivative works of, publicly display, publicly perform, and
- distribute this source code and such derivative works in source or
- object code form without any attribution requirements.
-
- The name "Adobe Systems Incorporated" must not be used to endorse or promote products
- derived from the source code without prior written permission.
-
- You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
- against any loss, damage, claims or lawsuits, including attorney's
- fees that arise or result from your use or distribution of the source
- code.
-
- THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
- ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
- NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
- OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-package com.adobe.webapis.events
-{
-
- import flash.events.Event;
-
- /**
- * Event class that contains data loaded from remote services.
- *
- * @author Mike Chambers
- */
- public class ServiceEvent extends Event
- {
- private var _data:Object = new Object();;
-
- /**
- * Constructor for ServiceEvent class.
- *
- * @param type The type of event that the instance represents.
- */
- public function ServiceEvent(type:String, bubbles:Boolean = false,
- cancelable:Boolean=false)
- {
- super(type, bubbles, cancelable);
- }
-
- /**
- * This object contains data loaded in response
- * to remote service calls, and properties associated with that call.
- */
- public function get data():Object
- {
- return _data;
- }
-
- public function set data(d:Object):void
- {
- _data = d;
- }
-
-
- }
+/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+package com.adobe.webapis.events
+{
+
+ import flash.events.Event;
+
+ /**
+ * Event class that contains data loaded from remote services.
+ *
+ * @author Mike Chambers
+ */
+ public class ServiceEvent extends Event
+ {
+ private var _data:Object = new Object();;
+
+ /**
+ * Constructor for ServiceEvent class.
+ *
+ * @param type The type of event that the instance represents.
+ */
+ public function ServiceEvent(type:String, bubbles:Boolean = false,
+ cancelable:Boolean=false)
+ {
+ super(type, bubbles, cancelable);
+ }
+
+ /**
+ * This object contains data loaded in response
+ * to remote service calls, and properties associated with that call.
+ */
+ public function get data():Object
+ {
+ return _data;
+ }
+
+ public function set data(d:Object):void
+ {
+ _data = d;
+ }
+
+
+ }
}
\ No newline at end of file
--
cgit v1.2.3-70-g09d2