PageSourceSearch

https://aussiefloyd.com/ScriptResource.axd?d=uSlD7ZLmtJcFkWiBkobsq…ZBpH5-9HC80m949hDtDnnaH-9U4eo1A2&t=51e37521

js aussiefloyd.com collected 2026-10-02 06:16:15 UTC 131,220 bytes, 3,162 lines download raw bytes

1// Name:        Animation.Animations.debug.js
2// Assembly:    AjaxControlToolkit
3// Version:     4.1.7.1213
4// FileVersion: 4.1.7.1213
5// (c) 2010 CodePlex Foundation
6
7
8
9/// <reference name="MicrosoftAjax.debug.js" />
10/// <reference name="MicrosoftAjaxTimer.debug.js" />
11/// <reference name="MicrosoftAjaxWebForms.debug.js" />
12/// <reference path="../Compat/Timer/Timer.js" />
13/// <reference path="../Common/Common.js" />
14
15(function() {
16var scriptName = "ExtendedAnimations";
17
18function execute() {
19
20Type.registerNamespace('Sys.Extended.UI.Animation');
21
22$AA = Sys.Extended.UI.Animation;
23
24$AA.registerAnimation = function(name, type) {
25    /// <summary>
26    /// Register an animation with the AJAX Control Toolkit animation framework. This serves a dual purpose:
27    /// 1) to add standard utility methods to the animation type (such as a <code>play</code> method that creates
28    /// an animation, plays it, and disposes it when the animation is over), and 2) to associate a name with the
29    /// type that will be used when creating animations from a JSON description.  This method can also be called
30    /// by other animation libraries to seamlessly interoperate with the AJAX Control Toolkit's animation
31    /// framework.
32    /// </summary>
33    /// <param name="name" type="String">
34    /// Name of the animation that will be used as the XML tag name in the XML animation description.  It
35    /// should be a valid XML tag (i.e. an alpha-numeric sequence with no spaces, special characters, etc.).
36    /// </param>
37    /// <param name="type" type="Type">
38    /// The type of the new animation must inherit from <see cref="Sys.Extended.UI.Animation.Animation" />.
39    /// </param>
40    /// <returns />
41
42    if (type && ((type === $AA.Animation) || (type.inheritsFrom && type.inheritsFrom($AA.Animation)))) {
43        if (!$AA.__animations) {
44            $AA.__animations = { };
45        }
46        
47        $AA.__animations[name.toLowerCase()] = type;
48        
49        type.play = function() {
50            /// <summary>
51            /// Create an animation, play it immediately, and dispose it when finished.
52            /// </summary>
53            /// <param parameterArray="true" elementType="Object">
54            /// The play function takes the same parameters as the type's constructor
55            /// </param>
56            /// <returns />
57        
58            var animation = new type();
59            type.apply(animation, arguments);
60            animation.initialize();
61            
62            var handler = Function.createDelegate(animation,
63                function() {
64                    /// <summary>
65                    /// Dispose the animation after playing
66                    /// </summary>
67                    /// <returns />
68                    animation.remove_ended(handler);
69                    handler = null;
70                    animation.dispose();
71                });
72            animation.add_ended(handler);
73            
74            animation.play();            
75        }
76    } else {
77        throw Error.argumentType('type', type, $AA.Animation, Sys.Extended.UI.Resources.Animation_InvalidBaseType);
78    }
79}
80
81$AA.buildAnimation = function(json, defaultTarget) {
82    /// <summary>
83    /// The <code>buildAnimation</code> function is used to turn a JSON animation description
84    /// into an actual animation object that can be played.
85    /// </summary>
86    /// <param name="json" type="String" mayBeNull="true">
87    /// JSON description of the animation in the format expected by createAnimation
88    /// </param>
89    /// <param name="defaultTarget" type="Sys.UI.DomElement" mayBeNull="true" domElement="true">
90    /// Target of the animation if none is specified in the JSON description.  The semantics of
91    /// target assignment are provided in more detail in createAnimation.
92    /// </param>
93    /// <returns type="Sys.Extended.UI.Animation.Animation" mayBeNull="true">
94    /// Animation created from the JSON description
95    /// </returns>
96    
97    if (!json || json === '') {
98        return null;
99    }
100
101    var obj;
102    json = '(' + json + ')';
103    if (! Sys.Debug.isDebug) {
104        try { obj = Sys.Serialization.JavaScriptSerializer.deserialize(json); } catch (ex) { } 
105    } else {
106        obj = Sys.Serialization.JavaScriptSerializer.deserialize(json);
107    }
108    
109    return $AA.createAnimation(obj, defaultTarget);    
110}
111
112$AA.createAnimation = function(obj, defaultTarget) {
113    /// <summary>
114    /// The <code>createAnimation</code> function builds a new
115    /// <see cref="Sys.Extended.UI.Animation.Animation" /> instance from an object
116    /// that describes it.
117    /// </summary>
118    /// <param name="obj" type="Object">
119    /// The object provides a description of the animation to be be generated in
120    /// a very specific format. It has two special properties: <code>AnimationName</code>
121    /// and <code>AnimationChildren</code>.  The <code>AnimationName</code> is required
122    /// and used to find the type of animation to create (this name should map to
123    /// one of the animation names supplied to <code>registerAnimation</code>).  The
124    /// <code>AnimationChildren</code> property supplies an optional array for
125    /// animations that use child animations (such as
126    /// <see cref="Sys.Extended.UI.Animation.ParallelAnimation" /> and
127    /// <see cref="Sys.Extended.UI.Animation.SequenceAnimation" />). The elements of
128    /// the <code>AnimationChildren</code> array are valid
129    /// <see cref="Sys.Extended.UI.Animation.Animation" /> objects that meet these same
130    /// requirements.  In order for an animation to support child animations, it must
131    /// derive from the <see cref="Sys.Extended.UI.Animation.ParentAnimation" /> class
132    /// which provides common methods like <code>add</code>, <code>clear</code>, etc. The
133    /// remaining properties of the object are used to set parameters specific to the type
134    /// of animation being created (e.g. <code>duration</code>, <code>minimumOpacity</code>,
135    /// <code>startValue</code>, etc.) and should have a corresponding property on the
136    /// animation.  You can also assign an arbitrary JavaScript expression to any property
137    /// by adding 'Script' to the end of its name (i.e., Height="70" can be replaced by
138    /// HeightScript="$get('myElement').offsetHeight") and have the property set to the
139    /// result of evaluating the expression before the animation is played each time.
140    /// </param>
141    /// <param name="defaultTarget" type="Sys.UI.DomElement" mayBeNull="true" domElement="true">
142    /// The function also takes a <code>defaultTarget</code> parameter that is used as the
143    /// target of the animation if the object does not specify one.  This parameter should be
144    /// an instance of <see cref="Sys.UI.DomElement" /> and not just the name of an element.
145    /// </param>
146    /// <returns type="Sys.Extended.UI.Animation.Animation">
147    /// <see cref="Sys.Extended.UI.Animation.Animation" /> created from the description
148    /// </returns>
149    /// <remarks>
150    /// Exceptions are thrown when the <code>AnimationName</code> cannot be found.  Also,
151    /// any exceptions raised by setting properties or providing properties with invalid
152    /// names will only be raised when debugging.
153    /// </remarks>
154
155    if (!obj || !obj.AnimationName) {
156        throw Error.argument('obj', Sys.Extended.UI.Resources.Animation_MissingAnimationName);
157    }
158    var type = $AA.__animations[obj.AnimationName.toLowerCase()];
159    if (!type) {
160        throw Error.argument('type', String.format(Sys.Extended.UI.Resources.Animation_UknownAnimationName, obj.AnimationName));
161    }
162    var animation = new type();
163    
164    if (defaultTarget) {
165        animation.set_target(defaultTarget);
166    }
167    
168    if (obj.AnimationChildren && obj.AnimationChildren.length) {
169        if ($AA.ParentAnimation.isInstanceOfType(animation)) {
170            for (var i = 0; i < obj.AnimationChildren.length; i++) {
171                var child = $AA.createAnimation(obj.AnimationChildren[i]);
172                if (child) {
173                    animation.add(child);
174                }
175            }
176        } else {
177            throw Error.argument('obj', String.format(Sys.Extended.UI.Resources.Animation_ChildrenNotAllowed, type.getName()));
178        }
179    }
180    
181    var properties = type.__animationProperties;
182    if (!properties) {
183        type.__animationProperties = { };
184        type.resolveInheritance();
185        for (var name in type.prototype) {
186            if (name.startsWith('set_')) {
187                type.__animationProperties[name.substr(4).toLowerCase()] = name;
188            }
189        }
190        
191        delete type.__animationProperties['id'];
192        properties = type.__animationProperties;
193    }
194    
195    for (var property in obj) {
196        var prop = property.toLowerCase();
197        if (prop == 'animationname' || prop == 'animationchildren') {
198            continue;
199        }
200        
201        var value = obj[property];
202        
203        var setter = properties[prop];
204        if (setter && String.isInstanceOfType(setter) && animation[setter]) {
205            if (! Sys.Debug.isDebug) {
206                try { animation[setter](value); } catch (ex) { }
207            } else {
208                animation[setter](value);
209            }
210        } else {
211            if (prop.endsWith('script')) {
212                setter = properties[prop.substr(0, property.length - 6)];
213                if (setter && String.isInstanceOfType(setter) && animation[setter]) {
214                    animation.DynamicProperties[setter] = value;
215                } else if ( Sys.Debug.isDebug) {
216                    throw Error.argument('obj', String.format(Sys.Extended.UI.Resources.Animation_NoDynamicPropertyFound, property, property.substr(0, property.length - 5)));
217                }
218            } else if ( Sys.Debug.isDebug) {
219                throw Error.argument('obj', String.format(Sys.Extended.UI.Resources.Animation_NoPropertyFound, property));
220            }
221        }
222    }
223    
224    return animation;
225}
226
227
228
229
230$AA.Animation = function(target, duration, fps) {
231    /// <summary>
232    /// <code>Animation</code> is an abstract base class used as a starting point for all the other animations.
233    /// It provides the basic mechanics for the animation (playing, pausing, stopping, timing, etc.)
234    /// and leaves the actual animation to be done in the abstract methods <code>getAnimatedValue</code>
235    /// and <code>setValue</code>.
236    /// </summary>
237    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
238    /// Target of the animation
239    /// </param>
240    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
241    /// Length of the animation in seconds.  The default is 1.
242    /// </param>
243    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
244    /// Number of steps per second.  The default is 25.
245    /// </param>
246    /// <field name="DynamicProperties" type="Object">
247    /// The DynamicProperties collection is used to associate JavaScript expressions with
248    /// properties.  The expressions are evaluated just before the animation is played
249    /// everytime (in the base onStart method).  The object itself maps strings with the
250    /// names of property setters (like "set_verticalOffset") to JavaScript expressions
251    /// (like "$find('MyBehavior').get_element().offsetHeight").  Note specifically that
252    /// the dynamic properties are JavaScript expressions and not abitrary statements (i.e.
253    /// you can't include things like "return foo;"), although you can include anything
254    /// inside an anonymous function definition that you immediately invoke (i.e.,
255    /// "(function() { return foo; })()").  A dynamic property can be set in the generic
256    /// XML animation description by appending Script onto any legitimate property name
257    /// (for example, instead of Height="70" we could use
258    /// HeightScript="$find('MyBehavior').get_element().offsetHeight").  Any exceptions
259    /// raised when setting dynamic properties (including both JavaScript evaluation errors
260    /// and other exceptions raised by property setters) will only be propogated when
261    /// debugging.
262    /// </field>
263    /// <remarks>
264    /// Animations need to be as fast as possible - even in debug mode.  Don't add validation code to
265    /// methods involved in every step of the animation.
266    /// </remarks>
267    /// <animation>Animation</animation>
268    $AA.Animation.initializeBase(this);
269    
270    this._duration = 1;
271    
272    this._fps = 25;
273    
274    this._target = null;
275    
276    this._tickHandler = null;
277    
278    this._timer = null;
279    
280    this._percentComplete = 0;
281    
282    this._percentDelta = null;
283    
284    this._owner = null;
285    
286    this._parentAnimation = null;
287    
288    this.DynamicProperties = { };
289    
290    if (target) {
291        this.set_target(target);
292    }
293    if (duration) {
294        this.set_duration(duration);
295    }
296    if (fps) { 
297        this.set_fps(fps);
298    }
299}
300$AA.Animation.prototype = {
301    dispose: function() {
302        /// <summary>
303        /// Dispose the animation
304        /// </summary>
305        /// <returns />
306
307        if (this._timer) {
308            this._timer.dispose();
309            this._timer = null;
310        }
311
312        this._tickHandler = null;
313        this._target = null;
314
315        $AA.Animation.callBaseMethod(this, 'dispose');
316    },
317
318    play: function() {
319        /// <summary>
320        /// Play the animation from the beginning or where it was left off when paused.
321        /// </summary>
322        /// <returns />
323        /// <remarks>
324        /// If this animation is the child of another, you must call <code>play</code> on its parent instead.
325        /// </remarks>
326
327        if (!this._owner) {
328            var resume = true;
329            if (!this._timer) {
330                resume = false;
331
332                if (!this._tickHandler) {
333                    this._tickHandler = Function.createDelegate(this, this._onTimerTick);
334                }
335
336                this._timer = new Sys.Timer();
337                this._timer.add_tick(this._tickHandler);
338
339                this.onStart();
340
341                this._timer.set_interval(1000 / this._fps);
342                this._percentDelta = 100 / (this._duration * this._fps);
343                this._updatePercentComplete(0, true);
344            }
345
346            this._timer.set_enabled(true);
347
348            this.raisePropertyChanged('isPlaying');
349            if (!resume) {
350                this.raisePropertyChanged('isActive');
351            }
352        }
353    },
354
355    pause: function() {
356        /// <summary>
357        /// Pause the animation if it is playing.  Calling <code>play</code> will resume where
358        /// the animation left off.
359        /// </summary>
360        /// <returns />
361        /// <remarks>
362        /// If this animation is the child of another, you must call <code>pause</code> on its parent instead.
363        /// </remarks>
364
365        if (!this._owner) {
366            if (this._timer) {
367                this._timer.set_enabled(false);
368
369                this.raisePropertyChanged('isPlaying');
370            }
371        }
372    },
373
374    stop: function(finish) {
375        /// <summary>
376        /// Stop playing the animation.
377        /// </summary>
378        /// <param name="finish" type="Boolean" mayBeNull="true" optional="true">
379        /// Whether or not stopping the animation should leave the target element in a state
380        /// consistent with the animation playing completely by performing the last step.
381        /// The default value is true.
382        /// </param>
383        /// <returns />
384        /// <remarks>
385        /// If this animation is the child of another, you must call <code>stop</code> on
386        /// its parent instead.
387        /// </remarks>
388
389        if (!this._owner) {
390            var t = this._timer;
391            this._timer = null;
392            if (t) {
393                t.dispose();
394
395                if (this._percentComplete !== 100) {
396                    this._percentComplete = 100;
397                    this.raisePropertyChanged('percentComplete');
398                    if (finish || finish === undefined) {
399                        this.onStep(100);
400                    }
401                }
402                this.onEnd();
403
404                this.raisePropertyChanged('isPlaying');
405                this.raisePropertyChanged('isActive');
406            }
407        }
408    },
409
410    onStart: function() {
411        /// <summary>
412        /// The <code>onStart</code> method is called just before the animation is played each time.
413        /// </summary>
414        /// <returns />
415
416        this.raiseStarted();
417
418        for (var property in this.DynamicProperties) {
419            try {
420                this[property](eval(this.DynamicProperties[property]));
421            } catch (ex) {
422                if (Sys.Debug.isDebug) {
423                    throw ex;
424                }
425            }
426        }
427    },
428
429    onStep: function(percentage) {
430        /// <summary>
431        /// The <code>onStep</code> method is called repeatedly to progress the animation through each frame
432        /// </summary>
433        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
434        /// <returns />
435
436        this.setValue(this.getAnimatedValue(percentage));
437        this.raiseStep();
438    },
439
440    onEnd: function() {
441        /// <summary>
442        /// The <code>onEnd</code> method is called just after the animation is played each time.
443        /// </summary>
444        /// <returns />
445
446        this.raiseEnded();
447    },
448
449    getAnimatedValue: function(percentage) {
450        /// <summary>
451        /// Determine the state of the animation after the given percentage of its duration has elapsed
452        /// </summary>
453        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
454        /// <returns type="Object">
455        /// State of the animation after the given percentage of its duration has elapsed that will
456        /// be passed to <code>setValue</code>
457        /// </returns>
458        throw Error.notImplemented();
459    },
460
461    setValue: function(value) {
462        /// <summary>
463        /// Set the current state of the animation
464        /// </summary>
465        /// <param name="value" type="Object">Current state of the animation (as retreived from <code>getAnimatedValue</code>)</param>
466        /// <returns />
467        throw Error.notImplemented();
468    },
469
470    interpolate: function(start, end, percentage) {
471        /// <summary>
472        /// The <code>interpolate</code> function is used to find the appropriate value between starting and
473        /// ending values given the current percentage.
474        /// </summary>
475        /// <param name="start" type="Number">
476        /// Start of the range to interpolate
477        /// </param>
478        /// <param name="end" type="Number">
479        /// End of the range to interpolate
480        /// </param>
481        /// <param name="percentage" type="Number">
482        /// Percentage completed in the range to interpolate
483        /// </param>
484        /// <returns type="Number">
485        /// Value the desired percentage between the start and end values
486        /// </returns>
487        /// <remarks>
488        /// In the future, we hope to make several implementations of this available so we can dynamically
489        /// change the apparent speed of the animations, although it may make more sense to modify the
490        /// <code>_updatePercentComplete</code> function instead.
491        /// </remarks>
492        return start + (end - start) * (percentage / 100);
493    },
494
495    _onTimerTick: function() {
496        /// <summary>
497        /// Handler for the tick event to move the animation along through its duration
498        /// </summary>
499        /// <returns />
500        this._updatePercentComplete(this._percentComplete + this._percentDelta, true);
501    },
502
503    _updatePercentComplete: function(percentComplete, animate) {
504        /// <summary>
505        /// Update the animation and its target given the current percentage of its duration that
506        /// has already elapsed
507        /// </summary>
508        /// <param name="percentComplete" type="Number">
509        /// Percentage of the animation duration that has already elapsed
510        /// </param>
511        /// <param name="animate" type="Boolean" mayBeNull="true" optional="true">
512        /// Whether or not updating the animation should visually modify the animation's target
513        /// </param>
514        /// <returns />
515
516        if (percentComplete > 100) {
517            percentComplete = 100;
518        }
519
520        this._percentComplete = percentComplete;
521        this.raisePropertyChanged('percentComplete');
522
523        if (animate) {
524            this.onStep(percentComplete);
525        }
526
527        if (percentComplete === 100) {
528            this.stop(false);
529        }
530    },
531
532    setOwner: function(owner) {
533        /// <summary>
534        /// Make this animation the child of another animation
535        /// </summary>
536        /// <param name="owner" type="Sys.Extended.UI.Animation.Animation">
537        /// Parent animation
538        /// </param>
539        /// <returns />
540        this._owner = owner;
541    },
542
543    raiseStarted: function() {
544        /// <summary>
545        /// Raise the <code>started</code> event
546        /// </summary>
547        /// <returns />
548        var handlers = this.get_events().getHandler('started');
549        if (handlers) {
550            handlers(this, Sys.EventArgs.Empty);
551        }
552    },
553
554    add_started: function(handler) {
555        /// <summary>
556        /// Adds an event handler for the <code>started</code> event.
557        /// </summary>
558        /// <param name="handler" type="Function">
559        /// The handler to add to the event.
560        /// </param>
561        /// <returns />
562        this.get_events().addHandler("started", handler);
563    },
564
565    remove_started: function(handler) {
566        /// <summary>
567        /// Removes an event handler for the <code>started</code> event.
568        /// </summary>
569        /// <param name="handler" type="Function">
570        /// The handler to remove from the event.
571        /// </param>
572        /// <returns />
573        this.get_events().removeHandler("started", handler);
574    },
575
576    raiseEnded: function() {
577        /// <summary>
578        /// Raise the <code>ended</code> event
579        /// </summary>
580        /// <returns />
581        var handlers = this.get_events().getHandler('ended');
582        if (handlers) {
583            handlers(this, Sys.EventArgs.Empty);
584        }
585    },
586
587    add_ended: function(handler) {
588        /// <summary>
589        /// Adds an event handler for the <code>ended</code> event.
590        /// </summary>
591        /// <param name="handler" type="Function">
592        /// The handler to add to the event.
593        /// </param>
594        /// <returns />
595        this.get_events().addHandler("ended", handler);
596    },
597
598    remove_ended: function(handler) {
599        /// <summary>
600        /// Removes an event handler for the <code>ended</code> event.
601        /// </summary>
602        /// <param name="handler" type="Function">
603        /// The handler to remove from the event.
604        /// </param>
605        /// <returns />
606        this.get_events().removeHandler("ended", handler);
607    },
608
609    raiseStep: function() {
610        /// <summary>
611        /// Raise the <code>step</code> event
612        /// </summary>
613        /// <returns />
614        var handlers = this.get_events().getHandler('step');
615        if (handlers) {
616            handlers(this, Sys.EventArgs.Empty);
617        }
618    },
619
620    add_step: function(handler) {
621        /// <summary>
622        /// Adds an event handler for the <code>step</code> event.
623        /// </summary>
624        /// <param name="handler" type="Function">
625        /// The handler to add to the event.
626        /// </param>
627        /// <returns />
628        this.get_events().addHandler("step", handler);
629    },
630
631    remove_step: function(handler) {
632        /// <summary>
633        /// Removes an event handler for the <code>step</code> event.
634        /// </summary>
635        /// <param name="handler" type="Function">
636        /// The handler to remove from the event.
637        /// </param>
638        /// <returns />
639        this.get_events().removeHandler("step", handler);
640    },
641
642    get_target: function() {
643        /// <value type="Sys.UI.DomElement" domElement="true" mayBeNull="true">
644        /// Target of the animation.  If the target of this animation is null and
645        /// the animation has a parent, then it will recursively use the target of
646        /// the parent animation instead.
647        /// </value>
648        /// <remarks>
649        /// Do not set this property in a generic Xml animation description. It should be set
650        /// using either the extender's TargetControlID or the AnimationTarget property (the latter
651        /// maps to Sys.Extended.UI.Animation.set_animationTarget).  The only valid way to
652        /// set this property in the generic Xml animation description is to use the dynamic
653        /// property TargetScript="$get('myElement')".
654        /// <remarks>
655        if (!this._target && this._parentAnimation) {
656            return this._parentAnimation.get_target();
657        }
658        return this._target;
659    },
660    set_target: function(value) {
661        if (this._target != value) {
662            this._target = value;
663            this.raisePropertyChanged('target');
664        }
665    },
666
667    set_animationTarget: function(id) {
668        /// <value type="string" mayBeNull="false">
669        /// ID of a Sys.UI.DomElement or Sys.UI.Control to use as the target of the animation
670        /// </value>
671        /// <remarks>
672        /// If no Sys.UI.DomElement or Sys.UI.Control can be found for the given ID, an
673        /// argument exception will be thrown.
674        /// <remarks>
675
676        var target = null;
677        var element = $get(id);
678        if (element) {
679            target = element;
680        } else {
681            var ctrl = $find(id);
682            if (ctrl) {
683                element = ctrl.get_element();
684                if (element) {
685                    target = element;
686                }
687            }
688        }
689
690        if (target) {
691            this.set_target(target);
692        } else {
693            throw Error.argument('id', String.format(Sys.Extended.UI.Resources.Animation_TargetNotFound, id));
694        }
695    },
696
697    get_duration: function() {
698        /// <value type="Number">
699        /// Length of the animation in seconds.  The default is 1.
700        /// </value>
701        return this._duration;
702    },
703    set_duration: function(value) {
704        value = this._getFloat(value);
705        if (this._duration != value) {
706            this._duration = value;
707            this.raisePropertyChanged('duration');
708        }
709    },
710
711    get_fps: function() {
712        /// <value type="Number" integer="true">
713        /// Number of steps per second.  The default is 25.
714        /// </value>
715        return this._fps;
716    },
717    set_fps: function(value) {
718        value = this._getInteger(value);
719        if (this.fps != value) {
720            this._fps = value;
721            this.raisePropertyChanged('fps');
722        }
723    },
724
725    get_isActive: function() {
726        /// <value type="Boolean">
727        /// <code>true</code> if animation is active, <code>false</code> if not.
728        /// </value>
729        return (this._timer !== null);
730    },
731
732    get_isPlaying: function() {
733        /// <value type="Boolean">
734        /// <code>true</code> if animation is playing, <code>false</code> if not.
735        /// </value>
736        return (this._timer !== null) && this._timer.get_enabled();
737    },
738
739    get_percentComplete: function() {
740        /// <value type="Number">
741        /// Percentage of the animation already played.
742        /// </value>
743        return this._percentComplete;
744    },
745
746    _getBoolean: function(value) {
747        /// <summary>
748        /// Helper to convert strings to booleans for property setters
749        /// </summary>
750        /// <param name="value" type="Object">
751        /// Value to convert if it's a string
752        /// </param>
753        /// <returns type="Object">
754        /// Value that has been converted if it was a string
755        /// </returns>
756        if (String.isInstanceOfType(value)) {
757            return Boolean.parse(value);
758        }
759        return value;
760    },
761
762    _getInteger: function(value) {
763        /// <summary>
764        /// Helper to convert strings to integers for property setters
765        /// </summary>
766        /// <param name="value" type="Object">Value to convert if it's a string</param>
767        /// <returns type="Object">Value that has been converted if it was a string</returns>
768        if (String.isInstanceOfType(value)) {
769            return parseInt(value);
770        }
771        return value;
772    },
773
774    _getFloat: function(value) {
775        /// <summary>
776        /// Helper to convert strings to floats for property setters
777        /// </summary>
778        /// <param name="value" type="Object">Value to convert if it's a string</param>
779        /// <returns type="Object">Value that has been converted if it was a string</returns>
780        if (String.isInstanceOfType(value)) {
781            return parseFloat(value);
782        }
783        return value;
784    },
785
786    _getEnum: function(value, type) {
787        /// <summary>
788        /// Helper to convert strings to enum values for property setters
789        /// </summary>
790        /// <param name="value" type="Object">Value to convert if it's a string</param>
791        /// <param name="type" type="Type">Type of the enum to convert to</param>
792        /// <returns type="Object">Value that has been converted if it was a string</returns>
793        if (String.isInstanceOfType(value) && type && type.parse) {
794            return type.parse(value);
795        }
796        return value;
797    }
798}
799$AA.Animation.registerClass('Sys.Extended.UI.Animation.Animation', Sys.Component);
800$AA.registerAnimation('animation', $AA.Animation);
801
802
803$AA.ParentAnimation = function(target, duration, fps, animations) {
804    /// <summary>
805    /// The <code>ParentAnimation</code> serves as a base class for all animations that contain children (such as
806    /// <see cref="Sys.Extended.UI.Animation.ParallelAnimation" />, <see cref="Sys.Extended.UI.SequenceAnimation" />,
807    /// etc.).  It does not actually play the animations, so any classes that inherit from it must do so.  Any animation
808    /// that requires nested child animations must inherit from this class, although it will likely want to inherit off of
809    /// <see cref="Sys.Extended.UI.Animation.ParallelAnimation" /> or <see cref="Sys.Extended.UI.SequenceAnimation" />
810    /// which will actually play their child animations.
811    /// </summary>
812    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
813    /// Target of the animation
814    /// </param>
815    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
816    /// Length of the animation in seconds.  The default is 1.
817    /// </param>
818    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
819    /// Number of steps per second.  The default is 25.
820    /// </param>
821    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Sys.Extended.UI.Animation.Animation">
822    /// Array of child animations to be played
823    /// </param>
824    /// <animation>Parent</animation>
825    $AA.ParentAnimation.initializeBase(this, [target, duration, fps]);
826    
827    this._animations = [];
828    
829    if (animations && animations.length) {
830        for (var i = 0; i < animations.length; i++) {
831            this.add(animations[i]);
832        }
833    }
834}
835$AA.ParentAnimation.prototype = {
836    initialize : function() {
837    	/// <summary>
838        /// Initialize the parent along with any child animations that have not yet been initialized themselves
839    	/// </summary>
840    	/// <returns />
841        $AA.ParentAnimation.callBaseMethod(this, 'initialize');
842        
843        if (this._animations) {
844            for (var i = 0; i < this._animations.length; i++) {
845                var animation = this._animations[i];
846                if (animation && !animation.get_isInitialized) {
847                    animation.initialize();
848                }
849            }
850        }
851    },
852    
853    dispose : function() {
854    	/// <summary>
855        /// Dispose of the child animations
856    	/// </summary>
857    	/// <returns />
858
859        this.clear();
860        this._animations = null;
861        $AA.ParentAnimation.callBaseMethod(this, 'dispose');
862    },
863    
864    get_animations : function() {
865    	/// <value elementType="Sys.Extended.UI.Animation.Animation">
866        /// Array of child animations to be played (there are no assumptions placed on order because it will matter for some
867        /// derived animations like <see cref="Sys.Extended.UI.Animation.SequenceAnimation" />, but not for
868        /// others like <see cref="Sys.Extended.UI.Animation.ParallelAnimation" />).  To manipulate the child
869        /// animations, use the functions <code>add</code>, <code>clear</code>, <code>remove</code>, and <code>removeAt</code>.
870    	/// </value>
871        return this._animations;
872    },
873    
874    add : function(animation) {
875    	/// <summary>
876        /// Add an animation as a child of this animation.
877    	/// </summary>
878    	/// <param name="animation" type="Sys.Extended.UI.Animation.Animation">Child animation to add</param>
879    	/// <returns />
880
881        if (this._animations) {
882            if (animation) {
883                animation._parentAnimation = this;
884            }
885            Array.add(this._animations, animation);
886            this.raisePropertyChanged('animations');
887        }
888    },
889    
890    remove : function(animation) {
891        /// <summary>
892        /// Remove the animation from the array of child animations.
893        /// </summary>
894        /// <param name="animation" type="Sys.Extended.UI.Animation.Animation">
895        /// Child animation to remove
896        /// </param>
897        /// <returns />
898        /// <remarks>
899        /// This will dispose the removed animation.
900        /// </remarks>
901
902        if (this._animations) {
903            if (animation) {
904                animation.dispose();
905            }
906            Array.remove(this._animations, animation);
907            this.raisePropertyChanged('animations');
908        }
909    },
910    
911    removeAt : function(index) {
912        /// <summary>
913        /// Remove the animation at a given index from the array of child animations.
914        /// </summary>
915        /// <param name="index" type="Number" integer="true">
916        /// Index of the child animation to remove
917        /// </param>
918        /// <returns />
919        
920        if (this._animations) {
921            var animation = this._animations[index];
922            if (animation) {
923                animation.dispose();
924            }
925            Array.removeAt(this._animations, index);
926            this.raisePropertyChanged('animations');
927        }
928    },
929    
930    clear : function() {
931    	/// <summary>
932        /// Clear the array of child animations.
933    	/// </summary>
934    	/// <remarks>
935    	/// This will dispose the cleared child animations.
936    	/// </remarks>
937    	/// <returns />
938
939        if (this._animations) {
940            for (var i = this._animations.length - 1; i >= 0; i--) {
941                this._animations[i].dispose();
942                this._animations[i] = null;
943            }
944            Array.clear(this._animations);
945            this._animations = [];
946            this.raisePropertyChanged('animations');
947        }
948    }
949}
950$AA.ParentAnimation.registerClass('Sys.Extended.UI.Animation.ParentAnimation', $AA.Animation);
951$AA.registerAnimation('parent', $AA.ParentAnimation);
952
953
954$AA.ParallelAnimation = function(target, duration, fps, animations) {
955    /// <summary>
956    /// The <code>ParallelAnimation</code> plays several animations simultaneously.  It inherits from
957    /// <see cref="Sys.Extended.UI.Animation.ParentAnimation" />, but makes itself the owner of all
958    /// its child animations to allow the use a single timer and syncrhonization mechanisms shared with
959    /// all the children (in other words, the <code>duration</code> properties of any child animations
960    /// are ignored in favor of the parent's <code>duration</code>).  It is very useful in creating
961    /// sophisticated effects through combination of simpler animations.
962    /// </summary>
963    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
964    /// Target of the animation
965    /// </param>
966    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
967    /// Length of the animation in seconds.  The default is 1.
968    /// </param>
969    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
970    /// Number of steps per second.  The default is 25.
971    /// </param>
972    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Sys.Extended.UI.Animation.Animation">
973    /// Array of child animations
974    /// </param>
975    /// <animation>Parallel</animation>
976    $AA.ParallelAnimation.initializeBase(this, [target, duration, fps, animations]);
977}
978$AA.ParallelAnimation.prototype = {
979    add : function(animation) {
980    	/// <summary>
981        /// Add an animation as a child of this animation and make ourselves its owner.
982    	/// </summary>
983    	/// <param name="animation" type="Sys.Extended.UI.Animation.Animation">Child animation to add</param>
984    	/// <returns />
985        $AA.ParallelAnimation.callBaseMethod(this, 'add', [animation]);
986        animation.setOwner(this);
987    },
988    
989    onStart : function() {
990        /// <summary>
991        /// Get the child animations ready to play
992        /// </summary>
993        /// <returns />
994
995        $AA.ParallelAnimation.callBaseMethod(this, 'onStart');
996        var animations = this.get_animations();
997        for (var i = 0; i < animations.length; i++) {
998            animations[i].onStart();
999        }
1000    },
1001    
1002    onStep : function(percentage) {
1003        /// <summary>
1004        /// Progress the child animations through each frame
1005        /// </summary>
1006        /// <param name="percentage" type="Number">
1007        /// Percentage of the animation already complete
1008        /// </param>
1009        /// <returns />
1010
1011        var animations = this.get_animations();
1012        for (var i = 0; i < animations.length; i++) {
1013            animations[i].onStep(percentage);
1014        }
1015    },
1016    
1017    onEnd : function() {
1018        /// <summary>
1019        /// Finish playing all of the child animations
1020        /// </summary>
1021        /// <returns />
1022
1023        var animations = this.get_animations();
1024        for (var i = 0; i < animations.length; i++) {
1025            animations[i].onEnd();
1026        }
1027        $AA.ParallelAnimation.callBaseMethod(this, 'onEnd');
1028    }
1029}
1030$AA.ParallelAnimation.registerClass('Sys.Extended.UI.Animation.ParallelAnimation', $AA.ParentAnimation);
1031$AA.registerAnimation('parallel', $AA.ParallelAnimation);
1032
1033
1034$AA.SequenceAnimation = function(target, duration, fps, animations, iterations) {
1035    /// <summary>
1036    /// The <code>SequenceAnimation</code> runs several animations one after the other.  It can also
1037    /// repeat the sequence of animations for a specified number of iterations (which defaults to a
1038    /// single iteration, but will repeat forever if you specify zero or less iterations).  Also, the
1039    /// <code>SequenceAnimation</code> cannot be a child of a <see cref="Sys.Extended.UI.Animation.ParallelAnimation" />
1040    /// (or any animation inheriting from it).
1041    /// </summary>
1042    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1043    /// Target of the animation
1044    /// </param>
1045    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1046    /// Length of the animation in seconds.  The default is 1.
1047    /// </param>
1048    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1049    /// Number of steps per second.  The default is 25.
1050    /// </param>
1051    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Sys.Extended.UI.Animation.Animation">
1052    /// Array of child animations
1053    /// </param>
1054    /// <param name="iterations" type="Number" mayBeNull="true" optional="true" integer="true">
1055    /// Number of times to repeatedly play the sequence.  If zero or less iterations are specified, the sequence
1056    /// will repeat forever.  The default value is 1 iteration.
1057    /// </param>
1058    /// <remarks>
1059    /// The <code>SequenceAnimation</code> ignores the <code>duration</code> and <code>fps</code>
1060    /// properties, and will let each of its child animations use any settings they please.
1061    /// </remarks>
1062    /// <animation>Sequence</animation>
1063    $AA.SequenceAnimation.initializeBase(this, [target, duration, fps, animations]);
1064
1065    this._handler = null;
1066    
1067    this._paused = false;
1068    this._playing = false;
1069    
1070    this._index = 0;
1071    
1072    this._remainingIterations = 0;
1073    
1074    this._iterations = (iterations !== undefined) ? iterations : 1;
1075}
1076$AA.SequenceAnimation.prototype = {
1077    dispose : function() {
1078    	/// <summary>
1079        /// Dispose the animation
1080        /// </summary>
1081        /// <returns />
1082        this._handler = null;
1083        $AA.SequenceAnimation.callBaseMethod(this, 'dispose');
1084    },
1085    
1086    stop : function() {
1087        /// <summary>
1088        /// Stop playing the entire sequence of animations
1089        /// </summary>
1090        /// <returns />
1091        /// <remarks>
1092        /// Stopping this animation will perform the last step of each child animation, thereby leaving their
1093        /// target elements in a state consistent with the animation playing completely. If this animation is
1094        /// the child of another, you must call <code>stop</code> on its parent instead.
1095        /// </remarks>
1096
1097        if (this._playing) {
1098            var animations = th
1098is.get_animations();
1099            if (this._index < animations.length) {
1100                animations[this._index].remove_ended(this._handler);
1101                for (var i = this._index; i < animations.length; i++) {
1102                    animations[i].stop();
1103                }
1104            }
1105            this._playing = false;
1106            this._paused = false;
1107            this.raisePropertyChanged('isPlaying');
1108            this.onEnd();
1109        }
1110    },
1111    
1112    pause : function() {
1113        /// <summary>
1114        /// Pause the animation if it is playing.  Calling <code>play</code> will resume where
1115        /// the animation left off.
1116        /// </summary>
1117        /// <returns />
1118        /// <remarks>
1119        /// If this animation is the child of another, you must call <code>pause</code> on its parent instead.
1120        /// </remarks>
1121
1122        if (this.get_isPlaying()) {
1123            var current = this.get_animations()[this._index];
1124            if (current != null) {
1125                current.pause();
1126            }
1127            this._paused = true;
1128            this.raisePropertyChanged('isPlaying');
1129        }
1130    },
1131    
1132    play : function() {
1133        /// <summary>
1134        /// Play the sequence of animations from the beginning or where it was left off when paused
1135        /// </summary>
1136        /// <returns />
1137        /// <remarks>
1138        /// If this animation is the child of another, you must call <code>play</code> on its parent instead
1139        /// </remarks>
1140
1141        var animations = this.get_animations();
1142        if (!this._playing) {
1143            this._playing = true;
1144            if (this._paused) {
1145                this._paused = false;
1146                var current = animations[this._index];
1147                if (current != null) {
1148                    current.play();
1149                    this.raisePropertyChanged('isPlaying');
1150                }
1151            } else {
1152                this.onStart();
1153                this._index = 0;
1154                var first = animations[this._index];
1155                if (first) {
1156                    first.add_ended(this._handler);
1157                    first.play();
1158                    this.raisePropertyChanged('isPlaying');
1159                } else {
1160                    this.stop();
1161                }
1162            }
1163        }
1164    },
1165    
1166    onStart : function() {
1167        /// <summary>
1168        /// The <code>onStart</code> method is called just before the animation is played each time
1169        /// </summary>
1170        /// <returns />
1171        $AA.SequenceAnimation.callBaseMethod(this, 'onStart');
1172        this._remainingIterations = this._iterations - 1;
1173        
1174        if (!this._handler) {
1175            this._handler = Function.createDelegate(this, this._onEndAnimation);
1176        }
1177    },
1178    
1179    _onEndAnimation : function() {
1180    	/// <summary>
1181        /// Wait for the end of each animation, and then continue by playing the other animations remaining
1182        /// in the sequence.  Stop when it reaches the last animation and there are no remaining iterations.
1183    	/// </summary>
1184    	/// <returns />
1185
1186        var animations = this.get_animations();
1187        var current = animations[this._index++];
1188        if (current) {
1189            current.remove_ended(this._handler);
1190        }
1191        
1192        if (this._index < animations.length) {
1193            var next = animations[this._index];
1194            next.add_ended(this._handler);
1195            next.play();
1196        } else if (this._remainingIterations >= 1 || this._iterations <= 0) {
1197            this._remainingIterations--;
1198            this._index = 0;
1199            var first = animations[0];
1200            first.add_ended(this._handler);
1201            first.play();
1202        } else {
1203            this.stop();
1204        }
1205    },
1206    
1207    onStep : function(percentage) {
1208        /// <summary>
1209        /// Raises an invalid operation exception because this will only be called if a <code>SequenceAnimation</code>
1210        /// has been nested inside an <see cref="Sys.Extended.UI.Animation.ParallelAnimation" /> (or a derived type).
1211        /// </summary>
1212        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
1213        /// <returns />
1214        throw Error.invalidOperation(Sys.Extended.UI.Resources.Animation_CannotNestSequence);
1215    },
1216    
1217    onEnd : function() {
1218        /// <summary>
1219        /// The <code>onEnd</code> method is called just after the animation is played each time.
1220        /// </summary>
1221        /// <returns />
1222        this._remainingIterations = 0;
1223        $AA.SequenceAnimation.callBaseMethod(this, 'onEnd');
1224    },
1225    
1226    get_isActive : function() {
1227    	/// <value type="Boolean">
1228        /// <code>true</code> if animation is active, <code>false</code> if not.
1229        /// </value>
1230        return true;
1231    },
1232    
1233    get_isPlaying : function() {
1234    	/// <value type="Boolean">
1235        /// <code>true</code> if animation is playing, <code>false</code> if not.
1236        /// </value>
1237        return this._playing && !this._paused;
1238    },
1239    
1240    get_iterations : function() {
1241        /// <value type="Number" integer="true">
1242        /// Number of times to repeatedly play the sequence.  If zero or less iterations are specified, the sequence
1243        /// will repeat forever.  The default value is 1 iteration.
1244        /// </value>
1245        return this._iterations;
1246    },
1247    set_iterations : function(value) {
1248        value = this._getInteger(value);
1249        if (this._iterations != value) {
1250            this._iterations = value;
1251            this.raisePropertyChanged('iterations');
1252        }
1253    },
1254    
1255    get_isInfinite : function() {
1256    	/// <value type="Boolean">
1257        /// <code>true</code> if this animation will repeat forever, <code>false</code> otherwise.
1258    	/// </value>
1259        return this._iterations <= 0;
1260    }
1261}
1262$AA.SequenceAnimation.registerClass('Sys.Extended.UI.Animation.SequenceAnimation', $AA.ParentAnimation);
1263$AA.registerAnimation('sequence', $AA.SequenceAnimation);
1264
1265
1266$AA.SelectionAnimation = function(target, duration, fps, animations) {
1267    /// <summary>
1268    /// The <code>SelectionAnimation</code> will run a single animation chosen from of its child animations. It is
1269    /// important to note that the <code>SelectionAnimation</code> ignores the <code>duration</code> and <code>fps</code>
1270    /// properties, and will let each of its child animations use any settings they please.  This is a base class with no
1271    /// functional implementation, so consider using <see cref="Sys.Extended.UI.Animation.ConditionAnimation" /> or
1272    /// <see cref="Sys.Extended.UI.Animation.CaseAnimation" /> instead.
1273    /// </summary>
1274    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1275    /// Target of the animation
1276    /// </param>
1277    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1278    /// Length of the animation in seconds.  The default is 1.
1279    /// </param>
1280    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1281    /// Number of steps per second.  The default is 25.
1282    /// </param>
1283    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Sys.Extended.UI.Animation.Animation">
1284    /// Array of child animations
1285    /// </param>
1286    /// <animation>Selection</animation>
1287    $AA.SelectionAnimation.initializeBase(this, [target, duration, fps, animations]);
1288    
1289    this._selectedIndex = -1;
1290    
1291    this._selected = null;
1292}
1293$AA.SelectionAnimation.prototype = {    
1294    getSelectedIndex : function() {
1295        /// <summary>
1296        /// Get the index of the animation that is selected to be played.  If this returns an index outside the bounds of
1297        /// the child animations array, then nothing is played.
1298        /// </summary>
1299        /// <returns type="Number" integer="true">
1300        /// Index of the selected child animation to play
1301        /// </returns>
1302        throw Error.notImplemented();
1303    },
1304    
1305    onStart : function() {
1306    	/// <summary>
1307        /// The <code>onStart</code> method is called just before the animation is played each time.
1308        /// </summary>
1309        /// <returns />
1310	    $AA.SelectionAnimation.callBaseMethod(this, 'onStart');
1311	    
1312	    var animations = this.get_animations();
1313	    this._selectedIndex = this.getSelectedIndex();
1314	    if (this._selectedIndex >= 0 && this._selectedIndex < animations.length) {
1315	        this._selected = animations[this._selectedIndex];
1316	        if (this._selected) {
1317	            this._selected.setOwner(this);
1318	            this._selected.onStart();
1319	        }
1320	    }
1321    },
1322    
1323    onStep : function(percentage) {
1324    	/// <summary>
1325        /// The <code>onStep</code> method is called repeatedly to progress the animation through each frame
1326        /// </summary>
1327        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
1328        /// <returns />
1329
1330        if (this._selected) {
1331    	    this._selected.onStep(percentage);
1332    	}
1333    },
1334    
1335    onEnd : function() {
1336    	/// <summary>
1337        /// The <code>onEnd</code> method is called just after the animation is played each time.
1338        /// </summary>
1339        /// <returns />
1340
1341        if (this._selected) {
1342    	    this._selected.onEnd();
1343    	    this._selected.setOwner(null);
1344    	}
1345    	this._selected = null;
1346    	this._selectedIndex = null;
1347	    $AA.SelectionAnimation.callBaseMethod(this, 'onEnd');
1348    }
1349}
1350$AA.SelectionAnimation.registerClass('Sys.Extended.UI.Animation.SelectionAnimation', $AA.ParentAnimation);
1351$AA.registerAnimation('selection', $AA.SelectionAnimation);
1352
1353
1354$AA.ConditionAnimation = function(target, duration, fps, animations, conditionScript) {
1355    /// <summary>
1356    /// The <code>ConditionAnimation</code> is used as a control structure to play a specific child animation
1357    /// depending on the result of executing the <code>conditionScript</code>.  If the <code>conditionScript</code>
1358    /// evaluates to <code>true</code>, the first child animation is played.  If it evaluates to <code>false</code>,
1359    /// the second child animation is played (although nothing is played if a second animation is not present).
1360    /// </summary>
1361    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1362    /// Target of the animation
1363    /// </param>
1364    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1365    /// Length of the animation in seconds.  The default is 1.
1366    /// </param>
1367    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1368    /// Number of steps per second.  The default is 25.
1369    /// </param>
1370    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Sys.Extended.UI.Animation.Animation">
1371    /// Array of child animations
1372    /// </param>
1373    /// <param name="conditionScript" type="String" mayBeNull="true" optional="true">
1374    /// JavaScript that should evaluate to <code>true</code> or <code>false</code> to determine which child
1375    /// animation to play.
1376    /// </param>
1377    /// <animation>Condition</animation>
1378    $AA.ConditionAnimation.initializeBase(this, [target, duration, fps, animations]);
1379    
1380    this._conditionScript = conditionScript;   
1381}
1382$AA.ConditionAnimation.prototype = {    
1383   getSelectedIndex : function() {
1384       /// <summary>
1385       /// Get the index of the animation that is selected to be played.  If this returns an index outside the bounds of
1386       /// the child animations array, then nothing is played.
1387       /// </summary>
1388       /// <returns type="Number" integer="true">
1389       /// Index of the selected child animation to play
1390       /// </returns>
1391
1392        var selected = -1;
1393        if (this._conditionScript && this._conditionScript.length > 0) {
1394            try {
1395                selected = eval(this._conditionScript) ? 0 : 1;
1396            } catch(ex) {
1397            }
1398        }
1399        return selected;
1400    },
1401    
1402    get_conditionScript : function() {
1403    	/// <value type="String">
1404        /// JavaScript that should evaluate to <code>true</code> or <code>false</code> to determine which
1405        /// child animation to play.
1406    	/// </value>
1407        return this._conditionScript;
1408    },
1409    set_conditionScript : function(value) {
1410        if (this._conditionScript != value) {
1411            this._conditionScript = value;
1412            this.raisePropertyChanged('conditionScript');
1413        }
1414    }
1415}
1416$AA.ConditionAnimation.registerClass('Sys.Extended.UI.Animation.ConditionAnimation', $AA.SelectionAnimation);
1417$AA.registerAnimation('condition', $AA.ConditionAnimation);
1418
1419
1420$AA.CaseAnimation = function(target, duration, fps, animations, selectScript) {
1421    /// <summary>
1422    /// The <code>CaseAnimation</code> is used as a control structure to play a specific child animation depending on
1423    /// the result of executing the <code>selectScript</code>, which should return the index of the child animation to
1424    /// play (this is similar to the <code>case</code> or <code>select</code> statements in C#/VB, etc.).  If the provided
1425    /// index is outside the bounds of the child animations array (or if nothing was returned) then we will not play anything.
1426    /// </summary>
1427    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1428    /// Target of the animation
1429    /// </param>
1430    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1431    /// Length of the animation in seconds.  The default is 1.
1432    /// </param>
1433    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1434    /// Number of steps per second.  The default is 25.
1435    /// </param>
1436    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Sys.Extended.UI.Animation.Animation">
1437    /// Array of child animations
1438    /// </param>
1439    /// <param name="selectScript" type="String" mayBeNull="true" optional="true">
1440    /// JavaScript that should evaluate to the index of the appropriate child animation to play.  If this returns an index outside the bounds of the child animations array, then nothing is played.
1441    /// </param>
1442    /// <animation>Case</animation>
1443    $AA.CaseAnimation.initializeBase(this, [target, duration, fps, animations]);
1444
1445    this._selectScript = selectScript;
1446}
1447$AA.CaseAnimation.prototype = {
1448    getSelectedIndex : function() {
1449        /// <summary>
1450        /// Get the index of the animation that is selected to be played.  If this returns an index outside the bounds of
1451        /// the child animations array, then nothing is played.
1452        /// </summary>
1453        /// <returns type="Number" integer="true">
1454        /// Index of the selected child animation to play
1455        /// </returns>
1456
1457        var selected = -1;
1458        if (this._selectScript && this._selectScript.length > 0) {
1459            try {
1460                var result = eval(this._selectScript)
1461                if (result !== undefined)
1462                    selected = result;
1463            } catch (ex) {
1464            }
1465        }
1466        return selected;
1467    },
1468    
1469    get_selectScript : function() {
1470        /// <value type="String">
1471        /// JavaScript that should evaluate to the index of the appropriate child animation to play.  If this returns an index outside the bounds of the child animations array, then nothing is played.
1472        /// </value>
1473        return this._selectScript;
1474    },
1475    set_selectScript : function(value) {
1476        if (this._selectScript != value) {
1477            this._selectScript = value;
1478            this.raisePropertyChanged('selectScript');
1479        }
1480    }
1481}
1482$AA.CaseAnimation.registerClass('Sys.Extended.UI.Animation.CaseAnimation', $AA.SelectionAnimation);
1483$AA.registerAnimation('case', $AA.CaseAnimation);
1484
1485
1486$AA.FadeEffect = function() {
1487    /// <summary>
1488    /// The FadeEffect enumeration determines whether a fade animation is used to fade in or fade out.
1489    /// </summary>
1490    /// <field name="FadeIn" type="Number" integer="true" />
1491    /// <field name="FadeOut" type="Number" integer="true" />
1492    throw Error.invalidOperation();
1493}
1494$AA.FadeEffect.prototype = {
1495    FadeIn : 0,
1496    FadeOut : 1
1497}
1498$AA.FadeEffect.registerEnum("Sys.Extended.UI.Animation.FadeEffect", false);
1499
1500
1501$AA.FadeAnimation = function(target, duration, fps, effect, minimumOpacity, maximumOpacity, forceLayoutInIE) {
1502    /// <summary>
1503    /// The <code>FadeAnimation</code> is used to fade an element in or out of view, depending on the
1504    /// provided <see cref="Sys.Extended.UI.Animation.FadeEffect" />, by settings its opacity.
1505    /// The minimum and maximum opacity values can be specified to precisely control the fade.
1506    /// You may also consider using <see cref="Sys.Extended.UI.Animation.FadeInAnimation" /> or
1507    /// <see cref="Sys.Extended.UI.Animation.FadeOutAnimation" /> if you know the only direction you
1508    /// are fading.
1509    /// </summary>
1510    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1511    /// Target of the animation
1512    /// </param>
1513    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1514    /// Length of the animation in seconds.  The default is 1.
1515    /// </param>
1516    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1517    /// Number of steps per second.  The default is 25.
1518    /// </param>
1519    /// <param name="effect" type="Sys.Extended.UI.Animation.FadeEffect" mayBeNull="true" optional="true">
1520    /// Determine whether to fade the element in or fade the element out.  The possible values are <code>FadeIn</code>
1521    /// and <code>FadeOut</code>.  The default value is <code>FadeOut</code>.
1522    /// </param>
1523    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
1524    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
1525    /// </param>
1526    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
1527    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
1528    /// </param>
1529    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
1530    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
1531    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
1532    /// This is obviously ignored when working in other browsers.
1533    /// </param>
1534    /// <animation>Fade</animation>
1535    $AA.FadeAnimation.initializeBase(this, [target, duration, fps]);
1536
1537    this._effect = (effect !== undefined) ? effect : $AA.FadeEffect.FadeIn;
1538    
1539    this._max = (maximumOpacity !== undefined) ? maximumOpacity : 1;
1540    this._min = (minimumOpacity !== undefined) ? minimumOpacity : 0;
1541    
1542    this._start = this._min;
1543    this._end = this._max;
1544    
1545    this._layoutCreated = false;
1546
1547    this._forceLayoutInIE = (forceLayoutInIE === undefined || forceLayoutInIE === null) ? true : forceLayoutInIE;
1548    
1549    this._currentTarget = null;
1550
1551    this._resetOpacities();  
1552}
1553$AA.FadeAnimation.prototype = {
1554    _resetOpacities : function() {
1555    	/// <summary>
1556        /// Set the starting and ending opacity values based on the effect (i.e. when we're fading
1557        /// in we go from <code>_min</code> to <code>_max</code>, but we go <code>_max</code> to
1558        /// <code>_min</code> when fading out)
1559    	/// </summary>
1560    	/// <returns />
1561
1562        if (this._effect == $AA.FadeEffect.FadeIn) {
1563            this._start = this._min;
1564            this._end = this._max;
1565        } else {
1566            this._start = this._max;
1567            this._end = this._min;
1568        }
1569    },
1570    
1571    _createLayout : function() {
1572    	/// <summary>
1573        /// Create a layout when using Internet Explorer (which entails setting a width and also
1574        /// a background color if it currently has neither)
1575    	/// </summary>
1576    	/// <returns />
1577
1578        var element = this._currentTarget;
1579        if (element) {
1580            this._originalWidth = $common.getCurrentStyle(element, 'width');
1581            var originalHeight = $common.getCurrentStyle(element, 'height');
1582            this._originalBackColor = $common.getCurrentStyle(element, 'backgroundColor');
1583
1584            if ((!this._originalWidth || this._originalWidth == '' || this._originalWidth == 'auto') &&
1585                (!originalHeight || originalHeight == '' || originalHeight == 'auto')) {
1586                element.style.width = element.offsetWidth + 'px';
1587            }
1588            
1589            if (!this._originalBackColor || this._originalBackColor == '' || this._originalBackColor == 'transparent' || this._originalBackColor == 'rgba(0, 0, 0, 0)') {
1590                element.style.backgroundColor = $common.getInheritedBackgroun
1590dColor(element);
1591            }
1592            
1593            this._layoutCreated = true;
1594        }
1595    },
1596    
1597    onStart : function() {
1598    	/// <summary>
1599        /// The <code>onStart</code> method is called just before the animation is played each time.
1600        /// </summary>
1601        /// <returns />       
1602        $AA.FadeAnimation.callBaseMethod(this, 'onStart');
1603        
1604        this._currentTarget = this.get_target();
1605        this.setValue(this._start);
1606        
1607        if (this._forceLayoutInIE && !this._layoutCreated && Sys.Browser.agent == Sys.Browser.InternetExplorer) {
1608            this._createLayout();
1609        }
1610    },
1611    
1612    getAnimatedValue : function(percentage) {
1613    	/// <summary>
1614        /// Determine the current opacity after the given percentage of its duration has elapsed
1615        /// </summary>
1616        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
1617        /// <returns type="Number">
1618        /// Current opacity after the given percentage of its duration has elapsed that will
1619        /// be passed to <code>setValue</code>
1620        /// </returns>
1621        return this.interpolate(this._start, this._end, percentage);
1622    },
1623    
1624    setValue : function(value) {
1625        /// <summary>
1626        /// Set the current opacity of the element.
1627        /// </summary>
1628        /// <param name="value" type="Number">
1629        /// Current opacity (as retreived from <code>getAnimatedValue</code>)
1630        /// </param>
1631        /// <returns />
1632        /// <remarks>
1633        /// This method will be replaced by a dynamically generated function that requires no logic
1634        /// to determine whether it should use filters or the style's opacity.
1635        /// </remarks>
1636        if (this._currentTarget) {
1637            $common.setElementOpacity(this._currentTarget, value);
1638        }
1639    },
1640    
1641    
1642    get_effect : function() {
1643    	/// <value type="Sys.Extended.UI.Animation.FadeEffect">
1644        /// Determine whether to fade the element in or fade the element out.  The possible values are
1645        /// <code>FadeIn</code> and <code>FadeOut</code>.  The default value is <code>FadeOut</code>.
1646    	/// </value>
1647        return this._effect;
1648    },
1649    set_effect : function(value) {
1650        value = this._getEnum(value, $AA.FadeEffect);
1651        if (this._effect != value) {
1652            this._effect = value;
1653            this._resetOpacities();
1654            this.raisePropertyChanged('effect');
1655        }
1656    },
1657    
1658    get_minimumOpacity : function() {
1659        /// <value type="Number">
1660        /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1.
1661        /// The default value is 0.
1662        /// </value>
1663	    return this._min;
1664    },
1665    set_minimumOpacity : function(value) {
1666        value = this._getFloat(value);
1667        if (this._min != value) {
1668            this._min = value;
1669            this._resetOpacities();
1670            this.raisePropertyChanged('minimumOpacity');
1671        }
1672    },
1673    
1674    get_maximumOpacity : function() {
1675        /// <value type="Number">
1676        /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1.
1677        /// The default value is 1.
1678        /// </value>
1679        return this._max;
1680    },
1681    set_maximumOpacity : function(value) {
1682        value = this._getFloat(value);
1683        if (this._max != value) {
1684            this._max = value;
1685            this._resetOpacities();
1686            this.raisePropertyChanged('maximumOpacity');
1687        }
1688    },
1689    
1690    get_forceLayoutInIE : function() {
1691        /// <value type="Boolean">
1692        /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
1693        /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
1694        /// This is obviously ignored when working in other browsers.
1695        /// </value>
1696        return this._forceLayoutInIE;
1697    },
1698    set_forceLayoutInIE : function(value) {
1699        value = this._getBoolean(value);
1700        if (this._forceLayoutInIE != value) {
1701            this._forceLayoutInIE = value;
1702            this.raisePropertyChanged('forceLayoutInIE');
1703        }
1704    },
1705    
1706    set_startValue : function(value) {
1707        /// <value type="Number">
1708        /// Set the start value (so that child animations can set the current opacity as the start value when fading in or out)
1709        /// </value>
1710        value = this._getFloat(value);
1711        this._start = value;
1712    }
1713}
1714$AA.FadeAnimation.registerClass('Sys.Extended.UI.Animation.FadeAnimation', $AA.Animation);
1715$AA.registerAnimation('fade', $AA.FadeAnimation);
1716
1717
1718$AA.FadeInAnimation = function(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE) {
1719    /// <summary>
1720    /// The <code>FadeInAnimation</code> will fade the target in by moving from hidden to visible.
1721    /// It starts the animation the target's current opacity.
1722    /// </summary>
1723    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1724    /// Target of the animation
1725    /// </param>
1726    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1727    /// Length of the animation in seconds.  The default is 1.
1728    /// </param>
1729    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1730    /// Number of steps per second.  The default is 25.
1731    /// </param>
1732    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
1733    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
1734    /// </param>
1735    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
1736    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
1737    /// </param>
1738    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
1739    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
1740    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
1741    /// This is obviously ignored when working in other browsers.
1742    /// </param>
1743    /// <animation>FadeIn</animation>
1744    $AA.FadeInAnimation.initializeBase(this, [target, duration, fps, $AA.FadeEffect.FadeIn, minimumOpacity, maximumOpacity, forceLayoutInIE]);
1745}
1746$AA.FadeInAnimation.prototype = {
1747    onStart : function() {
1748    	/// <summary>
1749        /// The <code>onStart</code> method is called just before the animation is played each time.
1750        /// </summary>
1751        /// <returns />
1752        $AA.FadeInAnimation.callBaseMethod(this, 'onStart');
1753        
1754        if (this._currentTarget) {
1755            this.set_startValue($common.getElementOpacity(this._currentTarget));
1756        }
1757    }
1758}
1759$AA.FadeInAnimation.registerClass('Sys.Extended.UI.Animation.FadeInAnimation', $AA.FadeAnimation);
1760$AA.registerAnimation('fadeIn', $AA.FadeInAnimation);
1761
1762
1763$AA.FadeOutAnimation = function(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE) {
1764    /// <summary>
1765    /// The FadeInAnimation will fade the element out by moving from visible to hidden. It starts the animation
1766    /// at the element's current opacity.
1767    /// </summary>
1768    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1769    /// Target of the animation
1770    /// </param>
1771    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1772    /// Length of the animation in seconds.  The default is 1.
1773    /// </param>
1774    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1775    /// Number of steps per second.  The default is 25.
1776    /// </param>
1777    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
1778    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
1779    /// </param>
1780    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
1781    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
1782    /// </param>
1783    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
1784    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
1785    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
1786    /// This is obviously ignored when working in other browsers.
1787    /// </param>
1788    /// <animation>FadeOut</animation>
1789    $AA.FadeOutAnimation.initializeBase(this, [target, duration, fps, $AA.FadeEffect.FadeOut, minimumOpacity, maximumOpacity, forceLayoutInIE]);
1790}
1791$AA.FadeOutAnimation.prototype = {
1792    onStart : function() {
1793    	/// <summary>
1794        /// The <code>onStart</code> method is called just before the animation is played each time.
1795        /// </summary>
1796        /// <returns />
1797        $AA.FadeOutAnimation.callBaseMethod(this, 'onStart');
1798
1799        if (this._currentTarget) {
1800            this.set_startValue($common.getElementOpacity(this._currentTarget));
1801        }
1802    }
1803}
1804$AA.FadeOutAnimation.registerClass('Sys.Extended.UI.Animation.FadeOutAnimation', $AA.FadeAnimation);
1805$AA.registerAnimation('fadeOut', $AA.FadeOutAnimation);
1806
1807
1808$AA.PulseAnimation = function(target, duration, fps, iterations, minimumOpacity, maximumOpacity, forceLayoutInIE) {
1809    /// <summary>
1810    /// The PulseAnimation fades an element in and our repeatedly to create a pulsating
1811    /// effect.  The iterations determines how many pulses there will be (which defaults
1812    /// to three, but it will repeat infinitely if given zero or less).  The duration
1813    /// property defines the duration of each fade in or fade out, not the duration of
1814    /// the animation as a whole.
1815    /// </summary>
1816    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1817    /// Target of the animation
1818    /// </param>
1819    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1820    /// Length of the animation in seconds.  The default is 1.
1821    /// </param>
1822    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1823    /// Number of steps per second.  The default is 25.
1824    /// </param>
1825    /// <param name="iterations" type="Number" mayBeNull="true" optional="true" integer="true">
1826    /// Number of times to repeatedly play the sequence.  If zero or less iterations are specified, the sequence
1827    /// will repeat forever.  The default value is 1 iteration.
1828    /// </param>
1829    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
1830    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
1831    /// </param>
1832    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
1833    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
1834    /// </param>
1835    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
1836    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
1837    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
1838    /// This is obviously ignored when working in other browsers.
1839    /// </param>
1840    /// <animation>Pulse</animation>
1841    $AA.PulseAnimation.initializeBase(this, [target, duration, fps, null, ((iterations !== undefined) ? iterations : 3)]);
1842
1843    this._out = new $AA.FadeOutAnimation(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE);
1844    this.add(this._out);
1845    
1846    this._in = new $AA.FadeInAnimation(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE);
1847    this.add(this._in);
1848}
1849$AA.PulseAnimation.prototype = {
1850   
1851    get_minimumOpacity : function() {
1852        /// <value type="Number">
1853        /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
1854        /// </value>
1855        return this._out.get_minimumOpacity();
1856    },
1857    set_minimumOpacity : function(value) {
1858        value = this._getFloat(value);
1859        this._out.set_minimumOpacity(value);
1860        this._in.set_minimumOpacity(value);
1861        this.raisePropertyChanged('minimumOpacity');
1862    },
1863    
1864    get_maximumOpacity : function() {
1865        /// <value type="Number">
1866        /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
1867        /// </value>
1868        return this._out.get_maximumOpacity();
1869    },
1870    set_maximumOpacity : function(value) {
1871        value = this._getFloat(value);
1872        this._out.set_maximumOpacity(value);
1873        this._in.set_maximumOpacity(value);
1874        this.raisePropertyChanged('maximumOpacity');
1875    },
1876    
1877    get_forceLayoutInIE : function() {
1878        /// <value type="Boolean">
1879        /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
1880        /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
1881        /// This is obviously ignored when working in other browsers.
1882        /// </value>
1883        return this._out.get_forceLayoutInIE();
1884    },
1885    set_forceLayoutInIE : function(value) {
1886        value = this._getBoolean(value);
1887        this._out.set_forceLayoutInIE(value);
1888        this._in.set_forceLayoutInIE(value);
1889        this.raisePropertyChanged('forceLayoutInIE');
1890    },
1891    
1892    set_duration : function(value) {
1893        /// <value type="Number">
1894        /// Override the <code>duration</code> property
1895        /// </value>
1896        value = this._getFloat(value);
1897        $AA.PulseAnimation.callBaseMethod(this, 'set_duration', [value]);
1898        this._in.set_duration(value);
1899        this._out.set_duration(value);
1900    },
1901    
1902    set_fps : function(value) {
1903        /// <value type="Number" integer="true">
1904        /// Override the <code>fps</code> property
1905        /// </value>
1906        value = this._getInteger(value);
1907        $AA.PulseAnimation.callBaseMethod(this, 'set_fps', [value]);
1908        this._in.set_fps(value);
1909        this._out.set_fps(value);
1910    }
1911    
1912}
1913$AA.PulseAnimation.registerClass('Sys.Extended.UI.Animation.PulseAnimation', $AA.SequenceAnimation);
1914$AA.registerAnimation('pulse', $AA.PulseAnimation);
1915
1916
1917$AA.PropertyAnimation = function(target, duration, fps, property, propertyKey) {
1918    /// <summary>
1919    /// The <code>PropertyAnimation</code> is a useful base animation that will assign the value from
1920    /// <code>getAnimatedValue</code> to a specified <code>property</code>. You can provide the name of
1921    /// a <code>property</code> alongside an optional <code>propertyKey</code> (which indicates the value
1922    /// <code>property[propertyKey]</code>, like <code>style['backgroundColor']</code>).
1923    /// </summary>
1924    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
1925    /// Target of the animation
1926    /// </param>
1927    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
1928    /// Length of the animation in seconds.  The default is 1.
1929    /// </param>
1930    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
1931    /// Number of steps per second.  The default is 25.
1932    /// </param>
1933    /// <param name="property" type="String" mayBeNull="true" optional="true">
1934    /// Property of the <code>target</code> element to set when animating
1935    /// </param>
1936    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
1937    /// Optional key of the property to be set (which indic
1937ates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
1938    /// </param>
1939    /// <animation>Property</animation>
1940    $AA.PropertyAnimation.initializeBase(this, [target, duration, fps]);
1941
1942    this._property = property;
1943    
1944    this._propertyKey = propertyKey;
1945    
1946    this._currentTarget = null;
1947}
1948$AA.PropertyAnimation.prototype = {
1949    onStart : function() {
1950    	/// <summary>
1951        /// The <code>onStart</code> method is called just before the animation is played each time.
1952        /// </summary>
1953        /// <returns />
1954        $AA.PropertyAnimation.callBaseMethod(this, 'onStart');
1955
1956        this._currentTarget = this.get_target();
1957    },
1958
1959    setValue : function(value) {
1960        /// <summary>
1961        /// Set the current value of the property
1962        /// </summary>
1963        /// <param name="value" type="Object" mayBeNull="true">
1964        /// Value to assign
1965        /// </param>
1966        /// <returns />
1967
1968        var element = this._currentTarget;
1969        if (element && this._property && this._property.length > 0) { 
1970            if (this._propertyKey && this._propertyKey.length > 0 && element[this._property]) {
1971                element[this._property][this._propertyKey] = value;
1972            } else {
1973                element[this._property] = value;
1974            }
1975        }
1976    },
1977    
1978    getValue : function() {
1979        /// <summary>
1980        /// Get the current value from the property
1981        /// </summary>
1982        /// <returns type="Object" mayBeNull="true">
1983        /// Current value of the property
1984        /// </returns>
1985
1986        var element = this.get_target();
1987        if (element && this._property && this._property.length > 0) { 
1988            var property = element[this._property];
1989            if (property) {
1990                if (this._propertyKey && this._propertyKey.length > 0) {
1991                    return property[this._propertyKey];
1992                }
1993                return property;
1994            }
1995        }
1996        return null;
1997    },
1998    
1999    get_property : function() {
2000        /// <value type="String">
2001        /// Property of the <code>target</code> element to set when animating
2002        /// </value>
2003        return this._property;
2004    },
2005    set_property : function(value) {
2006        if (this._property != value) {
2007            this._property = value;
2008            this.raisePropertyChanged('property');
2009        }
2010    },
2011    
2012    get_propertyKey : function() {
2013        /// <value type="String" mayBeNull="true" optional="true">
2014        /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
2015        /// </value>
2016        return this._propertyKey;
2017    },
2018    set_propertyKey : function(value) {
2019        if (this._propertyKey != value) {
2020            this._propertyKey = value;
2021            this.raisePropertyChanged('propertyKey');
2022        }
2023    }
2024}
2025$AA.PropertyAnimation.registerClass('Sys.Extended.UI.Animation.PropertyAnimation', $AA.Animation);
2026$AA.registerAnimation('property', $AA.PropertyAnimation);
2027
2028
2029$AA.DiscreteAnimation = function(target, duration, fps, property, propertyKey, values) {
2030    /// <summary>
2031    /// The <code>DiscreteAnimation</code> inherits from <see cref="Sys.Extended.UI.Animation.PropertyAnimation" />
2032    /// and sets the value of the <code>property</code> to the elements in a provided array of <code>values</code>.
2033    /// </summary>
2034    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true">
2035    /// Target of the animation
2036    /// </param>
2037    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2038    /// Length of the animation in seconds.  The default is 1.
2039    /// </param>
2040    /// <param name="fps" type="Number" mayBeNull="true" optional="true">
2041    /// Number of steps per second.  The default is 25.
2042    /// </param>
2043    /// <param name="property" type="String" mayBeNull="true" optional="true">
2044    /// Property of the <code>target</code> element to set when animating
2045    /// </param>
2046    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
2047    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
2048    /// </param>
2049    /// <param name="values" mayBeNull="true" optional="true" parameterArray="true" elementType="Object">
2050    /// Array of possible values of the property that will be iterated over as the animation is played
2051    /// </param>
2052    /// <animation>Discrete</animation>
2053    $AA.DiscreteAnimation.initializeBase(this, [target, duration, fps, property, propertyKey]);
2054
2055    this._values = (values && values.length) ? values : [];
2056}
2057$AA.DiscreteAnimation.prototype = {
2058    getAnimatedValue : function(percentage) {
2059        /// <summary>
2060        /// Assign the value whose index corresponds to the current percentage
2061        /// </summary>
2062        /// <param name="percentage" type="Number">
2063        /// Percentage of the animation already complete
2064        /// </param>
2065        /// <returns type="Object">
2066        /// State of the animation after the given percentage of its duration has elapsed that will
2067        /// be passed to <code>setValue</code>
2068        /// </returns>
2069        var index = Math.floor(this.interpolate(0, this._values.length - 1, percentage));
2070        return this._values[index];
2071    },
2072    
2073    get_values : function() {
2074        /// <value parameterArray="true" elementType="Object">
2075        /// Array of possible values of the property that will be iterated over as the animation is played
2076        /// </value>
2077        return this._values;
2078    },
2079    set_values : function(value) {
2080        if (this._values != value) {
2081            this._values = value;
2082            this.raisePropertyChanged('values');
2083        }
2084    }
2085}
2086$AA.DiscreteAnimation.registerClass('Sys.Extended.UI.Animation.DiscreteAnimation', $AA.PropertyAnimation);
2087$AA.registerAnimation('discrete', $AA.DiscreteAnimation);
2088
2089
2090$AA.InterpolatedAnimation = function(target, duration, fps, property, propertyKey, startValue, endValue) {
2091    /// <summary>
2092    /// The <code>InterpolatedAnimation</code> assigns a range of values between <code>startValue</code>
2093    /// and <code>endValue</code> to the designated property.
2094    /// </summary>
2095    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2096    /// Target of the animation
2097    /// </param>
2098    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2099    /// Length of the animation in seconds.  The default is 1.
2100    /// </param>
2101    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2102    /// Number of steps per second.  The default is 25.
2103    /// </param>
2104    /// <param name="property" type="String" mayBeNull="true" optional="true">
2105    /// Property of the <code>target</code> element to set when animating.  The default value is 'style'.
2106    /// </param>
2107    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
2108    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
2109    /// </param>
2110    /// <param name="startValue" type="Number" mayBeNull="true" optional="true">
2111    /// Start of the range of values
2112    /// </param>
2113    /// <param name="endValue" type="Number" mayBeNull="true" optional="true">
2114    /// End of the range of values
2115    /// </param>
2116    /// <animation>Interpolated</animation>
2117    $AA.InterpolatedAnimation.initializeBase(this, [target, duration, fps, ((property !== undefined) ? property : 'style'), propertyKey]);
2118
2119    this._startValue = startValue;
2120    this._endValue = endValue;
2121}
2122$AA.InterpolatedAnimation.prototype = {
2123    get_startValue : function() {
2124        /// <value type="Number">
2125        /// Start of the range of values
2126        /// </value>
2127        return this._startValue;
2128    },
2129    set_startValue : function(value) {
2130        value = this._getFloat(value);
2131        if (this._startValue != value) {
2132            this._startValue = value;
2133            this.raisePropertyChanged('startValue');
2134        }
2135    },
2136    
2137    get_endValue : function() {
2138        /// <value type="Number">
2139        /// End of the range of values
2140        /// </value>
2141        return this._endValue;
2142    },
2143    set_endValue : function(value) {
2144        value = this._getFloat(value);
2145        if (this._endValue != value) {
2146            this._endValue = value;
2147            this.raisePropertyChanged('endValue');
2148        }
2149    }   
2150}
2151$AA.InterpolatedAnimation.registerClass('Sys.Extended.UI.Animation.InterpolatedAnimation', $AA.PropertyAnimation);
2152$AA.registerAnimation('interpolated', $AA.InterpolatedAnimation);
2153
2154
2155$AA.ColorAnimation = function(target, duration, fps, property, propertyKey, startValue, endValue) {
2156    /// <summary>
2157    /// The <code>ColorAnimation</code> transitions the value of the <code>property</code> between
2158    /// two colors (although it does ignore the alpha channel). The colors must be 7-character hex strings
2159    /// (like <code>#246ACF</code>).
2160    /// </summary>
2161    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true">
2162    /// Target of the animation
2163    /// </param>
2164    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2165    /// Length of the animation in seconds.  The default is 1.
2166    /// </param>
2167    /// <param name="fps" type="Number" mayBeNull="true" optional="true">
2168    /// Number of steps per second.  The default is 25.
2169    /// </param>
2170    /// <param name="property" type="String" mayBeNull="true" optional="true">
2171    /// Property of the <code>target</code> element to set when animating.  The default value is 'style'.
2172    /// </param>
2173    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
2174    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
2175    /// </param>
2176    /// <param name="startValue" type="String" mayBeNull="true" optional="true">
2177    /// Start of the range of colors
2178    /// </param>
2179    /// <param name="endValue" type="String" mayBeNull="true" optional="true">
2180    /// End of the range of colors
2181    /// </param>
2182    /// <animation>Color</animation>
2183    $AA.ColorAnimation.initializeBase(this, [target, duration, fps, property, propertyKey, startValue, endValue]);
2184    
2185    this._start = null;
2186    this._end = null;
2187    
2188    this._interpolateRed = false;
2189    this._interpolateGreen = false;
2190    this._interpolateBlue = false;
2191}
2192$AA.ColorAnimation.prototype = {
2193    onStart : function() {
2194        /// <summary>
2195        /// Determine which dimensions of color will be animated
2196        /// </summary>
2197        /// <returns />
2198        $AA.ColorAnimation.callBaseMethod(this, 'onStart');
2199       
2200        this._start = $AA.ColorAnimation.getRGB(this.get_startValue());
2201        this._end = $AA.ColorAnimation.getRGB(this.get_endValue());
2202        
2203        this._interpolateRed = (this._start.Red != this._end.Red);
2204        this._interpolateGreen = (this._start.Green != this._end.Green);
2205        this._interpolateBlue = (this._start.Blue != this._end.Blue);
2206    },
2207    
2208    getAnimatedValue : function(percentage) {
2209        /// <summary>
2210        /// Get the interpolated color values
2211        /// </summary>
2212        /// <param name="percentage" type="Number">
2213        /// Percentage of the animation already complete
2214        /// </param>
2215        /// <returns type="String">
2216        /// Current color formatted as a 7-character hex string (like <code>#246ACF</code>).
2217        /// </returns>
2218
2219        var r = this._start.Red;
2220        var g = this._start.Green;
2221        var b = this._start.Blue;
2222        
2223        if (this._interpolateRed)
2224            r = Math.round(this.interpolate(r, this._end.Red, percentage));
2225        
2226        if (this._interpolateGreen)
2227            g = Math.round(this.interpolate(g, this._end.Green, percentage));
2228        
2229        if (this._interpolateBlue)
2230            b = Math.round(this.interpolate(b, this._end.Blue, percentage));
2231        
2232        return $AA.ColorAnimation.toColor(r, g, b);
2233    },
2234    
2235    set_startValue : function(value) {
2236        /// <value type="String">
2237        /// Starting color of the transition formatted as a 7-character hex string (like <code>#246ACF</code>).
2238        /// </value>
2239
2240        if (this._startValue != value) {
2241            this._startValue = value;
2242            this.raisePropertyChanged('startValue');
2243        }
2244    },
2245    
2246    set_endValue : function(value) {
2247        /// <value type="String">
2248        /// Ending color of the transition formatted as a 7-character hex string (like <code>#246ACF</code>).
2249        /// </value>
2250
2251        if (this._endValue != value) {
2252            this._endValue = value;
2253            this.raisePropertyChanged('endValue');
2254        }
2255    }   
2256}
2257$AA.ColorAnimation.getRGB = function(color) {
2258    /// <summary>
2259    /// Convert the color to an RGB triplet
2260    /// </summary>
2261    /// <param name="color" type="String">
2262    /// Color formatted as a 7-character hex string (like <code>#246ACF</code>)
2263    /// </param>
2264    /// <returns type="Object">
2265    /// Object representing the color with <code>Red</code>, <code>Green</code>, and <code>Blue</code> properties.
2266    /// </returns>
2267
2268    if (!color || color.length != 7) {
2269        throw String.format(Sys.Extended.UI.Resources.Animation_InvalidColor, color);
2270    }
2271    return { 'Red': parseInt(color.substr(1,2), 16),
2272             'Green': parseInt(color.substr(3,2), 16),
2273             'Blue': parseInt(color.substr(5,2), 16) };
2274}
2275$AA.ColorAnimation.toColor = function(red, green, blue) {
2276    /// <summary>
2277    /// Convert an RBG triplet into a 7-character hex string (like <code>#246ACF</code>)
2278    /// </summary>
2279    /// <param name="red" type="Number" integer="true">
2280    /// Value of the color's red dimension
2281    /// </param>
2282    /// <param name="green" type="Number" integer="true">
2283    /// Value of the color's green dimension
2284    /// </param>
2285    /// <param name="blue" type="Number" integer="true">
2286    /// Value of the color's blue dimension
2287    /// </param>
2288    /// <returns type="String">
2289    /// Color as a 7-character hex string (like <code>#246ACF</code>)
2290    /// </returns>
2291
2292    var r = red.toString(16);
2293    var g = green.toString(16);
2294    var b = blue.toString(16);
2295    if (r.length == 1) r = '0' + r;
2296    if (g.length == 1) g = '0' + g;
2297    if (b.length == 1) b = '0' + b;
2298    return '#' + r + g + b;
2299}
2300$AA.ColorAnimation.registerClass('Sys.Extended.UI.Animation.ColorAnimation', $AA.InterpolatedAnimation);
2301$AA.registerAnimation('color', $AA.ColorAnimation);
2302
2303
2304$AA.LengthAnimation = function(target, duration, fps, property, propertyKey, startValue, endValue, unit) {
2305    /// <summary>
2306    /// The <code>LengthAnimation</code> is identical to <see cref="Sys.Extended.UI.Animation.InterpolatedAnimation" />
2307    /// except it adds a <code>unit</code> to the value before assigning it to the <code>property</code>.
2308    /// </summary>
2309    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true">
2310    /// Target of the animation
2311    /// </param>
2312    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2313    /// Length of the animation in seconds.  The default is 1.
2314    /// </param>
2315    /// <param name="fps" type="Number" mayBeNull="true" optional="true">
2316    /// Number of steps per second.  The default is 25.
2317    /// </param>
2318    /// <param name="property" type="String" mayBeNull="true" optional="true">
2319    /// Property of the <code>target</code> element to set when animating.  The default value is 'style'.
2320    /// </param>
2321    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
2322    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
2323    /// </param>
2324    /// <param name="startValue" type="Number" mayBeNull="true" optional="true">
2325    /// Start of the range of values
2326    /// </param>
2327    /// <param name="endValue" type="Number" mayBeNull="true" optional="true">
2328    /// End of the range of values
2329    /// </param>
2330    /// <param name="unit" type="String" mayBeNull="true" optional="true">
2331    /// Unit of the interpolated values.  The default value is <code>'px'</code>.
2332    /// </param>
2333    /// <animation>Length</animation>
2334    $AA.LengthAnimation.initializeBase(this, [target, duration, fps, property, propertyKey, startValue, endValue]);
2335    
2336    this._unit = (unit != null) ? unit : 'px';
2337}
2338$AA.LengthAnimation.prototype = {
2339
2340    getAnimatedValue : function(percentage) {
2341        /// <summary>
2342        /// Get the interpolated length value
2343        /// </summary>
2344        /// <param name="percentage" type="Number">
2345        /// Percentage of the animation already complete
2346        /// </param>
2347        /// <returns type="String">
2348        /// Interpolated length
2349        /// </returns>
2350
2351        var value = this.interpolate(this.get_startValue(), this.get_endValue(), percentage);
2352        return Math.round(value) + this._unit;
2353    },
2354    
2355    get_unit : function() {
2356        /// <value type="String">
2357        /// Unit of the interpolated values.  The default value is <code>'px'</code>.
2358        /// </value>
2359        return this._unit;
2360    },
2361    set_unit : function(value) {
2362        if (this._unit != value) {
2363            this._unit = value;
2364            this.raisePropertyChanged('unit');
2365        }
2366    }
2367}
2368$AA.LengthAnimation.registerClass('Sys.Extended.UI.Animation.LengthAnimation', $AA.InterpolatedAnimation);
2369$AA.registerAnimation('length', $AA.LengthAnimation);
2370
2371
2372$AA.MoveAnimation = function(target, duration, fps, horizontal, vertical, relative, unit) {
2373    /// <summary>
2374    /// The <code>MoveAnimation</code> is used to move the <code>target</code> element. If the
2375    /// <code>relative</code> flag is set to <code>true</code>, then it treats the <code>horizontal</code>
2376    /// and <code>vertical</code> properties as offsets to move the element. If the <code>relative</code>
2377    /// flag is <code>false</code>, then it will treat the <code>horizontal</code> and <code>vertical</code>
2378    /// properties as coordinates on the page where the <code>target</code> element should be moved. It is
2379    /// important to note that the <code>target</code> must be positioned (i.e. <code>absolutely</code>) so
2380    /// that settings its <code>top</code>/<code>left<code> style attributes will change its location.
2381    /// </summary>
2382    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2383    /// Target of the animation
2384    /// </param>
2385    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2386    /// Length of the animation in seconds.  The default is 1.
2387    /// </param>
2388    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2389    /// Number of steps per second.  The default is 25.
2390    /// </param>
2391    /// <param name="horizontal" type="Number" mayBeNull="true" optional="true">
2392    /// If <code>relative</code>  is <code>true</code>, this is the offset to move horizontally. Otherwise this is the x
2393    /// coordinate on the page where the <code>target</code> should be moved.
2394    /// </param>
2395    /// <param name="vertical" type="Number" mayBeNull="true" optional="true">
2396    /// If <code>relative</code> is <code>true</code>, this is the offset to move vertically. Otherwise this is the y
2397    /// coordinate on the page where the <code>target</code> should be moved.
2398    /// </param>
2399    /// <param name="relative" type="Boolean" mayBeNull="true" optional="true">
2400    /// <code>true</code> if we are moving relative to the current position, <code>false</code> if we are moving absolutely
2401    /// </param>
2402    /// <param name="unit" type="String" mayBeNull="true" optional="true">
2403    /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
2404    /// </param>
2405    /// <animation>Move</animation>
2406    $AA.MoveAnimation.initializeBase(this, [target, duration, fps, null]);
2407
2408    this._horizontal = horizontal ? horizontal : 0;
2409    this._vertical = vertical ? vertical : 0;
2410    this._relative = (relative === undefined) ? true : relative;
2411    
2412    this._horizontalAnimation = new $AA.LengthAnimation(target, duration, fps, 'style', 'left', null, null, unit);
2413    this._verticalAnimation = new $AA.LengthAnimation(target, duration, fps, 'style', 'top', null, null, unit);
2414    this.add(this._verticalAnimation);
2415    this.add(this._horizontalAnimation);
2416}
2417$AA.MoveAnimation.prototype = {
2418    
2419    onStart : function() {
2420        /// <summary>
2421        /// Use the <code>target</code>'s current position as the starting point for the animation
2422        /// </summary>
2423        /// <returns />
2424        $AA.MoveAnimation.callBaseMethod(this, 'onStart');
2425        
2426        var element = this.get_target();
2427        this._horizontalAnimation.set_startValue(element.offsetLeft);
2428        this._horizontalAnimation.set_endValue(this._relative ? element.offsetLeft + this._horizontal : this._horizontal);
2429        this._verticalAnimation.set_startValue(element.offsetTop); 
2430        this._verticalAnimation.set_endValue(this._relative ? element.offsetTop + this._vertical : this._vertical);
2431    },
2432    
2433    get_horizontal : function() {
2434        /// <value type="Number">
2435        /// If <code>relative</code>  is <code>true</code>, this is the offset to move horizontally. Otherwise this is the x
2436        /// coordinate on the page where the <code>target</code> should be moved.
2437        /// </value>
2438        return this._horizontal;
2439    },
2440    set_horizontal : function(value) {
2441        value = this._getFloat(value);
2442        if (this._horizontal != value) {
2443            this._horizontal = value;
2444            this.raisePropertyChanged('horizontal');
2445        }
2446    },
2447    
2448    get_vertical : function() {
2449        /// <value type="Number">
2450        /// If <code>relative</code> is <code>true</code>, this is the offset to move vertically. Otherwise this is the y
2451        /// coordinate on the page where the <code>target</code> should be moved.
2452        /// </value>
2453        return this._vertical;
2454    },
2455    set_vertical : function(value) {
2456        value = this._getFloat(value);
2457        if (this._vertical != value) {
2458            this._vertical = value;
2459            this.raisePropertyChanged('vertical');
2460        }
2461    },
2462    
2463    get_relative : function() {
2464        /// <value type="Boolean">
2465        /// <code>true</code> if we are moving relative to the current position, <code>false</code> if we are moving absolutely
2466        /// </value>
2467        return this._relative;
2468    },
2469    set_relative : function(value) {
2470        value = this._getBoolean(value);
2471        if (this._relative != value) {
2472            this._relative = value;
2473            this.raisePropertyChanged('relative');
2474        }
2475    },
2476    
2477    get_unit : function() {
2478        /// <value type="String" mayBeNull="true">
2479        /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
2480        /// </value>
2481        this._horizontalAnimation.get_unit();
2482    },
2483    set_unit : function(value) {
2484        var unit = this._horizontalAnimation.get_unit();
2485        if (unit != value) {
2486            this._horizontalAnimation.set_unit(value);
2487            this._verticalAnimation.set_unit(value);
2488            this.raisePropertyChanged('unit');
2489        }
2490    }
2491}
2492$AA.MoveAnimation.registerClass('Sys.Extended.UI.Animation.MoveAnimation', $AA.ParallelAnimation);
2493$AA.registerAnimation('move', $AA.MoveAnimation);
2494
2495
2496$AA.ResizeAnimation = function(target, duration, fps, width, height, unit) {
2497    /// <summary>
2498    /// The <code>ResizeAnimation</code> changes the size of the <code>target</code> from its
2499    /// current value to the specified <code>width</code> and <code>height</code>.
2500    /// </summary>
2501    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2502    /// Target of the animation
2503    /// </param>
2504    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2505    /// Length of the animation in seconds.  The default is 1.
2506    /// </param>
2507    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2508    /// Number of steps per second.  The default is 25.
2509    /// </param>
2510    /// <param name="width" type="Number" mayBeNull="true" optional="true">
2511    /// New width of the <code>target</code>
2512    /// </param>
2513    /// <param name="height" type="Number" mayBeNull="true" optional="true">
2514    /// New height of the <code>target</code>
2515    /// </param>
2516    /// <param name="unit" type="String" mayBeNull="true" optional="true">
2517    /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
2518    /// </param>
2519    /// <animation>Resize</animation>
2520    $AA.ResizeAnimation.initializeBase(this, [target, duration, fps, null]);
2521
2522    this._width = width;
2523    this._height = height;
2524    
2525    this._horizontalAnimation = new $AA.LengthAnimation(target, duration, fps, 'style', 'width', null, null, unit);
2526    this._verticalAnimation = new $AA.LengthAnimation(target, duration, fps, 'style', 'height', null, null, unit);
2527    this.add(this._horizontalAnimation);
2528    this.add(this._verticalAnimation);
2529}
2530$AA.ResizeAnimation.prototype = {
2531    
2532    onStart : function() {
2533        /// <summary>
2534        /// Use the <code>target</code>'s current size as the starting point for the animation
2535        /// </summary>
2536        /// <returns />
2537
2538        $AA.ResizeAnimation.callBaseMethod(this, 'onStart');
2539        
2540        var element = this.get_target();
2541        this._horizontalAnimation.set_startValue(element.offsetWidth);
2542        this._verticalAnimation.set_startValue(element.offsetHeight);
2543        this._horizontalAnimation.set_endValue((this._width !== null && this._width !== undefined) ?
2544            this._width : element.offsetWidth);
2545        this._verticalAnimation.set_endValue((this._height !== null && this._height !== undefined) ?
2546            this._height : element.offsetHeight);
2547    },
2548    
2549    get_width : function() {
2550        /// <value type="Number">
2551        /// New width of the <code>target</code>
2552        /// </value>
2553
2554        return this._width;
2555    },
2556    set_width : function(value) {
2557        value = this._getFloat(value);
2558        if (this._width != value) {
2559            this._width = value;
2560            this.raisePropertyChanged('width');
2561        }
2562    },
2563    
2564    get_height : function() {
2565        /// <value type="Number">
2566        /// New height of the <code>target</code>
2567        /// </value>
2568
2569        return this._height;
2570    },
2571    set_height : function(value) {
2572        value = this._getFloat(value);
2573        if (this._height != value) {
2574            this._height = value;   
2575            this.raisePropertyChanged('height');
2576        }
2577    },
2578    
2579    get_unit : function() {
2580        /// <value type="String">
2581        /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
2582        /// </value>
2583
2584        this._horizontalAnimation.get_unit();
2585    },
2586    set_unit : function(value) {
2587        var unit = this._horizontalAnimation.get_unit();
2588        if (unit != value) {
2589            this._horizontalAnimation.set_unit(value);
2590            this._verticalAnimation.set_unit(value);
2591            this.raisePropertyChanged('unit');
2592        }
2593    }
2594}
2595$AA.ResizeAnimation.registerClass('Sys.Extended.UI.Animation.ResizeAnimation', $AA.ParallelAnimation);
2596$AA.registerAnimation('resize', $AA.ResizeAnimation);
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606$AA.ScaleAnimation = function(target, duration, fps, scaleFactor, unit, center, scaleFont, fontUnit) {
2607    /// <summary>
2608    /// The <code>ScaleAnimation</code> scales the size of the <code>target</code> element by the given <code>scaleFactor</code>
2609    /// (i.e. a <code>scaleFactor</code> of <code>.5</code> will shrink it in half and a <code>scaleFactor</code> of <code>2.0</code>
2610    /// will double it).  If <code>scaleFont</code> is <code>true</code>, the size of the font will also scale with the element.  If
2611    /// <code>center</code> is <code>true</code>, then the element's center will not move as it is scaled.  It is important to note that
2612    /// the target must be positioned (i.e. absolutely) so that setting its <code>top</code>/<code>left</code> properties will change
2613    /// its location in order for <code>center</code> to have an effect.
2614    /// </summary>
2615    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2616    /// Target of the animation
2617    /// </param>
2618    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2619    /// Length of the animation in seconds.  The default is 1.
2620    /// </param>
2621    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2622    /// Number of steps per second.  The default is 25.
2623    /// </param>
2624    /// <param name="scaleFactor" type="Number" mayBeNull="true" optional="true">
2625    /// The amount to scale the <code>target</code> (a <code>scaleFactor</code> of <code>.5</code> will
2626    /// shrink it in half and a <code>scaleFactor</code> of <code>2.0</code> will double it). The default value is
2627    /// <code>1</code>, which does no scaling.
2628    /// </param>
2629    /// <param name="unit" type="String" mayBeNull="true" optional="true">
2630    /// Length unit for the size of the <code>target</code>.  The default value is <code>'px'</code>.
2631    /// </param>
2632    /// <param name="center" type="Boolean" mayBeNull="true" optional="true">
2633    /// Whether the <code>target</code> should stay centered while scaling
2634    /// </param>
2635    /// <param name="scaleFont" type="Boolean" mayBeNull="true" optional="true">
2636    /// Whether the font should be scaled along with the size
2637    /// </param>
2638    /// <param name="fontUnit" type="String" mayBeNull="true" optional="true">
2639    /// Unit of the font, which is only used if <code>scaleFont</code> is <code>true</code>.
2640    /// The default value is <code>'pt'</code>.
2641    /// </param>
2642    /// <animation>Scale</animation>
2643    $AA.ScaleAnimation.initializeBase(this, [target, duration, fps]);
2644
2645    this._scaleFactor = (scaleFactor !== undefined) ? scaleFactor : 1;
2646    this._unit = (unit !== undefined) ? unit : 'px';
2647    
2648    this._center = center;
2649    
2650    this._scaleFont = scaleFont;
2651    this._fontUnit = (fontUnit !== undefined) ? fontUnit : 'pt';
2652    
2653    this._element = null;
2654    this._initialHeight = null;
2655    this._initialWidth = null;
2656    this._initialTop = null;
2657    this._initialLeft = null;
2658    this._initialFontSize = null;
2659}
2660$AA.ScaleAnimation.prototype = {    
2661    getAnimatedValue : function(percentage) {
2662        /// <summary>
2663        /// Get the amount to scale the <code>target</code>
2664        /// </summary>
2665        /// <param name="percentage" type="Number">
2666        /// Percentage of the animation already complete
2667        /// </param>
2668        /// <returns type="Number">
2669        /// Percentage to scale the <code>target</code>
2670        /// </returns>
2671        return this.interpolate(1.0, this._scaleFactor, percentage);
2672    },
2673    
2674    onStart : function() {
2675        /// <summary>
2676        /// Cache the initial size because it will be used to determine how much to scale the element at each step of the animation
2677        /// </summary>
2678        /// <returns />
2679        $AA.ScaleAnimation.callBaseMethod(this, 'onStart');
2680        
2681        this._element = this.get_target();
2682        if (this._element) {
2683            this._initialHeight = this._element.offsetHeight;
2684            this._initialWidth = this._element.offsetWidth;
2685            if (this._center) {
2686                this._initialTop = this._element.offsetTop;
2687                this._initialLeft = this._element.offsetLeft;
2688            }
2689            if (this._scaleFont) {
2690                this._initialFontSize = parseFloat(
2691                    $common.getCurrentStyle(this._element, 'fontSize'));
2692            }
2693        }
2694    },
2695    
2696    setValue : function(scale) {
2697        /// <summary>
2698        /// Scale the <code>target</code> by the given percentage
2699        /// </summary>
2700        /// <param name="scale" type="Number">
2701        /// Percentage to scale the <code>target</code>
2702        /// </param>
2703        /// <returns />
2704
2705        if (this._element) {
2706            var width = Math.round(this._initialWidth * scale);
2707            var height = Math.round(this._initialHeight * scale);
2708            this._element.style.width = width + this._unit; 
2709            this._element.style.height = height + this._unit;
2710            
2711            if (this._center) {
2712                this._element.style.top = (this._initialTop +
2713                    Math.round((this._initialHeight - height) / 2)) + this._unit;
2714                this._element.style.left = (this._initialLeft +
2715                    Math.round((this._initialWidth - width) / 2)) + this._unit;
2716            }
2717            
2718            if (this._scaleFont) {
2719                var size = this._initialFontSize * scale;
2720                if (this._fontUnit == 'px' || this._fontUnit == 'pt') {
2721                    size = Math.round(size);
2722                }
2723                this._element.style.fontSize = size + this._fontUnit;
2724            }
2725        }
2726    },
2727    
2728    onEnd : function() {
2729        /// <summary>
2730        /// Wipe the cached values after the animation completes
2731        /// </summary>
2732        /// <returns />
2733
2734        this._element = null;
2735        this._initialHeight = null;
2736        this._initialWidth = null;
2737        this._initialTop = null;
2738        this._initialLeft = null;
2739        this._initialFontSize = null;
2740        $AA.ScaleAnimation.callBaseMethod(this, 'onEnd');
2741    },
2742    
2743    get_scaleFactor : function() {
2744        /// <value type="Number">
2745        /// The amount to scale the <code>target</code> (a <code>scaleFactor</code> of <code>.5</code> will
2746        /// shrink it in half and a <code>scaleFactor</code> of <code>2.0</code> will double it). The default value is
2747        /// <code>1</code>, which does no scaling.
2748        /// </value>
2749
2750        return this._scaleFactor;
2751    },
2752    set_scaleFactor : function(value) {
2753        value = this._getFloat(value);
2754        if (this._scaleFactor != value) {
2755            this._scaleFactor = value;
2756            this.raisePropertyChanged('scaleFactor');
2757        }
2758    },
2759    
2760    get_unit : function() {
2761        /// <value type="String">
2762        /// Length unit for the size of the <code>target</code>.  The default value is <code>'px'</code>.
2763        /// </value>
2764        return this._unit;
2765    },
2766    set_unit : function(value) {
2767        if (this._unit != value) {
2768            this._unit = value;
2769            this.raisePropertyChanged('unit');
2770        }
2771    },
2772    
2773    get_center : function() {
2774        /// <value type="Boolean">
2775        /// Whether the <code>target</code> should stay centered while scaling
2776        /// </value>
2777        return this._center;
2778    },
2779    set_center : function(value) {
2780        value = this._getBoolean(value);
2781        if (this._center != value) {
2782            this._center = value;
2783            this.raisePropertyChanged('center');
2784        }
2785    },
2786    
2787    get_scaleFont : function() {
2788        /// <value type="Boolean">
2789        /// Whether the font should be scaled along with the size
2790        /// </value>
2791        return this._scaleFont;
2792    },
2793    set_scaleFont : function(value) {
2794        value = this._getBoolean(value);
2795        if (this._scaleFont != value) {
2796            this._scaleFont = value;
2797            this.raisePropertyChanged('scaleFont');
2798        }
2799    },
2800    
2801    get_fontUnit : function() {
2802        /// <value type="String">
2803        /// Unit of the font, which is only used if <code>scaleFont</code> is <code>true</code>.
2804        /// The default value is <code>'pt'</code>.
2805        /// </value>
2806        return this._fontUnit;
2807    },
2808    set_fontUnit : function(value) {
2809        if (this._fontUnit != value) { 
2810            this._fontUnit = value; 
2811            this.raisePropertyChanged('fontUnit');
2812        }
2813    }
2814}
2815$AA.ScaleAnimation.registerClass('Sys.Extended.UI.Animation.ScaleAnimation', $AA.Animation);
2816$AA.registerAnimation('scale', $AA.ScaleAnimation);
2817
2818
2819$AA.Action = function(target, duration, fps) {
2820    /// <summary>
2821    /// <code>Action</code> is a base class for all "non-animating" animations that provides empty implementations
2822    /// for abstract methods and adds a <code>doAction</code> method that will be called to perform the action's
2823    /// operation.  While regular animations perform an operation in a sequence of small steps spread over an interval,
2824    /// the actions perform a single operation instantaneously.  By default, all actions have a <code>duration</code>
2825    /// of zero.  The actions are very useful for defining complex animations.
2826    /// </summary>
2827    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2828    /// Target of the animation
2829    /// </param>
2830    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2831    /// Length of the animation in seconds.  The default is 0.
2832    /// </param>
2833    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2834    /// Number of steps per second.  The default is 25.
2835    /// </param>
2836    /// <animation>Action</animation>
2837    $AA.Action.initializeBase(this, [target, duration, fps]);
2838
2839    if (duration === undefined) {
2840        this.set_duration(0);
2841    }
2842}
2843$AA.Action.prototype = {
2844    
2845    onEnd : function() {
2846        /// <summary>
2847        /// Call the <code>doAction</code> method when the animation completes
2848        /// </summary>
2849        /// <returns />
2850        this.doAction();
2851        $AA.Action.callBaseMethod(this, 'onEnd');
2852    },
2853    
2854    doAction : function() {
2855        /// <summary>
2856        /// The <code>doAction</code> method must be implemented by all actions
2857        /// </summary>
2858        /// <returns />
2859        throw Error.notImplemented();
2860    },
2861    
2862    getAnimatedValue : function() {
2863        /// <summary>
2864        /// Empty implementation of required abstract method
2865        /// </summary>
2866    },
2867    setValue : function() {
2868        /// <summary>
2869        /// Empty implementation of required abstract method
2870        /// </summary>
2871    }
2872}
2873$AA.Action.registerClass('Sys.Extended.UI.Animation.Action', $AA.Animation);
2874$AA.registerAnimation('action', $AA.Action);
2875
2876
2877$AA.EnableAction = function(target, duration, fps, enabled) {
2878    /// <summary>
2879    /// The <code>EnableAction</code> changes whether or not the <code>target</code> is disabled.
2880    /// </summary>
2881    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2882    /// Target of the animation
2883    /// </param>
2884    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2885    /// Length of the animation in seconds.  The default is 0.
2886    /// </param>
2887    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2888    /// Number of steps per second.  The default is 25.
2889    /// </param>
2890    /// <param name="enabled" type="Boolean" mayBeNull="true" optional="true">
2891    /// Whether or not the <code>target</code> is disabled. The default value is <code>true</code>.
2892    /// </param>
2893    /// <animation>EnableAction</animation>
2894    $AA.EnableAction.initializeBase(this, [target, duration, fps]);
2895
2896    this._enabled = (enabled !== undefined) ? enabled : true;
2897}
2898$AA.EnableAction.prototype = {
2899    doAction : function() {
2900    	/// <summary>
2901        /// Set the enabled property of the <code>target</code>
2902    	/// </summary>
2903    	/// <returns />
2904    	
2905        var element = this.get_target();
2906        if (element) {
2907            element.disabled = !this._enabled;
2908        }
2909    },
2910    
2911    get_enabled : function() {
2912        /// <value type="Boolean">
2913        /// Whether or not the <code>target</code> is disabled. The default value is <code>true</code>.
2914        /// </value>
2915        return this._enabled;
2916    },
2917    set_enabled : function(value) {
2918        value = this._getBoolean(value);
2919        if (this._enabled != value) {
2920            this._enabled = value;
2921            this.raisePropertyChanged('enabled');
2922        }
2923    }
2924}
2925$AA.EnableAction.registerClass('Sys.Extended.UI.Animation.EnableAction', $AA.Action);
2926$AA.registerAnimation('enableAction', $AA.EnableAction);
2927
2928
2929$AA.HideAction = function(target, duration, fps, visible) {
2930    /// <summary>
2931    /// The <code>HideAction</code> simply hides the <code>target</code> from view
2932    /// (by setting its style's <code>display</code> attribute to <code>'none'</code>)
2933    /// </summary>
2934    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2935    /// Target of the animation
2936    /// </param>
2937    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2938    /// Length of the animation in seconds.  The default is 0.
2939    /// </param>
2940    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2941    /// Number of steps per second.  The default is 25.
2942    /// </param>
2943    /// <param name="visible" type="Boolean" mayBeNull="False">
2944    /// True to show the target, false to hide it.  The default value is false.
2945    /// </param>
2946    /// <animation>HideAction</animation>
2947    $AA.HideAction.initializeBase(this, [target, duration, fps]);
2948
2949    this._visible = visible;
2950}
2951$AA.HideAction.prototype = {
2952    doAction : function() {
2953        /// <summary>
2954        /// Hide the <code>target</code>
2955        /// </summary>
2956        /// <returns />
2957        var element = this.get_target();
2958        if (element) {
2959            $common.setVisible(element, this._visible);
2960        }
2961    },
2962    
2963    get_visible : function() {
2964        /// <value type="Boolean" mayBeNull="False">
2965        /// True to show the target, false to hide it.  The default value is false.
2966        /// </value>
2967        return this._visible;
2968    },
2969    set_visible : function(value) {
2970        if (this._visible != value) {
2971            this._visible = value;
2972            this.raisePropertyChanged('visible');
2973        }
2974    }
2975}
2976$AA.HideAction.registerClass('Sys.Extended.UI.Animation.HideAction', $AA.Action);
2977$AA.registerAnimation('hideAction', $AA.HideAction);
2978
2979
2980$AA.StyleAction = function(target, duration, fps, attribute, value) {
2981    /// <summary>
2982    /// The <code>StyleAction<code> is used to set a particular <code>attribute</code> of the <code>target</code>'s style
2983    /// </summary>
2984    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
2985    /// Target of the animation
2986    /// </param>
2987    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
2988    /// Length of the animation in seconds.  The default is 0.
2989    /// </param>
2990    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
2991    /// Number of steps per second.  The default is 25.
2992    /// </param>
2993    /// <param name="attribute" type="String" mayBeNull="true" optional="true">
2994    /// Style attribute to set (this must be in a JavaScript friendly format, i.e. <code>backgroundColor</code>
2995    /// instead of <code>background-color</code>)
2996    /// </param>
2997    /// <param name="value" type="String" mayBeNull="true" optional="true">
2998    /// Value to set the <code>attribute</code>
2999    /// </param>
3000    /// <animation>StyleAction</animation>
3001    $AA.StyleAction.initializeBase(this, [target, duration, fps]);
3002
3003    this._attribute = attribute;
3004    
3005    this._value = value;
3006    
3007}
3008$AA.StyleAction.prototype = {
3009    doAction : function() {
3010    	/// <summary>
3011        /// Assign the <code>value</code> to the style's <code>attribute</code>
3012    	/// </summary>
3013    	/// <returns />
3014        var element = this.get_target();
3015        if (element) {
3016            element.style[this._attribute] = this._value;
3017        }
3018    },
3019    
3020    get_attribute : function() {
3021        /// <value type="String">
3022        /// Style attribute to set (this must be in a JavaScript friendly format, i.e. <code>backgroundColor</code>
3023        /// instead of <code>background-color</code>)
3024        /// </value>
3025        return this._attribute;
3026    },
3027    set_attribute : function(value) {
3028        if (this._attribute != value) {
3029            this._attribute = value;
3030            this.raisePropertyChanged('attribute');
3031        }
3032    },
3033    
3034    get_value : function() {
3035        /// <value type="String">
3036        /// Value to set the <code>attribute</code>
3037        /// </value>
3038        return this._value;
3039    },
3040    set_value : function(value) {
3041        if (this._value != value) {
3042            this._value = value;
3043            this.raisePropertyChanged('value');
3044        }
3045    }
3046}
3047$AA.StyleAction.registerClass('Sys.Extended.UI.Animation.StyleAction', $AA.Action);
3048$AA.registerAnimation('styleAction', $AA.StyleAction);
3049
3050
3051$AA.OpacityAction = function(target, duration, fps, opacity) {
3052    /// <summary>
3053    /// <code>OpacityAction</code> allows you to set the <code>opacity</code> of the <code>target</code>
3054    /// </summary>
3055    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
3056    /// Target of the animation
3057    /// </param>
3058    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
3059    /// Length of the animation in seconds.  The default is 0.
3060    /// </param>
3061    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
3062    /// Number of steps per second.  The default is 25.
3063    /// </param>
3064    /// <param name="opacity" type="Number" mayBeNull="true" optional="true">
3065    /// Opacity to set the <code>target</code>
3066    /// </param>
3067    /// <animation>OpacityAction</animation>
3068    $AA.OpacityAction.initializeBase(this, [target, duration, fps]);
3069    
3070    this._opacity = opacity;
3071}
3072$AA.OpacityAction.prototype = {
3073    doAction : function() {
3074    	/// <summary>
3075        /// Set the opacity
3076    	/// </summary>
3077    	/// <returns />
3078        var element = this.get_target();
3079        if (element) {
3080            $common.setElementOpacity(element, this._opacity);
3081        }
3082    },
3083    
3084    get_opacity : function() {
3085        /// <value type="Number">
3086        /// Opacity to set the <code>target</code>
3087        /// </value>
3088        return this._opacity;
3089    },
3090    set_opacity : function(value) {
3091        value = this._getFloat(value);
3092        if (this._opacity != value) {
3093            this._opacity = value;
3094            this.raisePropertyChanged('opacity');
3095        }
3096    }
3097}
3098$AA.OpacityAction.registerClass('Sys.Extended.UI.Animation.OpacityAction', $AA.Action);
3099$AA.registerAnimation('opacityAction', $AA.OpacityAction);
3100
3101
3102$AA.ScriptAction = function(target, duration, fps, script) {
3103    /// <summary>
3104    /// The <code>ScriptAction</code> is used to execute arbitrary JavaScript
3105    /// </summary>
3106    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
3107    /// Target of the animation
3108    /// </param>
3109    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
3110    /// Length of the animation in seconds.  The default is 0.
3111    /// </param>
3112    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
3113    /// Number of steps per second.  The default is 25.
3114    /// </param>
3115    /// <param name="script" type="String" mayBeNull="true" optional="true">
3116    /// JavaScript to execute
3117    /// </param>
3118    /// <animation>ScriptAction</animation>
3119    $AA.ScriptAction.initializeBase(this, [target, duration, fps]);
3120
3121    this._script = script;
3122}
3123$AA.ScriptAction.prototype = {
3124    doAction : function() {
3125    	/// <summary>
3126        /// Execute the script
3127    	/// </summary>
3128    	/// <returns />
3129        try {
3130            eval(this._script);
3131        } catch (ex) {
3132        }
3133    },
3134    
3135    get_script : function() {
3136        /// <value type="String">
3137        /// JavaScript to execute
3138        /// </value>
3139        return this._script;
3140    },
3141    set_script : function(value) {
3142        if (this._script != value) {
3143            this._script = value;
3144            this.raisePropertyChanged('script');
3145        }
3146    }
3147}
3148$AA.ScriptAction.registerClass('Sys.Extended.UI.Animation.ScriptAction', $AA.Action);
3149$AA.registerAnimation('scriptAction', $AA.ScriptAction);
3150
3151} // execute
3152
3153if (window.Sys && Sys.loader) {
3154    Sys.loader.registerScript(scriptName, ["ExtendedCommon", "ExtendedTimer"], execute);
3155}
3156else {
3157    execute();
3158}
3159
3160})();
3161
3162var $AA;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.