diff --git a/build/caat-box2d-min.js b/build/caat-box2d-min.js index ae679185..4a9637a9 100644 --- a/build/caat-box2d-min.js +++ b/build/caat-box2d-min.js @@ -22,25 +22,56 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Version: 0.3 build: 212 +Version: 0.3 build: 289 Created on: -DATE: 2012-02-23 -TIME: 17:37:53 +DATE: 2012-02-28 +TIME: 09:21:50 +*/ + + +/* +The MIT License + +Copyright (c) 2010-2011-2012 Ibon Tolosana [@hyperandroid] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Version: 0.3 build: 289 + +Created on: +DATE: 2012-02-28 +TIME: 09:21:50 */ (function(){CAAT.enableBox2DDebug=function(b,a,c){if(b){b=new Box2D.Dynamics.b2DebugDraw;try{b.m_sprite.graphics.clear=function(){}}catch(d){}c.SetDebugDraw(b);b.SetSprite(a.ctx);b.SetDrawScale(CAAT.PMR);b.SetFillAlpha(0.5);b.SetLineThickness(1);b.SetFlags(3)}else c.setDebugDraw(null)}})(); -(function(){CAAT.B2DBodyActor=function(){CAAT.B2DBodyActor.superclass.constructor.call(this);return this};CAAT.B2DBodyActor.prototype={restitution:0.5,friction:0.5,density:1,bodyType:Box2D.Dynamics.b2Body.b2_dynamicBody,worldBody:null,world:null,worldBodyFixture:null,bodyDef:null,fixtureDef:null,bodyData:null,recycle:false,setRecycle:function(){this.recycle=true;return this},destroy:function(){CAAT.B2DBodyActor.superclass.destroy.call(this);if(this.recycle)this.setLocation(-Number.MAX_VALUE,-Number.MAX_VALUE), -this.setAwake(false);else{var b=this.worldBody;b.DestroyFixture(this.worldBodyFixture);this.world.DestroyBody(b)}return this},setAwake:function(b){this.worldBody.SetAwake(b);return this},setSleepingAllowed:function(b){this.worldBody.SetSleepingAllowed(b);return this},setLocation:function(b,a){this.worldBody.SetPosition(new Box2D.Common.Math.b2Vec2((b+this.width/2)/CAAT.PMR,(a+this.height/2)/CAAT.PMR));return this},setDensity:function(b){this.density=b;return this},setFriction:function(b){this.friction= -b;return this},setRestitution:function(b){this.restitution=b;return this},setBodyType:function(b){this.bodyType=b;return this},check:function(b,a,c){b[a]||(b[a]=c)},createBody:function(b,a){if(a)this.check(a,"density",1),this.check(a,"friction",0.5),this.check(a,"restitution",0.2),this.check(a,"bodyType",Box2D.Dynamics.b2Body.b2_staticBody),this.check(a,"userData",{}),this.check(a,"image",null),this.density=a.density,this.friction=a.friction,this.restitution=a.restitution,this.bodyType=a.bodyType, -this.image=a.image;this.world=b;return this},getCenter:function(){return{x:0,y:0}},getDistanceJointLocalAnchor:function(){return{x:0,y:0}}};extend(CAAT.B2DBodyActor,CAAT.Actor)})(); +(function(){CAAT.B2DBodyActor=function(){CAAT.B2DBodyActor.superclass.constructor.call(this);return this};CAAT.B2DBodyActor.prototype={restitution:0.5,friction:0.5,density:1,bodyType:Box2D.Dynamics.b2Body.b2_dynamicBody,worldBody:null,world:null,worldBodyFixture:null,bodyDef:null,fixtureDef:null,bodyData:null,recycle:!1,setRecycle:function(){this.recycle=!0;return this},destroy:function(){CAAT.B2DBodyActor.superclass.destroy.call(this);if(this.recycle)this.setLocation(-Number.MAX_VALUE,-Number.MAX_VALUE), +this.setAwake(!1);else{var b=this.worldBody;b.DestroyFixture(this.worldBodyFixture);this.world.DestroyBody(b)}return this},setAwake:function(b){this.worldBody.SetAwake(b);return this},setSleepingAllowed:function(b){this.worldBody.SetSleepingAllowed(b);return this},setLocation:function(b,a){this.worldBody.SetPosition(new Box2D.Common.Math.b2Vec2((b+this.width/2)/CAAT.PMR,(a+this.height/2)/CAAT.PMR));return this},setDensity:function(b){this.density=b;return this},setFriction:function(b){this.friction= +b;return this},setRestitution:function(b){this.restitution=b;return this},setBodyType:function(b){this.bodyType=b;return this},check:function(b,a,c){b[a]||(b[a]=c)},createBody:function(b,a){a&&(this.check(a,"density",1),this.check(a,"friction",0.5),this.check(a,"restitution",0.2),this.check(a,"bodyType",Box2D.Dynamics.b2Body.b2_staticBody),this.check(a,"userData",{}),this.check(a,"image",null),this.density=a.density,this.friction=a.friction,this.restitution=a.restitution,this.bodyType=a.bodyType, +this.image=a.image);this.world=b;return this},getCenter:function(){return{x:0,y:0}},getDistanceJointLocalAnchor:function(){return{x:0,y:0}}};extend(CAAT.B2DBodyActor,CAAT.Actor)})(); (function(){CAAT.B2DPolygonBody=function(){CAAT.B2DPolygonBody.superclass.constructor.call(this);return this};CAAT.B2DPolygonBody.Type={EDGE:"edge",BOX:"box",POLYGON:"polygon"};CAAT.B2DPolygonBody.prototype={boundingBox:null,getDistanceJointLocalAnchor:function(){return this.worldBody.GetFixtureList().GetShape().m_centroid},getCenter:function(){var b=this.worldBody,a=b.m_xf,b=b.GetFixtureList().GetShape();return Box2D.Common.Math.b2Math.MulX(a,b.m_centroid)},animate:function(b,a){var c=this.worldBody, d=c.m_xf,e=this.worldBodyFixture.GetShape();e&&(d=Box2D.Common.Math.b2Math.MulX(d,e.m_centroid),CAAT.Actor.prototype.setLocation.call(this,d.x*CAAT.PMR-this.width/2,d.y*CAAT.PMR-this.height/2),this.setRotation(c.GetAngle()));return CAAT.B2DPolygonBody.superclass.animate.call(this,b,a)},createBody:function(b,a){CAAT.B2DPolygonBody.superclass.createBody.call(this,b,a);var c=CAAT.B2DPolygonBody.createPolygonBody(b,a);a.userData.actor=this;this.worldBody=c.worldBody;this.worldBodyFixture=c.worldBodyFixture; this.fixtureDef=c.fixDef;this.bodyDef=c.bodyDef;this.bodyData=a;this.boundingBox=c.boundingBox;this.setBackgroundImage(a.image).setSize(c.boundingBox[1].x-c.boundingBox[0].x+1,c.boundingBox[1].y-c.boundingBox[0].y+1).setFillStyle(c.worldBodyFixture.IsSensor()?"red":"green").setImageTransformation(CAAT.SpriteImage.prototype.TR_FIXED_TO_SIZE);return this}};CAAT.B2DPolygonBody.createPolygonBody=function(b,a){var c=new Box2D.Dynamics.b2FixtureDef;c.density=a.density;c.friction=a.friction;c.restitution= -a.restitution;c.shape=new Box2D.Collision.Shapes.b2PolygonShape;var d=Number.MAX_VALUE,e=-Number.MAX_VALUE,g=Number.MAX_VALUE,j=-Number.MAX_VALUE,k=[],l=a.bodyDefScale||1;l+=(a.bodyDefScaleTolerance||0)*Math.random();for(var f=0;fe&&(e=h);ij&&(j=i);h+=a.x||0;i+=a.y||0;k.push(new Box2D.Common.Math.b2Vec2(h/CAAT.PMR,i/CAAT.PMR))}l=[{x:d,y:g},{x:e,y:j}];f=new Box2D.Dynamics.b2BodyDef;f.type=a.bodyType;if(a.polygonType=== -CAAT.B2DPolygonBody.Type.EDGE)c.shape.SetAsEdge(k[0],k[1]);else if(a.polygonType===CAAT.B2DPolygonBody.Type.BOX)c.shape.SetAsBox((e-d)/2/CAAT.PMR,(j-g)/2/CAAT.PMR),f.position.x=((e-d)/2+(a.x||0))/CAAT.PMR,f.position.y=((j-g)/2+(a.y||0))/CAAT.PMR;else if(a.polygonType===CAAT.B2DPolygonBody.Type.POLYGON)c.shape.SetAsArray(k,k.length);else throw"Unkown bodyData polygonType: "+a.polygonType;c.userData=a.userData;f.userData=a.userData;d=b.CreateBody(f);e=d.CreateFixture(c);a.isSensor&&e.SetSensor(true); -return{worldBody:d,worldBodyFixture:e,fixDef:c,bodyDef:f,boundingBox:l}};extend(CAAT.B2DPolygonBody,CAAT.B2DBodyActor)})(); +a.restitution;c.shape=new Box2D.Collision.Shapes.b2PolygonShape;for(var d=Number.MAX_VALUE,e=-Number.MAX_VALUE,g=Number.MAX_VALUE,k=-Number.MAX_VALUE,l=[],j=a.bodyDefScale||1,j=j+(a.bodyDefScaleTolerance||0)*Math.random(),f=0;fe&&(e=h);ik&&(k=i);h+=a.x||0;i+=a.y||0;l.push(new Box2D.Common.Math.b2Vec2(h/CAAT.PMR,i/CAAT.PMR))}j=[{x:d,y:g},{x:e,y:k}];f=new Box2D.Dynamics.b2BodyDef;f.type=a.bodyType;if(a.polygonType=== +CAAT.B2DPolygonBody.Type.EDGE)c.shape.SetAsEdge(l[0],l[1]);else if(a.polygonType===CAAT.B2DPolygonBody.Type.BOX)c.shape.SetAsBox((e-d)/2/CAAT.PMR,(k-g)/2/CAAT.PMR),f.position.x=((e-d)/2+(a.x||0))/CAAT.PMR,f.position.y=((k-g)/2+(a.y||0))/CAAT.PMR;else if(a.polygonType===CAAT.B2DPolygonBody.Type.POLYGON)c.shape.SetAsArray(l,l.length);else throw"Unkown bodyData polygonType: "+a.polygonType;c.userData=a.userData;f.userData=a.userData;d=b.CreateBody(f);e=d.CreateFixture(c);a.isSensor&&e.SetSensor(!0); +return{worldBody:d,worldBodyFixture:e,fixDef:c,bodyDef:f,boundingBox:j}};extend(CAAT.B2DPolygonBody,CAAT.B2DBodyActor)})(); (function(){CAAT.B2DCircularBody=function(){CAAT.B2DCircularBody.superclass.constructor.call(this);return this};CAAT.B2DCircularBody.prototype={radius:1,getDistanceJointLocalAnchor:function(){return new Box2D.Common.Math.b2Vec2(0,0)},getCenter:function(){return this.worldBody.m_xf.position},animate:function(b,a){var c=this.worldBody,d=c.m_xf;CAAT.Actor.prototype.setLocation.call(this,CAAT.PMR*d.position.x-this.width/2,CAAT.PMR*d.position.y-this.height/2);this.setRotation(c.GetAngle());return CAAT.B2DCircularBody.superclass.animate.call(this, -b,a)},createBody:function(b,a){var c=a.radius||1;c+=(a.bodyDefScaleTolerance||0)*Math.random();a.radius=c;CAAT.B2DCircularBody.superclass.createBody.call(this,b,a);if(a.radius)this.radius=a.radius;c=new Box2D.Dynamics.b2FixtureDef;c.density=this.density;c.friction=this.friction;c.restitution=this.restitution;c.shape=new Box2D.Collision.Shapes.b2CircleShape(this.radius/CAAT.PMR);var d=new Box2D.Dynamics.b2BodyDef;d.type=this.bodyType;d.position.x=a.x/CAAT.PMR;d.position.y=a.y/CAAT.PMR;a.userData.actor= -this;c.userData=a.userData;d.userData=a.userData;var e=b.CreateBody(d),g=e.CreateFixture(c);a.isSensor&&g.SetSensor(true);this.worldBody=e;this.worldBodyFixture=g;this.fixtureDef=c;this.bodyDef=d;this.bodyData=a;this.setFillStyle(this.worldBodyFixture.IsSensor()?"red":"blue").setBackgroundImage(this.image).setSize(2*this.radius,2*this.radius).setImageTransformation(CAAT.SpriteImage.prototype.TR_FIXED_TO_SIZE);return this}};extend(CAAT.B2DCircularBody,CAAT.B2DBodyActor)})(); +b,a)},createBody:function(b,a){var c=a.radius||1,c=c+(a.bodyDefScaleTolerance||0)*Math.random();a.radius=c;CAAT.B2DCircularBody.superclass.createBody.call(this,b,a);a.radius&&(this.radius=a.radius);c=new Box2D.Dynamics.b2FixtureDef;c.density=this.density;c.friction=this.friction;c.restitution=this.restitution;c.shape=new Box2D.Collision.Shapes.b2CircleShape(this.radius/CAAT.PMR);var d=new Box2D.Dynamics.b2BodyDef;d.type=this.bodyType;d.position.x=a.x/CAAT.PMR;d.position.y=a.y/CAAT.PMR;a.userData.actor= +this;c.userData=a.userData;d.userData=a.userData;var e=b.CreateBody(d),g=e.CreateFixture(c);a.isSensor&&g.SetSensor(!0);this.worldBody=e;this.worldBodyFixture=g;this.fixtureDef=c;this.bodyDef=d;this.bodyData=a;this.setFillStyle(this.worldBodyFixture.IsSensor()?"red":"blue").setBackgroundImage(this.image).setSize(2*this.radius,2*this.radius).setImageTransformation(CAAT.SpriteImage.prototype.TR_FIXED_TO_SIZE);return this}};extend(CAAT.B2DCircularBody,CAAT.B2DBodyActor)})(); diff --git a/build/caat-box2d.js b/build/caat-box2d.js index 572d179f..aa5ca543 100644 --- a/build/caat-box2d.js +++ b/build/caat-box2d.js @@ -21,11 +21,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Version: 0.3 build: 213 +Version: 0.3 build: 291 Created on: -DATE: 2012-02-23 -TIME: 17:38:27 +DATE: 2012-02-28 +TIME: 09:22:12 */ diff --git a/build/caat-css-min.js b/build/caat-css-min.js index 5495382a..2d3c9822 100644 --- a/build/caat-css-min.js +++ b/build/caat-css-min.js @@ -22,285 +22,338 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Version: 0.3 build: 212 +Version: 0.3 build: 289 Created on: -DATE: 2012-02-23 -TIME: 17:37:53 +DATE: 2012-02-28 +TIME: 09:21:50 */ -var CAAT=CAAT||{};Function.prototype.bind=Function.prototype.bind||function(){var a=this,b=Array.prototype.slice.call(arguments),c=b.shift();return function(){return a.apply(c,b.concat(Array.prototype.slice.call(arguments)))}};CAAT.__CSS__=1;CAAT.__CSS__=1;(function(){CAAT.BrowserDetect=function(){this.init();return this};CAAT.BrowserDetect.prototype={browser:"",version:0,OS:"",init:function(){this.browser=this.searchString(this.dataBrowser)||"An unknown browser";this.version=this.searchVersion(navigator.userAgent)||this.searchVersion(navigator.appVersion)||"an unknown version";this.OS=this.searchString(this.dataOS)||"an unknown OS"},searchString:function(a){for(var b=0;b>8&255,a&255)};Array.prototype.push32=function(a){this.push(a>>24&255,a>>16&255,a>>8&255,a&255)};Array.prototype.map||(Array.prototype.map=function(a,b){var c=this.length;if("function"!=typeof a)throw new TypeError;for(var d=Array(c),e=0;e=b)b+=32;else if(3===a.keyLocation)switch(b){case 96:b=48;break;case 97:b=49;break;case 98:b=50;break;case 99:b=51;break;case 100:b=52;break;case 101:b=53;break;case 102:b=54;break;case 103:b=55;break;case 104:b=56;break;case 105:b=57;break;case 109:b=45;break;case 110:b=46;break;case 111:b=47}}return b}function c(a){if(!g.focused)return!0;for(var c=null,d=a?a:window.event,e=null,f=!1,c="type,keyCode,charCode,which,altKey,ctrlKey,shiftKey,keyLocation,keyIdentifier".split(","), +l={},e=0;ee&&(f="Mapping character code "+e,e=unicodeTable[e],"undefined"===typeof e&&(e=0),Util.Debug(f+" to "+e));0a;a++)for(var b=0;4>b;b++)this.matrix[a][b]=a===b?1:0;return this},getMatrix:function(){return this.matrix},rotateXY:function(a){return this.rotate(a,0,0)},rotateXZ:function(a){return this.rotate(0,a,0)},rotateYZ:function(a){return this.rotate(0,0,a)},setRotate:function(a,b,c){this.copy(this.rotate(a,b,c));return this},rotate:function(a,b,c){var d=new CAAT.Matrix3,e,f;0!==a&&(f=new CAAT.Matrix3, +e=Math.sin(a),a=Math.cos(a),f.matrix[1][1]=a,f.matrix[1][2]=-e,f.matrix[2][1]=e,f.matrix[2][2]=a,d.multiply(f));0!==b&&(f=new CAAT.Matrix3,e=Math.sin(b),a=Math.cos(b),f.matrix[0][0]=a,f.matrix[0][2]=-e,f.matrix[2][0]=e,f.matrix[2][2]=a,d.multiply(f));0!==c&&(f=new CAAT.Matrix3,e=Math.sin(c),a=Math.cos(c),f.matrix[0][0]=a,f.matrix[0][1]=-e,f.matrix[1][0]=e,f.matrix[1][1]=a,d.multiply(f));return d},getClone:function(){var a=new CAAT.Matrix3;a.copy(this);return a},multiply:function(a){var b=this.getClone().matrix, c=b[0][0],d=b[0][1],e=b[0][2],f=b[0][3],g=b[1][0],h=b[1][1],i=b[1][2],j=b[1][3],k=b[2][0],m=b[2][1],n=b[2][2],b=b[2][3],l=a.matrix,a=l[0][0],o=l[0][1],p=l[0][2],q=l[0][3],r=l[1][0],s=l[1][1],t=l[1][2],u=l[1][3],v=l[2][0],w=l[2][1],x=l[2][2],y=l[2][3],z=l[3][0],A=l[3][1],B=l[3][2],l=l[3][3];this.matrix[0][0]=c*a+d*r+e*v+f*z;this.matrix[0][1]=c*o+d*s+e*w+f*A;this.matrix[0][2]=c*p+d*t+e*x+f*B;this.matrix[0][3]=c*q+d*u+e*y+f*l;this.matrix[1][0]=g*a+h*r+i*v+j*z;this.matrix[1][1]=g*o+h*s+i*w+j*A;this.matrix[1][2]= g*p+h*t+i*x+j*B;this.matrix[1][3]=g*q+h*u+i*y+j*l;this.matrix[2][0]=k*a+m*r+n*v+b*z;this.matrix[2][1]=k*o+m*s+n*w+b*A;this.matrix[2][2]=k*p+m*t+n*x+b*B;this.matrix[2][3]=k*q+m*u+n*y+b*l;return this},premultiply:function(a){var b=this.getClone().matrix,c=b[0][0],d=b[0][1],e=b[0][2],f=b[0][3],g=b[1][0],h=b[1][1],i=b[1][2],j=b[1][3],k=b[2][0],m=b[2][1],n=b[2][2],b=b[2][3],l=a.matrix,a=l[0][0],o=l[0][1],p=l[0][2],q=l[0][3],r=l[1][0],s=l[1][1],t=l[1][2],u=l[1][3],v=l[2][0],w=l[2][1],x=l[2][2],l=l[2][3]; this.matrix[0][0]=c*a+d*r+e*v;this.matrix[0][1]=c*o+d*s+e*w;this.matrix[0][2]=c*p+d*t+e*x;this.matrix[0][3]=c*q+d*u+e*l+f;this.matrix[1][0]=g*a+h*r+i*v;this.matrix[1][1]=g*o+h*s+i*w;this.matrix[1][2]=g*p+h*t+i*x;this.matrix[1][3]=g*q+h*u+i*l+j;this.matrix[2][0]=k*a+m*r+n*v;this.matrix[2][1]=k*o+m*s+n*w;this.matrix[2][2]=k*p+m*t+n*x;this.matrix[2][3]=k*q+m*u+n*l+b;return this},setTranslate:function(a,b,c){this.identity();this.matrix[0][3]=a;this.matrix[1][3]=b;this.matrix[2][3]=c;return this},translate:function(a, b,c){var d=new CAAT.Matrix3;d.setTranslate(a,b,c);return d},setScale:function(a,b,c){this.identity();this.matrix[0][0]=a;this.matrix[1][1]=b;this.matrix[2][2]=c;return this},scale:function(a,b,c){var d=new CAAT.Matrix3;d.setScale(a,b,c);return d},rotateModelView:function(a,b,c){var d=Math.sin(a),e=Math.sin(b),f=Math.sin(c),a=Math.cos(a),b=Math.cos(b),c=Math.cos(c);this.matrix[0][0]=b*a;this.matrix[0][1]=-b*d;this.matrix[0][2]=e;this.matrix[0][3]=0;this.matrix[1][0]=f*e*a+d*c;this.matrix[1][1]=c*a- -f*e*d;this.matrix[1][2]=-f*b;this.matrix[1][3]=0;this.matrix[2][0]=f*d-c*e*a;this.matrix[2][1]=c*e*d+f*a;this.matrix[2][2]=c*b;this.matrix[2][3]=0;this.matrix[3][0]=0;this.matrix[3][1]=0;this.matrix[3][2]=0;this.matrix[3][3]=1;return this},copy:function(a){for(var b=0;b<4;b++)for(var c=0;c<4;c++)this.matrix[b][c]=a.matrix[b][c];return this},calculateDeterminant:function(){var a=this.matrix,b=a[0][0],c=a[0][1],d=a[0][2],e=a[0][3],f=a[1][0],g=a[1][1],h=a[1][2],i=a[1][3],j=a[2][0],k=a[2][1],m=a[2][2], +f*e*d;this.matrix[1][2]=-f*b;this.matrix[1][3]=0;this.matrix[2][0]=f*d-c*e*a;this.matrix[2][1]=c*e*d+f*a;this.matrix[2][2]=c*b;this.matrix[2][3]=0;this.matrix[3][0]=0;this.matrix[3][1]=0;this.matrix[3][2]=0;this.matrix[3][3]=1;return this},copy:function(a){for(var b=0;4>b;b++)for(var c=0;4>c;c++)this.matrix[b][c]=a.matrix[b][c];return this},calculateDeterminant:function(){var a=this.matrix,b=a[0][0],c=a[0][1],d=a[0][2],e=a[0][3],f=a[1][0],g=a[1][1],h=a[1][2],i=a[1][3],j=a[2][0],k=a[2][1],m=a[2][2], n=a[2][3],l=a[3][0],o=a[3][1],p=a[3][2],a=a[3][3];return e*g*m*l+c*i*m*l+e*h*j*o+d*i*j*o+d*f*n*o+b*h*n*o+e*f*k*p+b*i*k*p+d*g*j*a+c*h*j*a+c*f*m*a+b*g*m*a+e*h*k*l-d*i*k*l-d*g*n*l-c*h*n*l-e*f*m*o-b*i*m*o-e*g*j*p-c*i*j*p-c*f*n*p-b*g*n*p-d*f*k*a-b*h*k*a},getInverse:function(){var a=this.matrix,b=a[0][0],c=a[0][1],d=a[0][2],e=a[0][3],f=a[1][0],g=a[1][1],h=a[1][2],i=a[1][3],j=a[2][0],k=a[2][1],m=a[2][2],n=a[2][3],l=a[3][0],o=a[3][1],p=a[3][2],a=a[3][3],q=new CAAT.Matrix3;q.matrix[0][0]=h*n*o+i*k*p+g*m*a- i*m*o-g*n*p-h*k*a;q.matrix[0][1]=e*m*o+c*n*p+d*k*a-c*m*a-d*n*o-e*k*p;q.matrix[0][2]=d*i*o+c*h*a+e*g*p-c*i*p-d*g*a-e*h*o;q.matrix[0][3]=e*h*k+c*i*m+d*g*n-d*i*k-e*g*m-c*h*n;q.matrix[1][0]=i*m*l+f*n*p+h*j*a-h*n*l-i*j*p-f*m*a;q.matrix[1][1]=d*n*l+e*j*p+b*m*a-e*m*l-b*n*p-d*j*a;q.matrix[1][2]=e*h*l+b*i*p+d*f*a-d*i*l-e*f*p-b*h*a;q.matrix[1][3]=d*i*j+e*f*m+b*h*n-e*h*j-b*i*m-d*f*n;q.matrix[2][0]=g*n*l+i*j*o+f*k*a-i*k*l-f*n*o-g*j*a;q.matrix[2][1]=e*k*l+b*n*o+c*j*a-b*k*a-c*n*l-e*j*o;q.matrix[2][2]=d*i*l+e*f* -o+b*g*a-e*g*l-b*i*o-c*f*a;q.matrix[2][3]=e*g*j+b*i*k+c*f*n-b*g*n-c*i*j-e*f*k;q.matrix[3][0]=h*k*l+f*m*o+g*j*p-g*m*l-h*j*o-f*k*p;q.matrix[3][1]=c*m*l+d*j*o+b*k*p-d*k*l-b*m*o-c*j*p;q.matrix[3][2]=d*g*l+b*h*o+c*f*p-b*g*p-c*h*l-d*f*o;q.matrix[3][3]=c*h*j+d*f*k+b*g*m-d*g*j-b*h*k-c*f*m;return q.multiplyScalar(1/this.calculateDeterminant())},multiplyScalar:function(a){var b,c;for(b=0;b<4;b++)for(c=0;c<4;c++)this.matrix[b][c]*=a;return this}}})(); +o+b*g*a-e*g*l-b*i*o-c*f*a;q.matrix[2][3]=e*g*j+b*i*k+c*f*n-b*g*n-c*i*j-e*f*k;q.matrix[3][0]=h*k*l+f*m*o+g*j*p-g*m*l-h*j*o-f*k*p;q.matrix[3][1]=c*m*l+d*j*o+b*k*p-d*k*l-b*m*o-c*j*p;q.matrix[3][2]=d*g*l+b*h*o+c*f*p-b*g*p-c*h*l-d*f*o;q.matrix[3][3]=c*h*j+d*f*k+b*g*m-d*g*j-b*h*k-c*f*m;return q.multiplyScalar(1/this.calculateDeterminant())},multiplyScalar:function(a){var b,c;for(b=0;4>b;b++)for(c=0;4>c;c++)this.matrix[b][c]*=a;return this}}})(); (function(){CAAT.Matrix=function(){this.matrix=[1,0,0,0,1,0,0,0,1];return this};CAAT.Matrix.prototype={matrix:null,transformCoord:function(a){var b=a.x,c=a.y,d=this.matrix;a.x=b*d[0]+c*d[1]+d[2];a.y=b*d[3]+c*d[4]+d[5];return a},rotate:function(a){var b=new CAAT.Matrix;b.setRotation(a);return b},setRotation:function(a){this.identity();var b=this.matrix,c=Math.cos(a),a=Math.sin(a);b[0]=c;b[1]=-a;b[3]=a;b[4]=c;return this},scale:function(a,b){var c=new CAAT.Matrix;c.matrix[0]=a;c.matrix[4]=b;return c}, setScale:function(a,b){this.identity();this.matrix[0]=a;this.matrix[4]=b;return this},translate:function(a,b){var c=new CAAT.Matrix;c.matrix[2]=a;c.matrix[5]=b;return c},setTranslate:function(a,b){this.identity();this.matrix[2]=a;this.matrix[5]=b;return this},copy:function(a){var a=a.matrix,b=this.matrix;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},identity:function(){var a=this.matrix;a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]= 0;a[8]=1;return this},multiply:function(a){var b=this.matrix,c=a.matrix,a=b[0],d=b[1],e=b[2],f=b[3],g=b[4],h=b[5],i=b[6],j=b[7],k=b[8],m=c[0],n=c[1],l=c[2],o=c[3],p=c[4],q=c[5],r=c[6],s=c[7],c=c[8];b[0]=a*m+d*o+e*r;b[1]=a*n+d*p+e*s;b[2]=a*l+d*q+e*c;b[3]=f*m+g*o+h*r;b[4]=f*n+g*p+h*s;b[5]=f*l+g*q+h*c;b[6]=i*m+j*o+k*r;b[7]=i*n+j*p+k*s;b[8]=i*l+j*q+k*c;return this},premultiply:function(a){var b=a.matrix[0]*this.matrix[1]+a.matrix[1]*this.matrix[4]+a.matrix[2]*this.matrix[7],c=a.matrix[0]*this.matrix[2]+ a.matrix[1]*this.matrix[5]+a.matrix[2]*this.matrix[8],d=a.matrix[3]*this.matrix[0]+a.matrix[4]*this.matrix[3]+a.matrix[5]*this.matrix[6],e=a.matrix[3]*this.matrix[1]+a.matrix[4]*this.matrix[4]+a.matrix[5]*this.matrix[7],f=a.matrix[3]*this.matrix[2]+a.matrix[4]*this.matrix[5]+a.matrix[5]*this.matrix[8],g=a.matrix[6]*this.matrix[0]+a.matrix[7]*this.matrix[3]+a.matrix[8]*this.matrix[6],h=a.matrix[6]*this.matrix[1]+a.matrix[7]*this.matrix[4]+a.matrix[8]*this.matrix[7],i=a.matrix[6]*this.matrix[2]+a.matrix[7]* -this.matrix[5]+a.matrix[8]*this.matrix[8];this.matrix[0]=a.matrix[0]*this.matrix[0]+a.matrix[1]*this.matrix[3]+a.matrix[2]*this.matrix[6];this.matrix[1]=b;this.matrix[2]=c;this.matrix[3]=d;this.matrix[4]=e;this.matrix[5]=f;this.matrix[6]=g;this.matrix[7]=h;this.matrix[8]=i;return this},getInverse:function(){var a=this.matrix,b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],a=a[8],j=new CAAT.Matrix,k=b*(f*a-i*g)-e*(c*a-i*d)+h*(c*g-f*d);if(k===0)return null;var m=j.matrix;m[0]=f*a-g*i;m[1]=d* -i-c*a;m[2]=c*g-d*f;m[3]=g*h-e*a;m[4]=b*a-d*h;m[5]=d*e-b*g;m[6]=e*i-f*h;m[7]=c*h-b*i;m[8]=b*f-c*e;j.multiplyScalar(1/k);return j},multiplyScalar:function(a){var b;for(b=0;b<9;b++)this.matrix[b]*=a;return this},transformRenderingContextSet:null,transformRenderingContext:null,transformRenderingContextSet_NoClamp:function(a){var b=this.matrix;a.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]);return this},transformRenderingContext_NoClamp:function(a){var b=this.matrix;a.transform(b[0],b[3],b[1],b[4],b[2], +this.matrix[5]+a.matrix[8]*this.matrix[8];this.matrix[0]=a.matrix[0]*this.matrix[0]+a.matrix[1]*this.matrix[3]+a.matrix[2]*this.matrix[6];this.matrix[1]=b;this.matrix[2]=c;this.matrix[3]=d;this.matrix[4]=e;this.matrix[5]=f;this.matrix[6]=g;this.matrix[7]=h;this.matrix[8]=i;return this},getInverse:function(){var a=this.matrix,b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],a=a[8],j=new CAAT.Matrix,k=b*(f*a-i*g)-e*(c*a-i*d)+h*(c*g-f*d);if(0===k)return null;var m=j.matrix;m[0]=f*a-g*i;m[1]=d* +i-c*a;m[2]=c*g-d*f;m[3]=g*h-e*a;m[4]=b*a-d*h;m[5]=d*e-b*g;m[6]=e*i-f*h;m[7]=c*h-b*i;m[8]=b*f-c*e;j.multiplyScalar(1/k);return j},multiplyScalar:function(a){var b;for(b=0;9>b;b++)this.matrix[b]*=a;return this},transformRenderingContextSet:null,transformRenderingContext:null,transformRenderingContextSet_NoClamp:function(a){var b=this.matrix;a.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]);return this},transformRenderingContext_NoClamp:function(a){var b=this.matrix;a.transform(b[0],b[3],b[1],b[4],b[2], b[5]);return this},transformRenderingContextSet_Clamp:function(a){var b=this.matrix;a.setTransform(b[0],b[3],b[1],b[4],b[2]>>0,b[5]>>0);return this},transformRenderingContext_Clamp:function(a){var b=this.matrix;a.transform(b[0],b[3],b[1],b[4],b[2]>>0,b[5]>>0);return this}};CAAT.Matrix.prototype.transformRenderingContext=CAAT.Matrix.prototype.transformRenderingContext_Clamp;CAAT.Matrix.prototype.transformRenderingContextSet=CAAT.Matrix.prototype.transformRenderingContextSet_Clamp})(); -(function(){CAAT.MatrixStack=function(){this.stack=[];this.saved=[];return this};CAAT.MatrixStack.prototype={stack:null,saved:null,pushMatrix:function(a){this.stack.push(a);return this},popMatrix:function(){return this.stack.pop()},save:function(){this.saved.push(this.stack.length);return this},restore:function(){for(var a=this.saved.pop();this.stack.length!==a;)this.popMatrix();return this},getMatrix:function(){for(var a=new CAAT.Matrix,b=0;b=g)return{r:d,g:e,b:f};a=a+(d-a)/g*h>>0;b=b+(e-b)/g*h>>0;c=c+(f-c)/g*h>>0;a>255?a=255:a<0&&(a=0);b>255?b=255:b<0&&(b=0);c>255?c=255:c<0&&(c=0);return{r:a,g:b,b:c}},makeRGBColorRamp:function(a,b,c){var d=[],e=a.length-1;b/=e;for(var f=0;f>24&255,i=(g&16711680)>>16,j=(g&65280)>>8;g&=255;for(var k=a[f+1],m=((k>>24&255)-h)/b,n=(((k&16711680)>>16)-i)/b,l=(((k&65280)>>8)-j)/b,k=((k&255)-g)/b,o=0;o>0,q=i+n*o>>0,r=j+l*o>>0,s=g+k*o>>0;switch(c){case this.RampEnumeration.RAMP_RGBA:d.push("argb("+p+","+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_RGB:d.push("rgb("+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_CHANNEL_RGB:d.push(4278190080|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA:d.push(p<< -24|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY:d.push([q,r,s,p]);break;case this.RampEnumeration.RAMP_CHANNEL_RGB_ARRAY:d.push([q,r,s])}}}return d}}})();(function(){CAAT.Color.RGB=function(a,b,c){this.r=a||255;this.g=b||255;this.b=c||255;return this};CAAT.Color.RGB.prototype={r:255,g:255,b:255,toHex:function(){return("000000"+((this.r<<16)+(this.g<<8)+this.b).toString(16)).slice(-6)}}})();(function(){CAAT.Rectangle=function(){return this};CAAT.Rectangle.prototype={x:0,y:0,x1:0,y1:0,width:-1,height:-1,setEmpty:function(){this.height=this.width=-1;this.y1=this.x1=this.y=this.x=0;return this},setLocation:function(a,b){this.x=a;this.y=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setDimension:function(a,b){this.width=a;this.height=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setBounds:function(a,b,c,d){this.setLocation(a,b);this.setDimension(c, -d);return this},contains:function(a,b){return a>=0&&a=0&&bthis.y1)this.y1=b;if(a>this.x1)this.x1=a;this.width=this.x1-this.x;this.height=this.y1-this.y}},unionRectangle:function(a){this.union(a.x,a.y);this.union(a.x1, -a.y);this.union(a.x,a.y1);this.union(a.x1,a.y1);return this},intersects:function(a){return a.isEmpty()||this.isEmpty()?false:a.x1this.x1?false:a.y1this.y1?false:true},intersectsRect:function(a,b,c,d){return-1===c||-1===d?false:a+c-1this.x1?false:b+d-1this.y1?false:true},intersect:function(a,b){typeof b==="undefined"&&(b=new CAAT.Rectangle);b.x=Math.max(this.x,a.x);b.y=Math.max(this.y,a.y);b.x1=Math.min(this.x1,a.x1);b.y1=Math.min(this.y1, -a.y1);b.width=b.x1-b.x;b.height=b.y1-b.y;return b}}})();(function(){CAAT.Curve=function(){return this};CAAT.Curve.prototype={coordlist:null,k:0.05,length:-1,interpolator:false,HANDLE_SIZE:20,drawHandles:true,paint:function(a){if(false!==this.drawHandles){a=a.ctx;a.save();a.beginPath();a.strokeStyle="#a0a0a0";a.moveTo(this.coordlist[0].x,this.coordlist[0].y);a.lineTo(this.coordlist[1].x,this.coordlist[1].y);a.stroke();this.cubic&&(a.moveTo(this.coordlist[2].x,this.coordlist[2].y),a.lineTo(this.coordlist[3].x,this.coordlist[3].y),a.stroke());a.globalAlpha= -0.5;for(var b=0;b=0&&b=h)return{r:a,g:b,b:c};if(h>=g)return{r:d,g:e,b:f};a=a+(d-a)/g*h>>0;b=b+(e-b)/g*h>>0;c=c+(f-c)/g*h>>0;255a&&(a=0);255b&&(b=0);255c&&(c=0);return{r:a,g:b,b:c}},makeRGBColorRamp:function(a,b,c){for(var d=[],e=a.length-1,b=b/e,f=0;f>24&255,i=(g&16711680)>>16,j=(g&65280)>>8,g=g&255,k=a[f+1],m=((k>>24&255)-h)/b,n=(((k&16711680)>>16)-i)/b,l=(((k&65280)>>8)-j)/b,k=((k&255)-g)/b,o=0;o>0,q=i+n*o>>0,r=j+l*o>>0,s=g+k*o>>0;switch(c){case this.RampEnumeration.RAMP_RGBA:d.push("argb("+p+","+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_RGB:d.push("rgb("+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_CHANNEL_RGB:d.push(4278190080|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA:d.push(p<< +24|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY:d.push([q,r,s,p]);break;case this.RampEnumeration.RAMP_CHANNEL_RGB_ARRAY:d.push([q,r,s])}}return d}}})();(function(){CAAT.Color.RGB=function(a,b,c){this.r=a||255;this.g=b||255;this.b=c||255;return this};CAAT.Color.RGB.prototype={r:255,g:255,b:255,toHex:function(){return("000000"+((this.r<<16)+(this.g<<8)+this.b).toString(16)).slice(-6)}}})();(function(){CAAT.Rectangle=function(){return this};CAAT.Rectangle.prototype={x:0,y:0,x1:0,y1:0,width:-1,height:-1,setEmpty:function(){this.height=this.width=-1;this.y1=this.x1=this.y=this.x=0;return this},setLocation:function(a,b){this.x=a;this.y=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setDimension:function(a,b){this.width=a;this.height=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setBounds:function(a,b,c,d){this.setLocation(a,b);this.setDimension(c, +d);return this},contains:function(a,b){return 0<=a&&athis.y1&&(this.y1=b),a>this.x1&&(this.x1=a),this.width=this.x1-this.x,this.height=this.y1-this.y)},unionRectangle:function(a){this.union(a.x,a.y);this.union(a.x1, +a.y);this.union(a.x,a.y1);this.union(a.x1,a.y1);return this},intersects:function(a){return a.isEmpty()||this.isEmpty()||a.x1this.x1||a.y1this.y1?!1:!0},intersectsRect:function(a,b,c,d){return-1===c||-1===d||a+c-1this.x1||b+d-1this.y1?!1:!0},intersect:function(a,b){"undefined"===typeof b&&(b=new CAAT.Rectangle);b.x=Math.max(this.x,a.x);b.y=Math.max(this.y,a.y);b.x1=Math.min(this.x1,a.x1);b.y1=Math.min(this.y1,a.y1);b.width=b.x1-b.x;b.height=b.y1-b.y; +return b}}})();(function(){CAAT.Curve=function(){return this};CAAT.Curve.prototype={coordlist:null,k:0.05,length:-1,interpolator:!1,HANDLE_SIZE:20,drawHandles:!0,paint:function(a){if(!1!==this.drawHandles){a=a.ctx;a.save();a.beginPath();a.strokeStyle="#a0a0a0";a.moveTo(this.coordlist[0].x,this.coordlist[0].y);a.lineTo(this.coordlist[1].x,this.coordlist[1].y);a.stroke();this.cubic&&(a.moveTo(this.coordlist[2].x,this.coordlist[2].y),a.lineTo(this.coordlist[3].x,this.coordlist[3].y),a.stroke());a.globalAlpha=0.5;for(var b= +0;ba*a)b=Math.sqrt(b),this.x=this.x/b*a,this.y=this.y/b*a,this.z=this.z/b*a;return this},getLength:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);return a<0.0050&&a>-0.0050?1.0E-6:a},getLengthSquared:function(){var a=this.x*this.x+this.y*this.y+this.z*this.z;return a<0.0050&&a>-0.0050?0:a},getDistance:function(a){var b=this.x-a.x,c=this.y-a.y,a=this.z-a.z;return Math.sqrt(b*b+c*c+a*a)},getDistanceSquared:function(a){var b=this.x-a.x,c=this.y-a.y, -a=this.z-a.z;return b*b+c*c+a*a},toString:function(){return"(CAAT.Point) x:"+String(Math.round(Math.floor(this.x*10))/10)+" y:"+String(Math.round(Math.floor(this.y*10))/10)+" z:"+String(Math.round(Math.floor(this.z*10))/10)}}})();(function(){CAAT.QuadTree=function(){return this};CAAT.QuadTree.prototype={bgActors:null,quadData:null,create:function(a,b,c,d,e,f,g){typeof f==="undefined"&&(f=32);typeof g==="undefined"&&(g=1);var h=(a+c)/2,i=(b+d)/2;this.x=a;this.y=b;this.x1=c;this.y1=d;this.width=c-a;this.height=d-b;this.bgActors=this.__getOverlappingActorList(e);if(this.bgActors.length<=g||this.width<=f)return this;this.quadData=Array(4);this.quadData[0]=(new CAAT.QuadTree).create(a,b,h,i,this.bgActors);this.quadData[1]=(new CAAT.QuadTree).create(h, -b,c,i,this.bgActors);this.quadData[2]=(new CAAT.QuadTree).create(a,i,h,d,this.bgActors);this.quadData[3]=(new CAAT.QuadTree).create(h,i,c,d,this.bgActors);return this},__getOverlappingActorList:function(a){for(var b=[],c=0,d=a.length;ca*a&&(b=Math.sqrt(b),this.x=this.x/b*a,this.y=this.y/b*a,this.z=this.z/b*a);return this},getLength:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);return 0.005>a&&-0.005a&&-0.005b;b++){if(this.quadData[b].intersects(a)){f=this.quadData[b].getOverlappingActors(a);for(c=0,d=f.length;c>0);this.ycache=[];for(e=0;e>0);this.xycache=[];for(e=0;e< this.rows;e++){this.xycache.push([]);for(c=0;c=this.behaviorStartTime&&(a=(a-this.behaviorStartTime)%this.behaviorDuration+this.behaviorStartTime);if(a>this.behaviorStartTime+this.behaviorDuration)return this.status!==e.EXPIRED&&this.setExpired(b,a),false;if(this.status===e.NOT_STARTED)this.status=e.STARTED,this.fireBehaviorStartedEvent(b,a);return this.behaviorStartTime<=a},fireBehaviorStartedEvent:function(a,b){for(var e=0;ec?2*c:1-2*(c-0.5));null!==b&&b&&(c=1-c);return this.interpolated.set(d,c)};return this},createBackOutInterpolator:function(a){this.getPosition=function(b){var c=b;a&&(b=0.5>b?2*b:1-2*(b-0.5));b-=1;return this.interpolated.set(c,b*b*(2.70158*b+1.70158)+1)};return this}, +createExponentialInInterpolator:function(a,b){this.getPosition=function(c){var d=c;b&&(c=0.5>c?2*c:1-2*(c-0.5));return this.interpolated.set(d,Math.pow(c,a))};return this},createExponentialOutInterpolator:function(a,b){this.getPosition=function(c){var d=c;b&&(c=0.5>c?2*c:1-2*(c-0.5));return this.interpolated.set(d,1-Math.pow(1-c,a))};return this},createExponentialInOutInterpolator:function(a,b){this.getPosition=function(c){var d=c;b&&(c=0.5>c?2*c:1-2*(c-0.5));return 1>2*c?this.interpolated.set(d, +Math.pow(2*c,a)/2):this.interpolated.set(d,1-Math.abs(Math.pow(2*c-2,a))/2)};return this},createQuadricBezierInterpolator:function(a,b,c,d){this.getPosition=function(e){var f=e;d&&(e=0.5>e?2*e:1-2*(e-0.5));e=(1-e)*(1-e)*a.y+2*(1-e)*e*b.y+e*e*c.y;return this.interpolated.set(f,e)};return this},createCubicBezierInterpolator:function(a,b,c,d,e){this.getPosition=function(f){var g=f;e&&(f=0.5>f?2*f:1-2*(f-0.5));var h=f*f,f=a.y+f*(3*-a.y+f*(3*a.y-a.y*f))+f*(3*b.y+f*(-6*b.y+3*b.y*f))+h*(3*c.y-3*c.y*f)+d.y* +f*h;return this.interpolated.set(g,f)};return this},createElasticOutInterpolator:function(a,b,c){this.getPosition=function(d){c&&(d=0.5>d?2*d:1-2*(d-0.5));if(0===d)return{x:0,y:0};if(1===d)return{x:1,y:1};var e=b/(2*Math.PI)*Math.asin(1/a);return this.interpolated.set(d,a*Math.pow(2,-10*d)*Math.sin((d-e)*2*Math.PI/b)+1)};return this},createElasticInInterpolator:function(a,b,c){this.getPosition=function(d){c&&(d=0.5>d?2*d:1-2*(d-0.5));if(0===d)return{x:0,y:0};if(1===d)return{x:1,y:1};var e=b/(2*Math.PI)* +Math.asin(1/a);return this.interpolated.set(d,-(a*Math.pow(2,10*(d-=1))*Math.sin((d-e)*2*Math.PI/b)))};return this},createElasticInOutInterpolator:function(a,b,c){this.getPosition=function(d){c&&(d=0.5>d?2*d:1-2*(d-0.5));var e=b/(2*Math.PI)*Math.asin(1/a),d=2*d;return 1>=d?this.interpolated.set(d,-0.5*a*Math.pow(2,10*(d-=1))*Math.sin((d-e)*2*Math.PI/b)):this.interpolated.set(d,1+0.5*a*Math.pow(2,-10*(d-=1))*Math.sin((d-e)*2*Math.PI/b))};return this},bounce:function(a){return(a/=1)<1/2.75?{x:a,y:7.5625* +a*a}:a<2/2.75?{x:a,y:7.5625*(a-=1.5/2.75)*a+0.75}:a<2.5/2.75?{x:a,y:7.5625*(a-=2.25/2.75)*a+0.9375}:{x:a,y:7.5625*(a-=2.625/2.75)*a+0.984375}},createBounceOutInterpolator:function(a){this.getPosition=function(b){a&&(b=0.5>b?2*b:1-2*(b-0.5));return this.bounce(b)};return this},createBounceInInterpolator:function(a){this.getPosition=function(b){a&&(b=0.5>b?2*b:1-2*(b-0.5));b=this.bounce(1-b);b.y=1-b.y;return b};return this},createBounceInOutInterpolator:function(a){this.getPosition=function(b){a&&(b= +0.5>b?2*b:1-2*(b-0.5));if(0.5>b)return b=this.bounce(1-2*b),b.y=0.5*(1-b.y),b;b=this.bounce(2*b-1,a);b.y=0.5*b.y+0.5;return b};return this},paint:function(a){a=a.crc;a.save();a.beginPath();a.moveTo(0,this.getPosition(0).y*this.paintScale);for(var b=0;b<=this.paintScale;b++)a.lineTo(b,this.getPosition(b/this.paintScale).y*this.paintScale);a.strokeStyle="black";a.stroke();a.restore()},getContour:function(a){for(var b=[],c=0;c<=a;c++)b.push({x:c/a,y:this.getPosition(c/a).y});return b},enumerateInterpolators:function(){return[(new CAAT.Interpolator).createLinearInterpolator(!1, +!1),"Linear pingpong=false, inverse=false",(new CAAT.Interpolator).createLinearInterpolator(!0,!1),"Linear pingpong=true, inverse=false",(new CAAT.Interpolator).createLinearInterpolator(!1,!0),"Linear pingpong=false, inverse=true",(new CAAT.Interpolator).createLinearInterpolator(!0,!0),"Linear pingpong=true, inverse=true",(new CAAT.Interpolator).createExponentialInInterpolator(2,!1),"ExponentialIn pingpong=false, exponent=2",(new CAAT.Interpolator).createExponentialOutInterpolator(2,!1),"ExponentialOut pingpong=false, exponent=2", +(new CAAT.Interpolator).createExponentialInOutInterpolator(2,!1),"ExponentialInOut pingpong=false, exponent=2",(new CAAT.Interpolator).createExponentialInInterpolator(2,!0),"ExponentialIn pingpong=true, exponent=2",(new CAAT.Interpolator).createExponentialOutInterpolator(2,!0),"ExponentialOut pingpong=true, exponent=2",(new CAAT.Interpolator).createExponentialInOutInterpolator(2,!0),"ExponentialInOut pingpong=true, exponent=2",(new CAAT.Interpolator).createExponentialInInterpolator(4,!1),"ExponentialIn pingpong=false, exponent=4", +(new CAAT.Interpolator).createExponentialOutInterpolator(4,!1),"ExponentialOut pingpong=false, exponent=4",(new CAAT.Interpolator).createExponentialInOutInterpolator(4,!1),"ExponentialInOut pingpong=false, exponent=4",(new CAAT.Interpolator).createExponentialInInterpolator(4,!0),"ExponentialIn pingpong=true, exponent=4",(new CAAT.Interpolator).createExponentialOutInterpolator(4,!0),"ExponentialOut pingpong=true, exponent=4",(new CAAT.Interpolator).createExponentialInOutInterpolator(4,!0),"ExponentialInOut pingpong=true, exponent=4", +(new CAAT.Interpolator).createExponentialInInterpolator(6,!1),"ExponentialIn pingpong=false, exponent=6",(new CAAT.Interpolator).createExponentialOutInterpolator(6,!1),"ExponentialOut pingpong=false, exponent=6",(new CAAT.Interpolator).createExponentialInOutInterpolator(6,!1),"ExponentialInOut pingpong=false, exponent=6",(new CAAT.Interpolator).createExponentialInInterpolator(6,!0),"ExponentialIn pingpong=true, exponent=6",(new CAAT.Interpolator).createExponentialOutInterpolator(6,!0),"ExponentialOut pingpong=true, exponent=6", +(new CAAT.Interpolator).createExponentialInOutInterpolator(6,!0),"ExponentialInOut pingpong=true, exponent=6",(new CAAT.Interpolator).createBounceInInterpolator(!1),"BounceIn pingpong=false",(new CAAT.Interpolator).createBounceOutInterpolator(!1),"BounceOut pingpong=false",(new CAAT.Interpolator).createBounceInOutInterpolator(!1),"BounceInOut pingpong=false",(new CAAT.Interpolator).createBounceInInterpolator(!0),"BounceIn pingpong=true",(new CAAT.Interpolator).createBounceOutInterpolator(!0),"BounceOut pingpong=true", +(new CAAT.Interpolator).createBounceInOutInterpolator(!0),"BounceInOut pingpong=true",(new CAAT.Interpolator).createElasticInInterpolator(1.1,0.4,!1),"ElasticIn pingpong=false, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4,!1),"ElasticOut pingpong=false, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInOutInterpolator(1.1,0.4,!1),"ElasticInOut pingpong=false, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInInterpolator(1.1,0.4,!0),"ElasticIn pingpong=true, amp=1.1, d=.4", +(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4,!0),"ElasticOut pingpong=true, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInOutInterpolator(1.1,0.4,!0),"ElasticInOut pingpong=true, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInInterpolator(1,0.2,!1),"ElasticIn pingpong=false, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticOutInterpolator(1,0.2,!1),"ElasticOut pingpong=false, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticInOutInterpolator(1,0.2,!1),"ElasticInOut pingpong=false, amp=1.0, d=.2", +(new CAAT.Interpolator).createElasticInInterpolator(1,0.2,!0),"ElasticIn pingpong=true, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticOutInterpolator(1,0.2,!0),"ElasticOut pingpong=true, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticInOutInterpolator(1,0.2,!0),"ElasticInOut pingpong=true, amp=1.0, d=.2"]}}})();(function(){CAAT.Behavior=function(){this.lifecycleListenerList=[];this.setDefaultInterpolator();return this};CAAT.Behavior.Status={NOT_STARTED:0,STARTED:1,EXPIRED:2};var a=(new CAAT.Interpolator).createLinearInterpolator(!1),b=(new CAAT.Interpolator).createLinearInterpolator(!0);CAAT.Behavior.prototype={lifecycleListenerList:null,behaviorStartTime:-1,behaviorDuration:-1,cycleBehavior:!1,status:CAAT.Behavior.NOT_STARTED,interpolator:null,actor:null,id:0,timeOffset:0,doValueApplication:!0,solved:!0, +setValueApplication:function(a){this.doValueApplication=a;return this},setTimeOffset:function(a){this.timeOffset=a;return this},setId:function(a){this.id=a;return this},setDefaultInterpolator:function(){this.interpolator=a;return this},setPingPong:function(){this.interpolator=b;return this},setStatus:function(a){this.status=a},setFrameTime:function(a,b){this.behaviorStartTime=a;this.behaviorDuration=b;this.setStatus(CAAT.Behavior.Status.NOT_STARTED);return this},setDelayTime:function(a,b){this.behaviorStartTime= +a;this.behaviorDuration=b;this.setStatus(CAAT.Behavior.Status.NOT_STARTED);this.solved=!1;return this},setOutOfFrameTime:function(){this.setStatus(CAAT.Behavior.Status.EXPIRED);this.behaviorStartTime=Number.MAX_VALUE;this.behaviorDuration=0;return this},setInterpolator:function(a){this.interpolator=a;return this},apply:function(a,b){this.solved||(this.behaviorStartTime+=a,this.solved=!0);var e=a+=this.timeOffset*this.behaviorDuration;this.isBehaviorInTime(a,b)&&(a=this.normalizeTime(a),this.fireBehaviorAppliedEvent(b, +e,a,this.setForTime(a,b)))},setCycle:function(a){this.cycleBehavior=a;return this},addListener:function(a){this.lifecycleListenerList.push(a);return this},emptyListenerList:function(){this.lifecycleListenerList=[];return this},getStartTime:function(){return this.behaviorStartTime},getDuration:function(){return this.behaviorDuration},isBehaviorInTime:function(a,b){var e=CAAT.Behavior.Status;if(this.status===e.EXPIRED||0>this.behaviorStartTime)return!1;this.cycleBehavior&&a>=this.behaviorStartTime&& +(a=(a-this.behaviorStartTime)%this.behaviorDuration+this.behaviorStartTime);if(a>this.behaviorStartTime+this.behaviorDuration)return this.status!==e.EXPIRED&&this.setExpired(b,a),!1;this.status===e.NOT_STARTED&&(this.status=e.STARTED,this.fireBehaviorStartedEvent(b,a));return this.behaviorStartTime<=a},fireBehaviorStartedEvent:function(a,b){for(var e=0;e=h&&(h=(h-f.behaviorStartTime)/f.behaviorDuration,h=f.calculateKeyFrameData(h),f=f.getPropertyName(b),typeof g[f]==="undefined"&&(g[f]=""),g[f]+=h+" "));var i="",j;d("translate");d("rotate");d("scale");a="";i&&(a="-"+b+"-transform: "+i+";");i="";d("opacity");i&&(a+=" opacity: "+i+";");return{rules:a,ret:g}},calculateKeyFramesData:function(a,b,c){if(this.duration===Number.MAX_VALUE)return""; -typeof c==="undefined"&&(c=100);for(var d=null,e="@-"+a+"-keyframes "+b+" {",f,b=0;b<=c;b++)f=this.interpolator.getPosition(b/c).y,d=this.calculateKeyFrameData(f,a,d),f=""+b/c*100+"%{"+d.rules+"}\n",d=d.ret,e+=f;e+="}";return e}};extend(CAAT.ContainerBehavior,CAAT.Behavior,null)})(); +CAAT.GenericBehavior)&&(h=a*this.behaviorDuration,f.behaviorStartTime<=h&&f.behaviorStartTime+f.behaviorDuration>=h&&(h=(h-f.behaviorStartTime)/f.behaviorDuration,h=f.calculateKeyFrameData(h),f=f.getPropertyName(b),"undefined"===typeof g[f]&&(g[f]=""),g[f]+=h+" "));var i="",j;d("translate");d("rotate");d("scale");a="";i&&(a="-"+b+"-transform: "+i+";");i="";d("opacity");i&&(a+=" opacity: "+i+";");return{rules:a,ret:g}},calculateKeyFramesData:function(a,b,c){if(this.duration===Number.MAX_VALUE)return""; +"undefined"===typeof c&&(c=100);for(var d=null,e="@-"+a+"-keyframes "+b+" {",f,b=0;b<=c;b++)f=this.interpolator.getPosition(b/c).y,d=this.calculateKeyFrameData(f,a,d),f=""+100*(b/c)+"%{"+d.rules+"}\n",d=d.ret,e+=f;return e+"}"}};extend(CAAT.ContainerBehavior,CAAT.Behavior,null)})(); (function(){CAAT.RotateBehavior=function(){CAAT.RotateBehavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.RotateBehavior.prototype={startAngle:0,endAngle:0,anchorX:0.5,anchorY:0.5,getPropertyName:function(){return"rotate"},setForTime:function(a,b){var c=this.startAngle+a*(this.endAngle-this.startAngle);this.doValueApplication&&b.setRotationAnchored(c,this.anchorX,this.anchorY);return c},setValues:function(a,b,c,d){this.startAngle=a;this.endAngle= -b;if(typeof c!=="undefined"&&typeof d!=="undefined")this.anchorX=c,this.anchorY=d;return this},setAngles:function(a,b){return this.setValues(a,b)},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"rotate("+(this.startAngle+a*(this.endAngle-this.startAngle))+"rad)"},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<= -c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}\n",e+=d;e+="}";return e}};extend(CAAT.RotateBehavior,CAAT.Behavior,null)})(); +b;"undefined"!==typeof c&&"undefined"!==typeof d&&(this.anchorX=c,this.anchorY=d);return this},setAngles:function(a,b){return this.setValues(a,b)},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"rotate("+(this.startAngle+a*(this.endAngle-this.startAngle))+"rad)"},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<= +c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}\n",e+=d;return e+"}"}};extend(CAAT.RotateBehavior,CAAT.Behavior,null)})(); (function(){CAAT.GenericBehavior=function(){CAAT.GenericBehavior.superclass.constructor.call(this);return this};CAAT.GenericBehavior.prototype={start:0,end:0,target:null,property:null,callback:null,setForTime:function(a,b){var c=this.start+a*(this.end-this.start);this.callback&&this.callback(c,this.target,b);this.property&&(this.target[this.property]=c)},setValues:function(a,b,c,d,e){this.start=a;this.end=b;this.target=c;this.property=d;this.callback=e;return this}};extend(CAAT.GenericBehavior,CAAT.Behavior, null)})(); (function(){CAAT.ScaleBehavior=function(){CAAT.ScaleBehavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.ScaleBehavior.prototype={startScaleX:1,endScaleX:1,startScaleY:1,endScaleY:1,anchorX:0.5,anchorY:0.5,getPropertyName:function(){return"scale"},setForTime:function(a,b){var c=this.startScaleX+a*(this.endScaleX-this.startScaleX),d=this.startScaleY+a*(this.endScaleY-this.startScaleY);0===c&&(c=0.01);0===d&&(d=0.01);this.doValueApplication&&b.setScaleAnchored(c, -d,this.anchorX,this.anchorY);return{scaleX:c,scaleY:d}},setValues:function(a,b,c,d,e,f){this.startScaleX=a;this.endScaleX=b;this.startScaleY=c;this.endScaleY=d;if(typeof e!=="undefined"&&typeof f!=="undefined")this.anchorX=e,this.anchorY=f;return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"scaleX("+(this.startScaleX+a*(this.endScaleX-this.startScaleX))+") scaleY("+(this.startScaleY+ -a*(this.endScaleY-this.startScaleY))+")"},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;e+="}";return e}};extend(CAAT.ScaleBehavior,CAAT.Behavior,null)})(); +d,this.anchorX,this.anchorY);return{scaleX:c,scaleY:d}},setValues:function(a,b,c,d,e,f){this.startScaleX=a;this.endScaleX=b;this.startScaleY=c;this.endScaleY=d;"undefined"!==typeof e&&"undefined"!==typeof f&&(this.anchorX=e,this.anchorY=f);return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"scaleX("+(this.startScaleX+a*(this.endScaleX-this.startScaleX))+") scaleY("+(this.startScaleY+ +a*(this.endScaleY-this.startScaleY))+")"},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;return e+"}"}};extend(CAAT.ScaleBehavior,CAAT.Behavior,null)})(); (function(){CAAT.AlphaBehavior=function(){CAAT.AlphaBehavior.superclass.constructor.call(this);return this};CAAT.AlphaBehavior.prototype={startAlpha:0,endAlpha:0,getPropertyName:function(){return"opacity"},setForTime:function(a,b){var c=this.startAlpha+a*(this.endAlpha-this.startAlpha);this.doValueApplication&&b.setAlpha(c);return c},setValues:function(a,b){this.startAlpha=a;this.endAlpha=b;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return this.startAlpha+ -a*(this.endAlpha-this.startAlpha)},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d="@-"+a+"-keyframes "+b+" {",a=0;a<=c;a++)b=""+a/c*100+"%{opacity: "+this.calculateKeyFrameData(a/c)+"}",d+=b;d+="}";return d}};extend(CAAT.AlphaBehavior,CAAT.Behavior,null)})(); -(function(){CAAT.PathBehavior=function(){CAAT.PathBehavior.superclass.constructor.call(this);return this};CAAT.PathBehavior.autorotate={LEFT_TO_RIGHT:0,RIGHT_TO_LEFT:1,FREE:2};CAAT.PathBehavior.prototype={path:null,autoRotate:false,prevX:-1,prevY:-1,autoRotateOp:CAAT.PathBehavior.autorotate.FREE,getPropertyName:function(){return"translate"},setAutoRotate:function(a,b){this.autoRotate=a;if(b!==void 0)this.autoRotateOp=b;return this},setPath:function(a){this.path=a;return this},setValues:function(a){return this.setPath(a)}, -setTranslation:function(){return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.path.getPosition(a);return"translateX("+a.x+"px) translateY("+a.y+"px)"},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;e+="}";return e},setForTime:function(a,b){if(!this.path)return{x:b.x,y:b.y};var c=this.path.getPosition(a); -if(this.autoRotate){if(-1===this.prevX&&-1===this.prevY)this.prevX=c.x,this.prevY=c.y;var d=c.x-this.prevX,e=c.y-this.prevY;if(d===0&&e===0)return b.setLocation(c.x,c.y),{x:b.x,y:b.y};var f=Math.atan2(e,d),g=CAAT.SpriteImage.prototype,h=CAAT.PathBehavior.autorotate;this.autoRotateOp===h.LEFT_TO_RIGHT?this.prevX<=c.x?b.setImageTransformation(g.TR_NONE):(b.setImageTransformation(g.TR_FLIP_HORIZONTAL),f+=Math.PI):this.autoRotateOp===h.RIGHT_TO_LEFT&&(this.prevX<=c.x?b.setImageTransformation(g.TR_FLIP_HORIZONTAL): +a*(this.endAlpha-this.startAlpha)},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d="@-"+a+"-keyframes "+b+" {",a=0;a<=c;a++)b=""+100*(a/c)+"%{opacity: "+this.calculateKeyFrameData(a/c)+"}",d+=b;return d+"}"}};extend(CAAT.AlphaBehavior,CAAT.Behavior,null)})(); +(function(){CAAT.PathBehavior=function(){CAAT.PathBehavior.superclass.constructor.call(this);return this};CAAT.PathBehavior.autorotate={LEFT_TO_RIGHT:0,RIGHT_TO_LEFT:1,FREE:2};CAAT.PathBehavior.prototype={path:null,autoRotate:!1,prevX:-1,prevY:-1,autoRotateOp:CAAT.PathBehavior.autorotate.FREE,getPropertyName:function(){return"translate"},setAutoRotate:function(a,b){this.autoRotate=a;void 0!==b&&(this.autoRotateOp=b);return this},setPath:function(a){this.path=a;return this},setValues:function(a){return this.setPath(a)}, +setTranslation:function(){return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.path.getPosition(a);return"translateX("+a.x+"px) translateY("+a.y+"px)"},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;return e+"}"},setForTime:function(a,b){if(!this.path)return{x:b.x,y:b.y};var c=this.path.getPosition(a); +if(this.autoRotate){-1===this.prevX&&-1===this.prevY&&(this.prevX=c.x,this.prevY=c.y);var d=c.x-this.prevX,e=c.y-this.prevY;if(0===d&&0===e)return b.setLocation(c.x,c.y),{x:b.x,y:b.y};var f=Math.atan2(e,d),g=CAAT.SpriteImage.prototype,h=CAAT.PathBehavior.autorotate;this.autoRotateOp===h.LEFT_TO_RIGHT?this.prevX<=c.x?b.setImageTransformation(g.TR_NONE):(b.setImageTransformation(g.TR_FLIP_HORIZONTAL),f+=Math.PI):this.autoRotateOp===h.RIGHT_TO_LEFT&&(this.prevX<=c.x?b.setImageTransformation(g.TR_FLIP_HORIZONTAL): (b.setImageTransformation(g.TR_NONE),f-=Math.PI));b.setRotation(f);this.prevX=c.x;this.prevY=c.y;Math.sqrt(d*d+e*e)}return this.doValueApplication?(b.setLocation(c.x,c.y),{x:b.x,y:b.y}):{x:c.x,y:c.y}},positionOnTime:function(a){return this.isBehaviorInTime(a,null)?(a=this.normalizeTime(a),this.path.getPosition(a)):{x:-1,y:-1}}};extend(CAAT.PathBehavior,CAAT.Behavior)})();(function(){CAAT.ColorBehavior=function(){return this};CAAT.ColorBehavior.prototype={};extend(CAAT.ColorBehavior,CAAT.Behavior)})(); -(function(){CAAT.Scale1Behavior=function(){CAAT.Scale1Behavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.Scale1Behavior.prototype={startScale:1,endScale:1,anchorX:0.5,anchorY:0.5,sx:1,sy:1,applyOnX:true,getPropertyName:function(){return"scale"},setForTime:function(a,b){var c=this.startScale+a*(this.endScale-this.startScale);0===c&&(c=0.01);this.doValueApplication&&(this.applyOnX?b.setScaleAnchored(c,b.scaleY,this.anchorX,this.anchorY):b.setScaleAnchored(b.scaleX, -c,this.anchorX,this.anchorY));return c},setValues:function(a,b,c,d,e){this.startScale=a;this.endScale=b;this.applyOnX=!!c;if(typeof d!=="undefined"&&typeof e!=="undefined")this.anchorX=d,this.anchorY=e;return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.startScale+a*(this.endScale-this.startScale);return this.applyOnX?"scaleX("+a+")":"scaleY("+a+")"},calculateKeyFramesData:function(a, -b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;e+="}";return e}};extend(CAAT.Scale1Behavior,CAAT.Behavior)})();(function(){CAAT.Debug=function(){return this};CAAT.Debug.prototype={width:0,height:0,canvas:null,ctx:null,statistics:null,framerate:null,textContainer:null,textFPS:null,textEntitiesTotal:null,textEntitiesActive:null,textDraws:null,textDrawTime:null,textRAFTime:null,textDirtyRects:null,frameTimeAcc:0,frameRAFAcc:0,canDebug:false,SCALE:60,debugTpl:'
CAAT Debug panel Performance Controls Draw Time: 5.46 ms. FPS: 48
RAF Time: 20.76 ms. Entities Total: 41 Entities Active: 37 Draws: 0 DirtyRects: 0
Sound
Music
AA Bounding Boxes
Bounding Boxes
Dirty Rects
', +(function(){CAAT.Scale1Behavior=function(){CAAT.Scale1Behavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.Scale1Behavior.prototype={startScale:1,endScale:1,anchorX:0.5,anchorY:0.5,sx:1,sy:1,applyOnX:!0,getPropertyName:function(){return"scale"},setForTime:function(a,b){var c=this.startScale+a*(this.endScale-this.startScale);0===c&&(c=0.01);this.doValueApplication&&(this.applyOnX?b.setScaleAnchored(c,b.scaleY,this.anchorX,this.anchorY):b.setScaleAnchored(b.scaleX, +c,this.anchorX,this.anchorY));return c},setValues:function(a,b,c,d,e){this.startScale=a;this.endScale=b;this.applyOnX=!!c;"undefined"!==typeof d&&"undefined"!==typeof e&&(this.anchorX=d,this.anchorY=e);return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.startScale+a*(this.endScale-this.startScale);return this.applyOnX?"scaleX("+a+")":"scaleY("+a+")"},calculateKeyFramesData:function(a, +b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;return e+"}"}};extend(CAAT.Scale1Behavior,CAAT.Behavior)})();(function(){CAAT.Debug=function(){return this};CAAT.Debug.prototype={width:0,height:0,canvas:null,ctx:null,statistics:null,framerate:null,textContainer:null,textFPS:null,textEntitiesTotal:null,textEntitiesActive:null,textDraws:null,textDrawTime:null,textRAFTime:null,textDirtyRects:null,frameTimeAcc:0,frameRAFAcc:0,canDebug:!1,SCALE:60,debugTpl:'
CAAT Debug panel Performance Controls Draw Time: 5.46 ms. FPS: 48
RAF Time: 20.76 ms. Entities Total: 41 Entities Active: 37 Draws: 0 DirtyRects: 0
Sound
Music
AA Bounding Boxes
Bounding Boxes
Dirty Rects
', setScale:function(a){this.scale=a;return this},initialize:function(a,b){this.width=a=window.innerWidth;this.height=b;this.framerate={refreshInterval:CAAT.FPS_REFRESH||500,frames:0,timeLastRefresh:0,fps:0,prevFps:-1,fpsMin:1E3,fpsMax:0};if(!document.getElementById("caat-debug")){var c=document.createElement("div");c.innerHTML=this.debugTpl;document.body.appendChild(c);eval(' function initCheck( name, bool, callback ) { var elem= document.getElementById(name); if ( elem ) { elem.className= (bool) ? "checkbox_enabled" : "checkbox_disabled"; if ( callback ) { elem.addEventListener( "click", (function(elem, callback) { return function(e) { elem.__value= !elem.__value; elem.className= (elem.__value) ? "checkbox_enabled" : "checkbox_disabled"; callback(e,elem.__value); } })(elem, callback), false ); } elem.__value= bool; } } function setupTabs() { var numTabs=0; var elem; var elemContent; do { elem= document.getElementById("caat-debug-tab"+numTabs); if ( elem ) { elemContent= document.getElementById("caat-debug-tab"+numTabs+"-content"); if ( elemContent ) { elemContent.style.display= numTabs===0 ? \'block\' : \'none\'; elem.className= numTabs===0 ? "debug_tab debug_tab_selected" : "debug_tab debug_tab_not_selected"; elem.addEventListener( "click", (function(tabIndex) { return function(e) { for( var i=0; ithis.framerate.timeLastRefresh+this.framerate.refreshInterval)this.framerate.fps=this.framerate.frames*1E3/(CAAT.RAF-this.framerate.timeLastRefresh)|0,this.framerate.fpsMin= -this.framerate.frames>0?Math.min(this.framerate.fpsMin,this.framerate.fps):this.framerate.fpsMin,this.framerate.fpsMax=Math.max(this.framerate.fpsMax,this.framerate.fps),this.textFPS.innerHTML=this.framerate.fps,a=(this.frameTimeAcc*100/this.framerate.frames|0)/100,this.frameTimeAcc=0,this.textDrawTime.innerHTML=a,a=(this.frameRAFAcc*100/this.framerate.frames|0)/100,this.frameRAFAcc=0,this.textRAFTime.innerHTML=a,this.framerate.timeLastRefresh=CAAT.RAF,this.framerate.frames=0,this.paint(a);this.textEntitiesTotal.innerHTML= +document.getElementById("caat-debug-canvas");if(null===this.canvas)this.canDebug=!1;else return this.canvas.width=a,this.canvas.height=b,this.ctx=this.canvas.getContext("2d"),this.ctx.fillStyle="#000",this.ctx.fillRect(0,0,this.width,this.height),this.textFPS=document.getElementById("textFPS"),this.textDrawTime=document.getElementById("textDrawTime"),this.textRAFTime=document.getElementById("textRAFTime"),this.textEntitiesTotal=document.getElementById("textEntitiesTotal"),this.textEntitiesActive= +document.getElementById("textEntitiesActive"),this.textDraws=document.getElementById("textDraws"),this.textDirtyRects=document.getElementById("textDirtyRects"),this.canDebug=!0,this},debugInfo:function(a){this.statistics=a;this.frameTimeAcc+=CAAT.FRAME_TIME;this.frameRAFAcc+=CAAT.REQUEST_ANIMATION_FRAME_TIME;this.framerate.frames++;CAAT.RAF>this.framerate.timeLastRefresh+this.framerate.refreshInterval&&(this.framerate.fps=1E3*this.framerate.frames/(CAAT.RAF-this.framerate.timeLastRefresh)|0,this.framerate.fpsMin= +0> -0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();b.strokeStyle="#aa2";b.beginPath();c=this.height-(30/this.SCALE*this.height>>0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();c=Math.min(this.height-this.framerate.fps/this.SCALE*this.height,59);if(-1===this.framerate.prevFps)this.framerate.prevFps=c|0;b.strokeStyle="#0ff";b.beginPath();b.moveTo(this.width,(c|0)-0.5);b.lineTo(this.width,this.framerate.prevFps-0.5);b.stroke();this.framerate.prevFps=c;a=(this.height-a/this.SCALE* +0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();b.strokeStyle="#aa2";b.beginPath();c=this.height-(30/this.SCALE*this.height>>0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();c=Math.min(this.height-this.framerate.fps/this.SCALE*this.height,59);-1===this.framerate.prevFps&&(this.framerate.prevFps=c|0);b.strokeStyle="#0ff";b.beginPath();b.moveTo(this.width,(c|0)-0.5);b.lineTo(this.width,this.framerate.prevFps-0.5);b.stroke();this.framerate.prevFps=c;a=(this.height-a/this.SCALE* this.height>>0)-0.5;b.strokeStyle="#ff0";b.beginPath();b.moveTo(this.width,a);b.lineTo(this.width,a);b.stroke()}}})();(function(){CAAT.Actor=function(){this.behaviorList=[];this.lifecycleListenerList=[];this.scaleAnchor=this.ANCHOR_CENTER;this.behaviorList=[];this.domElement=document.createElement("div");this.domElement.style.position="absolute";this.domElement.style["-webkit-transform"]="translate3d(0,0,0)";this.domElement.style["-webkit-transition"]="all 0s linear";this.style("display","none");this.AABB=new CAAT.Rectangle;this.viewVertices=[new CAAT.Point(0,0,0),new CAAT.Point(0,0,0),new CAAT.Point(0,0,0),new CAAT.Point(0, -0,0)];this.setVisible(true);this.resetTransform();this.setScale(1,1);this.setRotation(0);this.modelViewMatrix=new CAAT.Matrix;this.worldModelViewMatrix=new CAAT.Matrix;return this};CAAT.Actor.prototype={lifecycleListenerList:null,behaviorList:null,x:0,y:0,width:0,height:0,start_time:0,duration:Number.MAX_VALUE,clip:false,tAnchorX:0,tAnchorY:0,scaleX:0,scaleY:0,scaleTX:0.5,scaleTY:0.5,scaleAnchor:0,rotationAngle:0,rotationY:0.5,alpha:1,rotationX:0.5,isGlobalAlpha:false,frameAlpha:1,expired:false,discardable:false, -domParent:null,domElement:null,visible:true,ANCHOR_CENTER:0,ANCHOR_TOP:1,ANCHOR_BOTTOM:2,ANCHOR_LEFT:3,ANCHOR_RIGHT:4,ANCHOR_TOP_LEFT:5,ANCHOR_TOP_RIGHT:6,ANCHOR_BOTTOM_LEFT:7,ANCHOR_BOTTOM_RIGHT:8,ANCHOR_CUSTOM:9,mouseEnabled:true,time:0,inFrame:false,backgroundImage:null,size_active:1,size_total:1,id:null,__d_ax:-1,__d_ay:-1,gestureEnabled:false,AABB:null,viewVertices:null,isAA:true,setScreenBounds:function(){var a=this.AABB,b=this.viewVertices;if(this.isAA)return b=this.worldModelViewMatrix.matrix, -a.x=b[2],a.y=b[5],a.x1=b[2]+this.width,a.y1=b[5]+this.height,a.width=a.x1-a.x,a.height=a.y1-a.y,this;var c;c=b[0];c.x=0;c.y=0;c=b[1];c.x=this.width;c.y=0;c=b[2];c.x=this.width;c.y=this.height;c=b[3];c.x=0;c.y=this.height;this.modelToView(this.viewVertices);var d=Number.MAX_VALUE,e=-Number.MAX_VALUE,f=Number.MAX_VALUE,g=-Number.MAX_VALUE;c=b[0];if(c.xe)e=c.x;if(c.yg)g=c.y;c=b[1];if(c.xe)e=c.x;if(c.yg)g=c.y;c=b[2];if(c.x -e)e=c.x;if(c.yg)g=c.y;c=b[3];if(c.xe)e=c.x;if(c.yg)g=c.y;a.x=d;a.y=f;a.x1=e;a.y1=g;a.width=e-d;a.height=g-f;return this},setGestureEnabled:function(a){this.gestureEnabled=!!a},isGestureEnabled:function(){return this.gestureEnabled},getId:function(){return this.id},setId:function(a){this.id=a;return this},setParent:function(a){this.parent&&this.domParent.removeChild(this.domElement);this.parent=a;null!=a?(this.parent.domElement.appendChild(this.domElement), -this.domParent=this.parent.domElement):this.domParent=null;this.dirty=true;return this},setBackgroundImage:function(a,b){if(a){if(a instanceof HTMLImageElement)a=(new CAAT.SpriteImage).initialize(a,1,1);else if(a instanceof HTMLCanvasElement)a.src=a.toDataURL(),a=(new CAAT.SpriteImage).initialize(a,1,1);else if(a instanceof CAAT.SpriteImage){if(a.image instanceof HTMLCanvasElement&&!a.image.src)a.image.src=a.image.toDataURL()}else throw"Invalid image object to set actor's background";a.setOwner(this); -this.backgroundImage=a;(typeof b==="undefined"||b)&&this.setSize(a.getWidth(),a.getHeight());this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition())}else this.backgroundImage=null,this.style("background","none");return this},setSpriteIndex:function(a){this.backgroundImage&&(this.backgroundImage.setSpriteIndex(a),this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition())); -return this},setBackgroundImageOffset:function(a,b){this.backgroundImage&&(this.backgroundImage.setOffset(a,b),this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition()));return this},setAnimationImageIndex:function(a){this.backgroundImage&&(this.backgroundImage.setAnimationImageIndex(a),this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition()));return this},setImageTransformation:function(a){this.transformation= -a;a===CAAT.SpriteImage.prototype.TR_FIXED_TO_SIZE&&this.style("background-size","100%");return this},centerOn:function(a,b){this.setLocation(a-this.width/2,b-this.height/2);return this},centerAt:function(a,b){return this.centerOn(a,b)},setVisible:function(a){this.visible=a;return this},style:function(a,b){this.domElement.style[a]=b},style3:function(){var a="";this.transformation===CAAT.SpriteImage.prototype.TR_FLIP_HORIZONTAL&&(a=" scale(-1,1) ");a="translate("+this.x+"px,"+this.y+"px) rotate("+this.rotationAngle+ -"rad) scale("+this.scaleX+","+this.scaleY+")"+a;this.domElement.style["-ms-transform"]=a;this.domElement.style["-webkit-transform"]="translate3d(0,0,0) "+a;this.domElement.style.OTransform=a;this.domElement.style.MozTransform=a;this.domElement.style.transform=a;a=""+this.rotationX*100+"% "+this.rotationY*100+"% ";this.domElement.style["transform-origin"]=a;this.domElement.style["-webkit-transform-origin"]=a;this.domElement.style["-ms-transform-origin"]=a;this.domElement.style.OTransformOrigin=a;this.domElement.style.MozTransformOrigin= -a;return this},styleAlpha:function(){this.domElement.style.filter="alpha(opacity="+(this.alpha*100>>0)+")";this.domElement.style.Oopacity=this.alpha;this.domElement.style.MozOpacity=this.alpha;this.domElement.style["-khtml-opacity"]=this.alpha;this.domElement.style.opacity=this.alpha;return this},setOutOfFrameTime:function(){this.setFrameTime(-1,0);this.style("display","none");return this},addListener:function(a){this.lifecycleListenerList.push(a)},removeListener:function(a){for(var b=this.lifecycleListenerList.length;b--;)if(this.lifecycleListenerList[b]=== -a){this.lifecycleListenerList.splice(b,1);break}},setGlobalAlpha:function(a){this.isGlobalAlpha=a;return this},fireEvent:function(a,b){for(var c=0;ce&&(e=c.x);c.yg&&(g=c.y);c=b[1];c.xe&&(e=c.x);c.yg&&(g=c.y);c=b[2];c.xe&&(e=c.x); +c.yg&&(g=c.y);c=b[3];c.xe&&(e=c.x);c.yg&&(g=c.y);a.x=d;a.y=f;a.x1=e;a.y1=g;a.width=e-d;a.height=g-f;return this},setGestureEnabled:function(a){this.gestureEnabled=!!a},isGestureEnabled:function(){return this.gestureEnabled},getId:function(){return this.id},setId:function(a){this.id=a;return this},setParent:function(a){this.parent&&this.domParent.removeChild(this.domElement);this.parent=a;null!=a?(this.parent.domElement.appendChild(this.domElement),this.domParent= +this.parent.domElement):this.domParent=null;this.dirty=!0;return this},setBackgroundImage:function(a,b){if(a){if(a instanceof HTMLImageElement)a=(new CAAT.SpriteImage).initialize(a,1,1);else if(a instanceof HTMLCanvasElement)a.src=a.toDataURL(),a=(new CAAT.SpriteImage).initialize(a,1,1);else if(a instanceof CAAT.SpriteImage)a.image instanceof HTMLCanvasElement&&!a.image.src&&(a.image.src=a.image.toDataURL());else throw"Invalid image object to set actor's background";a.setOwner(this);this.backgroundImage= +a;("undefined"===typeof b||b)&&this.setSize(a.getWidth(),a.getHeight());this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition())}else this.backgroundImage=null,this.style("background","none");return this},setSpriteIndex:function(a){this.backgroundImage&&(this.backgroundImage.setSpriteIndex(a),this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition()));return this},setBackgroundImageOffset:function(a, +b){this.backgroundImage&&(this.backgroundImage.setOffset(a,b),this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition()));return this},setAnimationImageIndex:function(a){this.backgroundImage&&(this.backgroundImage.setAnimationImageIndex(a),this.style("background","url("+this.backgroundImage.image.src+") "+this.backgroundImage.getCurrentSpriteImageCSSPosition()));return this},setImageTransformation:function(a){this.transformation=a;a=== +CAAT.SpriteImage.prototype.TR_FIXED_TO_SIZE&&this.style("background-size","100%");return this},centerOn:function(a,b){this.setLocation(a-this.width/2,b-this.height/2);return this},centerAt:function(a,b){return this.centerOn(a,b)},setVisible:function(a){this.visible=a;return this},style:function(a,b){this.domElement.style[a]=b},style3:function(){var a="";this.transformation===CAAT.SpriteImage.prototype.TR_FLIP_HORIZONTAL&&(a=" scale(-1,1) ");a="translate("+this.x+"px,"+this.y+"px) rotate("+this.rotationAngle+ +"rad) scale("+this.scaleX+","+this.scaleY+")"+a;this.domElement.style["-ms-transform"]=a;this.domElement.style["-webkit-transform"]="translate3d(0,0,0) "+a;this.domElement.style.OTransform=a;this.domElement.style.MozTransform=a;this.domElement.style.transform=a;a=""+100*this.rotationX+"% "+100*this.rotationY+"% ";this.domElement.style["transform-origin"]=a;this.domElement.style["-webkit-transform-origin"]=a;this.domElement.style["-ms-transform-origin"]=a;this.domElement.style.OTransformOrigin=a;this.domElement.style.MozTransformOrigin= +a;return this},styleAlpha:function(){this.domElement.style.filter="alpha(opacity="+(100*this.alpha>>0)+")";this.domElement.style.Oopacity=this.alpha;this.domElement.style.MozOpacity=this.alpha;this.domElement.style["-khtml-opacity"]=this.alpha;this.domElement.style.opacity=this.alpha;return this},setOutOfFrameTime:function(){this.setFrameTime(-1,0);this.style("display","none");return this},addListener:function(a){this.lifecycleListenerList.push(a)},removeListener:function(a){for(var b=this.lifecycleListenerList.length;b--;)if(this.lifecycleListenerList[b]=== +a){this.lifecycleListenerList.splice(b,1);break}},setGlobalAlpha:function(a){this.isGlobalAlpha=a;return this},fireEvent:function(a,b){for(var c=0;c=this.start_time+this.duration?(this.expired||this.setExpired(a),false):this.start_time<=a&&a=0&&b>=0&&a=this.start_time+this.duration?(this.expired||this.setExpired(a),!1):this.start_time<=a&&a=this.childrenList.length)b=this.childrenList.length;a.setParent(this);this.childrenList.splice(b,0,a);this.domElement.insertBefore(a.domElement,this.domElement.childNodes[b]);a.dirty= -true;return this},findChild:function(a){for(var b=0,c=this.childrenList.length,b=0;b=0;b--){var c=this.childrenList[b],d=new CAAT.Point(a.x,a.y,0),c=c.findActorAtPosition(d); -if(null!==c)return c}return this},destroy:function(){for(var a=this.childrenList.length-1;a>=0;a--)this.childrenList[a].destroy();CAAT.ActorContainer.superclass.destroy.call(this);return this},getNumChildren:function(){return this.childrenList.length},getNumActiveChildren:function(){return this.activeChildren.length},getChildAt:function(a){return this.childrenList[a]},setZOrder:function(a,b){var c=this.findChild(a);if(-1!==c){var d=this.childrenList;if(b!==c){if(b>=d.length)d.splice(c,1),d.push(a); -else{c=d.splice(c,1);if(b<0)b=0;else if(b>d.length)b=d.length;d.splice(b,0,c[0])}for(var c=0,e=d.length;c -0){var b=this.channels.shift();b.src=a.src;b.load();b.volume=a.volume;b.play();this.workingChannels.push(b)}return this},loop:function(a){if(!this.musicEnabled)return this;a=this.getAudio(a);if(null!==a){var b=document.createElement("audio");if(null!==b)return b.src=a.src,b.preload="auto",this.browserInfo.browser==="Firefox"?b.addEventListener("ended",function(a){a.target.currentTime=0},false):b.loop=true,b.load(),b.play(),this.loopingChannels.push(b),b}return null},endSound:function(){var a;for(a= -0;ac.x?0:c.x,0>c.y?0:c.y,c.width,c.height),a.unionRectangle(this.runion);this.setSize(a.x1,a.y1);return this},addChildDelayed:function(a){this.pendingChildrenList.push(a);return this},addChildAt:function(a,b){if(0>=b)return a.parent=this,a.dirty=!0,this.childrenList.splice(0,0,a),this;b>=this.childrenList.length&&(b=this.childrenList.length);a.setParent(this);this.childrenList.splice(b,0,a);this.domElement.insertBefore(a.domElement,this.domElement.childNodes[b]);a.dirty= +!0;return this},findChild:function(a){for(var b=0,c=this.childrenList.length,b=0;b=d.length?(d.splice(c,1),d.push(a)): +(c=d.splice(c,1),0>b?b=0:b>d.length&&(b=d.length),d.splice(b,0,c[0]));for(var c=0,e=d.length;cd+this.range?this.minSize:a===d?this.maxSize:ad+this.range?this.minSize:a===d?this.maxSize:aa;a++)this.dirtyRects.push(new CAAT.Rectangle);this.dirtyRectsIndex= +0;return this};CAAT.Director.CLEAR_DIRTY_RECTS=1;CAAT.Director.CLEAR_ALL=!0;CAAT.Director.CLEAR_NONE=!1;CAAT.Director.prototype={debug:!1,onRenderStart:null,onRenderEnd:null,mousePoint:null,prevMousePoint:null,screenMousePoint:null,isMouseDown:!1,lastSelectedActor:null,dragging:!1,scenes:null,currentScene:null,canvas:null,crc:null,ctx:null,time:0,timeline:0,imagesCache:null,audioManager:null,clear:!0,transitionScene:null,browserInfo:null,gl:null,glEnabled:!1,glTextureManager:null,glTtextureProgram:null, +glColorProgram:null,pMatrix:null,coords:null,coordsIndex:0,uv:null,uvIndex:0,front_to_back:!1,statistics:{size_total:0,size_active:0,size_dirtyRects:0,draws:0},currentTexturePage:0,currentOpacity:1,intervalId:null,frameCounter:0,RESIZE_NONE:1,RESIZE_WIDTH:2,RESIZE_HEIGHT:4,RESIZE_BOTH:8,RESIZE_PROPORTIONAL:16,resize:1,onResizeCallback:null,__gestureScale:0,__gestureRotation:0,dirtyRects:null,cDirtyRects:null,dirtyRectsIndex:0,dirtyRectsEnabled:!1,nDirtyRects:0,checkDebug:function(){if(CAAT.DEBUG){var a= (new CAAT.Debug).initialize(this.width,60);this.debugInfo=a.debugInfo.bind(a)}},getRenderType:function(){return this.glEnabled?"WEBGL":"CANVAS"},windowResized:function(a,b){switch(this.resize){case this.RESIZE_WIDTH:this.setBounds(0,0,a,this.height);break;case this.RESIZE_HEIGHT:this.setBounds(0,0,this.width,b);break;case this.RESIZE_BOTH:this.setBounds(0,0,a,b);break;case this.RESIZE_PROPORTIONAL:this.setScaleProportional(a,b)}this.glEnabled&&this.glReset();if(this.onResizeCallback)this.onResizeCallback(this, a,b)},setScaleProportional:function(a,b){var c=Math.min(a/this.referenceWidth,b/this.referenceHeight);this.setScaleAnchored(c,c,0,0);this.canvas.width=this.referenceWidth*c;this.canvas.height=this.referenceHeight*c;this.crc=this.ctx=this.canvas.getContext(this.glEnabled?"experimental-webgl":"2d");this.glEnabled&&this.glReset()},enableResizeEvents:function(a,b){a===this.RESIZE_BOTH||a===this.RESIZE_WIDTH||a===this.RESIZE_HEIGHT||a===this.RESIZE_PROPORTIONAL?(this.referenceWidth=this.width,this.referenceHeight= this.height,this.resize=a,CAAT.registerResizeListener(this),this.onResizeCallback=b,this.windowResized(window.innerWidth,window.innerHeight)):(CAAT.unregisterResizeListener(this),this.onResizeCallback=null)},setBounds:function(a,b,c,d){CAAT.Director.superclass.setBounds.call(this,a,b,c,d);this.canvas.width=c;this.canvas.height=d;this.crc=this.ctx=this.canvas.getContext(this.glEnabled?"experimental-webgl":"2d");for(a=0;a=0;b--){var c=this.childrenList[b],d=new CAAT.Point(a.x,a.y,0),c=c.findActorAtPosition(d);if(null!==c)return c}return this},resetStats:function(){this.statistics.size_total=0;this.statistics.size_active=0;this.statistics.draws=0}, +c.width=a;c.height=b;this.referenceWidth=a;this.referenceHeight=b;try{this.gl=c.getContext("experimental-webgl"),this.gl.viewportWidth=a,this.gl.viewportHeight=b,CAAT.GLRENDER=!0}catch(d){}if(this.gl)this.canvas=c,this.create(),this.setBounds(0,0,a,b),this.crc=this.ctx,this.enableEvents(c),this.timeline=(new Date).getTime(),this.glColorProgram=(new CAAT.ColorProgram(this.gl)).create().initialize(),this.glTextureProgram=(new CAAT.TextureProgram(this.gl)).create().initialize(),this.glTextureProgram.useProgram(), +this.glReset(),this.coords=new Float32Array(6144),this.uv=new Float32Array(4096),this.gl.clearColor(0,0,0,255),this.front_to_back?(this.gl.clearDepth(1),this.gl.enable(this.gl.DEPTH_TEST),this.gl.depthFunc(this.gl.LESS)):this.gl.disable(this.gl.DEPTH_TEST),this.gl.enable(this.gl.BLEND),this.gl.blendFunc(this.gl.ONE,this.gl.ONE_MINUS_SRC_ALPHA),this.glEnabled=!0,this.checkDebug();else return this.initialize(a,b,c);return this},createScene:function(){var a=(new CAAT.Scene).create();this.addScene(a); +return a},setImagesCache:function(a,b,c){var d;null!==this.glTextureManager&&(this.glTextureManager.deletePages(),this.glTextureManager=null);if(this.imagesCache){var e=[];for(d=0;d0&&CAAT.DEBUG&&CAAT.DEBUG_DIRTYRECTS){f.beginPath();this.nDirtyRects=0;d=this.cDirtyRects;for(c=0;c=this.dirtyRects.length)for(b=0;b<32;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0, -0,this.width,this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc;this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=true;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null=== -this.currentScene&&this.setScene(0)},getNumScenes:function(){return this.scenes.length},easeInOut:function(a,b,c,d,e,f,g,h,i,j){if(a!==this.getCurrentSceneIndex()){a=this.scenes[a];d=this.scenes[d];if(!this.glEnabled&&!navigator.browser==="iOS")this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene;a.setExpired(false);d.setExpired(false);a.mouseEnabled=false;d.mouseEnabled=false;a.resetTransform();d.resetTransform(); -a.setLocation(0,0);d.setLocation(0,0);a.alpha=1;d.alpha=1;b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i);e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j);this.childrenList=[];this.addChild(d);this.addChild(a)}},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;e< -0.33?(e=CAAT.Scene.prototype.EASE_ROTATION,g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):e<0.66?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;f<0.33?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):f<0.66?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)): -(f=CAAT.Scene.prototype.EASE_TRANSLATE,h=(new CAAT.Interpolator).createBounceOutInterpolator());this.easeInOut(a,e,Math.random()*8.99>>0,b,f,Math.random()*8.99>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=false;a.setExpired(false)}, -setScene:function(a){a=this.scenes[a];this.childrenList=[];this.addChild(a);this.currentScene=a;a.setExpired(false);a.mouseEnabled=true;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===0||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a, -b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===this.getNumScenes()-1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(true);a.mouseEnabled=true;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b500&&(b=500);if(this.onRenderStart)this.onRenderStart(b);this.render(b);this.debugInfo&&this.debugInfo(this.statistics);this.timeline=a;if(this.onRenderEnd)this.onRenderEnd(b)}, -endLoop:function(){},setClear:function(a){this.clear=a;if(this.clear===CAAT.Director.CLEAR_DIRTY_RECTS)this.dirtyRectsEnabled=true;return this},getAudioManager:function(){return this.audioManager},cumulateOffset:function(a,b,c){var d=c+"Left";c+="Top";for(var e=0,f=0,g;navigator.browser!=="iOS"&&a&&a.style;)if(g=a.currentStyle?a.currentStyle.position:(g=(a.ownerDocument.defaultView||a.ownerDocument.parentWindow).getComputedStyle(a,null))?g.getPropertyValue("position"):null,/^(fixed)$/.test(g))break; -else e+=a[d],f+=a[c],a=a[b];return{x:e,y:f,style:g}},getOffset:function(a){var b=this.cumulateOffset(a,"offsetParent","offset");return b.style==="fixed"?(a=this.cumulateOffset(a,a.parentNode?"parentNode":"parentElement","scroll"),{x:b.x+a.x,y:b.y+a.y}):{x:b.x,y:b.y}},getCanvasCoord:function(a,b){var c=0,d=0;if(!b)b=window.event;if(b.pageX||b.pageY)c=b.pageX,d=b.pageY;else if(b.clientX||b.clientY)c=b.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,d=b.clientY+document.body.scrollTop+ -document.documentElement.scrollTop;var e=this.getOffset(b.target);c-=e.x;d-=e.y;d=new CAAT.Point(c,d);if(!this.modelViewMatrixI)this.modelViewMatrixI=this.modelViewMatrix.getInverse();this.modelViewMatrixI.transformCoord(d);c=d.x;d=d.y;a.set(c,d);this.screenMousePoint.set(c,d)},__mouseDownHandler:function(a){if(this.dragging&&this.lastSelectedActor)this.__mouseUpHandler(a);else{this.getCanvasCoord(this.mousePoint,a);this.isMouseDown=true;var b=this.findActorAtPosition(this.mousePoint);if(null!==b){var c= -b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));b.mouseDown((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y)))}this.lastSelectedActor=b}},__mouseUpHandler:function(a){this.isMouseDown=false;this.getCanvasCoord(this.mousePoint,a);var b=null,c=this.lastSelectedActor;null!==c&&(b=c.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),c.actionPerformed&&c.contains(b.x,b.y)&&c.actionPerformed(a), -c.mouseUp((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time)));!this.dragging&&null!==c&&c.contains(b.x,b.y)&&c.mouseClick((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time));this.in_=this.dragging=false},__mouseMoveHandler:function(a){this.getCanvasCoord(this.mousePoint,a);var b,c,d=this.currentScene?this.currentScene.time:0;if(this.isMouseDown&&null!==this.lastSelectedActor){b=this.lastSelectedActor;c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x, -this.screenMousePoint.y,0));this.dragging=true;var e=b.x,f=b.y;b.mouseDrag((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y),d));this.prevMousePoint.x=c.x;this.prevMousePoint.y=c.y;if(e===b.x&&f===b.y){e=b.contains(c.x,c.y);if(this.in_&&!e)b.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,d)),this.in_=false;if(!this.in_&&e)b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,d)),this.in_=true}}else this.in_= -true,b=this.findActorAtPosition(this.mousePoint),b!==this.lastSelectedActor&&(null!==this.lastSelectedActor&&(c=this.lastSelectedActor.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),this.lastSelectedActor.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,this.lastSelectedActor,this.screenMousePoint,d))),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint, -d)))),c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),null!==b&&b.mouseMove((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,d)),this.lastSelectedActor=b},__mouseOutHandler:function(a){if(null!==this.lastSelectedActor){this.getCanvasCoord(this.mousePoint,a);var b=new CAAT.Point(this.mousePoint.x,this.mousePoint.y,0);this.lastSelectedActor.viewToModel(b);a=(new CAAT.MouseEvent).init(b.x,b.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time); -this.lastSelectedActor.mouseExit(a);this.lastSelectedActor.mouseOut(a);if(!this.dragging)this.lastSelectedActor=null}else this.in_=this.isMouseDown=false},__mouseOverHandler:function(a){var b,c;this.getCanvasCoord(this.mousePoint,a);null==this.lastSelectedActor?(b=this.findActorAtPosition(this.mousePoint),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScane?this.currentScene.time: -0),b.mouseOver(a),b.mouseEnter(a)),this.lastSelectedActor=b):(b=this.lastSelectedActor,c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a))},__mouseDBLClickHandler:function(a){this.getCanvasCoord(this.mousePoint,a);null!==this.lastSelectedActor&&this.lastSelectedActor.mouseDblClick((new CAAT.MouseEvent).init(this.mousePoint.x,this.mousePoint.y,a,this.lastSelectedActor, -this.screenMousePoint,this.currentScene.time))},__touchStartHandler:function(a){a.preventDefault();a=a.targetTouches[0];this.__mouseDownHandler(a)},__touchEndHandler:function(a){a.preventDefault();a=a.changedTouches[0];this.__mouseUpHandler(a)},__touchMoveHandler:function(a){a.preventDefault();if(!this.gesturing)for(var b=0;b=this.dirtyRects.length)for(b=0;32>b;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0,0,this.width, +this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc;this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=!0;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null===this.currentScene&& +this.setScene(0)},getNumScenes:function(){return this.scenes.length},easeInOut:function(a,b,c,d,e,f,g,h,i,j){a!==this.getCurrentSceneIndex()&&(a=this.scenes[a],d=this.scenes[d],!this.glEnabled&&"iOS"===!navigator.browser&&(this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene),a.setExpired(!1),d.setExpired(!1),a.mouseEnabled=!1,d.mouseEnabled=!1,a.resetTransform(),d.resetTransform(),a.setLocation(0,0), +d.setLocation(0,0),a.alpha=1,d.alpha=1,b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i),e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j),this.childrenList=[],this.addChild(d),this.addChild(a))},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;0.33>e?(e=CAAT.Scene.prototype.EASE_ROTATION, +g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):0.66>e?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;0.33>f?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):0.66>f?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)):(f=CAAT.Scene.prototype.EASE_TRANSLATE, +h=(new CAAT.Interpolator).createBounceOutInterpolator());this.easeInOut(a,e,8.99*Math.random()>>0,b,f,8.99*Math.random()>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=!1;a.setExpired(!1)},setScene:function(a){a=this.scenes[a];this.childrenList= +[];this.addChild(a);this.currentScene=a;a.setExpired(!1);a.mouseEnabled=!0;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);1>=this.getNumScenes()||0===d||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene); +1>=this.getNumScenes()||d===this.getNumScenes()-1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(!0);a.mouseEnabled=!0;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b>0)*e;var k=i+(d/h>>0)*f,m=g+e,n=k+f;g=(new CAAT.SpriteImageHelper(g,k,m-g,n-k,j.width,j.height)).setGL(g/j.width,k/j.height,m/j.width,n/j.height);this.mapInfo[d]=g}}else for(d=0;d0&&(g-=e);var h=(this.offsetY-this.ownerActor.y)%f;h>0&&(h-=f);var e=((d.width-g)/e>>0)+1,f=((d.height-h)/f>>0)+1,i,j,k=a.ctx;for(i=0;i>0)*e;var k=i+(d/h>>0)*f,m=g+e,n=k+f;g=(new CAAT.SpriteImageHelper(g,k,m-g,n-k,j.width,j.height)).setGL(g/j.width,k/j.height,m/j.width,n/j.height);this.mapInfo[d]=g}}else for(d=0;d>0)+1,f=((d.height-h)/f>>0)+1,i,j,k=a.ctx;for(i=0;i>0,d.y-this.ownerActor.y+h+i*c.height>>0,c.width,c.height)},paintInvertedH:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate((c|0)+b.width,d|0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex]; a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedHV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.translate(b.width,0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this}, paintN:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,b.width,b.height);return this},paintScaled:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,this.ownerActor.width,this.ownerActor.height);return this},getCurrentSpriteImageCSSPosition:function(){var a=this.mapInfo[this.spriteIndex]; return"-"+(a.x-this.offsetX)+"px -"+(a.y-this.offsetY)+"px "+(this.transformation===this.TR_TILE?"":"no-repeat")},getNumImages:function(){return this.rows*this.columns},setUV:function(a,b){var c=this.image;if(c.__texturePage){var d=b,e=this.mapInfo[this.spriteIndex],f=e.u,g=e.v,h=e.u1,e=e.v1;if(this.offsetX||this.offsetY)f=c.__texturePage,g=-this.offsetY/f.height,h=(this.ownerActor.width-this.offsetX)/f.width,e=(this.ownerActor.height-this.offsetY)/f.height,f=-this.offsetX/f.width+c.__u,g+=c.__v, h+=c.__u,e+=c.__v;c.inverted?(a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e,a[d++]=f,a[d++]=g):(a[d++]=f,a[d++]=g,a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e)}},setChangeFPS:function(a){this.changeFPS=a;return this},setSpriteTransformation:function(a){this.transformation=a;switch(a){case this.TR_FLIP_HORIZONTAL:this.paint=this.paintInvertedH;break;case this.TR_FLIP_VERTICAL:this.paint=this.paintInvertedV;break;case this.TR_FLIP_ALL:this.paint=this.paintInvertedHV;break;case this.TR_FIXED_TO_SIZE:this.paint= -this.paintScaled;break;case this.TR_TILE:this.paint=this.paintTiled;break;default:this.paint=this.paintN}return this},setAnimationImageIndex:function(a){this.animationImageIndex=a;this.spriteIndex=a[0];return this},setSpriteIndex:function(a){this.spriteIndex=a;return this},setSpriteIndexAtTime:function(a){if(this.animationImageIndex.length>1)this.prevAnimationTime===-1?(this.prevAnimationTime=a,this.spriteIndex=0):(a-=this.prevAnimationTime,a/=this.changeFPS,a%=this.animationImageIndex.length,this.spriteIndex= -this.animationImageIndex[Math.floor(a)])},getMapInfo:function(a){return this.mapInfo[a]},initializeFromMap:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b)d=b[c],d=new CAAT.SpriteImageHelper(d.x,d.y,d.width,d.height,a.width,a.height),this.mapInfo[c]=d,e||this.setAnimationImageIndex([c]),e++;return this},initializeAsGlyphDesigner:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b){var f=b[c];d=new CAAT.SpriteImageHelper(f.x,f.y,f.width,f.height,a.width,a.height);d.xoffset=typeof f.xoffset=== -"undefined"?0:f.xoffset;d.yoffset=typeof f.yoffset==="undefined"?0:f.yoffset;d.xadvance=typeof f.xadvance==="undefined"?f.width:f.xadvance;this.mapInfo[c]=d;e||this.setAnimationImageIndex([c]);e++}return this},initializeAsFontMap:function(a,b){this.initialize(a,1,1);for(var c,d=0,e=0;e>0,f=0;fa&&(a=c)}return this.fontHeight=a},drawString:function(a,b,c,d){for(var e, -f,g=b.split(""),b=0;b=this.duration?(this.remove=true,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, -b,this);return this},reset:function(a){this.remove=false;this.startTime=a;this.scene.ensureTimerTask(this);return this},cancel:function(){this.remove=true;null!=this.callback_cancel&&this.callback_cancel(this.scene.time,this.scene.time-this.startTime,this);return this}}})();(function(){CAAT.Scene=function(){CAAT.Scene.superclass.constructor.call(this);this.timerList=[];this.style("overflow","hidden");return this};CAAT.Scene.prototype={easeContainerBehaviour:null,easeContainerBehaviourListener:null,easeIn:false,EASE_ROTATION:1,EASE_SCALE:2,EASE_TRANSLATE:3,timerList:null,timerSequence:0,paused:false,isPaused:function(){return this.paused},setPaused:function(a){this.paused=a},checkTimers:function(a){for(var b=this.timerList.length-1;b>=0;)this.timerList[b].remove||this.timerList[b].checkTask(a), -b--},ensureTimerTask:function(a){this.hasTimer(a)||this.timerList.push(a);return this},hasTimer:function(a){for(var b=this.timerList.length-1;b>=0;){if(this.timerList[b]===a)return true;b--}return false},createTimer:function(a,b,c,d,e){a=(new CAAT.TimerTask).create(a,b,c,d,e);a.taskId=this.timerSequence++;a.sceneTime=this.time;a.scene=this;this.timerList.push(a);return a},removeExpiredTimers:function(){var a;for(a=0;a4&&(c=4);switch(c){case CAAT.Actor.prototype.ANCHOR_TOP:d?f.setPath((new CAAT.Path).setLinear(0,-this.height,0,0)):f.setPath((new CAAT.Path).setLinear(0,0,0,-this.height));break;case CAAT.Actor.prototype.ANCHOR_BOTTOM:d?f.setPath((new CAAT.Path).setLinear(0,this.height,0,0)):f.setPath((new CAAT.Path).setLinear(0,0,0,this.height));break;case CAAT.Actor.prototype.ANCHOR_LEFT:d?f.setPath((new CAAT.Path).setLinear(-this.width, +f,g=b.split(""),b=0;b=this.duration?(this.remove=!0,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, +b,this);return this},reset:function(a){this.remove=!1;this.startTime=a;this.scene.ensureTimerTask(this);return this},cancel:function(){this.remove=!0;null!=this.callback_cancel&&this.callback_cancel(this.scene.time,this.scene.time-this.startTime,this);return this}}})();(function(){CAAT.Scene=function(){CAAT.Scene.superclass.constructor.call(this);this.timerList=[];this.style("overflow","hidden");return this};CAAT.Scene.prototype={easeContainerBehaviour:null,easeContainerBehaviourListener:null,easeIn:!1,EASE_ROTATION:1,EASE_SCALE:2,EASE_TRANSLATE:3,timerList:null,timerSequence:0,paused:!1,isPaused:function(){return this.paused},setPaused:function(a){this.paused=a},checkTimers:function(a){for(var b=this.timerList.length-1;0<=b;)this.timerList[b].remove||this.timerList[b].checkTask(a), +b--},ensureTimerTask:function(a){this.hasTimer(a)||this.timerList.push(a);return this},hasTimer:function(a){for(var b=this.timerList.length-1;0<=b;){if(this.timerList[b]===a)return!0;b--}return!1},createTimer:function(a,b,c,d,e){a=(new CAAT.TimerTask).create(a,b,c,d,e);a.taskId=this.timerSequence++;a.sceneTime=this.time;a.scene=this;this.timerList.push(a);return a},removeExpiredTimers:function(){var a;for(a=0;ac?c=1:4Math.random()?1:-1);break;case CAAT.Actor.prototype.ANCHOR_TOP_LEFT:case CAAT.Actor.prototype.ANCHOR_TOP_RIGHT:case CAAT.Actor.prototype.ANCHOR_BOTTOM_LEFT:case CAAT.Actor.prototype.ANCHOR_BOTTOM_RIGHT:f=Math.PI/2*(0.5>Math.random()?1:-1);break;default:alert("rot anchor ?? "+c)}if(!1===d)var h=f,f=g,g=h;b&&this.createAlphaBehaviour(a, d);b=this.getAnchorPercent(c);f=(new CAAT.RotateBehavior).setFrameTime(0,a).setValues(f,g,b.x,b.y);e&&f.setInterpolator(e);this.easeContainerBehaviour.addBehavior(f);this.easeContainerBehaviour.setFrameTime(this.time,a);this.easeContainerBehaviour.addListener(this);this.emptyBehaviorList();CAAT.Scene.superclass.addBehavior.call(this,this.easeContainerBehaviour)},setEaseListener:function(a){this.easeContainerBehaviourListener=a},behaviorExpired:function(){this.easeContainerBehaviourListener.easeEnd(this, -this.easeIn)},activated:function(){},setExpired:function(a){this.expired=a;this.style("display",a?"none":"block")},paint:function(){}};extend(CAAT.Scene,CAAT.ActorContainer,null)})();CAAT.modules=CAAT.modules||{};CAAT.modules.CircleManager=CAAT.modules.CircleManager||{};(function(){CAAT.modules.LayoutUtils={};CAAT.modules.LayoutUtils.row=function(a,b,c){for(var d=a.width,e=0,f=0,g=0,h=0,h=-Number.MAX_VALUE,i=Number.MAX_VALUE,g=b.length-1;g;g-=1){if(ithis.bounds.right)a.position.x=this.bounds.left+e;else if(b&1&&c+fthis.bounds.bottom)a.position.y=this.bounds.top-e;else if(b&4&&d+f=this.bounds.right)a.position.x=a.position.x=this.bounds.right-e;else if(b&8&&c-ethis.bounds.bottom)a.position.y=this.bounds.bottom-e;else if(b&16&&d-ed?e=-1:c=0;a--)this.allCircles[a]===null&&this.allCircles.splice(a,1)},initialize:function(a){if(a)for(var b in a)this[b]=a[b];return this}}})();(function(){CAAT.modules.LocalStorage=function(){return this};CAAT.modules.LocalStorage.prototype={save:function(a,b){try{localStorage.setItem(a,JSON.stringify(b))}catch(c){}return this},load:function(a){try{return JSON.parse(localStorage.getItem(a))}catch(b){return null}},remove:function(a){try{localStorage.removeItem(a)}catch(b){}return this}}})();(function(){CAAT.modules.ImageUtil={};CAAT.modules.ImageUtil.createAlphaSpriteSheet=function(a,b,c,d,e){if(a>=0;var d=true,e=true,f=true,g=true;if(typeof c!=="undefined"){if(typeof c.top!== -"undefined")d=c.top;if(typeof c.bottom!=="undefined")e=c.bottom;if(typeof c.left!=="undefined")f=c.left;if(typeof c.right!=="undefined")g=c.right}c=document.createElement("canvas");c.width=a.width;c.height=a.height;var h=c.getContext("2d");h.fillStyle="rgba(0,0,0,0)";h.fillRect(0,0,a.width,a.height);h.drawImage(a,0,0);var i=h.getImageData(0,0,a.width,a.height).data,j,a=0,k=c.height-1,m=0,n=c.width-1,l=false;if(d){for(d=0;db){l=true;break}if(l)break}a= -d}if(e){l=false;for(d=c.height-1;d>=a;d--){for(j=0;jb){l=true;break}if(l)break}k=d}if(f){l=false;for(j=0;jb){l=true;break}if(l)break}m=j}if(g){l=false;for(j=c.width-1;j>=m;j--){for(d=a;d<=k;d++)if(i[d*c.width*4+3+j*4]>b){l=true;break}if(l)break}n=j}if(0===m&&0===a&&c.width-1===n&&c.height-1===k)return c;b=n-m+1;e=k-a+1;f=h.getImageData(m,a,b,e);c.width=b;c.height=e;h=c.getContext("2d");h.putImageData(f,0,0); -return c};CAAT.modules.ImageUtil.createThumb=function(a,b,c,d){var b=b||24,c=c||24,e=document.createElement("canvas");e.width=b;e.height=c;var f=e.getContext("2d");if(d){var g=Math.max(a.width,a.height),d=a.width/g*b,g=a.height/g*c;f.drawImage(a,(b-d)/2,(c-g)/2,d,g)}else f.drawImage(a,0,0,b,c);return e}})();(function(){CAAT.Font=function(){return this};CAAT.Font.prototype={fontSize:10,fontSizeUnit:"px",font:"Sans-Serif",fontStyle:"",fillStyle:"#fff",strokeStyle:null,padding:0,image:null,charMap:null,height:0,setPadding:function(a){this.padding=a;return this},setFontStyle:function(a){this.fontStyle=a;return this},setFontSize:function(a){this.fontSize=a;this.fontSizeUnit="px";return this},setFont:function(a){this.font=a;return this},setFillStyle:function(a){this.fillStyle=a;return this},setStrokeStyle:function(a){this.strokeStyle= -a;return this},createDefault:function(a){for(var b="",c=32;c<128;c++)b+=String.fromCharCode(c);return this.create(b,a)},create:function(a,b){this.padding=b;var c=document.createElement("canvas");c.width=1;c.height=1;var d=c.getContext("2d");d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;var e=0,f=[],g,h;for(g=0;g>0)+1)+2*b,f.push(h),e+=h;c.width=e;c.height=this.fontSize*1.5>>0;d=c.getContext("2d"); -d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;d.fillStyle=this.fillStyle;d.strokeStyle=this.strokeStyle;this.charMap={};for(g=e=0;gthis.bounds.right?a.position.x=this.bounds.left+e:b&1&&c+fthis.bounds.bottom? +a.position.y=this.bounds.top-e:b&4&&d+f=this.bounds.right?a.position.x=a.position.x=this.bounds.right-e:b&8&&c-ethis.bounds.bottom?a.position.y=this.bounds.bottom-e:b&16&&d-ed?e=-1:c>0,d=!0,e=!0,f=!0,g=!0;"undefined"!==typeof c&&("undefined"!== +typeof c.top&&(d=c.top),"undefined"!==typeof c.bottom&&(e=c.bottom),"undefined"!==typeof c.left&&(f=c.left),"undefined"!==typeof c.right&&(g=c.right));c=document.createElement("canvas");c.width=a.width;c.height=a.height;var h=c.getContext("2d");h.fillStyle="rgba(0,0,0,0)";h.fillRect(0,0,a.width,a.height);h.drawImage(a,0,0);var i=h.getImageData(0,0,a.width,a.height).data,j,a=0,k=c.height-1,m=0,n=c.width-1,l=!1;if(d){for(d=0;db){l=!0;break}if(l)break}a= +d}if(e){l=!1;for(d=c.height-1;d>=a;d--){for(j=0;jb){l=!0;break}if(l)break}k=d}if(f){l=!1;for(j=0;jb){l=!0;break}if(l)break}m=j}if(g){l=!1;for(j=c.width-1;j>=m;j--){for(d=a;d<=k;d++)if(i[4*d*c.width+3+4*j]>b){l=!0;break}if(l)break}n=j}if(0===m&&0===a&&c.width-1===n&&c.height-1===k)return c;b=n-m+1;e=k-a+1;f=h.getImageData(m,a,b,e);c.width=b;c.height=e;h=c.getContext("2d");h.putImageData(f,0,0);return c};CAAT.modules.ImageUtil.createThumb= +function(a,b,c,d){var b=b||24,c=c||24,e=document.createElement("canvas");e.width=b;e.height=c;var f=e.getContext("2d");if(d){var g=Math.max(a.width,a.height),d=a.width/g*b,g=a.height/g*c;f.drawImage(a,(b-d)/2,(c-g)/2,d,g)}else f.drawImage(a,0,0,b,c);return e}})();(function(){CAAT.Font=function(){return this};CAAT.Font.prototype={fontSize:10,fontSizeUnit:"px",font:"Sans-Serif",fontStyle:"",fillStyle:"#fff",strokeStyle:null,padding:0,image:null,charMap:null,height:0,setPadding:function(a){this.padding=a;return this},setFontStyle:function(a){this.fontStyle=a;return this},setFontSize:function(a){this.fontSize=a;this.fontSizeUnit="px";return this},setFont:function(a){this.font=a;return this},setFillStyle:function(a){this.fillStyle=a;return this},setStrokeStyle:function(a){this.strokeStyle= +a;return this},createDefault:function(a){for(var b="",c=32;128>c;c++)b+=String.fromCharCode(c);return this.create(b,a)},create:function(a,b){this.padding=b;var c=document.createElement("canvas");c.width=1;c.height=1;var d=c.getContext("2d");d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;var e=0,f=[],g,h;for(g=0;g>0)+1)+2*b,h=Math.max(1,(d.measureText(a.charAt(g)).width>>0)+1),f.push(h),e+= +h+2*b;c.width=e;c.height=1.5*this.fontSize>>0;d=c.getContext("2d");d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;d.fillStyle=this.fillStyle;d.strokeStyle=this.strokeStyle;this.charMap={};e=b;for(g=0;g1||a<0)a%=1;a<0&&(a=1+a);this.newPosition.set(this.points[0].x+(this.points[1].x-this.points[0].x)*a,this.points[0].y+(this.points[1].y-this.points[0].y)*a);return this.newPosition},getPositionFromLength:function(a){return this.getPosition(a/this.length)},initialPositionX:function(){return this.points[0].x},finalPositionX:function(){return this.points[1].x},paint:function(a,b){var c=a.ctx;c.save();c.strokeStyle=this.color; -c.beginPath();c.moveTo(this.points[0].x,this.points[0].y);c.lineTo(this.points[1].x,this.points[1].y);c.stroke();if(b)c.globalAlpha=0.5,c.fillStyle="#7f7f00",c.beginPath(),this.drawHandle(c,this.points[0].x,this.points[0].y),this.drawHandle(c,this.points[1].x,this.points[1].y);c.restore()},numControlPoints:function(){return 2},getControlPoint:function(a){if(0===a)return this.points[0];else if(1===a)return this.points[1]},getContour:function(){var a=[];a.push(this.getPosition(0).clone());a.push(this.getPosition(1).clone()); +startCurvePosition:function(){return this.points[0]},getPosition:function(a){if(1a)a%=1;0>a&&(a=1+a);this.newPosition.set(this.points[0].x+(this.points[1].x-this.points[0].x)*a,this.points[0].y+(this.points[1].y-this.points[0].y)*a);return this.newPosition},getPositionFromLength:function(a){return this.getPosition(a/this.length)},initialPositionX:function(){return this.points[0].x},finalPositionX:function(){return this.points[1].x},paint:function(a,b){var c=a.ctx;c.save();c.strokeStyle=this.color; +c.beginPath();c.moveTo(this.points[0].x,this.points[0].y);c.lineTo(this.points[1].x,this.points[1].y);c.stroke();b&&(c.globalAlpha=0.5,c.fillStyle="#7f7f00",c.beginPath(),this.drawHandle(c,this.points[0].x,this.points[0].y),this.drawHandle(c,this.points[1].x,this.points[1].y));c.restore()},numControlPoints:function(){return 2},getControlPoint:function(a){if(0===a)return this.points[0];if(1===a)return this.points[1]},getContour:function(){var a=[];a.push(this.getPosition(0).clone());a.push(this.getPosition(1).clone()); return a}};extend(CAAT.LinearPath,CAAT.PathSegment)})(); (function(){CAAT.CurvePath=function(){CAAT.CurvePath.superclass.constructor.call(this);this.newPosition=new CAAT.Point(0,0,0);return this};CAAT.CurvePath.prototype={curve:null,newPosition:null,applyAsPath:function(a){this.curve.applyAsPath(a);return this},setPoint:function(a,b){this.curve&&this.curve.setPoint(a,b)},setPoints:function(a){var b=new CAAT.Bezier;b.setPoints(a);this.curve=b;return this},setQuadric:function(a,b,c,d,e,f){var g=new CAAT.Bezier;g.setQuadric(a,b,c,d,e,f);this.curve=g;this.updatePath(); -return this},setCubic:function(a,b,c,d,e,f,g,h){var i=new CAAT.Bezier;i.setCubic(a,b,c,d,e,f,g,h);this.curve=i;this.updatePath();return this},updatePath:function(){this.curve.update();this.length=this.curve.getLength();this.curve.getBoundingBox(this.bbox);return this},getPosition:function(a){if(a>1||a<0)a%=1;a<0&&(a=1+a);this.curve.solve(this.newPosition,a);return this.newPosition},getPositionFromLength:function(a){this.curve.solve(this.newPosition,a/this.length);return this.newPosition},initialPositionX:function(){return this.curve.coordlist[0].x}, +return this},setCubic:function(a,b,c,d,e,f,g,h){var i=new CAAT.Bezier;i.setCubic(a,b,c,d,e,f,g,h);this.curve=i;this.updatePath();return this},updatePath:function(){this.curve.update();this.length=this.curve.getLength();this.curve.getBoundingBox(this.bbox);return this},getPosition:function(a){if(1a)a%=1;0>a&&(a=1+a);this.curve.solve(this.newPosition,a);return this.newPosition},getPositionFromLength:function(a){this.curve.solve(this.newPosition,a/this.length);return this.newPosition},initialPositionX:function(){return this.curve.coordlist[0].x}, finalPositionX:function(){return this.curve.coordlist[this.curve.coordlist.length-1].x},paint:function(a,b){this.curve.drawHandles=b;a.ctx.strokeStyle=this.color;this.curve.paint(a,b)},numControlPoints:function(){return this.curve.coordlist.length},getControlPoint:function(a){return this.curve.coordlist[a]},endCurvePosition:function(){return this.curve.endCurvePosition()},startCurvePosition:function(){return this.curve.startCurvePosition()},getContour:function(a){for(var b=[],c=0;c<=a;c++)b.push({x:c/ a,y:this.getPosition(c/a).y});return b}};extend(CAAT.CurvePath,CAAT.PathSegment,null)})(); -(function(){CAAT.ShapePath=function(){CAAT.ShapePath.superclass.constructor.call(this);this.points=[];this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.newPosition=new CAAT.Point;return this};CAAT.ShapePath.prototype={points:null,length:-1,cw:true,bbox:null,newPosition:null,applyAsPath:function(a){a=a.ctx;this.cw?(a.lineTo(this.points[0].x,this.points[0].y),a.lineTo(this.points[1].x, -this.points[1].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[4].x,this.points[4].y)):(a.lineTo(this.points[4].x,this.points[4].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[1].x,this.points[1].y),a.lineTo(this.points[0].x,this.points[0].y));return this},setPoint:function(a,b){b>=0&&b1||a<0)a%=1;a<0&&(a=1+a);if(-1===this.length)this.newPosition.set(0,0);else{var b=this.bbox.width/this.length,c=this.bbox.height/this.length,d=0,e,f=0;this.cw?(e=[0,1,2,3,4],b=[b,c, +(function(){CAAT.ShapePath=function(){CAAT.ShapePath.superclass.constructor.call(this);this.points=[];this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.newPosition=new CAAT.Point;return this};CAAT.ShapePath.prototype={points:null,length:-1,cw:!0,bbox:null,newPosition:null,applyAsPath:function(a){a=a.ctx;this.cw?(a.lineTo(this.points[0].x,this.points[0].y),a.lineTo(this.points[1].x, +this.points[1].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[4].x,this.points[4].y)):(a.lineTo(this.points[4].x,this.points[4].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[1].x,this.points[1].y),a.lineTo(this.points[0].x,this.points[0].y));return this},setPoint:function(a,b){0<=b&&ba)a%=1;0>a&&(a=1+a);if(-1===this.length)this.newPosition.set(0,0);else{var b=this.bbox.width/this.length,c=this.bbox.height/this.length,d=0,e,f=0;this.cw?(e=[0,1,2,3,4],b=[b,c, b,c]):(e=[4,3,2,1,0],b=[c,b,c,b]);for(;fa;a++)this.bbox.union(this.points[a].x,this.points[a].y);this.length=2*this.bbox.width+2*this.bbox.height;this.points[0].x=this.bbox.x;this.points[0].y=this.bbox.y;this.points[1].x=this.bbox.x+this.bbox.width;this.points[1].y=this.bbox.y;this.points[2].x= this.bbox.x+this.bbox.width;this.points[2].y=this.bbox.y+this.bbox.height;this.points[3].x=this.bbox.x;this.points[3].y=this.bbox.y+this.bbox.height;this.points[4].x=this.bbox.x;this.points[4].y=this.bbox.y;return this}};extend(CAAT.ShapePath,CAAT.PathSegment)})(); -(function(){CAAT.Path=function(){CAAT.Path.superclass.constructor.call(this);this.newPosition=new CAAT.Point(0,0,0);this.pathSegments=[];this.behaviorList=[];this.matrix=new CAAT.Matrix;this.tmpMatrix=new CAAT.Matrix;return this};CAAT.Path.prototype={pathSegments:null,pathSegmentDurationTime:null,pathSegmentStartTime:null,newPosition:null,pathLength:-1,beginPathX:-1,beginPathY:-1,trackPathX:-1,trackPathY:-1,ax:-1,ay:-1,point:[],interactive:true,behaviorList:null,rb_angle:0,rb_rotateAnchorX:0.5,rb_rotateAnchorY:0.5, +(function(){CAAT.Path=function(){CAAT.Path.superclass.constructor.call(this);this.newPosition=new CAAT.Point(0,0,0);this.pathSegments=[];this.behaviorList=[];this.matrix=new CAAT.Matrix;this.tmpMatrix=new CAAT.Matrix;return this};CAAT.Path.prototype={pathSegments:null,pathSegmentDurationTime:null,pathSegmentStartTime:null,newPosition:null,pathLength:-1,beginPathX:-1,beginPathY:-1,trackPathX:-1,trackPathY:-1,ax:-1,ay:-1,point:[],interactive:!0,behaviorList:null,rb_angle:0,rb_rotateAnchorX:0.5,rb_rotateAnchorY:0.5, sb_scaleX:1,sb_scaleY:1,sb_scaleAnchorX:0.5,sb_scaleAnchorY:0.5,tAnchorX:0,tAnchorY:0,tb_x:0,tb_y:0,matrix:null,tmpMatrix:null,pathPoints:null,width:0,height:0,clipOffsetX:0,clipOffsetY:0,applyAsPath:function(a){var b=a.ctx;a.modelViewMatrix.transformRenderingContext(b);b.beginPath();b.globalCompositeOperation="source-out";b.moveTo(this.getFirstPathSegment().startCurvePosition().x,this.getFirstPathSegment().startCurvePosition().y);for(var c=0;c1||a<0)a%=1;a<0&&(a=1+a);for(var b=this.pathSegments,c=this.pathSegmentStartTime,d=this.pathSegmentDurationTime,e=0,f=b.length,g,h=this.newPosition,i;e!==f;)if(g=(f+e)/2|0,i=c[g],i<=a&&a<=i+d[g])return a=d[g]?(a-i)/d[g]:0,a=b[g].getPosition(a),h.x=a.x,h.y=a.y,h;else aa)a%=1;0>a&&(a=1+a);for(var b=this.pathSegments,c=this.pathSegmentStartTime,d=this.pathSegmentDurationTime,e=0,f=b.length,g,h=this.newPosition,i;e!==f;){g=(f+e)/2|0;i=c[g];if(i<=a&&a<=i+d[g])return a=d[g]?(a-i)/d[g]:0,a=b[g].getPosition(a),h.x=a.x,h.y=a.y,h;aa&&(a+=this.getLength());for(var b=0,c=0;c0?this.pathSegmentStartTime[c]=this.pathSegmentStartTime[c-1]+this.pathSegmentDurationTime[c-1]:this.pathSegmentStartTime[0]=0,this.pathSegments[c].endPath();this.extractPathPoints();typeof b!=="undefined"&&b(this);return this},press:function(a,b){if(this.interactive){for(var c=CAAT.Curve.prototype.HANDLE_SIZE/2,d=0;d=f.x-c&&b>=f.y-c&&a=f.x-c&&b>=f.y-c&&a=0&&b> 8) & 0xFF, + (num ) & 0xFF ); +}; +Array.prototype.push32 = function (num) { + this.push((num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + (num ) & 0xFF ); +}; + +// IE does not support map (even in IE9) +//This prototype is provided by the Mozilla foundation and +//is distributed under the MIT license. +//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license +if (!Array.prototype.map) +{ + Array.prototype.map = function(fun /*, thisp*/) + { + var len = this.length; + if (typeof fun != "function") + throw new TypeError(); + + var res = new Array(len); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + { + if (i in this) + res[i] = fun.call(thisp, this[i], i, this); + } + + return res; + }; +} + +/* + * ------------------------------------------------------ + * Namespaced in Util + * ------------------------------------------------------ + */ + +/* + * Logging/debug routines + */ + +Util._log_level = 'warn'; +Util.init_logging = function (level) { + if (typeof level === 'undefined') { + level = Util._log_level; + } else { + Util._log_level = level; + } + if (typeof window.console === "undefined") { + if (typeof window.opera !== "undefined") { + window.console = { + 'log' : window.opera.postError, + 'warn' : window.opera.postError, + 'error': window.opera.postError }; + } else { + window.console = { + 'log' : function(m) {}, + 'warn' : function(m) {}, + 'error': function(m) {}}; + } + } + + Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; + switch (level) { + case 'debug': Util.Debug = function (msg) { console.log(msg); }; + case 'info': Util.Info = function (msg) { console.log(msg); }; + case 'warn': Util.Warn = function (msg) { console.warn(msg); }; + case 'error': Util.Error = function (msg) { console.error(msg); }; + case 'none': + break; + default: + throw("invalid logging type '" + level + "'"); + } +}; +Util.get_logging = function () { + return Util._log_level; +}; +// Initialize logging level +Util.init_logging(); + + +// Set configuration default for Crockford style function namespaces +Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) { + var getter, setter; + + // Default getter function + getter = function (idx) { + if ((type in {'arr':1, 'array':1}) && + (typeof idx !== 'undefined')) { + return cfg[v][idx]; + } else { + return cfg[v]; + } + }; + + // Default setter function + setter = function (val, idx) { + if (type in {'boolean':1, 'bool':1}) { + if ((!val) || (val in {'0':1, 'no':1, 'false':1})) { + val = false; + } else { + val = true; + } + } else if (type in {'integer':1, 'int':1}) { + val = parseInt(val, 10); + } else if (type === 'func') { + if (!val) { + val = function () {}; + } + } + if (typeof idx !== 'undefined') { + cfg[v][idx] = val; + } else { + cfg[v] = val; + } + }; + + // Set the description + api[v + '_description'] = desc; + + // Set the getter function + if (typeof api['get_' + v] === 'undefined') { + api['get_' + v] = getter; + } + + // Set the setter function with extra sanity checks + if (typeof api['set_' + v] === 'undefined') { + api['set_' + v] = function (val, idx) { + if (mode in {'RO':1, 'ro':1}) { + throw(v + " is read-only"); + } else if ((mode in {'WO':1, 'wo':1}) && + (typeof cfg[v] !== 'undefined')) { + throw(v + " can only be set once"); + } + setter(val, idx); + }; + } + + // Set the default value + if (typeof defaults[v] !== 'undefined') { + defval = defaults[v]; + } else if ((type in {'arr':1, 'array':1}) && + (! (defval instanceof Array))) { + defval = []; + } + // Coerce existing setting to the right type + //Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]); + setter(defval); +}; + +// Set group of configuration defaults +Util.conf_defaults = function(cfg, api, defaults, arr) { + var i; + for (i = 0; i < arr.length; i++) { + Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1], + arr[i][2], arr[i][3], arr[i][4]); + } +}; + + +/* + * Cross-browser routines + */ + +// Get DOM element position on page +Util.getPosition = function (obj) { + var x = 0, y = 0; + if (obj.offsetParent) { + do { + x += obj.offsetLeft; + y += obj.offsetTop; + obj = obj.offsetParent; + } while (obj); + } + return {'x': x, 'y': y}; +}; + +// Get mouse event position in DOM element +Util.getEventPosition = function (e, obj, scale) { + var evt, docX, docY, pos; + //if (!e) evt = window.event; + evt = (e ? e : window.event); + evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt); + if (evt.pageX || evt.pageY) { + docX = evt.pageX; + docY = evt.pageY; + } else if (evt.clientX || evt.clientY) { + docX = evt.clientX + document.body.scrollLeft + + document.documentElement.scrollLeft; + docY = evt.clientY + document.body.scrollTop + + document.documentElement.scrollTop; + } + pos = Util.getPosition(obj); + if (typeof scale === "undefined") { + scale = 1; + } + return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale}; +}; + + +// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events +Util.addEvent = function (obj, evType, fn){ + if (obj.attachEvent){ + var r = obj.attachEvent("on"+evType, fn); + return r; + } else if (obj.addEventListener){ + obj.addEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be attached"); + } +}; + +Util.removeEvent = function(obj, evType, fn){ + if (obj.detachEvent){ + var r = obj.detachEvent("on"+evType, fn); + return r; + } else if (obj.removeEventListener){ + obj.removeEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be removed"); + } +}; + +Util.stopEvent = function(e) { + if (e.stopPropagation) { e.stopPropagation(); } + else { e.cancelBubble = true; } + + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } +}; + + +// Set browser engine versions. Based on mootools. +Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; + +Util.Engine = { + // Version detection break in Opera 11.60 (errors on arguments.callee.caller reference) + //'presto': (function() { + // return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), + 'presto': (function() { return (!window.opera) ? false : true; }()), + + 'trident': (function() { + return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()), + 'webkit': (function() { + try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), + //'webkit': (function() { + // return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()), + 'gecko': (function() { + return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }()) +}; +if (Util.Engine.webkit) { + // Extract actual webkit version if available + Util.Engine.webkit = (function(v) { + var re = new RegExp('WebKit/([0-9\.]*) '); + v = (navigator.userAgent.match(re) || ['', v])[1]; + return parseFloat(v, 10); + })(Util.Engine.webkit); +} + +Util.Flash = (function(){ + var v, version; + try { + v = navigator.plugins['Shockwave Flash'].description; + } catch(err1) { + try { + v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch(err2) { + v = '0 r0'; + } + } + version = v.match(/\d+/g); + return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; +}()); +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2011 Joel Martin + * Licensed under LGPL-2 or any later version (see LICENSE.txt) + */ + +/*jslint browser: true, white: false, bitwise: false */ +/*global window, Util */ + + +// +// Keyboard event handler +// + +function Keyboard(defaults) { +//"use strict"; + +var that = {}, // Public API methods + conf = {}, // Configuration attributes + + keyDownList = []; // List of depressed keys + // (even if they are happy) + +// Configuration attributes +Util.conf_defaults(conf, that, defaults, [ + ['target', 'wo', 'dom', document, 'DOM element that captures keyboard input'], + ['focused', 'rw', 'bool', true, 'Capture and send key events'], + + ['onKeyPress', 'rw', 'func', null, 'Handler for key press/release'] + ]); + + +// +// Private functions +// + +// From the event keyCode return the keysym value for keys that need +// to be suppressed otherwise they may trigger unintended browser +// actions +function getKeysymSpecial(evt) { + var keysym = null; + + switch ( evt.keyCode ) { + // These generate a keyDown and keyPress in Firefox and Opera + case 8 : keysym = 0xFF08; break; // BACKSPACE + case 13 : keysym = 0xFF0D; break; // ENTER + + // This generates a keyDown and keyPress in Opera + case 9 : keysym = 0xFF09; break; // TAB + default : break; + } + + if (evt.type === 'keydown') { + switch ( evt.keyCode ) { + case 27 : keysym = 0xFF1B; break; // ESCAPE + case 46 : keysym = 0xFFFF; break; // DELETE + + case 36 : keysym = 0xFF50; break; // HOME + case 35 : keysym = 0xFF57; break; // END + case 33 : keysym = 0xFF55; break; // PAGE_UP + case 34 : keysym = 0xFF56; break; // PAGE_DOWN + case 45 : keysym = 0xFF63; break; // INSERT + // '-' during keyPress + case 37 : keysym = 0xFF51; break; // LEFT + case 38 : keysym = 0xFF52; break; // UP + case 39 : keysym = 0xFF53; break; // RIGHT + case 40 : keysym = 0xFF54; break; // DOWN + case 16 : keysym = 0xFFE1; break; // SHIFT + case 17 : keysym = 0xFFE3; break; // CONTROL + //case 18 : keysym = 0xFFE7; break; // Left Meta (Mac Option) + case 18 : keysym = 0xFFE9; break; // Left ALT (Mac Command) + + case 112 : keysym = 0xFFBE; break; // F1 + case 113 : keysym = 0xFFBF; break; // F2 + case 114 : keysym = 0xFFC0; break; // F3 + case 115 : keysym = 0xFFC1; break; // F4 + case 116 : keysym = 0xFFC2; break; // F5 + case 117 : keysym = 0xFFC3; break; // F6 + case 118 : keysym = 0xFFC4; break; // F7 + case 119 : keysym = 0xFFC5; break; // F8 + case 120 : keysym = 0xFFC6; break; // F9 + case 121 : keysym = 0xFFC7; break; // F10 + case 122 : keysym = 0xFFC8; break; // F11 + case 123 : keysym = 0xFFC9; break; // F12 + + default : break; + } + } + + if ((!keysym) && (evt.ctrlKey || evt.altKey)) { + if ((typeof(evt.which) !== "undefined") && (evt.which > 0)) { + keysym = evt.which; + } else { + // IE9 always + // Firefox and Opera when ctrl/alt + special + Util.Warn("which not set, using keyCode"); + keysym = evt.keyCode; + } + + /* Remap symbols */ + switch (keysym) { + case 186 : keysym = 59; break; // ; (IE) + case 187 : keysym = 61; break; // = (IE) + case 188 : keysym = 44; break; // , (Mozilla, IE) + case 109 : // - (Mozilla, Opera) + if (Util.Engine.gecko || Util.Engine.presto) { + keysym = 45; } + break; + case 189 : keysym = 45; break; // - (IE) + case 190 : keysym = 46; break; // . (Mozilla, IE) + case 191 : keysym = 47; break; // / (Mozilla, IE) + case 192 : keysym = 96; break; // ` (Mozilla, IE) + case 219 : keysym = 91; break; // [ (Mozilla, IE) + case 220 : keysym = 92; break; // \ (Mozilla, IE) + case 221 : keysym = 93; break; // ] (Mozilla, IE) + case 222 : keysym = 39; break; // ' (Mozilla, IE) + } + + /* Remap shifted and unshifted keys */ + if (!!evt.shiftKey) { + switch (keysym) { + case 48 : keysym = 41 ; break; // ) (shifted 0) + case 49 : keysym = 33 ; break; // ! (shifted 1) + case 50 : keysym = 64 ; break; // @ (shifted 2) + case 51 : keysym = 35 ; break; // # (shifted 3) + case 52 : keysym = 36 ; break; // $ (shifted 4) + case 53 : keysym = 37 ; break; // % (shifted 5) + case 54 : keysym = 94 ; break; // ^ (shifted 6) + case 55 : keysym = 38 ; break; // & (shifted 7) + case 56 : keysym = 42 ; break; // * (shifted 8) + case 57 : keysym = 40 ; break; // ( (shifted 9) + + case 59 : keysym = 58 ; break; // : (shifted `) + case 61 : keysym = 43 ; break; // + (shifted ;) + case 44 : keysym = 60 ; break; // < (shifted ,) + case 45 : keysym = 95 ; break; // _ (shifted -) + case 46 : keysym = 62 ; break; // > (shifted .) + case 47 : keysym = 63 ; break; // ? (shifted /) + case 96 : keysym = 126; break; // ~ (shifted `) + case 91 : keysym = 123; break; // { (shifted [) + case 92 : keysym = 124; break; // | (shifted \) + case 93 : keysym = 125; break; // } (shifted ]) + case 39 : keysym = 34 ; break; // " (shifted ') + } + } else if ((keysym >= 65) && (keysym <=90)) { + /* Remap unshifted A-Z */ + keysym += 32; + } else if (evt.keyLocation === 3) { + // numpad keys + switch (keysym) { + case 96 : keysym = 48; break; // 0 + case 97 : keysym = 49; break; // 1 + case 98 : keysym = 50; break; // 2 + case 99 : keysym = 51; break; // 3 + case 100: keysym = 52; break; // 4 + case 101: keysym = 53; break; // 5 + case 102: keysym = 54; break; // 6 + case 103: keysym = 55; break; // 7 + case 104: keysym = 56; break; // 8 + case 105: keysym = 57; break; // 9 + case 109: keysym = 45; break; // - + case 110: keysym = 46; break; // . + case 111: keysym = 47; break; // / + } + } + } + + return keysym; +} + +/* Translate DOM keyPress event to keysym value */ +function getKeysym(evt) { + var keysym, msg; + + if (typeof(evt.which) !== "undefined") { + // WebKit, Firefox, Opera + keysym = evt.which; + } else { + // IE9 + Util.Warn("which not set, using keyCode"); + keysym = evt.keyCode; + } + + if ((keysym > 255) && (keysym < 0xFF00)) { + msg = "Mapping character code " + keysym; + // Map Unicode outside Latin 1 to X11 keysyms + keysym = unicodeTable[keysym]; + if (typeof(keysym) === 'undefined') { + keysym = 0; + } + Util.Debug(msg + " to " + keysym); + } + + return keysym; +} + +function show_keyDownList(kind) { + var c; + var msg = "keyDownList (" + kind + "):\n"; + for (c = 0; c < keyDownList.length; c++) { + msg = msg + " " + c + " - keyCode: " + keyDownList[c].keyCode + + " - which: " + keyDownList[c].which + "\n"; + } + Util.Debug(msg); +} + +function copyKeyEvent(evt) { + var members = ['type', 'keyCode', 'charCode', 'which', + 'altKey', 'ctrlKey', 'shiftKey', + 'keyLocation', 'keyIdentifier'], i, obj = {}; + for (i = 0; i < members.length; i++) { + if (typeof(evt[members[i]]) !== "undefined") { + obj[members[i]] = evt[members[i]]; + } + } + return obj; +} + +function pushKeyEvent(fevt) { + keyDownList.push(fevt); +} + +function getKeyEvent(keyCode, pop) { + var i, fevt = null; + for (i = keyDownList.length-1; i >= 0; i--) { + if (keyDownList[i].keyCode === keyCode) { + if ((typeof(pop) !== "undefined") && (pop)) { + fevt = keyDownList.splice(i, 1)[0]; + } else { + fevt = keyDownList[i]; + } + break; + } + } + return fevt; +} + +function ignoreKeyEvent(evt) { + // Blarg. Some keys have a different keyCode on keyDown vs keyUp + if (evt.keyCode === 229) { + // French AZERTY keyboard dead key. + // Lame thing is that the respective keyUp is 219 so we can't + // properly ignore the keyUp event + return true; + } + return false; +} + + +// +// Key Event Handling: +// +// There are several challenges when dealing with key events: +// - The meaning and use of keyCode, charCode and which depends on +// both the browser and the event type (keyDown/Up vs keyPress). +// - We cannot automatically determine the keyboard layout +// - The keyDown and keyUp events have a keyCode value that has not +// been translated by modifier keys. +// - The keyPress event has a translated (for layout and modifiers) +// character code but the attribute containing it differs. keyCode +// contains the translated value in WebKit (Chrome/Safari), Opera +// 11 and IE9. charCode contains the value in WebKit and Firefox. +// The which attribute contains the value on WebKit, Firefox and +// Opera 11. +// - The keyDown/Up keyCode value indicates (sort of) the physical +// key was pressed but only for standard US layout. On a US +// keyboard, the '-' and '_' characters are on the same key and +// generate a keyCode value of 189. But on an AZERTY keyboard even +// though they are different physical keys they both still +// generate a keyCode of 189! +// - To prevent a key event from propagating to the browser and +// causing unwanted default actions (such as closing a tab, +// opening a menu, shifting focus, etc) we must suppress this +// event in both keyDown and keyPress because not all key strokes +// generate on a keyPress event. Also, in WebKit and IE9 +// suppressing the keyDown prevents a keyPress but other browsers +// still generated a keyPress even if keyDown is suppressed. +// +// For safe key events, we wait until the keyPress event before +// reporting a key down event. For unsafe key events, we report a key +// down event when the keyDown event fires and we suppress any further +// actions (including keyPress). +// +// In order to report a key up event that matches what we reported +// for the key down event, we keep a list of keys that are currently +// down. When the keyDown event happens, we add the key event to the +// list. If it is a safe key event, then we update the which attribute +// in the most recent item on the list when we received a keyPress +// event (keyPress should immediately follow keyDown). When we +// received a keyUp event we search for the event on the list with +// a matching keyCode and we report the character code using the value +// in the 'which' attribute that was stored with that key. +// + +function onKeyDown(e) { + if (! conf.focused) { + return true; + } + var fevt = null, evt = (e ? e : window.event), + keysym = null, suppress = false; + //Util.Debug("onKeyDown kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + fevt = copyKeyEvent(evt); + + keysym = getKeysymSpecial(evt); + // Save keysym decoding for use in keyUp + fevt.keysym = keysym; + if (keysym) { + // If it is a key or key combination that might trigger + // browser behaviors or it has no corresponding keyPress + // event, then send it immediately + if (conf.onKeyPress && !ignoreKeyEvent(evt)) { + Util.Debug("onKeyPress down, keysym: " + keysym + + " (onKeyDown key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 1, evt); + } + suppress = true; + } + + if (! ignoreKeyEvent(evt)) { + // Add it to the list of depressed keys + pushKeyEvent(fevt); + //show_keyDownList('down'); + } + + if (suppress) { + // Suppress bubbling/default actions + Util.stopEvent(e); + return false; + } else { + // Allow the event to bubble and become a keyPress event which + // will have the character code translated + return true; + } +} + +function onKeyPress(e) { + if (! conf.focused) { + return true; + } + var evt = (e ? e : window.event), + kdlen = keyDownList.length, keysym = null; + //Util.Debug("onKeyPress kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + if (((evt.which !== "undefined") && (evt.which === 0)) || + (getKeysymSpecial(evt))) { + // Firefox and Opera generate a keyPress event even if keyDown + // is suppressed. But the keys we want to suppress will have + // either: + // - the which attribute set to 0 + // - getKeysymSpecial() will identify it + Util.Debug("Ignoring special key in keyPress"); + Util.stopEvent(e); + return false; + } + + keysym = getKeysym(evt); + + // Modify the the which attribute in the depressed keys list so + // that the keyUp event will be able to have the character code + // translation available. + if (kdlen > 0) { + keyDownList[kdlen-1].keysym = keysym; + } else { + Util.Warn("keyDownList empty when keyPress triggered"); + } + + //show_keyDownList('press'); + + // Send the translated keysym + if (conf.onKeyPress && (keysym > 0)) { + Util.Debug("onKeyPress down, keysym: " + keysym + + " (onKeyPress key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 1, evt); + } + + // Stop keypress events just in case + Util.stopEvent(e); + return false; +} + +function onKeyUp(e) { + if (! conf.focused) { + return true; + } + var fevt = null, evt = (e ? e : window.event), keysym; + //Util.Debug("onKeyUp kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + fevt = getKeyEvent(evt.keyCode, true); + + if (fevt) { + keysym = fevt.keysym; + } else { + Util.Warn("Key event (keyCode = " + evt.keyCode + + ") not found on keyDownList"); + keysym = 0; + } + + //show_keyDownList('up'); + + if (conf.onKeyPress && (keysym > 0)) { + //Util.Debug("keyPress up, keysym: " + keysym + + // " (key: " + evt.keyCode + ", which: " + evt.which + ")"); + Util.Debug("onKeyPress up, keysym: " + keysym + + " (onKeyPress key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 0, evt); + } + Util.stopEvent(e); + return false; +} + +// +// Public API interface functions +// + +that.grab = function() { + //Util.Debug(">> Keyboard.grab"); + var c = conf.target; + + Util.addEvent(c, 'keydown', onKeyDown); + Util.addEvent(c, 'keyup', onKeyUp); + Util.addEvent(c, 'keypress', onKeyPress); + + //Util.Debug("<< Keyboard.grab"); +}; + +that.ungrab = function() { + //Util.Debug(">> Keyboard.ungrab"); + var c = conf.target; + + Util.removeEvent(c, 'keydown', onKeyDown); + Util.removeEvent(c, 'keyup', onKeyUp); + Util.removeEvent(c, 'keypress', onKeyPress); + + //Util.Debug(">> Keyboard.ungrab"); +}; + +return that; // Return the public API interface + +} // End of Keyboard() + + +// +// Mouse event handler +// + +function Mouse(defaults) { +//"use strict"; + +var that = {}, // Public API methods + conf = {}; // Configuration attributes + +// Configuration attributes +Util.conf_defaults(conf, that, defaults, [ + ['target', 'ro', 'dom', document, 'DOM element that captures mouse input'], + ['focused', 'rw', 'bool', true, 'Capture and send mouse clicks/movement'], + ['scale', 'rw', 'float', 1.0, 'Viewport scale factor 0.0 - 1.0'], + + ['onMouseButton', 'rw', 'func', null, 'Handler for mouse button click/release'], + ['onMouseMove', 'rw', 'func', null, 'Handler for mouse movement'], + ['touchButton', 'rw', 'int', 1, 'Button mask (1, 2, 4) for touch devices (0 means ignore clicks)'] + ]); + + +// +// Private functions +// + +function onMouseButton(e, down) { + var evt, pos, bmask; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + if (e.touches || e.changedTouches) { + // Touch device + bmask = conf.touchButton; + // If bmask is set + } else if (evt.which) { + /* everything except IE */ + bmask = 1 << evt.button; + } else { + /* IE including 9 */ + bmask = (evt.button & 0x1) + // Left + (evt.button & 0x2) * 2 + // Right + (evt.button & 0x4) / 2; // Middle + } + //Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down + + // " bmask: " + bmask + "(evt.button: " + evt.button + ")"); + if (bmask > 0 && conf.onMouseButton) { + Util.Debug("onMouseButton " + (down ? "down" : "up") + + ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); + conf.onMouseButton(pos.x, pos.y, down, bmask); + } + Util.stopEvent(e); + return false; +} + +function onMouseDown(e) { + onMouseButton(e, 1); +} + +function onMouseUp(e) { + onMouseButton(e, 0); +} + +function onMouseWheel(e) { + var evt, pos, bmask, wheelData; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40; + if (wheelData > 0) { + bmask = 1 << 3; + } else { + bmask = 1 << 4; + } + //Util.Debug('mouse scroll by ' + wheelData + ':' + pos.x + "," + pos.y); + if (conf.onMouseButton) { + conf.onMouseButton(pos.x, pos.y, 1, bmask); + conf.onMouseButton(pos.x, pos.y, 0, bmask); + } + Util.stopEvent(e); + return false; +} + +function onMouseMove(e) { + var evt, pos; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + //Util.Debug('mouse ' + evt.which + '/' + evt.button + ' up:' + pos.x + "," + pos.y); + if (conf.onMouseMove) { + conf.onMouseMove(pos.x, pos.y); + } + Util.stopEvent(e); + return false; +} + +function onMouseDisable(e) { + var evt, pos; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + /* Stop propagation if inside canvas area */ + if ((pos.x >= 0) && (pos.y >= 0) && + (pos.x < conf.target.offsetWidth) && + (pos.y < conf.target.offsetHeight)) { + //Util.Debug("mouse event disabled"); + Util.stopEvent(e); + return false; + } + //Util.Debug("mouse event not disabled"); + return true; +} + +// +// Public API interface functions +// + +that.grab = function() { + //Util.Debug(">> Mouse.grab"); + var c = conf.target; + + if ('ontouchstart' in document.documentElement) { + Util.addEvent(c, 'touchstart', onMouseDown); + Util.addEvent(c, 'touchend', onMouseUp); + Util.addEvent(c, 'touchmove', onMouseMove); + } else { + Util.addEvent(c, 'mousedown', onMouseDown); + Util.addEvent(c, 'mouseup', onMouseUp); + Util.addEvent(c, 'mousemove', onMouseMove); + Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } + + /* Work around right and middle click browser behaviors */ + Util.addEvent(document, 'click', onMouseDisable); + Util.addEvent(document.body, 'contextmenu', onMouseDisable); + + //Util.Debug("<< Mouse.grab"); +}; + +that.ungrab = function() { + //Util.Debug(">> Mouse.ungrab"); + var c = conf.target; + + if ('ontouchstart' in document.documentElement) { + Util.removeEvent(c, 'touchstart', onMouseDown); + Util.removeEvent(c, 'touchend', onMouseUp); + Util.removeEvent(c, 'touchmove', onMouseMove); + } else { + Util.removeEvent(c, 'mousedown', onMouseDown); + Util.removeEvent(c, 'mouseup', onMouseUp); + Util.removeEvent(c, 'mousemove', onMouseMove); + Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } + + /* Work around right and middle click browser behaviors */ + Util.removeEvent(document, 'click', onMouseDisable); + Util.removeEvent(document.body, 'contextmenu', onMouseDisable); + + //Util.Debug(">> Mouse.ungrab"); +}; + +return that; // Return the public API interface + +} // End of Mouse() + + +/* + * Browser keypress to X11 keysym for Unicode characters > U+00FF + */ +unicodeTable = { + 0x0104 : 0x01a1, + 0x02D8 : 0x01a2, + 0x0141 : 0x01a3, + 0x013D : 0x01a5, + 0x015A : 0x01a6, + 0x0160 : 0x01a9, + 0x015E : 0x01aa, + 0x0164 : 0x01ab, + 0x0179 : 0x01ac, + 0x017D : 0x01ae, + 0x017B : 0x01af, + 0x0105 : 0x01b1, + 0x02DB : 0x01b2, + 0x0142 : 0x01b3, + 0x013E : 0x01b5, + 0x015B : 0x01b6, + 0x02C7 : 0x01b7, + 0x0161 : 0x01b9, + 0x015F : 0x01ba, + 0x0165 : 0x01bb, + 0x017A : 0x01bc, + 0x02DD : 0x01bd, + 0x017E : 0x01be, + 0x017C : 0x01bf, + 0x0154 : 0x01c0, + 0x0102 : 0x01c3, + 0x0139 : 0x01c5, + 0x0106 : 0x01c6, + 0x010C : 0x01c8, + 0x0118 : 0x01ca, + 0x011A : 0x01cc, + 0x010E : 0x01cf, + 0x0110 : 0x01d0, + 0x0143 : 0x01d1, + 0x0147 : 0x01d2, + 0x0150 : 0x01d5, + 0x0158 : 0x01d8, + 0x016E : 0x01d9, + 0x0170 : 0x01db, + 0x0162 : 0x01de, + 0x0155 : 0x01e0, + 0x0103 : 0x01e3, + 0x013A : 0x01e5, + 0x0107 : 0x01e6, + 0x010D : 0x01e8, + 0x0119 : 0x01ea, + 0x011B : 0x01ec, + 0x010F : 0x01ef, + 0x0111 : 0x01f0, + 0x0144 : 0x01f1, + 0x0148 : 0x01f2, + 0x0151 : 0x01f5, + 0x0171 : 0x01fb, + 0x0159 : 0x01f8, + 0x016F : 0x01f9, + 0x0163 : 0x01fe, + 0x02D9 : 0x01ff, + 0x0126 : 0x02a1, + 0x0124 : 0x02a6, + 0x0130 : 0x02a9, + 0x011E : 0x02ab, + 0x0134 : 0x02ac, + 0x0127 : 0x02b1, + 0x0125 : 0x02b6, + 0x0131 : 0x02b9, + 0x011F : 0x02bb, + 0x0135 : 0x02bc, + 0x010A : 0x02c5, + 0x0108 : 0x02c6, + 0x0120 : 0x02d5, + 0x011C : 0x02d8, + 0x016C : 0x02dd, + 0x015C : 0x02de, + 0x010B : 0x02e5, + 0x0109 : 0x02e6, + 0x0121 : 0x02f5, + 0x011D : 0x02f8, + 0x016D : 0x02fd, + 0x015D : 0x02fe, + 0x0138 : 0x03a2, + 0x0156 : 0x03a3, + 0x0128 : 0x03a5, + 0x013B : 0x03a6, + 0x0112 : 0x03aa, + 0x0122 : 0x03ab, + 0x0166 : 0x03ac, + 0x0157 : 0x03b3, + 0x0129 : 0x03b5, + 0x013C : 0x03b6, + 0x0113 : 0x03ba, + 0x0123 : 0x03bb, + 0x0167 : 0x03bc, + 0x014A : 0x03bd, + 0x014B : 0x03bf, + 0x0100 : 0x03c0, + 0x012E : 0x03c7, + 0x0116 : 0x03cc, + 0x012A : 0x03cf, + 0x0145 : 0x03d1, + 0x014C : 0x03d2, + 0x0136 : 0x03d3, + 0x0172 : 0x03d9, + 0x0168 : 0x03dd, + 0x016A : 0x03de, + 0x0101 : 0x03e0, + 0x012F : 0x03e7, + 0x0117 : 0x03ec, + 0x012B : 0x03ef, + 0x0146 : 0x03f1, + 0x014D : 0x03f2, + 0x0137 : 0x03f3, + 0x0173 : 0x03f9, + 0x0169 : 0x03fd, + 0x016B : 0x03fe, + 0x1E02 : 0x1001e02, + 0x1E03 : 0x1001e03, + 0x1E0A : 0x1001e0a, + 0x1E80 : 0x1001e80, + 0x1E82 : 0x1001e82, + 0x1E0B : 0x1001e0b, + 0x1EF2 : 0x1001ef2, + 0x1E1E : 0x1001e1e, + 0x1E1F : 0x1001e1f, + 0x1E40 : 0x1001e40, + 0x1E41 : 0x1001e41, + 0x1E56 : 0x1001e56, + 0x1E81 : 0x1001e81, + 0x1E57 : 0x1001e57, + 0x1E83 : 0x1001e83, + 0x1E60 : 0x1001e60, + 0x1EF3 : 0x1001ef3, + 0x1E84 : 0x1001e84, + 0x1E85 : 0x1001e85, + 0x1E61 : 0x1001e61, + 0x0174 : 0x1000174, + 0x1E6A : 0x1001e6a, + 0x0176 : 0x1000176, + 0x0175 : 0x1000175, + 0x1E6B : 0x1001e6b, + 0x0177 : 0x1000177, + 0x0152 : 0x13bc, + 0x0153 : 0x13bd, + 0x0178 : 0x13be, + 0x203E : 0x047e, + 0x3002 : 0x04a1, + 0x300C : 0x04a2, + 0x300D : 0x04a3, + 0x3001 : 0x04a4, + 0x30FB : 0x04a5, + 0x30F2 : 0x04a6, + 0x30A1 : 0x04a7, + 0x30A3 : 0x04a8, + 0x30A5 : 0x04a9, + 0x30A7 : 0x04aa, + 0x30A9 : 0x04ab, + 0x30E3 : 0x04ac, + 0x30E5 : 0x04ad, + 0x30E7 : 0x04ae, + 0x30C3 : 0x04af, + 0x30FC : 0x04b0, + 0x30A2 : 0x04b1, + 0x30A4 : 0x04b2, + 0x30A6 : 0x04b3, + 0x30A8 : 0x04b4, + 0x30AA : 0x04b5, + 0x30AB : 0x04b6, + 0x30AD : 0x04b7, + 0x30AF : 0x04b8, + 0x30B1 : 0x04b9, + 0x30B3 : 0x04ba, + 0x30B5 : 0x04bb, + 0x30B7 : 0x04bc, + 0x30B9 : 0x04bd, + 0x30BB : 0x04be, + 0x30BD : 0x04bf, + 0x30BF : 0x04c0, + 0x30C1 : 0x04c1, + 0x30C4 : 0x04c2, + 0x30C6 : 0x04c3, + 0x30C8 : 0x04c4, + 0x30CA : 0x04c5, + 0x30CB : 0x04c6, + 0x30CC : 0x04c7, + 0x30CD : 0x04c8, + 0x30CE : 0x04c9, + 0x30CF : 0x04ca, + 0x30D2 : 0x04cb, + 0x30D5 : 0x04cc, + 0x30D8 : 0x04cd, + 0x30DB : 0x04ce, + 0x30DE : 0x04cf, + 0x30DF : 0x04d0, + 0x30E0 : 0x04d1, + 0x30E1 : 0x04d2, + 0x30E2 : 0x04d3, + 0x30E4 : 0x04d4, + 0x30E6 : 0x04d5, + 0x30E8 : 0x04d6, + 0x30E9 : 0x04d7, + 0x30EA : 0x04d8, + 0x30EB : 0x04d9, + 0x30EC : 0x04da, + 0x30ED : 0x04db, + 0x30EF : 0x04dc, + 0x30F3 : 0x04dd, + 0x309B : 0x04de, + 0x309C : 0x04df, + 0x06F0 : 0x10006f0, + 0x06F1 : 0x10006f1, + 0x06F2 : 0x10006f2, + 0x06F3 : 0x10006f3, + 0x06F4 : 0x10006f4, + 0x06F5 : 0x10006f5, + 0x06F6 : 0x10006f6, + 0x06F7 : 0x10006f7, + 0x06F8 : 0x10006f8, + 0x06F9 : 0x10006f9, + 0x066A : 0x100066a, + 0x0670 : 0x1000670, + 0x0679 : 0x1000679, + 0x067E : 0x100067e, + 0x0686 : 0x1000686, + 0x0688 : 0x1000688, + 0x0691 : 0x1000691, + 0x060C : 0x05ac, + 0x06D4 : 0x10006d4, + 0x0660 : 0x1000660, + 0x0661 : 0x1000661, + 0x0662 : 0x1000662, + 0x0663 : 0x1000663, + 0x0664 : 0x1000664, + 0x0665 : 0x1000665, + 0x0666 : 0x1000666, + 0x0667 : 0x1000667, + 0x0668 : 0x1000668, + 0x0669 : 0x1000669, + 0x061B : 0x05bb, + 0x061F : 0x05bf, + 0x0621 : 0x05c1, + 0x0622 : 0x05c2, + 0x0623 : 0x05c3, + 0x0624 : 0x05c4, + 0x0625 : 0x05c5, + 0x0626 : 0x05c6, + 0x0627 : 0x05c7, + 0x0628 : 0x05c8, + 0x0629 : 0x05c9, + 0x062A : 0x05ca, + 0x062B : 0x05cb, + 0x062C : 0x05cc, + 0x062D : 0x05cd, + 0x062E : 0x05ce, + 0x062F : 0x05cf, + 0x0630 : 0x05d0, + 0x0631 : 0x05d1, + 0x0632 : 0x05d2, + 0x0633 : 0x05d3, + 0x0634 : 0x05d4, + 0x0635 : 0x05d5, + 0x0636 : 0x05d6, + 0x0637 : 0x05d7, + 0x0638 : 0x05d8, + 0x0639 : 0x05d9, + 0x063A : 0x05da, + 0x0640 : 0x05e0, + 0x0641 : 0x05e1, + 0x0642 : 0x05e2, + 0x0643 : 0x05e3, + 0x0644 : 0x05e4, + 0x0645 : 0x05e5, + 0x0646 : 0x05e6, + 0x0647 : 0x05e7, + 0x0648 : 0x05e8, + 0x0649 : 0x05e9, + 0x064A : 0x05ea, + 0x064B : 0x05eb, + 0x064C : 0x05ec, + 0x064D : 0x05ed, + 0x064E : 0x05ee, + 0x064F : 0x05ef, + 0x0650 : 0x05f0, + 0x0651 : 0x05f1, + 0x0652 : 0x05f2, + 0x0653 : 0x1000653, + 0x0654 : 0x1000654, + 0x0655 : 0x1000655, + 0x0698 : 0x1000698, + 0x06A4 : 0x10006a4, + 0x06A9 : 0x10006a9, + 0x06AF : 0x10006af, + 0x06BA : 0x10006ba, + 0x06BE : 0x10006be, + 0x06CC : 0x10006cc, + 0x06D2 : 0x10006d2, + 0x06C1 : 0x10006c1, + 0x0492 : 0x1000492, + 0x0493 : 0x1000493, + 0x0496 : 0x1000496, + 0x0497 : 0x1000497, + 0x049A : 0x100049a, + 0x049B : 0x100049b, + 0x049C : 0x100049c, + 0x049D : 0x100049d, + 0x04A2 : 0x10004a2, + 0x04A3 : 0x10004a3, + 0x04AE : 0x10004ae, + 0x04AF : 0x10004af, + 0x04B0 : 0x10004b0, + 0x04B1 : 0x10004b1, + 0x04B2 : 0x10004b2, + 0x04B3 : 0x10004b3, + 0x04B6 : 0x10004b6, + 0x04B7 : 0x10004b7, + 0x04B8 : 0x10004b8, + 0x04B9 : 0x10004b9, + 0x04BA : 0x10004ba, + 0x04BB : 0x10004bb, + 0x04D8 : 0x10004d8, + 0x04D9 : 0x10004d9, + 0x04E2 : 0x10004e2, + 0x04E3 : 0x10004e3, + 0x04E8 : 0x10004e8, + 0x04E9 : 0x10004e9, + 0x04EE : 0x10004ee, + 0x04EF : 0x10004ef, + 0x0452 : 0x06a1, + 0x0453 : 0x06a2, + 0x0451 : 0x06a3, + 0x0454 : 0x06a4, + 0x0455 : 0x06a5, + 0x0456 : 0x06a6, + 0x0457 : 0x06a7, + 0x0458 : 0x06a8, + 0x0459 : 0x06a9, + 0x045A : 0x06aa, + 0x045B : 0x06ab, + 0x045C : 0x06ac, + 0x0491 : 0x06ad, + 0x045E : 0x06ae, + 0x045F : 0x06af, + 0x2116 : 0x06b0, + 0x0402 : 0x06b1, + 0x0403 : 0x06b2, + 0x0401 : 0x06b3, + 0x0404 : 0x06b4, + 0x0405 : 0x06b5, + 0x0406 : 0x06b6, + 0x0407 : 0x06b7, + 0x0408 : 0x06b8, + 0x0409 : 0x06b9, + 0x040A : 0x06ba, + 0x040B : 0x06bb, + 0x040C : 0x06bc, + 0x0490 : 0x06bd, + 0x040E : 0x06be, + 0x040F : 0x06bf, + 0x044E : 0x06c0, + 0x0430 : 0x06c1, + 0x0431 : 0x06c2, + 0x0446 : 0x06c3, + 0x0434 : 0x06c4, + 0x0435 : 0x06c5, + 0x0444 : 0x06c6, + 0x0433 : 0x06c7, + 0x0445 : 0x06c8, + 0x0438 : 0x06c9, + 0x0439 : 0x06ca, + 0x043A : 0x06cb, + 0x043B : 0x06cc, + 0x043C : 0x06cd, + 0x043D : 0x06ce, + 0x043E : 0x06cf, + 0x043F : 0x06d0, + 0x044F : 0x06d1, + 0x0440 : 0x06d2, + 0x0441 : 0x06d3, + 0x0442 : 0x06d4, + 0x0443 : 0x06d5, + 0x0436 : 0x06d6, + 0x0432 : 0x06d7, + 0x044C : 0x06d8, + 0x044B : 0x06d9, + 0x0437 : 0x06da, + 0x0448 : 0x06db, + 0x044D : 0x06dc, + 0x0449 : 0x06dd, + 0x0447 : 0x06de, + 0x044A : 0x06df, + 0x042E : 0x06e0, + 0x0410 : 0x06e1, + 0x0411 : 0x06e2, + 0x0426 : 0x06e3, + 0x0414 : 0x06e4, + 0x0415 : 0x06e5, + 0x0424 : 0x06e6, + 0x0413 : 0x06e7, + 0x0425 : 0x06e8, + 0x0418 : 0x06e9, + 0x0419 : 0x06ea, + 0x041A : 0x06eb, + 0x041B : 0x06ec, + 0x041C : 0x06ed, + 0x041D : 0x06ee, + 0x041E : 0x06ef, + 0x041F : 0x06f0, + 0x042F : 0x06f1, + 0x0420 : 0x06f2, + 0x0421 : 0x06f3, + 0x0422 : 0x06f4, + 0x0423 : 0x06f5, + 0x0416 : 0x06f6, + 0x0412 : 0x06f7, + 0x042C : 0x06f8, + 0x042B : 0x06f9, + 0x0417 : 0x06fa, + 0x0428 : 0x06fb, + 0x042D : 0x06fc, + 0x0429 : 0x06fd, + 0x0427 : 0x06fe, + 0x042A : 0x06ff, + 0x0386 : 0x07a1, + 0x0388 : 0x07a2, + 0x0389 : 0x07a3, + 0x038A : 0x07a4, + 0x03AA : 0x07a5, + 0x038C : 0x07a7, + 0x038E : 0x07a8, + 0x03AB : 0x07a9, + 0x038F : 0x07ab, + 0x0385 : 0x07ae, + 0x2015 : 0x07af, + 0x03AC : 0x07b1, + 0x03AD : 0x07b2, + 0x03AE : 0x07b3, + 0x03AF : 0x07b4, + 0x03CA : 0x07b5, + 0x0390 : 0x07b6, + 0x03CC : 0x07b7, + 0x03CD : 0x07b8, + 0x03CB : 0x07b9, + 0x03B0 : 0x07ba, + 0x03CE : 0x07bb, + 0x0391 : 0x07c1, + 0x0392 : 0x07c2, + 0x0393 : 0x07c3, + 0x0394 : 0x07c4, + 0x0395 : 0x07c5, + 0x0396 : 0x07c6, + 0x0397 : 0x07c7, + 0x0398 : 0x07c8, + 0x0399 : 0x07c9, + 0x039A : 0x07ca, + 0x039B : 0x07cb, + 0x039C : 0x07cc, + 0x039D : 0x07cd, + 0x039E : 0x07ce, + 0x039F : 0x07cf, + 0x03A0 : 0x07d0, + 0x03A1 : 0x07d1, + 0x03A3 : 0x07d2, + 0x03A4 : 0x07d4, + 0x03A5 : 0x07d5, + 0x03A6 : 0x07d6, + 0x03A7 : 0x07d7, + 0x03A8 : 0x07d8, + 0x03A9 : 0x07d9, + 0x03B1 : 0x07e1, + 0x03B2 : 0x07e2, + 0x03B3 : 0x07e3, + 0x03B4 : 0x07e4, + 0x03B5 : 0x07e5, + 0x03B6 : 0x07e6, + 0x03B7 : 0x07e7, + 0x03B8 : 0x07e8, + 0x03B9 : 0x07e9, + 0x03BA : 0x07ea, + 0x03BB : 0x07eb, + 0x03BC : 0x07ec, + 0x03BD : 0x07ed, + 0x03BE : 0x07ee, + 0x03BF : 0x07ef, + 0x03C0 : 0x07f0, + 0x03C1 : 0x07f1, + 0x03C3 : 0x07f2, + 0x03C2 : 0x07f3, + 0x03C4 : 0x07f4, + 0x03C5 : 0x07f5, + 0x03C6 : 0x07f6, + 0x03C7 : 0x07f7, + 0x03C8 : 0x07f8, + 0x03C9 : 0x07f9, + 0x23B7 : 0x08a1, + 0x2320 : 0x08a4, + 0x2321 : 0x08a5, + 0x23A1 : 0x08a7, + 0x23A3 : 0x08a8, + 0x23A4 : 0x08a9, + 0x23A6 : 0x08aa, + 0x239B : 0x08ab, + 0x239D : 0x08ac, + 0x239E : 0x08ad, + 0x23A0 : 0x08ae, + 0x23A8 : 0x08af, + 0x23AC : 0x08b0, + 0x2264 : 0x08bc, + 0x2260 : 0x08bd, + 0x2265 : 0x08be, + 0x222B : 0x08bf, + 0x2234 : 0x08c0, + 0x221D : 0x08c1, + 0x221E : 0x08c2, + 0x2207 : 0x08c5, + 0x223C : 0x08c8, + 0x2243 : 0x08c9, + 0x21D4 : 0x08cd, + 0x21D2 : 0x08ce, + 0x2261 : 0x08cf, + 0x221A : 0x08d6, + 0x2282 : 0x08da, + 0x2283 : 0x08db, + 0x2229 : 0x08dc, + 0x222A : 0x08dd, + 0x2227 : 0x08de, + 0x2228 : 0x08df, + 0x2202 : 0x08ef, + 0x0192 : 0x08f6, + 0x2190 : 0x08fb, + 0x2191 : 0x08fc, + 0x2192 : 0x08fd, + 0x2193 : 0x08fe, + 0x25C6 : 0x09e0, + 0x2592 : 0x09e1, + 0x2409 : 0x09e2, + 0x240C : 0x09e3, + 0x240D : 0x09e4, + 0x240A : 0x09e5, + 0x2424 : 0x09e8, + 0x240B : 0x09e9, + 0x2518 : 0x09ea, + 0x2510 : 0x09eb, + 0x250C : 0x09ec, + 0x2514 : 0x09ed, + 0x253C : 0x09ee, + 0x23BA : 0x09ef, + 0x23BB : 0x09f0, + 0x2500 : 0x09f1, + 0x23BC : 0x09f2, + 0x23BD : 0x09f3, + 0x251C : 0x09f4, + 0x2524 : 0x09f5, + 0x2534 : 0x09f6, + 0x252C : 0x09f7, + 0x2502 : 0x09f8, + 0x2003 : 0x0aa1, + 0x2002 : 0x0aa2, + 0x2004 : 0x0aa3, + 0x2005 : 0x0aa4, + 0x2007 : 0x0aa5, + 0x2008 : 0x0aa6, + 0x2009 : 0x0aa7, + 0x200A : 0x0aa8, + 0x2014 : 0x0aa9, + 0x2013 : 0x0aaa, + 0x2026 : 0x0aae, + 0x2025 : 0x0aaf, + 0x2153 : 0x0ab0, + 0x2154 : 0x0ab1, + 0x2155 : 0x0ab2, + 0x2156 : 0x0ab3, + 0x2157 : 0x0ab4, + 0x2158 : 0x0ab5, + 0x2159 : 0x0ab6, + 0x215A : 0x0ab7, + 0x2105 : 0x0ab8, + 0x2012 : 0x0abb, + 0x215B : 0x0ac3, + 0x215C : 0x0ac4, + 0x215D : 0x0ac5, + 0x215E : 0x0ac6, + 0x2122 : 0x0ac9, + 0x2018 : 0x0ad0, + 0x2019 : 0x0ad1, + 0x201C : 0x0ad2, + 0x201D : 0x0ad3, + 0x211E : 0x0ad4, + 0x2032 : 0x0ad6, + 0x2033 : 0x0ad7, + 0x271D : 0x0ad9, + 0x2663 : 0x0aec, + 0x2666 : 0x0aed, + 0x2665 : 0x0aee, + 0x2720 : 0x0af0, + 0x2020 : 0x0af1, + 0x2021 : 0x0af2, + 0x2713 : 0x0af3, + 0x2717 : 0x0af4, + 0x266F : 0x0af5, + 0x266D : 0x0af6, + 0x2642 : 0x0af7, + 0x2640 : 0x0af8, + 0x260E : 0x0af9, + 0x2315 : 0x0afa, + 0x2117 : 0x0afb, + 0x2038 : 0x0afc, + 0x201A : 0x0afd, + 0x201E : 0x0afe, + 0x22A4 : 0x0bc2, + 0x230A : 0x0bc4, + 0x2218 : 0x0bca, + 0x2395 : 0x0bcc, + 0x22A5 : 0x0bce, + 0x25CB : 0x0bcf, + 0x2308 : 0x0bd3, + 0x22A3 : 0x0bdc, + 0x22A2 : 0x0bfc, + 0x2017 : 0x0cdf, + 0x05D0 : 0x0ce0, + 0x05D1 : 0x0ce1, + 0x05D2 : 0x0ce2, + 0x05D3 : 0x0ce3, + 0x05D4 : 0x0ce4, + 0x05D5 : 0x0ce5, + 0x05D6 : 0x0ce6, + 0x05D7 : 0x0ce7, + 0x05D8 : 0x0ce8, + 0x05D9 : 0x0ce9, + 0x05DA : 0x0cea, + 0x05DB : 0x0ceb, + 0x05DC : 0x0cec, + 0x05DD : 0x0ced, + 0x05DE : 0x0cee, + 0x05DF : 0x0cef, + 0x05E0 : 0x0cf0, + 0x05E1 : 0x0cf1, + 0x05E2 : 0x0cf2, + 0x05E3 : 0x0cf3, + 0x05E4 : 0x0cf4, + 0x05E5 : 0x0cf5, + 0x05E6 : 0x0cf6, + 0x05E7 : 0x0cf7, + 0x05E8 : 0x0cf8, + 0x05E9 : 0x0cf9, + 0x05EA : 0x0cfa, + 0x0E01 : 0x0da1, + 0x0E02 : 0x0da2, + 0x0E03 : 0x0da3, + 0x0E04 : 0x0da4, + 0x0E05 : 0x0da5, + 0x0E06 : 0x0da6, + 0x0E07 : 0x0da7, + 0x0E08 : 0x0da8, + 0x0E09 : 0x0da9, + 0x0E0A : 0x0daa, + 0x0E0B : 0x0dab, + 0x0E0C : 0x0dac, + 0x0E0D : 0x0dad, + 0x0E0E : 0x0dae, + 0x0E0F : 0x0daf, + 0x0E10 : 0x0db0, + 0x0E11 : 0x0db1, + 0x0E12 : 0x0db2, + 0x0E13 : 0x0db3, + 0x0E14 : 0x0db4, + 0x0E15 : 0x0db5, + 0x0E16 : 0x0db6, + 0x0E17 : 0x0db7, + 0x0E18 : 0x0db8, + 0x0E19 : 0x0db9, + 0x0E1A : 0x0dba, + 0x0E1B : 0x0dbb, + 0x0E1C : 0x0dbc, + 0x0E1D : 0x0dbd, + 0x0E1E : 0x0dbe, + 0x0E1F : 0x0dbf, + 0x0E20 : 0x0dc0, + 0x0E21 : 0x0dc1, + 0x0E22 : 0x0dc2, + 0x0E23 : 0x0dc3, + 0x0E24 : 0x0dc4, + 0x0E25 : 0x0dc5, + 0x0E26 : 0x0dc6, + 0x0E27 : 0x0dc7, + 0x0E28 : 0x0dc8, + 0x0E29 : 0x0dc9, + 0x0E2A : 0x0dca, + 0x0E2B : 0x0dcb, + 0x0E2C : 0x0dcc, + 0x0E2D : 0x0dcd, + 0x0E2E : 0x0dce, + 0x0E2F : 0x0dcf, + 0x0E30 : 0x0dd0, + 0x0E31 : 0x0dd1, + 0x0E32 : 0x0dd2, + 0x0E33 : 0x0dd3, + 0x0E34 : 0x0dd4, + 0x0E35 : 0x0dd5, + 0x0E36 : 0x0dd6, + 0x0E37 : 0x0dd7, + 0x0E38 : 0x0dd8, + 0x0E39 : 0x0dd9, + 0x0E3A : 0x0dda, + 0x0E3F : 0x0ddf, + 0x0E40 : 0x0de0, + 0x0E41 : 0x0de1, + 0x0E42 : 0x0de2, + 0x0E43 : 0x0de3, + 0x0E44 : 0x0de4, + 0x0E45 : 0x0de5, + 0x0E46 : 0x0de6, + 0x0E47 : 0x0de7, + 0x0E48 : 0x0de8, + 0x0E49 : 0x0de9, + 0x0E4A : 0x0dea, + 0x0E4B : 0x0deb, + 0x0E4C : 0x0dec, + 0x0E4D : 0x0ded, + 0x0E50 : 0x0df0, + 0x0E51 : 0x0df1, + 0x0E52 : 0x0df2, + 0x0E53 : 0x0df3, + 0x0E54 : 0x0df4, + 0x0E55 : 0x0df5, + 0x0E56 : 0x0df6, + 0x0E57 : 0x0df7, + 0x0E58 : 0x0df8, + 0x0E59 : 0x0df9, + 0x0587 : 0x1000587, + 0x0589 : 0x1000589, + 0x055D : 0x100055d, + 0x058A : 0x100058a, + 0x055C : 0x100055c, + 0x055B : 0x100055b, + 0x055E : 0x100055e, + 0x0531 : 0x1000531, + 0x0561 : 0x1000561, + 0x0532 : 0x1000532, + 0x0562 : 0x1000562, + 0x0533 : 0x1000533, + 0x0563 : 0x1000563, + 0x0534 : 0x1000534, + 0x0564 : 0x1000564, + 0x0535 : 0x1000535, + 0x0565 : 0x1000565, + 0x0536 : 0x1000536, + 0x0566 : 0x1000566, + 0x0537 : 0x1000537, + 0x0567 : 0x1000567, + 0x0538 : 0x1000538, + 0x0568 : 0x1000568, + 0x0539 : 0x1000539, + 0x0569 : 0x1000569, + 0x053A : 0x100053a, + 0x056A : 0x100056a, + 0x053B : 0x100053b, + 0x056B : 0x100056b, + 0x053C : 0x100053c, + 0x056C : 0x100056c, + 0x053D : 0x100053d, + 0x056D : 0x100056d, + 0x053E : 0x100053e, + 0x056E : 0x100056e, + 0x053F : 0x100053f, + 0x056F : 0x100056f, + 0x0540 : 0x1000540, + 0x0570 : 0x1000570, + 0x0541 : 0x1000541, + 0x0571 : 0x1000571, + 0x0542 : 0x1000542, + 0x0572 : 0x1000572, + 0x0543 : 0x1000543, + 0x0573 : 0x1000573, + 0x0544 : 0x1000544, + 0x0574 : 0x1000574, + 0x0545 : 0x1000545, + 0x0575 : 0x1000575, + 0x0546 : 0x1000546, + 0x0576 : 0x1000576, + 0x0547 : 0x1000547, + 0x0577 : 0x1000577, + 0x0548 : 0x1000548, + 0x0578 : 0x1000578, + 0x0549 : 0x1000549, + 0x0579 : 0x1000579, + 0x054A : 0x100054a, + 0x057A : 0x100057a, + 0x054B : 0x100054b, + 0x057B : 0x100057b, + 0x054C : 0x100054c, + 0x057C : 0x100057c, + 0x054D : 0x100054d, + 0x057D : 0x100057d, + 0x054E : 0x100054e, + 0x057E : 0x100057e, + 0x054F : 0x100054f, + 0x057F : 0x100057f, + 0x0550 : 0x1000550, + 0x0580 : 0x1000580, + 0x0551 : 0x1000551, + 0x0581 : 0x1000581, + 0x0552 : 0x1000552, + 0x0582 : 0x1000582, + 0x0553 : 0x1000553, + 0x0583 : 0x1000583, + 0x0554 : 0x1000554, + 0x0584 : 0x1000584, + 0x0555 : 0x1000555, + 0x0585 : 0x1000585, + 0x0556 : 0x1000556, + 0x0586 : 0x1000586, + 0x055A : 0x100055a, + 0x10D0 : 0x10010d0, + 0x10D1 : 0x10010d1, + 0x10D2 : 0x10010d2, + 0x10D3 : 0x10010d3, + 0x10D4 : 0x10010d4, + 0x10D5 : 0x10010d5, + 0x10D6 : 0x10010d6, + 0x10D7 : 0x10010d7, + 0x10D8 : 0x10010d8, + 0x10D9 : 0x10010d9, + 0x10DA : 0x10010da, + 0x10DB : 0x10010db, + 0x10DC : 0x10010dc, + 0x10DD : 0x10010dd, + 0x10DE : 0x10010de, + 0x10DF : 0x10010df, + 0x10E0 : 0x10010e0, + 0x10E1 : 0x10010e1, + 0x10E2 : 0x10010e2, + 0x10E3 : 0x10010e3, + 0x10E4 : 0x10010e4, + 0x10E5 : 0x10010e5, + 0x10E6 : 0x10010e6, + 0x10E7 : 0x10010e7, + 0x10E8 : 0x10010e8, + 0x10E9 : 0x10010e9, + 0x10EA : 0x10010ea, + 0x10EB : 0x10010eb, + 0x10EC : 0x10010ec, + 0x10ED : 0x10010ed, + 0x10EE : 0x10010ee, + 0x10EF : 0x10010ef, + 0x10F0 : 0x10010f0, + 0x10F1 : 0x10010f1, + 0x10F2 : 0x10010f2, + 0x10F3 : 0x10010f3, + 0x10F4 : 0x10010f4, + 0x10F5 : 0x10010f5, + 0x10F6 : 0x10010f6, + 0x1E8A : 0x1001e8a, + 0x012C : 0x100012c, + 0x01B5 : 0x10001b5, + 0x01E6 : 0x10001e6, + 0x01D2 : 0x10001d1, + 0x019F : 0x100019f, + 0x1E8B : 0x1001e8b, + 0x012D : 0x100012d, + 0x01B6 : 0x10001b6, + 0x01E7 : 0x10001e7, + 0x01D2 : 0x10001d2, + 0x0275 : 0x1000275, + 0x018F : 0x100018f, + 0x0259 : 0x1000259, + 0x1E36 : 0x1001e36, + 0x1E37 : 0x1001e37, + 0x1EA0 : 0x1001ea0, + 0x1EA1 : 0x1001ea1, + 0x1EA2 : 0x1001ea2, + 0x1EA3 : 0x1001ea3, + 0x1EA4 : 0x1001ea4, + 0x1EA5 : 0x1001ea5, + 0x1EA6 : 0x1001ea6, + 0x1EA7 : 0x1001ea7, + 0x1EA8 : 0x1001ea8, + 0x1EA9 : 0x1001ea9, + 0x1EAA : 0x1001eaa, + 0x1EAB : 0x1001eab, + 0x1EAC : 0x1001eac, + 0x1EAD : 0x1001ead, + 0x1EAE : 0x1001eae, + 0x1EAF : 0x1001eaf, + 0x1EB0 : 0x1001eb0, + 0x1EB1 : 0x1001eb1, + 0x1EB2 : 0x1001eb2, + 0x1EB3 : 0x1001eb3, + 0x1EB4 : 0x1001eb4, + 0x1EB5 : 0x1001eb5, + 0x1EB6 : 0x1001eb6, + 0x1EB7 : 0x1001eb7, + 0x1EB8 : 0x1001eb8, + 0x1EB9 : 0x1001eb9, + 0x1EBA : 0x1001eba, + 0x1EBB : 0x1001ebb, + 0x1EBC : 0x1001ebc, + 0x1EBD : 0x1001ebd, + 0x1EBE : 0x1001ebe, + 0x1EBF : 0x1001ebf, + 0x1EC0 : 0x1001ec0, + 0x1EC1 : 0x1001ec1, + 0x1EC2 : 0x1001ec2, + 0x1EC3 : 0x1001ec3, + 0x1EC4 : 0x1001ec4, + 0x1EC5 : 0x1001ec5, + 0x1EC6 : 0x1001ec6, + 0x1EC7 : 0x1001ec7, + 0x1EC8 : 0x1001ec8, + 0x1EC9 : 0x1001ec9, + 0x1ECA : 0x1001eca, + 0x1ECB : 0x1001ecb, + 0x1ECC : 0x1001ecc, + 0x1ECD : 0x1001ecd, + 0x1ECE : 0x1001ece, + 0x1ECF : 0x1001ecf, + 0x1ED0 : 0x1001ed0, + 0x1ED1 : 0x1001ed1, + 0x1ED2 : 0x1001ed2, + 0x1ED3 : 0x1001ed3, + 0x1ED4 : 0x1001ed4, + 0x1ED5 : 0x1001ed5, + 0x1ED6 : 0x1001ed6, + 0x1ED7 : 0x1001ed7, + 0x1ED8 : 0x1001ed8, + 0x1ED9 : 0x1001ed9, + 0x1EDA : 0x1001eda, + 0x1EDB : 0x1001edb, + 0x1EDC : 0x1001edc, + 0x1EDD : 0x1001edd, + 0x1EDE : 0x1001ede, + 0x1EDF : 0x1001edf, + 0x1EE0 : 0x1001ee0, + 0x1EE1 : 0x1001ee1, + 0x1EE2 : 0x1001ee2, + 0x1EE3 : 0x1001ee3, + 0x1EE4 : 0x1001ee4, + 0x1EE5 : 0x1001ee5, + 0x1EE6 : 0x1001ee6, + 0x1EE7 : 0x1001ee7, + 0x1EE8 : 0x1001ee8, + 0x1EE9 : 0x1001ee9, + 0x1EEA : 0x1001eea, + 0x1EEB : 0x1001eeb, + 0x1EEC : 0x1001eec, + 0x1EED : 0x1001eed, + 0x1EEE : 0x1001eee, + 0x1EEF : 0x1001eef, + 0x1EF0 : 0x1001ef0, + 0x1EF1 : 0x1001ef1, + 0x1EF4 : 0x1001ef4, + 0x1EF5 : 0x1001ef5, + 0x1EF6 : 0x1001ef6, + 0x1EF7 : 0x1001ef7, + 0x1EF8 : 0x1001ef8, + 0x1EF9 : 0x1001ef9, + 0x01A0 : 0x10001a0, + 0x01A1 : 0x10001a1, + 0x01AF : 0x10001af, + 0x01B0 : 0x10001b0, + 0x20A0 : 0x10020a0, + 0x20A1 : 0x10020a1, + 0x20A2 : 0x10020a2, + 0x20A3 : 0x10020a3, + 0x20A4 : 0x10020a4, + 0x20A5 : 0x10020a5, + 0x20A6 : 0x10020a6, + 0x20A7 : 0x10020a7, + 0x20A8 : 0x10020a8, + 0x20A9 : 0x10020a9, + 0x20AA : 0x10020aa, + 0x20AB : 0x10020ab, + 0x20AC : 0x20ac, + 0x2070 : 0x1002070, + 0x2074 : 0x1002074, + 0x2075 : 0x1002075, + 0x2076 : 0x1002076, + 0x2077 : 0x1002077, + 0x2078 : 0x1002078, + 0x2079 : 0x1002079, + 0x2080 : 0x1002080, + 0x2081 : 0x1002081, + 0x2082 : 0x1002082, + 0x2083 : 0x1002083, + 0x2084 : 0x1002084, + 0x2085 : 0x1002085, + 0x2086 : 0x1002086, + 0x2087 : 0x1002087, + 0x2088 : 0x1002088, + 0x2089 : 0x1002089, + 0x2202 : 0x1002202, + 0x2205 : 0x1002205, + 0x2208 : 0x1002208, + 0x2209 : 0x1002209, + 0x220B : 0x100220B, + 0x221A : 0x100221A, + 0x221B : 0x100221B, + 0x221C : 0x100221C, + 0x222C : 0x100222C, + 0x222D : 0x100222D, + 0x2235 : 0x1002235, + 0x2245 : 0x1002248, + 0x2247 : 0x1002247, + 0x2262 : 0x1002262, + 0x2263 : 0x1002263, + 0x2800 : 0x1002800, + 0x2801 : 0x1002801, + 0x2802 : 0x1002802, + 0x2803 : 0x1002803, + 0x2804 : 0x1002804, + 0x2805 : 0x1002805, + 0x2806 : 0x1002806, + 0x2807 : 0x1002807, + 0x2808 : 0x1002808, + 0x2809 : 0x1002809, + 0x280a : 0x100280a, + 0x280b : 0x100280b, + 0x280c : 0x100280c, + 0x280d : 0x100280d, + 0x280e : 0x100280e, + 0x280f : 0x100280f, + 0x2810 : 0x1002810, + 0x2811 : 0x1002811, + 0x2812 : 0x1002812, + 0x2813 : 0x1002813, + 0x2814 : 0x1002814, + 0x2815 : 0x1002815, + 0x2816 : 0x1002816, + 0x2817 : 0x1002817, + 0x2818 : 0x1002818, + 0x2819 : 0x1002819, + 0x281a : 0x100281a, + 0x281b : 0x100281b, + 0x281c : 0x100281c, + 0x281d : 0x100281d, + 0x281e : 0x100281e, + 0x281f : 0x100281f, + 0x2820 : 0x1002820, + 0x2821 : 0x1002821, + 0x2822 : 0x1002822, + 0x2823 : 0x1002823, + 0x2824 : 0x1002824, + 0x2825 : 0x1002825, + 0x2826 : 0x1002826, + 0x2827 : 0x1002827, + 0x2828 : 0x1002828, + 0x2829 : 0x1002829, + 0x282a : 0x100282a, + 0x282b : 0x100282b, + 0x282c : 0x100282c, + 0x282d : 0x100282d, + 0x282e : 0x100282e, + 0x282f : 0x100282f, + 0x2830 : 0x1002830, + 0x2831 : 0x1002831, + 0x2832 : 0x1002832, + 0x2833 : 0x1002833, + 0x2834 : 0x1002834, + 0x2835 : 0x1002835, + 0x2836 : 0x1002836, + 0x2837 : 0x1002837, + 0x2838 : 0x1002838, + 0x2839 : 0x1002839, + 0x283a : 0x100283a, + 0x283b : 0x100283b, + 0x283c : 0x100283c, + 0x283d : 0x100283d, + 0x283e : 0x100283e, + 0x283f : 0x100283f, + 0x2840 : 0x1002840, + 0x2841 : 0x1002841, + 0x2842 : 0x1002842, + 0x2843 : 0x1002843, + 0x2844 : 0x1002844, + 0x2845 : 0x1002845, + 0x2846 : 0x1002846, + 0x2847 : 0x1002847, + 0x2848 : 0x1002848, + 0x2849 : 0x1002849, + 0x284a : 0x100284a, + 0x284b : 0x100284b, + 0x284c : 0x100284c, + 0x284d : 0x100284d, + 0x284e : 0x100284e, + 0x284f : 0x100284f, + 0x2850 : 0x1002850, + 0x2851 : 0x1002851, + 0x2852 : 0x1002852, + 0x2853 : 0x1002853, + 0x2854 : 0x1002854, + 0x2855 : 0x1002855, + 0x2856 : 0x1002856, + 0x2857 : 0x1002857, + 0x2858 : 0x1002858, + 0x2859 : 0x1002859, + 0x285a : 0x100285a, + 0x285b : 0x100285b, + 0x285c : 0x100285c, + 0x285d : 0x100285d, + 0x285e : 0x100285e, + 0x285f : 0x100285f, + 0x2860 : 0x1002860, + 0x2861 : 0x1002861, + 0x2862 : 0x1002862, + 0x2863 : 0x1002863, + 0x2864 : 0x1002864, + 0x2865 : 0x1002865, + 0x2866 : 0x1002866, + 0x2867 : 0x1002867, + 0x2868 : 0x1002868, + 0x2869 : 0x1002869, + 0x286a : 0x100286a, + 0x286b : 0x100286b, + 0x286c : 0x100286c, + 0x286d : 0x100286d, + 0x286e : 0x100286e, + 0x286f : 0x100286f, + 0x2870 : 0x1002870, + 0x2871 : 0x1002871, + 0x2872 : 0x1002872, + 0x2873 : 0x1002873, + 0x2874 : 0x1002874, + 0x2875 : 0x1002875, + 0x2876 : 0x1002876, + 0x2877 : 0x1002877, + 0x2878 : 0x1002878, + 0x2879 : 0x1002879, + 0x287a : 0x100287a, + 0x287b : 0x100287b, + 0x287c : 0x100287c, + 0x287d : 0x100287d, + 0x287e : 0x100287e, + 0x287f : 0x100287f, + 0x2880 : 0x1002880, + 0x2881 : 0x1002881, + 0x2882 : 0x1002882, + 0x2883 : 0x1002883, + 0x2884 : 0x1002884, + 0x2885 : 0x1002885, + 0x2886 : 0x1002886, + 0x2887 : 0x1002887, + 0x2888 : 0x1002888, + 0x2889 : 0x1002889, + 0x288a : 0x100288a, + 0x288b : 0x100288b, + 0x288c : 0x100288c, + 0x288d : 0x100288d, + 0x288e : 0x100288e, + 0x288f : 0x100288f, + 0x2890 : 0x1002890, + 0x2891 : 0x1002891, + 0x2892 : 0x1002892, + 0x2893 : 0x1002893, + 0x2894 : 0x1002894, + 0x2895 : 0x1002895, + 0x2896 : 0x1002896, + 0x2897 : 0x1002897, + 0x2898 : 0x1002898, + 0x2899 : 0x1002899, + 0x289a : 0x100289a, + 0x289b : 0x100289b, + 0x289c : 0x100289c, + 0x289d : 0x100289d, + 0x289e : 0x100289e, + 0x289f : 0x100289f, + 0x28a0 : 0x10028a0, + 0x28a1 : 0x10028a1, + 0x28a2 : 0x10028a2, + 0x28a3 : 0x10028a3, + 0x28a4 : 0x10028a4, + 0x28a5 : 0x10028a5, + 0x28a6 : 0x10028a6, + 0x28a7 : 0x10028a7, + 0x28a8 : 0x10028a8, + 0x28a9 : 0x10028a9, + 0x28aa : 0x10028aa, + 0x28ab : 0x10028ab, + 0x28ac : 0x10028ac, + 0x28ad : 0x10028ad, + 0x28ae : 0x10028ae, + 0x28af : 0x10028af, + 0x28b0 : 0x10028b0, + 0x28b1 : 0x10028b1, + 0x28b2 : 0x10028b2, + 0x28b3 : 0x10028b3, + 0x28b4 : 0x10028b4, + 0x28b5 : 0x10028b5, + 0x28b6 : 0x10028b6, + 0x28b7 : 0x10028b7, + 0x28b8 : 0x10028b8, + 0x28b9 : 0x10028b9, + 0x28ba : 0x10028ba, + 0x28bb : 0x10028bb, + 0x28bc : 0x10028bc, + 0x28bd : 0x10028bd, + 0x28be : 0x10028be, + 0x28bf : 0x10028bf, + 0x28c0 : 0x10028c0, + 0x28c1 : 0x10028c1, + 0x28c2 : 0x10028c2, + 0x28c3 : 0x10028c3, + 0x28c4 : 0x10028c4, + 0x28c5 : 0x10028c5, + 0x28c6 : 0x10028c6, + 0x28c7 : 0x10028c7, + 0x28c8 : 0x10028c8, + 0x28c9 : 0x10028c9, + 0x28ca : 0x10028ca, + 0x28cb : 0x10028cb, + 0x28cc : 0x10028cc, + 0x28cd : 0x10028cd, + 0x28ce : 0x10028ce, + 0x28cf : 0x10028cf, + 0x28d0 : 0x10028d0, + 0x28d1 : 0x10028d1, + 0x28d2 : 0x10028d2, + 0x28d3 : 0x10028d3, + 0x28d4 : 0x10028d4, + 0x28d5 : 0x10028d5, + 0x28d6 : 0x10028d6, + 0x28d7 : 0x10028d7, + 0x28d8 : 0x10028d8, + 0x28d9 : 0x10028d9, + 0x28da : 0x10028da, + 0x28db : 0x10028db, + 0x28dc : 0x10028dc, + 0x28dd : 0x10028dd, + 0x28de : 0x10028de, + 0x28df : 0x10028df, + 0x28e0 : 0x10028e0, + 0x28e1 : 0x10028e1, + 0x28e2 : 0x10028e2, + 0x28e3 : 0x10028e3, + 0x28e4 : 0x10028e4, + 0x28e5 : 0x10028e5, + 0x28e6 : 0x10028e6, + 0x28e7 : 0x10028e7, + 0x28e8 : 0x10028e8, + 0x28e9 : 0x10028e9, + 0x28ea : 0x10028ea, + 0x28eb : 0x10028eb, + 0x28ec : 0x10028ec, + 0x28ed : 0x10028ed, + 0x28ee : 0x10028ee, + 0x28ef : 0x10028ef, + 0x28f0 : 0x10028f0, + 0x28f1 : 0x10028f1, + 0x28f2 : 0x10028f2, + 0x28f3 : 0x10028f3, + 0x28f4 : 0x10028f4, + 0x28f5 : 0x10028f5, + 0x28f6 : 0x10028f6, + 0x28f7 : 0x10028f7, + 0x28f8 : 0x10028f8, + 0x28f9 : 0x10028f9, + 0x28fa : 0x10028fa, + 0x28fb : 0x10028fb, + 0x28fc : 0x10028fc, + 0x28fd : 0x10028fd, + 0x28fe : 0x10028fe, + 0x28ff : 0x10028ff +}; /** * See LICENSE file. * @@ -10427,26 +12614,53 @@ CAAT.registerKeyListener= function(f) { CAAT.keyListeners.push(f); }; + + +// Redefinitions of keyboard event to use noVNC code + +CAAT.registerKeyListenerIfNeeded= function(f) { + for( var i=0; i>0)+1 ) + 2 * padding ; + + // var cw= Math.max( 1, (ctx.measureText( chars.charAt(i) ).width>>0)+1 ) + 2 * padding ; + var cw= Math.max( 1, (ctx.measureText( chars.charAt(i) ).width>>0)+1 ); + charWidth.push(cw); - textWidth+= cw; + textWidth+= cw + 2 * padding; } canvas.width= textWidth; @@ -13261,19 +15507,19 @@ CAAT.modules.CircleManager = CAAT.modules.CircleManager || {};/** this.charMap= {}; - x=0; + x=padding; // x=0 for( i=0; i>8&255,a&255)};Array.prototype.push32=function(a){this.push(a>>24&255,a>>16&255,a>>8&255,a&255)};Array.prototype.map||(Array.prototype.map=function(a,b){var c=this.length;if("function"!=typeof a)throw new TypeError;for(var d=Array(c),e=0;e=b)b+=32;else if(3===a.keyLocation)switch(b){case 96:b=48;break;case 97:b=49;break;case 98:b=50;break;case 99:b=51;break;case 100:b=52;break;case 101:b=53;break;case 102:b=54;break;case 103:b=55;break;case 104:b=56;break;case 105:b=57;break;case 109:b=45;break;case 110:b=46;break;case 111:b=47}}return b}function c(a){if(!g.focused)return!0;for(var c=null,d=a?a:window.event,e=null,f=!1,c="type,keyCode,charCode,which,altKey,ctrlKey,shiftKey,keyLocation,keyIdentifier".split(","), +l={},e=0;ee&&(f="Mapping character code "+e,e=unicodeTable[e],"undefined"===typeof e&&(e=0),Util.Debug(f+" to "+e));0a;a++)for(var b=0;4>b;b++)this.matrix[a][b]=a===b?1:0;return this},getMatrix:function(){return this.matrix},rotateXY:function(a){return this.rotate(a,0,0)},rotateXZ:function(a){return this.rotate(0,a,0)},rotateYZ:function(a){return this.rotate(0,0,a)},setRotate:function(a,b,c){this.copy(this.rotate(a,b,c));return this},rotate:function(a,b,c){var d=new CAAT.Matrix3,e,f;0!==a&&(f=new CAAT.Matrix3, +e=Math.sin(a),a=Math.cos(a),f.matrix[1][1]=a,f.matrix[1][2]=-e,f.matrix[2][1]=e,f.matrix[2][2]=a,d.multiply(f));0!==b&&(f=new CAAT.Matrix3,e=Math.sin(b),a=Math.cos(b),f.matrix[0][0]=a,f.matrix[0][2]=-e,f.matrix[2][0]=e,f.matrix[2][2]=a,d.multiply(f));0!==c&&(f=new CAAT.Matrix3,e=Math.sin(c),a=Math.cos(c),f.matrix[0][0]=a,f.matrix[0][1]=-e,f.matrix[1][0]=e,f.matrix[1][1]=a,d.multiply(f));return d},getClone:function(){var a=new CAAT.Matrix3;a.copy(this);return a},multiply:function(a){var b=this.getClone().matrix, +c=b[0][0],d=b[0][1],e=b[0][2],f=b[0][3],g=b[1][0],h=b[1][1],i=b[1][2],j=b[1][3],k=b[2][0],m=b[2][1],n=b[2][2],b=b[2][3],l=a.matrix,a=l[0][0],o=l[0][1],p=l[0][2],q=l[0][3],r=l[1][0],s=l[1][1],t=l[1][2],u=l[1][3],v=l[2][0],w=l[2][1],x=l[2][2],y=l[2][3],z=l[3][0],A=l[3][1],B=l[3][2],l=l[3][3];this.matrix[0][0]=c*a+d*r+e*v+f*z;this.matrix[0][1]=c*o+d*s+e*w+f*A;this.matrix[0][2]=c*p+d*t+e*x+f*B;this.matrix[0][3]=c*q+d*u+e*y+f*l;this.matrix[1][0]=g*a+h*r+i*v+j*z;this.matrix[1][1]=g*o+h*s+i*w+j*A;this.matrix[1][2]= +g*p+h*t+i*x+j*B;this.matrix[1][3]=g*q+h*u+i*y+j*l;this.matrix[2][0]=k*a+m*r+n*v+b*z;this.matrix[2][1]=k*o+m*s+n*w+b*A;this.matrix[2][2]=k*p+m*t+n*x+b*B;this.matrix[2][3]=k*q+m*u+n*y+b*l;return this},premultiply:function(a){var b=this.getClone().matrix,c=b[0][0],d=b[0][1],e=b[0][2],f=b[0][3],g=b[1][0],h=b[1][1],i=b[1][2],j=b[1][3],k=b[2][0],m=b[2][1],n=b[2][2],b=b[2][3],l=a.matrix,a=l[0][0],o=l[0][1],p=l[0][2],q=l[0][3],r=l[1][0],s=l[1][1],t=l[1][2],u=l[1][3],v=l[2][0],w=l[2][1],x=l[2][2],l=l[2][3]; +this.matrix[0][0]=c*a+d*r+e*v;this.matrix[0][1]=c*o+d*s+e*w;this.matrix[0][2]=c*p+d*t+e*x;this.matrix[0][3]=c*q+d*u+e*l+f;this.matrix[1][0]=g*a+h*r+i*v;this.matrix[1][1]=g*o+h*s+i*w;this.matrix[1][2]=g*p+h*t+i*x;this.matrix[1][3]=g*q+h*u+i*l+j;this.matrix[2][0]=k*a+m*r+n*v;this.matrix[2][1]=k*o+m*s+n*w;this.matrix[2][2]=k*p+m*t+n*x;this.matrix[2][3]=k*q+m*u+n*l+b;return this},setTranslate:function(a,b,c){this.identity();this.matrix[0][3]=a;this.matrix[1][3]=b;this.matrix[2][3]=c;return this},translate:function(a, b,c){var d=new CAAT.Matrix3;d.setTranslate(a,b,c);return d},setScale:function(a,b,c){this.identity();this.matrix[0][0]=a;this.matrix[1][1]=b;this.matrix[2][2]=c;return this},scale:function(a,b,c){var d=new CAAT.Matrix3;d.setScale(a,b,c);return d},rotateModelView:function(a,b,c){var d=Math.sin(a),e=Math.sin(b),f=Math.sin(c),a=Math.cos(a),b=Math.cos(b),c=Math.cos(c);this.matrix[0][0]=b*a;this.matrix[0][1]=-b*d;this.matrix[0][2]=e;this.matrix[0][3]=0;this.matrix[1][0]=f*e*a+d*c;this.matrix[1][1]=c*a- -f*e*d;this.matrix[1][2]=-f*b;this.matrix[1][3]=0;this.matrix[2][0]=f*d-c*e*a;this.matrix[2][1]=c*e*d+f*a;this.matrix[2][2]=c*b;this.matrix[2][3]=0;this.matrix[3][0]=0;this.matrix[3][1]=0;this.matrix[3][2]=0;this.matrix[3][3]=1;return this},copy:function(a){for(var b=0;b<4;b++)for(var c=0;c<4;c++)this.matrix[b][c]=a.matrix[b][c];return this},calculateDeterminant:function(){var a=this.matrix,b=a[0][0],c=a[0][1],d=a[0][2],e=a[0][3],f=a[1][0],g=a[1][1],h=a[1][2],i=a[1][3],j=a[2][0],k=a[2][1],l=a[2][2], -n=a[2][3],m=a[3][0],o=a[3][1],p=a[3][2],a=a[3][3];return e*g*l*m+c*i*l*m+e*h*j*o+d*i*j*o+d*f*n*o+b*h*n*o+e*f*k*p+b*i*k*p+d*g*j*a+c*h*j*a+c*f*l*a+b*g*l*a+e*h*k*m-d*i*k*m-d*g*n*m-c*h*n*m-e*f*l*o-b*i*l*o-e*g*j*p-c*i*j*p-c*f*n*p-b*g*n*p-d*f*k*a-b*h*k*a},getInverse:function(){var a=this.matrix,b=a[0][0],c=a[0][1],d=a[0][2],e=a[0][3],f=a[1][0],g=a[1][1],h=a[1][2],i=a[1][3],j=a[2][0],k=a[2][1],l=a[2][2],n=a[2][3],m=a[3][0],o=a[3][1],p=a[3][2],a=a[3][3],q=new CAAT.Matrix3;q.matrix[0][0]=h*n*o+i*k*p+g*l*a- -i*l*o-g*n*p-h*k*a;q.matrix[0][1]=e*l*o+c*n*p+d*k*a-c*l*a-d*n*o-e*k*p;q.matrix[0][2]=d*i*o+c*h*a+e*g*p-c*i*p-d*g*a-e*h*o;q.matrix[0][3]=e*h*k+c*i*l+d*g*n-d*i*k-e*g*l-c*h*n;q.matrix[1][0]=i*l*m+f*n*p+h*j*a-h*n*m-i*j*p-f*l*a;q.matrix[1][1]=d*n*m+e*j*p+b*l*a-e*l*m-b*n*p-d*j*a;q.matrix[1][2]=e*h*m+b*i*p+d*f*a-d*i*m-e*f*p-b*h*a;q.matrix[1][3]=d*i*j+e*f*l+b*h*n-e*h*j-b*i*l-d*f*n;q.matrix[2][0]=g*n*m+i*j*o+f*k*a-i*k*m-f*n*o-g*j*a;q.matrix[2][1]=e*k*m+b*n*o+c*j*a-b*k*a-c*n*m-e*j*o;q.matrix[2][2]=d*i*m+e*f* -o+b*g*a-e*g*m-b*i*o-c*f*a;q.matrix[2][3]=e*g*j+b*i*k+c*f*n-b*g*n-c*i*j-e*f*k;q.matrix[3][0]=h*k*m+f*l*o+g*j*p-g*l*m-h*j*o-f*k*p;q.matrix[3][1]=c*l*m+d*j*o+b*k*p-d*k*m-b*l*o-c*j*p;q.matrix[3][2]=d*g*m+b*h*o+c*f*p-b*g*p-c*h*m-d*f*o;q.matrix[3][3]=c*h*j+d*f*k+b*g*l-d*g*j-b*h*k-c*f*l;return q.multiplyScalar(1/this.calculateDeterminant())},multiplyScalar:function(a){var b,c;for(b=0;b<4;b++)for(c=0;c<4;c++)this.matrix[b][c]*=a;return this}}})(); +f*e*d;this.matrix[1][2]=-f*b;this.matrix[1][3]=0;this.matrix[2][0]=f*d-c*e*a;this.matrix[2][1]=c*e*d+f*a;this.matrix[2][2]=c*b;this.matrix[2][3]=0;this.matrix[3][0]=0;this.matrix[3][1]=0;this.matrix[3][2]=0;this.matrix[3][3]=1;return this},copy:function(a){for(var b=0;4>b;b++)for(var c=0;4>c;c++)this.matrix[b][c]=a.matrix[b][c];return this},calculateDeterminant:function(){var a=this.matrix,b=a[0][0],c=a[0][1],d=a[0][2],e=a[0][3],f=a[1][0],g=a[1][1],h=a[1][2],i=a[1][3],j=a[2][0],k=a[2][1],m=a[2][2], +n=a[2][3],l=a[3][0],o=a[3][1],p=a[3][2],a=a[3][3];return e*g*m*l+c*i*m*l+e*h*j*o+d*i*j*o+d*f*n*o+b*h*n*o+e*f*k*p+b*i*k*p+d*g*j*a+c*h*j*a+c*f*m*a+b*g*m*a+e*h*k*l-d*i*k*l-d*g*n*l-c*h*n*l-e*f*m*o-b*i*m*o-e*g*j*p-c*i*j*p-c*f*n*p-b*g*n*p-d*f*k*a-b*h*k*a},getInverse:function(){var a=this.matrix,b=a[0][0],c=a[0][1],d=a[0][2],e=a[0][3],f=a[1][0],g=a[1][1],h=a[1][2],i=a[1][3],j=a[2][0],k=a[2][1],m=a[2][2],n=a[2][3],l=a[3][0],o=a[3][1],p=a[3][2],a=a[3][3],q=new CAAT.Matrix3;q.matrix[0][0]=h*n*o+i*k*p+g*m*a- +i*m*o-g*n*p-h*k*a;q.matrix[0][1]=e*m*o+c*n*p+d*k*a-c*m*a-d*n*o-e*k*p;q.matrix[0][2]=d*i*o+c*h*a+e*g*p-c*i*p-d*g*a-e*h*o;q.matrix[0][3]=e*h*k+c*i*m+d*g*n-d*i*k-e*g*m-c*h*n;q.matrix[1][0]=i*m*l+f*n*p+h*j*a-h*n*l-i*j*p-f*m*a;q.matrix[1][1]=d*n*l+e*j*p+b*m*a-e*m*l-b*n*p-d*j*a;q.matrix[1][2]=e*h*l+b*i*p+d*f*a-d*i*l-e*f*p-b*h*a;q.matrix[1][3]=d*i*j+e*f*m+b*h*n-e*h*j-b*i*m-d*f*n;q.matrix[2][0]=g*n*l+i*j*o+f*k*a-i*k*l-f*n*o-g*j*a;q.matrix[2][1]=e*k*l+b*n*o+c*j*a-b*k*a-c*n*l-e*j*o;q.matrix[2][2]=d*i*l+e*f* +o+b*g*a-e*g*l-b*i*o-c*f*a;q.matrix[2][3]=e*g*j+b*i*k+c*f*n-b*g*n-c*i*j-e*f*k;q.matrix[3][0]=h*k*l+f*m*o+g*j*p-g*m*l-h*j*o-f*k*p;q.matrix[3][1]=c*m*l+d*j*o+b*k*p-d*k*l-b*m*o-c*j*p;q.matrix[3][2]=d*g*l+b*h*o+c*f*p-b*g*p-c*h*l-d*f*o;q.matrix[3][3]=c*h*j+d*f*k+b*g*m-d*g*j-b*h*k-c*f*m;return q.multiplyScalar(1/this.calculateDeterminant())},multiplyScalar:function(a){var b,c;for(b=0;4>b;b++)for(c=0;4>c;c++)this.matrix[b][c]*=a;return this}}})(); (function(){CAAT.Matrix=function(){this.matrix=[1,0,0,0,1,0,0,0,1];return this};CAAT.Matrix.prototype={matrix:null,transformCoord:function(a){var b=a.x,c=a.y,d=this.matrix;a.x=b*d[0]+c*d[1]+d[2];a.y=b*d[3]+c*d[4]+d[5];return a},rotate:function(a){var b=new CAAT.Matrix;b.setRotation(a);return b},setRotation:function(a){this.identity();var b=this.matrix,c=Math.cos(a),a=Math.sin(a);b[0]=c;b[1]=-a;b[3]=a;b[4]=c;return this},scale:function(a,b){var c=new CAAT.Matrix;c.matrix[0]=a;c.matrix[4]=b;return c}, setScale:function(a,b){this.identity();this.matrix[0]=a;this.matrix[4]=b;return this},translate:function(a,b){var c=new CAAT.Matrix;c.matrix[2]=a;c.matrix[5]=b;return c},setTranslate:function(a,b){this.identity();this.matrix[2]=a;this.matrix[5]=b;return this},copy:function(a){var a=a.matrix,b=this.matrix;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},identity:function(){var a=this.matrix;a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]= -0;a[8]=1;return this},multiply:function(a){var b=this.matrix,c=a.matrix,a=b[0],d=b[1],e=b[2],f=b[3],g=b[4],h=b[5],i=b[6],j=b[7],k=b[8],l=c[0],n=c[1],m=c[2],o=c[3],p=c[4],q=c[5],r=c[6],s=c[7],c=c[8];b[0]=a*l+d*o+e*r;b[1]=a*n+d*p+e*s;b[2]=a*m+d*q+e*c;b[3]=f*l+g*o+h*r;b[4]=f*n+g*p+h*s;b[5]=f*m+g*q+h*c;b[6]=i*l+j*o+k*r;b[7]=i*n+j*p+k*s;b[8]=i*m+j*q+k*c;return this},premultiply:function(a){var b=a.matrix[0]*this.matrix[1]+a.matrix[1]*this.matrix[4]+a.matrix[2]*this.matrix[7],c=a.matrix[0]*this.matrix[2]+ +0;a[8]=1;return this},multiply:function(a){var b=this.matrix,c=a.matrix,a=b[0],d=b[1],e=b[2],f=b[3],g=b[4],h=b[5],i=b[6],j=b[7],k=b[8],m=c[0],n=c[1],l=c[2],o=c[3],p=c[4],q=c[5],r=c[6],s=c[7],c=c[8];b[0]=a*m+d*o+e*r;b[1]=a*n+d*p+e*s;b[2]=a*l+d*q+e*c;b[3]=f*m+g*o+h*r;b[4]=f*n+g*p+h*s;b[5]=f*l+g*q+h*c;b[6]=i*m+j*o+k*r;b[7]=i*n+j*p+k*s;b[8]=i*l+j*q+k*c;return this},premultiply:function(a){var b=a.matrix[0]*this.matrix[1]+a.matrix[1]*this.matrix[4]+a.matrix[2]*this.matrix[7],c=a.matrix[0]*this.matrix[2]+ a.matrix[1]*this.matrix[5]+a.matrix[2]*this.matrix[8],d=a.matrix[3]*this.matrix[0]+a.matrix[4]*this.matrix[3]+a.matrix[5]*this.matrix[6],e=a.matrix[3]*this.matrix[1]+a.matrix[4]*this.matrix[4]+a.matrix[5]*this.matrix[7],f=a.matrix[3]*this.matrix[2]+a.matrix[4]*this.matrix[5]+a.matrix[5]*this.matrix[8],g=a.matrix[6]*this.matrix[0]+a.matrix[7]*this.matrix[3]+a.matrix[8]*this.matrix[6],h=a.matrix[6]*this.matrix[1]+a.matrix[7]*this.matrix[4]+a.matrix[8]*this.matrix[7],i=a.matrix[6]*this.matrix[2]+a.matrix[7]* -this.matrix[5]+a.matrix[8]*this.matrix[8];this.matrix[0]=a.matrix[0]*this.matrix[0]+a.matrix[1]*this.matrix[3]+a.matrix[2]*this.matrix[6];this.matrix[1]=b;this.matrix[2]=c;this.matrix[3]=d;this.matrix[4]=e;this.matrix[5]=f;this.matrix[6]=g;this.matrix[7]=h;this.matrix[8]=i;return this},getInverse:function(){var a=this.matrix,b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],a=a[8],j=new CAAT.Matrix,k=b*(f*a-i*g)-e*(c*a-i*d)+h*(c*g-f*d);if(k===0)return null;var l=j.matrix;l[0]=f*a-g*i;l[1]=d* -i-c*a;l[2]=c*g-d*f;l[3]=g*h-e*a;l[4]=b*a-d*h;l[5]=d*e-b*g;l[6]=e*i-f*h;l[7]=c*h-b*i;l[8]=b*f-c*e;j.multiplyScalar(1/k);return j},multiplyScalar:function(a){var b;for(b=0;b<9;b++)this.matrix[b]*=a;return this},transformRenderingContextSet:null,transformRenderingContext:null,transformRenderingContextSet_NoClamp:function(a){var b=this.matrix;a.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]);return this},transformRenderingContext_NoClamp:function(a){var b=this.matrix;a.transform(b[0],b[3],b[1],b[4],b[2], +this.matrix[5]+a.matrix[8]*this.matrix[8];this.matrix[0]=a.matrix[0]*this.matrix[0]+a.matrix[1]*this.matrix[3]+a.matrix[2]*this.matrix[6];this.matrix[1]=b;this.matrix[2]=c;this.matrix[3]=d;this.matrix[4]=e;this.matrix[5]=f;this.matrix[6]=g;this.matrix[7]=h;this.matrix[8]=i;return this},getInverse:function(){var a=this.matrix,b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],a=a[8],j=new CAAT.Matrix,k=b*(f*a-i*g)-e*(c*a-i*d)+h*(c*g-f*d);if(0===k)return null;var m=j.matrix;m[0]=f*a-g*i;m[1]=d* +i-c*a;m[2]=c*g-d*f;m[3]=g*h-e*a;m[4]=b*a-d*h;m[5]=d*e-b*g;m[6]=e*i-f*h;m[7]=c*h-b*i;m[8]=b*f-c*e;j.multiplyScalar(1/k);return j},multiplyScalar:function(a){var b;for(b=0;9>b;b++)this.matrix[b]*=a;return this},transformRenderingContextSet:null,transformRenderingContext:null,transformRenderingContextSet_NoClamp:function(a){var b=this.matrix;a.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]);return this},transformRenderingContext_NoClamp:function(a){var b=this.matrix;a.transform(b[0],b[3],b[1],b[4],b[2], b[5]);return this},transformRenderingContextSet_Clamp:function(a){var b=this.matrix;a.setTransform(b[0],b[3],b[1],b[4],b[2]>>0,b[5]>>0);return this},transformRenderingContext_Clamp:function(a){var b=this.matrix;a.transform(b[0],b[3],b[1],b[4],b[2]>>0,b[5]>>0);return this}};CAAT.Matrix.prototype.transformRenderingContext=CAAT.Matrix.prototype.transformRenderingContext_Clamp;CAAT.Matrix.prototype.transformRenderingContextSet=CAAT.Matrix.prototype.transformRenderingContextSet_Clamp})(); -(function(){CAAT.MatrixStack=function(){this.stack=[];this.saved=[];return this};CAAT.MatrixStack.prototype={stack:null,saved:null,pushMatrix:function(a){this.stack.push(a);return this},popMatrix:function(){return this.stack.pop()},save:function(){this.saved.push(this.stack.length);return this},restore:function(){for(var a=this.saved.pop();this.stack.length!==a;)this.popMatrix();return this},getMatrix:function(){for(var a=new CAAT.Matrix,b=0;b=g)return{r:d,g:e,b:f};a=a+(d-a)/g*h>>0;b=b+(e-b)/g*h>>0;c=c+(f-c)/g*h>>0;a>255?a=255:a<0&&(a=0);b>255?b=255:b<0&&(b=0);c>255?c=255:c<0&&(c=0);return{r:a,g:b,b:c}},makeRGBColorRamp:function(a,b,c){var d=[],e=a.length-1;b/=e;for(var f=0;f>24&255,i=(g&16711680)>>16,j=(g&65280)>>8;g&=255;for(var k=a[f+1],l=((k>>24&255)-h)/b,n=(((k&16711680)>>16)-i)/b,m=(((k&65280)>>8)-j)/b,k=((k&255)-g)/b,o=0;o>0,q=i+n*o>>0,r=j+m*o>>0,s=g+k*o>>0;switch(c){case this.RampEnumeration.RAMP_RGBA:d.push("argb("+p+","+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_RGB:d.push("rgb("+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_CHANNEL_RGB:d.push(4278190080|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA:d.push(p<< -24|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY:d.push([q,r,s,p]);break;case this.RampEnumeration.RAMP_CHANNEL_RGB_ARRAY:d.push([q,r,s])}}}return d}}})();(function(){CAAT.Color.RGB=function(a,b,c){this.r=a||255;this.g=b||255;this.b=c||255;return this};CAAT.Color.RGB.prototype={r:255,g:255,b:255,toHex:function(){return("000000"+((this.r<<16)+(this.g<<8)+this.b).toString(16)).slice(-6)}}})();(function(){CAAT.Rectangle=function(){return this};CAAT.Rectangle.prototype={x:0,y:0,x1:0,y1:0,width:-1,height:-1,setEmpty:function(){this.height=this.width=-1;this.y1=this.x1=this.y=this.x=0;return this},setLocation:function(a,b){this.x=a;this.y=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setDimension:function(a,b){this.width=a;this.height=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setBounds:function(a,b,c,d){this.setLocation(a,b);this.setDimension(c, -d);return this},contains:function(a,b){return a>=0&&a=0&&bthis.y1)this.y1=b;if(a>this.x1)this.x1=a;this.width=this.x1-this.x;this.height=this.y1-this.y}},unionRectangle:function(a){this.union(a.x,a.y);this.union(a.x1, -a.y);this.union(a.x,a.y1);this.union(a.x1,a.y1);return this},intersects:function(a){return a.isEmpty()||this.isEmpty()?false:a.x1this.x1?false:a.y1this.y1?false:true},intersectsRect:function(a,b,c,d){return-1===c||-1===d?false:a+c-1this.x1?false:b+d-1this.y1?false:true},intersect:function(a,b){typeof b==="undefined"&&(b=new CAAT.Rectangle);b.x=Math.max(this.x,a.x);b.y=Math.max(this.y,a.y);b.x1=Math.min(this.x1,a.x1);b.y1=Math.min(this.y1, -a.y1);b.width=b.x1-b.x;b.height=b.y1-b.y;return b}}})();(function(){CAAT.Curve=function(){return this};CAAT.Curve.prototype={coordlist:null,k:0.05,length:-1,interpolator:false,HANDLE_SIZE:20,drawHandles:true,paint:function(a){if(false!==this.drawHandles){a=a.ctx;a.save();a.beginPath();a.strokeStyle="#a0a0a0";a.moveTo(this.coordlist[0].x,this.coordlist[0].y);a.lineTo(this.coordlist[1].x,this.coordlist[1].y);a.stroke();this.cubic&&(a.moveTo(this.coordlist[2].x,this.coordlist[2].y),a.lineTo(this.coordlist[3].x,this.coordlist[3].y),a.stroke());a.globalAlpha= -0.5;for(var b=0;b=0&&b=h)return{r:a,g:b,b:c};if(h>=g)return{r:d,g:e,b:f};a=a+(d-a)/g*h>>0;b=b+(e-b)/g*h>>0;c=c+(f-c)/g*h>>0;255a&&(a=0);255b&&(b=0);255c&&(c=0);return{r:a,g:b,b:c}},makeRGBColorRamp:function(a,b,c){for(var d=[],e=a.length-1,b=b/e,f=0;f>24&255,i=(g&16711680)>>16,j=(g&65280)>>8,g=g&255,k=a[f+1],m=((k>>24&255)-h)/b,n=(((k&16711680)>>16)-i)/b,l=(((k&65280)>>8)-j)/b,k=((k&255)-g)/b,o=0;o>0,q=i+n*o>>0,r=j+l*o>>0,s=g+k*o>>0;switch(c){case this.RampEnumeration.RAMP_RGBA:d.push("argb("+p+","+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_RGB:d.push("rgb("+q+","+r+","+s+")");break;case this.RampEnumeration.RAMP_CHANNEL_RGB:d.push(4278190080|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA:d.push(p<< +24|q<<16|r<<8|s);break;case this.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY:d.push([q,r,s,p]);break;case this.RampEnumeration.RAMP_CHANNEL_RGB_ARRAY:d.push([q,r,s])}}return d}}})();(function(){CAAT.Color.RGB=function(a,b,c){this.r=a||255;this.g=b||255;this.b=c||255;return this};CAAT.Color.RGB.prototype={r:255,g:255,b:255,toHex:function(){return("000000"+((this.r<<16)+(this.g<<8)+this.b).toString(16)).slice(-6)}}})();(function(){CAAT.Rectangle=function(){return this};CAAT.Rectangle.prototype={x:0,y:0,x1:0,y1:0,width:-1,height:-1,setEmpty:function(){this.height=this.width=-1;this.y1=this.x1=this.y=this.x=0;return this},setLocation:function(a,b){this.x=a;this.y=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setDimension:function(a,b){this.width=a;this.height=b;this.x1=this.x+this.width;this.y1=this.y+this.height;return this},setBounds:function(a,b,c,d){this.setLocation(a,b);this.setDimension(c, +d);return this},contains:function(a,b){return 0<=a&&athis.y1&&(this.y1=b),a>this.x1&&(this.x1=a),this.width=this.x1-this.x,this.height=this.y1-this.y)},unionRectangle:function(a){this.union(a.x,a.y);this.union(a.x1, +a.y);this.union(a.x,a.y1);this.union(a.x1,a.y1);return this},intersects:function(a){return a.isEmpty()||this.isEmpty()||a.x1this.x1||a.y1this.y1?!1:!0},intersectsRect:function(a,b,c,d){return-1===c||-1===d||a+c-1this.x1||b+d-1this.y1?!1:!0},intersect:function(a,b){"undefined"===typeof b&&(b=new CAAT.Rectangle);b.x=Math.max(this.x,a.x);b.y=Math.max(this.y,a.y);b.x1=Math.min(this.x1,a.x1);b.y1=Math.min(this.y1,a.y1);b.width=b.x1-b.x;b.height=b.y1-b.y; +return b}}})();(function(){CAAT.Curve=function(){return this};CAAT.Curve.prototype={coordlist:null,k:0.05,length:-1,interpolator:!1,HANDLE_SIZE:20,drawHandles:!0,paint:function(a){if(!1!==this.drawHandles){a=a.ctx;a.save();a.beginPath();a.strokeStyle="#a0a0a0";a.moveTo(this.coordlist[0].x,this.coordlist[0].y);a.lineTo(this.coordlist[1].x,this.coordlist[1].y);a.stroke();this.cubic&&(a.moveTo(this.coordlist[2].x,this.coordlist[2].y),a.lineTo(this.coordlist[3].x,this.coordlist[3].y),a.stroke());a.globalAlpha=0.5;for(var b= +0;ba*a)b=Math.sqrt(b),this.x=this.x/b*a,this.y=this.y/b*a,this.z=this.z/b*a;return this},getLength:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);return a<0.0050&&a>-0.0050?1.0E-6:a},getLengthSquared:function(){var a=this.x*this.x+this.y*this.y+this.z*this.z;return a<0.0050&&a>-0.0050?0:a},getDistance:function(a){var b=this.x-a.x,c=this.y-a.y,a=this.z-a.z;return Math.sqrt(b*b+c*c+a*a)},getDistanceSquared:function(a){var b=this.x-a.x,c=this.y-a.y, -a=this.z-a.z;return b*b+c*c+a*a},toString:function(){return"(CAAT.Point) x:"+String(Math.round(Math.floor(this.x*10))/10)+" y:"+String(Math.round(Math.floor(this.y*10))/10)+" z:"+String(Math.round(Math.floor(this.z*10))/10)}}})();(function(){CAAT.QuadTree=function(){return this};CAAT.QuadTree.prototype={bgActors:null,quadData:null,create:function(a,b,c,d,e,f,g){typeof f==="undefined"&&(f=32);typeof g==="undefined"&&(g=1);var h=(a+c)/2,i=(b+d)/2;this.x=a;this.y=b;this.x1=c;this.y1=d;this.width=c-a;this.height=d-b;this.bgActors=this.__getOverlappingActorList(e);if(this.bgActors.length<=g||this.width<=f)return this;this.quadData=Array(4);this.quadData[0]=(new CAAT.QuadTree).create(a,b,h,i,this.bgActors);this.quadData[1]=(new CAAT.QuadTree).create(h, -b,c,i,this.bgActors);this.quadData[2]=(new CAAT.QuadTree).create(a,i,h,d,this.bgActors);this.quadData[3]=(new CAAT.QuadTree).create(h,i,c,d,this.bgActors);return this},__getOverlappingActorList:function(a){for(var b=[],c=0,d=a.length;ca*a&&(b=Math.sqrt(b),this.x=this.x/b*a,this.y=this.y/b*a,this.z=this.z/b*a);return this},getLength:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);return 0.005>a&&-0.005a&&-0.005b;b++){if(this.quadData[b].intersects(a)){f=this.quadData[b].getOverlappingActors(a);for(c=0,d=f.length;c>0);this.ycache=[];for(e=0;e>0);this.xycache=[];for(e=0;e< this.rows;e++){this.xycache.push([]);for(c=0;c=this.behaviorStartTime&&(a=(a-this.behaviorStartTime)%this.behaviorDuration+this.behaviorStartTime);if(a>this.behaviorStartTime+this.behaviorDuration)return this.status!==e.EXPIRED&&this.setExpired(b,a),false;if(this.status===e.NOT_STARTED)this.status=e.STARTED,this.fireBehaviorStartedEvent(b,a);return this.behaviorStartTime<=a},fireBehaviorStartedEvent:function(a,b){for(var e=0;ec?2*c:1-2*(c-0.5));null!==b&&b&&(c=1-c);return this.interpolated.set(d,c)};return this},createBackOutInterpolator:function(a){this.getPosition=function(b){var c=b;a&&(b=0.5>b?2*b:1-2*(b-0.5));b-=1;return this.interpolated.set(c,b*b*(2.70158*b+1.70158)+1)};return this}, +createExponentialInInterpolator:function(a,b){this.getPosition=function(c){var d=c;b&&(c=0.5>c?2*c:1-2*(c-0.5));return this.interpolated.set(d,Math.pow(c,a))};return this},createExponentialOutInterpolator:function(a,b){this.getPosition=function(c){var d=c;b&&(c=0.5>c?2*c:1-2*(c-0.5));return this.interpolated.set(d,1-Math.pow(1-c,a))};return this},createExponentialInOutInterpolator:function(a,b){this.getPosition=function(c){var d=c;b&&(c=0.5>c?2*c:1-2*(c-0.5));return 1>2*c?this.interpolated.set(d, +Math.pow(2*c,a)/2):this.interpolated.set(d,1-Math.abs(Math.pow(2*c-2,a))/2)};return this},createQuadricBezierInterpolator:function(a,b,c,d){this.getPosition=function(e){var f=e;d&&(e=0.5>e?2*e:1-2*(e-0.5));e=(1-e)*(1-e)*a.y+2*(1-e)*e*b.y+e*e*c.y;return this.interpolated.set(f,e)};return this},createCubicBezierInterpolator:function(a,b,c,d,e){this.getPosition=function(f){var g=f;e&&(f=0.5>f?2*f:1-2*(f-0.5));var h=f*f,f=a.y+f*(3*-a.y+f*(3*a.y-a.y*f))+f*(3*b.y+f*(-6*b.y+3*b.y*f))+h*(3*c.y-3*c.y*f)+d.y* +f*h;return this.interpolated.set(g,f)};return this},createElasticOutInterpolator:function(a,b,c){this.getPosition=function(d){c&&(d=0.5>d?2*d:1-2*(d-0.5));if(0===d)return{x:0,y:0};if(1===d)return{x:1,y:1};var e=b/(2*Math.PI)*Math.asin(1/a);return this.interpolated.set(d,a*Math.pow(2,-10*d)*Math.sin((d-e)*2*Math.PI/b)+1)};return this},createElasticInInterpolator:function(a,b,c){this.getPosition=function(d){c&&(d=0.5>d?2*d:1-2*(d-0.5));if(0===d)return{x:0,y:0};if(1===d)return{x:1,y:1};var e=b/(2*Math.PI)* +Math.asin(1/a);return this.interpolated.set(d,-(a*Math.pow(2,10*(d-=1))*Math.sin((d-e)*2*Math.PI/b)))};return this},createElasticInOutInterpolator:function(a,b,c){this.getPosition=function(d){c&&(d=0.5>d?2*d:1-2*(d-0.5));var e=b/(2*Math.PI)*Math.asin(1/a),d=2*d;return 1>=d?this.interpolated.set(d,-0.5*a*Math.pow(2,10*(d-=1))*Math.sin((d-e)*2*Math.PI/b)):this.interpolated.set(d,1+0.5*a*Math.pow(2,-10*(d-=1))*Math.sin((d-e)*2*Math.PI/b))};return this},bounce:function(a){return(a/=1)<1/2.75?{x:a,y:7.5625* +a*a}:a<2/2.75?{x:a,y:7.5625*(a-=1.5/2.75)*a+0.75}:a<2.5/2.75?{x:a,y:7.5625*(a-=2.25/2.75)*a+0.9375}:{x:a,y:7.5625*(a-=2.625/2.75)*a+0.984375}},createBounceOutInterpolator:function(a){this.getPosition=function(b){a&&(b=0.5>b?2*b:1-2*(b-0.5));return this.bounce(b)};return this},createBounceInInterpolator:function(a){this.getPosition=function(b){a&&(b=0.5>b?2*b:1-2*(b-0.5));b=this.bounce(1-b);b.y=1-b.y;return b};return this},createBounceInOutInterpolator:function(a){this.getPosition=function(b){a&&(b= +0.5>b?2*b:1-2*(b-0.5));if(0.5>b)return b=this.bounce(1-2*b),b.y=0.5*(1-b.y),b;b=this.bounce(2*b-1,a);b.y=0.5*b.y+0.5;return b};return this},paint:function(a){a=a.crc;a.save();a.beginPath();a.moveTo(0,this.getPosition(0).y*this.paintScale);for(var b=0;b<=this.paintScale;b++)a.lineTo(b,this.getPosition(b/this.paintScale).y*this.paintScale);a.strokeStyle="black";a.stroke();a.restore()},getContour:function(a){for(var b=[],c=0;c<=a;c++)b.push({x:c/a,y:this.getPosition(c/a).y});return b},enumerateInterpolators:function(){return[(new CAAT.Interpolator).createLinearInterpolator(!1, +!1),"Linear pingpong=false, inverse=false",(new CAAT.Interpolator).createLinearInterpolator(!0,!1),"Linear pingpong=true, inverse=false",(new CAAT.Interpolator).createLinearInterpolator(!1,!0),"Linear pingpong=false, inverse=true",(new CAAT.Interpolator).createLinearInterpolator(!0,!0),"Linear pingpong=true, inverse=true",(new CAAT.Interpolator).createExponentialInInterpolator(2,!1),"ExponentialIn pingpong=false, exponent=2",(new CAAT.Interpolator).createExponentialOutInterpolator(2,!1),"ExponentialOut pingpong=false, exponent=2", +(new CAAT.Interpolator).createExponentialInOutInterpolator(2,!1),"ExponentialInOut pingpong=false, exponent=2",(new CAAT.Interpolator).createExponentialInInterpolator(2,!0),"ExponentialIn pingpong=true, exponent=2",(new CAAT.Interpolator).createExponentialOutInterpolator(2,!0),"ExponentialOut pingpong=true, exponent=2",(new CAAT.Interpolator).createExponentialInOutInterpolator(2,!0),"ExponentialInOut pingpong=true, exponent=2",(new CAAT.Interpolator).createExponentialInInterpolator(4,!1),"ExponentialIn pingpong=false, exponent=4", +(new CAAT.Interpolator).createExponentialOutInterpolator(4,!1),"ExponentialOut pingpong=false, exponent=4",(new CAAT.Interpolator).createExponentialInOutInterpolator(4,!1),"ExponentialInOut pingpong=false, exponent=4",(new CAAT.Interpolator).createExponentialInInterpolator(4,!0),"ExponentialIn pingpong=true, exponent=4",(new CAAT.Interpolator).createExponentialOutInterpolator(4,!0),"ExponentialOut pingpong=true, exponent=4",(new CAAT.Interpolator).createExponentialInOutInterpolator(4,!0),"ExponentialInOut pingpong=true, exponent=4", +(new CAAT.Interpolator).createExponentialInInterpolator(6,!1),"ExponentialIn pingpong=false, exponent=6",(new CAAT.Interpolator).createExponentialOutInterpolator(6,!1),"ExponentialOut pingpong=false, exponent=6",(new CAAT.Interpolator).createExponentialInOutInterpolator(6,!1),"ExponentialInOut pingpong=false, exponent=6",(new CAAT.Interpolator).createExponentialInInterpolator(6,!0),"ExponentialIn pingpong=true, exponent=6",(new CAAT.Interpolator).createExponentialOutInterpolator(6,!0),"ExponentialOut pingpong=true, exponent=6", +(new CAAT.Interpolator).createExponentialInOutInterpolator(6,!0),"ExponentialInOut pingpong=true, exponent=6",(new CAAT.Interpolator).createBounceInInterpolator(!1),"BounceIn pingpong=false",(new CAAT.Interpolator).createBounceOutInterpolator(!1),"BounceOut pingpong=false",(new CAAT.Interpolator).createBounceInOutInterpolator(!1),"BounceInOut pingpong=false",(new CAAT.Interpolator).createBounceInInterpolator(!0),"BounceIn pingpong=true",(new CAAT.Interpolator).createBounceOutInterpolator(!0),"BounceOut pingpong=true", +(new CAAT.Interpolator).createBounceInOutInterpolator(!0),"BounceInOut pingpong=true",(new CAAT.Interpolator).createElasticInInterpolator(1.1,0.4,!1),"ElasticIn pingpong=false, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4,!1),"ElasticOut pingpong=false, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInOutInterpolator(1.1,0.4,!1),"ElasticInOut pingpong=false, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInInterpolator(1.1,0.4,!0),"ElasticIn pingpong=true, amp=1.1, d=.4", +(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4,!0),"ElasticOut pingpong=true, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInOutInterpolator(1.1,0.4,!0),"ElasticInOut pingpong=true, amp=1.1, d=.4",(new CAAT.Interpolator).createElasticInInterpolator(1,0.2,!1),"ElasticIn pingpong=false, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticOutInterpolator(1,0.2,!1),"ElasticOut pingpong=false, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticInOutInterpolator(1,0.2,!1),"ElasticInOut pingpong=false, amp=1.0, d=.2", +(new CAAT.Interpolator).createElasticInInterpolator(1,0.2,!0),"ElasticIn pingpong=true, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticOutInterpolator(1,0.2,!0),"ElasticOut pingpong=true, amp=1.0, d=.2",(new CAAT.Interpolator).createElasticInOutInterpolator(1,0.2,!0),"ElasticInOut pingpong=true, amp=1.0, d=.2"]}}})();(function(){CAAT.Behavior=function(){this.lifecycleListenerList=[];this.setDefaultInterpolator();return this};CAAT.Behavior.Status={NOT_STARTED:0,STARTED:1,EXPIRED:2};var a=(new CAAT.Interpolator).createLinearInterpolator(!1),b=(new CAAT.Interpolator).createLinearInterpolator(!0);CAAT.Behavior.prototype={lifecycleListenerList:null,behaviorStartTime:-1,behaviorDuration:-1,cycleBehavior:!1,status:CAAT.Behavior.NOT_STARTED,interpolator:null,actor:null,id:0,timeOffset:0,doValueApplication:!0,solved:!0, +setValueApplication:function(a){this.doValueApplication=a;return this},setTimeOffset:function(a){this.timeOffset=a;return this},setId:function(a){this.id=a;return this},setDefaultInterpolator:function(){this.interpolator=a;return this},setPingPong:function(){this.interpolator=b;return this},setStatus:function(a){this.status=a},setFrameTime:function(a,b){this.behaviorStartTime=a;this.behaviorDuration=b;this.setStatus(CAAT.Behavior.Status.NOT_STARTED);return this},setDelayTime:function(a,b){this.behaviorStartTime= +a;this.behaviorDuration=b;this.setStatus(CAAT.Behavior.Status.NOT_STARTED);this.solved=!1;return this},setOutOfFrameTime:function(){this.setStatus(CAAT.Behavior.Status.EXPIRED);this.behaviorStartTime=Number.MAX_VALUE;this.behaviorDuration=0;return this},setInterpolator:function(a){this.interpolator=a;return this},apply:function(a,b){this.solved||(this.behaviorStartTime+=a,this.solved=!0);var e=a+=this.timeOffset*this.behaviorDuration;this.isBehaviorInTime(a,b)&&(a=this.normalizeTime(a),this.fireBehaviorAppliedEvent(b, +e,a,this.setForTime(a,b)))},setCycle:function(a){this.cycleBehavior=a;return this},addListener:function(a){this.lifecycleListenerList.push(a);return this},emptyListenerList:function(){this.lifecycleListenerList=[];return this},getStartTime:function(){return this.behaviorStartTime},getDuration:function(){return this.behaviorDuration},isBehaviorInTime:function(a,b){var e=CAAT.Behavior.Status;if(this.status===e.EXPIRED||0>this.behaviorStartTime)return!1;this.cycleBehavior&&a>=this.behaviorStartTime&& +(a=(a-this.behaviorStartTime)%this.behaviorDuration+this.behaviorStartTime);if(a>this.behaviorStartTime+this.behaviorDuration)return this.status!==e.EXPIRED&&this.setExpired(b,a),!1;this.status===e.NOT_STARTED&&(this.status=e.STARTED,this.fireBehaviorStartedEvent(b,a));return this.behaviorStartTime<=a},fireBehaviorStartedEvent:function(a,b){for(var e=0;e=h&&(h=(h-f.behaviorStartTime)/f.behaviorDuration,h=f.calculateKeyFrameData(h),f=f.getPropertyName(b),typeof g[f]==="undefined"&&(g[f]=""),g[f]+=h+" "));var i="",j;d("translate");d("rotate");d("scale");a="";i&&(a="-"+b+"-transform: "+i+";");i="";d("opacity");i&&(a+=" opacity: "+i+";");return{rules:a,ret:g}},calculateKeyFramesData:function(a,b,c){if(this.duration===Number.MAX_VALUE)return""; -typeof c==="undefined"&&(c=100);for(var d=null,e="@-"+a+"-keyframes "+b+" {",f,b=0;b<=c;b++)f=this.interpolator.getPosition(b/c).y,d=this.calculateKeyFrameData(f,a,d),f=""+b/c*100+"%{"+d.rules+"}\n",d=d.ret,e+=f;e+="}";return e}};extend(CAAT.ContainerBehavior,CAAT.Behavior,null)})(); +CAAT.GenericBehavior)&&(h=a*this.behaviorDuration,f.behaviorStartTime<=h&&f.behaviorStartTime+f.behaviorDuration>=h&&(h=(h-f.behaviorStartTime)/f.behaviorDuration,h=f.calculateKeyFrameData(h),f=f.getPropertyName(b),"undefined"===typeof g[f]&&(g[f]=""),g[f]+=h+" "));var i="",j;d("translate");d("rotate");d("scale");a="";i&&(a="-"+b+"-transform: "+i+";");i="";d("opacity");i&&(a+=" opacity: "+i+";");return{rules:a,ret:g}},calculateKeyFramesData:function(a,b,c){if(this.duration===Number.MAX_VALUE)return""; +"undefined"===typeof c&&(c=100);for(var d=null,e="@-"+a+"-keyframes "+b+" {",f,b=0;b<=c;b++)f=this.interpolator.getPosition(b/c).y,d=this.calculateKeyFrameData(f,a,d),f=""+100*(b/c)+"%{"+d.rules+"}\n",d=d.ret,e+=f;return e+"}"}};extend(CAAT.ContainerBehavior,CAAT.Behavior,null)})(); (function(){CAAT.RotateBehavior=function(){CAAT.RotateBehavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.RotateBehavior.prototype={startAngle:0,endAngle:0,anchorX:0.5,anchorY:0.5,getPropertyName:function(){return"rotate"},setForTime:function(a,b){var c=this.startAngle+a*(this.endAngle-this.startAngle);this.doValueApplication&&b.setRotationAnchored(c,this.anchorX,this.anchorY);return c},setValues:function(a,b,c,d){this.startAngle=a;this.endAngle= -b;if(typeof c!=="undefined"&&typeof d!=="undefined")this.anchorX=c,this.anchorY=d;return this},setAngles:function(a,b){return this.setValues(a,b)},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"rotate("+(this.startAngle+a*(this.endAngle-this.startAngle))+"rad)"},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<= -c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}\n",e+=d;e+="}";return e}};extend(CAAT.RotateBehavior,CAAT.Behavior,null)})(); +b;"undefined"!==typeof c&&"undefined"!==typeof d&&(this.anchorX=c,this.anchorY=d);return this},setAngles:function(a,b){return this.setValues(a,b)},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"rotate("+(this.startAngle+a*(this.endAngle-this.startAngle))+"rad)"},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<= +c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}\n",e+=d;return e+"}"}};extend(CAAT.RotateBehavior,CAAT.Behavior,null)})(); (function(){CAAT.GenericBehavior=function(){CAAT.GenericBehavior.superclass.constructor.call(this);return this};CAAT.GenericBehavior.prototype={start:0,end:0,target:null,property:null,callback:null,setForTime:function(a,b){var c=this.start+a*(this.end-this.start);this.callback&&this.callback(c,this.target,b);this.property&&(this.target[this.property]=c)},setValues:function(a,b,c,d,e){this.start=a;this.end=b;this.target=c;this.property=d;this.callback=e;return this}};extend(CAAT.GenericBehavior,CAAT.Behavior, null)})(); (function(){CAAT.ScaleBehavior=function(){CAAT.ScaleBehavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.ScaleBehavior.prototype={startScaleX:1,endScaleX:1,startScaleY:1,endScaleY:1,anchorX:0.5,anchorY:0.5,getPropertyName:function(){return"scale"},setForTime:function(a,b){var c=this.startScaleX+a*(this.endScaleX-this.startScaleX),d=this.startScaleY+a*(this.endScaleY-this.startScaleY);0===c&&(c=0.01);0===d&&(d=0.01);this.doValueApplication&&b.setScaleAnchored(c, -d,this.anchorX,this.anchorY);return{scaleX:c,scaleY:d}},setValues:function(a,b,c,d,e,f){this.startScaleX=a;this.endScaleX=b;this.startScaleY=c;this.endScaleY=d;if(typeof e!=="undefined"&&typeof f!=="undefined")this.anchorX=e,this.anchorY=f;return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"scaleX("+(this.startScaleX+a*(this.endScaleX-this.startScaleX))+") scaleY("+(this.startScaleY+ -a*(this.endScaleY-this.startScaleY))+")"},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;e+="}";return e}};extend(CAAT.ScaleBehavior,CAAT.Behavior,null)})(); +d,this.anchorX,this.anchorY);return{scaleX:c,scaleY:d}},setValues:function(a,b,c,d,e,f){this.startScaleX=a;this.endScaleX=b;this.startScaleY=c;this.endScaleY=d;"undefined"!==typeof e&&"undefined"!==typeof f&&(this.anchorX=e,this.anchorY=f);return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return"scaleX("+(this.startScaleX+a*(this.endScaleX-this.startScaleX))+") scaleY("+(this.startScaleY+ +a*(this.endScaleY-this.startScaleY))+")"},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;return e+"}"}};extend(CAAT.ScaleBehavior,CAAT.Behavior,null)})(); (function(){CAAT.AlphaBehavior=function(){CAAT.AlphaBehavior.superclass.constructor.call(this);return this};CAAT.AlphaBehavior.prototype={startAlpha:0,endAlpha:0,getPropertyName:function(){return"opacity"},setForTime:function(a,b){var c=this.startAlpha+a*(this.endAlpha-this.startAlpha);this.doValueApplication&&b.setAlpha(c);return c},setValues:function(a,b){this.startAlpha=a;this.endAlpha=b;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;return this.startAlpha+ -a*(this.endAlpha-this.startAlpha)},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d="@-"+a+"-keyframes "+b+" {",a=0;a<=c;a++)b=""+a/c*100+"%{opacity: "+this.calculateKeyFrameData(a/c)+"}",d+=b;d+="}";return d}};extend(CAAT.AlphaBehavior,CAAT.Behavior,null)})(); -(function(){CAAT.PathBehavior=function(){CAAT.PathBehavior.superclass.constructor.call(this);return this};CAAT.PathBehavior.autorotate={LEFT_TO_RIGHT:0,RIGHT_TO_LEFT:1,FREE:2};CAAT.PathBehavior.prototype={path:null,autoRotate:false,prevX:-1,prevY:-1,autoRotateOp:CAAT.PathBehavior.autorotate.FREE,getPropertyName:function(){return"translate"},setAutoRotate:function(a,b){this.autoRotate=a;if(b!==void 0)this.autoRotateOp=b;return this},setPath:function(a){this.path=a;return this},setValues:function(a){return this.setPath(a)}, -setTranslation:function(){return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.path.getPosition(a);return"translateX("+a.x+"px) translateY("+a.y+"px)"},calculateKeyFramesData:function(a,b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;e+="}";return e},setForTime:function(a,b){if(!this.path)return{x:b.x,y:b.y};var c=this.path.getPosition(a); -if(this.autoRotate){if(-1===this.prevX&&-1===this.prevY)this.prevX=c.x,this.prevY=c.y;var d=c.x-this.prevX,e=c.y-this.prevY;if(d===0&&e===0)return b.setLocation(c.x,c.y),{x:b.x,y:b.y};var f=Math.atan2(e,d),g=CAAT.SpriteImage.prototype,h=CAAT.PathBehavior.autorotate;this.autoRotateOp===h.LEFT_TO_RIGHT?this.prevX<=c.x?b.setImageTransformation(g.TR_NONE):(b.setImageTransformation(g.TR_FLIP_HORIZONTAL),f+=Math.PI):this.autoRotateOp===h.RIGHT_TO_LEFT&&(this.prevX<=c.x?b.setImageTransformation(g.TR_FLIP_HORIZONTAL): +a*(this.endAlpha-this.startAlpha)},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d="@-"+a+"-keyframes "+b+" {",a=0;a<=c;a++)b=""+100*(a/c)+"%{opacity: "+this.calculateKeyFrameData(a/c)+"}",d+=b;return d+"}"}};extend(CAAT.AlphaBehavior,CAAT.Behavior,null)})(); +(function(){CAAT.PathBehavior=function(){CAAT.PathBehavior.superclass.constructor.call(this);return this};CAAT.PathBehavior.autorotate={LEFT_TO_RIGHT:0,RIGHT_TO_LEFT:1,FREE:2};CAAT.PathBehavior.prototype={path:null,autoRotate:!1,prevX:-1,prevY:-1,autoRotateOp:CAAT.PathBehavior.autorotate.FREE,getPropertyName:function(){return"translate"},setAutoRotate:function(a,b){this.autoRotate=a;void 0!==b&&(this.autoRotateOp=b);return this},setPath:function(a){this.path=a;return this},setValues:function(a){return this.setPath(a)}, +setTranslation:function(){return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.path.getPosition(a);return"translateX("+a.x+"px) translateY("+a.y+"px)"},calculateKeyFramesData:function(a,b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;return e+"}"},setForTime:function(a,b){if(!this.path)return{x:b.x,y:b.y};var c=this.path.getPosition(a); +if(this.autoRotate){-1===this.prevX&&-1===this.prevY&&(this.prevX=c.x,this.prevY=c.y);var d=c.x-this.prevX,e=c.y-this.prevY;if(0===d&&0===e)return b.setLocation(c.x,c.y),{x:b.x,y:b.y};var f=Math.atan2(e,d),g=CAAT.SpriteImage.prototype,h=CAAT.PathBehavior.autorotate;this.autoRotateOp===h.LEFT_TO_RIGHT?this.prevX<=c.x?b.setImageTransformation(g.TR_NONE):(b.setImageTransformation(g.TR_FLIP_HORIZONTAL),f+=Math.PI):this.autoRotateOp===h.RIGHT_TO_LEFT&&(this.prevX<=c.x?b.setImageTransformation(g.TR_FLIP_HORIZONTAL): (b.setImageTransformation(g.TR_NONE),f-=Math.PI));b.setRotation(f);this.prevX=c.x;this.prevY=c.y;Math.sqrt(d*d+e*e)}return this.doValueApplication?(b.setLocation(c.x,c.y),{x:b.x,y:b.y}):{x:c.x,y:c.y}},positionOnTime:function(a){return this.isBehaviorInTime(a,null)?(a=this.normalizeTime(a),this.path.getPosition(a)):{x:-1,y:-1}}};extend(CAAT.PathBehavior,CAAT.Behavior)})();(function(){CAAT.ColorBehavior=function(){return this};CAAT.ColorBehavior.prototype={};extend(CAAT.ColorBehavior,CAAT.Behavior)})(); -(function(){CAAT.Scale1Behavior=function(){CAAT.Scale1Behavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.Scale1Behavior.prototype={startScale:1,endScale:1,anchorX:0.5,anchorY:0.5,sx:1,sy:1,applyOnX:true,getPropertyName:function(){return"scale"},setForTime:function(a,b){var c=this.startScale+a*(this.endScale-this.startScale);0===c&&(c=0.01);this.doValueApplication&&(this.applyOnX?b.setScaleAnchored(c,b.scaleY,this.anchorX,this.anchorY):b.setScaleAnchored(b.scaleX, -c,this.anchorX,this.anchorY));return c},setValues:function(a,b,c,d,e){this.startScale=a;this.endScale=b;this.applyOnX=!!c;if(typeof d!=="undefined"&&typeof e!=="undefined")this.anchorX=d,this.anchorY=e;return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.startScale+a*(this.endScale-this.startScale);return this.applyOnX?"scaleX("+a+")":"scaleY("+a+")"},calculateKeyFramesData:function(a, -b,c){typeof c==="undefined"&&(c=100);c>>=0;for(var d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+b/c*100+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;e+="}";return e}};extend(CAAT.Scale1Behavior,CAAT.Behavior)})();(function(){CAAT.Debug=function(){return this};CAAT.Debug.prototype={width:0,height:0,canvas:null,ctx:null,statistics:null,framerate:null,textContainer:null,textFPS:null,textEntitiesTotal:null,textEntitiesActive:null,textDraws:null,textDrawTime:null,textRAFTime:null,textDirtyRects:null,frameTimeAcc:0,frameRAFAcc:0,canDebug:false,SCALE:60,debugTpl:'
CAAT Debug panel Performance Controls Draw Time: 5.46 ms. FPS: 48
RAF Time: 20.76 ms. Entities Total: 41 Entities Active: 37 Draws: 0 DirtyRects: 0
Sound
Music
AA Bounding Boxes
Bounding Boxes
Dirty Rects
', +(function(){CAAT.Scale1Behavior=function(){CAAT.Scale1Behavior.superclass.constructor.call(this);this.anchor=CAAT.Actor.prototype.ANCHOR_CENTER;return this};CAAT.Scale1Behavior.prototype={startScale:1,endScale:1,anchorX:0.5,anchorY:0.5,sx:1,sy:1,applyOnX:!0,getPropertyName:function(){return"scale"},setForTime:function(a,b){var c=this.startScale+a*(this.endScale-this.startScale);0===c&&(c=0.01);this.doValueApplication&&(this.applyOnX?b.setScaleAnchored(c,b.scaleY,this.anchorX,this.anchorY):b.setScaleAnchored(b.scaleX, +c,this.anchorX,this.anchorY));return c},setValues:function(a,b,c,d,e){this.startScale=a;this.endScale=b;this.applyOnX=!!c;"undefined"!==typeof d&&"undefined"!==typeof e&&(this.anchorX=d,this.anchorY=e);return this},setAnchor:function(a,b,c){this.anchorX=b/a.width;this.anchorY=c/a.height;return this},calculateKeyFrameData:function(a){a=this.interpolator.getPosition(a).y;a=this.startScale+a*(this.endScale-this.startScale);return this.applyOnX?"scaleX("+a+")":"scaleY("+a+")"},calculateKeyFramesData:function(a, +b,c){"undefined"===typeof c&&(c=100);for(var c=c>>0,d,e="@-"+a+"-keyframes "+b+" {",b=0;b<=c;b++)d=""+100*(b/c)+"%{-"+a+"-transform:"+this.calculateKeyFrameData(b/c)+"}",e+=d;return e+"}"}};extend(CAAT.Scale1Behavior,CAAT.Behavior)})();(function(){CAAT.Debug=function(){return this};CAAT.Debug.prototype={width:0,height:0,canvas:null,ctx:null,statistics:null,framerate:null,textContainer:null,textFPS:null,textEntitiesTotal:null,textEntitiesActive:null,textDraws:null,textDrawTime:null,textRAFTime:null,textDirtyRects:null,frameTimeAcc:0,frameRAFAcc:0,canDebug:!1,SCALE:60,debugTpl:'
CAAT Debug panel Performance Controls Draw Time: 5.46 ms. FPS: 48
RAF Time: 20.76 ms. Entities Total: 41 Entities Active: 37 Draws: 0 DirtyRects: 0
Sound
Music
AA Bounding Boxes
Bounding Boxes
Dirty Rects
', setScale:function(a){this.scale=a;return this},initialize:function(a,b){this.width=a=window.innerWidth;this.height=b;this.framerate={refreshInterval:CAAT.FPS_REFRESH||500,frames:0,timeLastRefresh:0,fps:0,prevFps:-1,fpsMin:1E3,fpsMax:0};if(!document.getElementById("caat-debug")){var c=document.createElement("div");c.innerHTML=this.debugTpl;document.body.appendChild(c);eval(' function initCheck( name, bool, callback ) { var elem= document.getElementById(name); if ( elem ) { elem.className= (bool) ? "checkbox_enabled" : "checkbox_disabled"; if ( callback ) { elem.addEventListener( "click", (function(elem, callback) { return function(e) { elem.__value= !elem.__value; elem.className= (elem.__value) ? "checkbox_enabled" : "checkbox_disabled"; callback(e,elem.__value); } })(elem, callback), false ); } elem.__value= bool; } } function setupTabs() { var numTabs=0; var elem; var elemContent; do { elem= document.getElementById("caat-debug-tab"+numTabs); if ( elem ) { elemContent= document.getElementById("caat-debug-tab"+numTabs+"-content"); if ( elemContent ) { elemContent.style.display= numTabs===0 ? \'block\' : \'none\'; elem.className= numTabs===0 ? "debug_tab debug_tab_selected" : "debug_tab debug_tab_not_selected"; elem.addEventListener( "click", (function(tabIndex) { return function(e) { for( var i=0; ithis.framerate.timeLastRefresh+this.framerate.refreshInterval)this.framerate.fps=this.framerate.frames*1E3/(CAAT.RAF-this.framerate.timeLastRefresh)|0,this.framerate.fpsMin= -this.framerate.frames>0?Math.min(this.framerate.fpsMin,this.framerate.fps):this.framerate.fpsMin,this.framerate.fpsMax=Math.max(this.framerate.fpsMax,this.framerate.fps),this.textFPS.innerHTML=this.framerate.fps,a=(this.frameTimeAcc*100/this.framerate.frames|0)/100,this.frameTimeAcc=0,this.textDrawTime.innerHTML=a,a=(this.frameRAFAcc*100/this.framerate.frames|0)/100,this.frameRAFAcc=0,this.textRAFTime.innerHTML=a,this.framerate.timeLastRefresh=CAAT.RAF,this.framerate.frames=0,this.paint(a);this.textEntitiesTotal.innerHTML= +document.getElementById("caat-debug-canvas");if(null===this.canvas)this.canDebug=!1;else return this.canvas.width=a,this.canvas.height=b,this.ctx=this.canvas.getContext("2d"),this.ctx.fillStyle="#000",this.ctx.fillRect(0,0,this.width,this.height),this.textFPS=document.getElementById("textFPS"),this.textDrawTime=document.getElementById("textDrawTime"),this.textRAFTime=document.getElementById("textRAFTime"),this.textEntitiesTotal=document.getElementById("textEntitiesTotal"),this.textEntitiesActive= +document.getElementById("textEntitiesActive"),this.textDraws=document.getElementById("textDraws"),this.textDirtyRects=document.getElementById("textDirtyRects"),this.canDebug=!0,this},debugInfo:function(a){this.statistics=a;this.frameTimeAcc+=CAAT.FRAME_TIME;this.frameRAFAcc+=CAAT.REQUEST_ANIMATION_FRAME_TIME;this.framerate.frames++;CAAT.RAF>this.framerate.timeLastRefresh+this.framerate.refreshInterval&&(this.framerate.fps=1E3*this.framerate.frames/(CAAT.RAF-this.framerate.timeLastRefresh)|0,this.framerate.fpsMin= +0> -0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();b.strokeStyle="#aa2";b.beginPath();c=this.height-(30/this.SCALE*this.height>>0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();c=Math.min(this.height-this.framerate.fps/this.SCALE*this.height,59);if(-1===this.framerate.prevFps)this.framerate.prevFps=c|0;b.strokeStyle="#0ff";b.beginPath();b.moveTo(this.width,(c|0)-0.5);b.lineTo(this.width,this.framerate.prevFps-0.5);b.stroke();this.framerate.prevFps=c;a=(this.height-a/this.SCALE* +0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();b.strokeStyle="#aa2";b.beginPath();c=this.height-(30/this.SCALE*this.height>>0)-0.5;b.moveTo(0.5,c);b.lineTo(this.width+0.5,c);b.stroke();c=Math.min(this.height-this.framerate.fps/this.SCALE*this.height,59);-1===this.framerate.prevFps&&(this.framerate.prevFps=c|0);b.strokeStyle="#0ff";b.beginPath();b.moveTo(this.width,(c|0)-0.5);b.lineTo(this.width,this.framerate.prevFps-0.5);b.stroke();this.framerate.prevFps=c;a=(this.height-a/this.SCALE* this.height>>0)-0.5;b.strokeStyle="#ff0";b.beginPath();b.moveTo(this.width,a);b.lineTo(this.width,a);b.stroke()}}})();(function(){CAAT.Actor=function(){this.behaviorList=[];this.lifecycleListenerList=[];this.AABB=new CAAT.Rectangle;this.viewVertices=[new CAAT.Point(0,0,0),new CAAT.Point(0,0,0),new CAAT.Point(0,0,0),new CAAT.Point(0,0,0)];this.scaleAnchor=this.ANCHOR_CENTER;this.modelViewMatrix=new CAAT.Matrix;this.worldModelViewMatrix=new CAAT.Matrix;this.resetTransform();this.setScale(1,1);this.setRotation(0);return this};CAAT.Actor.ANCHOR_CENTER=0;CAAT.Actor.ANCHOR_TOP=1;CAAT.Actor.ANCHOR_BOTTOM=2;CAAT.Actor.ANCHOR_LEFT= -3;CAAT.Actor.ANCHOR_RIGHT=4;CAAT.Actor.ANCHOR_TOP_LEFT=5;CAAT.Actor.ANCHOR_TOP_RIGHT=6;CAAT.Actor.ANCHOR_BOTTOM_LEFT=7;CAAT.Actor.ANCHOR_BOTTOM_RIGHT=8;CAAT.Actor.ANCHOR_CUSTOM=9;CAAT.Actor.prototype={lifecycleListenerList:null,behaviorList:null,parent:null,x:0,y:0,width:0,height:0,start_time:0,duration:Number.MAX_VALUE,clip:false,clipPath:null,tAnchorX:0,tAnchorY:0,scaleX:0,scaleY:0,scaleTX:0.5,scaleTY:0.5,scaleAnchor:0,rotationAngle:0,rotationY:0.5,alpha:1,rotationX:0.5,isGlobalAlpha:false,frameAlpha:1, -expired:false,discardable:false,pointed:false,mouseEnabled:true,visible:true,ANCHOR_CENTER:0,ANCHOR_TOP:1,ANCHOR_BOTTOM:2,ANCHOR_LEFT:3,ANCHOR_RIGHT:4,ANCHOR_TOP_LEFT:5,ANCHOR_TOP_RIGHT:6,ANCHOR_BOTTOM_LEFT:7,ANCHOR_BOTTOM_RIGHT:8,ANCHOR_CUSTOM:9,fillStyle:null,strokeStyle:null,time:0,AABB:null,viewVertices:null,inFrame:false,dirty:true,wdirty:true,oldX:-1,oldY:-1,modelViewMatrix:null,worldModelViewMatrix:null,modelViewMatrixI:null,worldModelViewMatrixI:null,glEnabled:false,backgroundImage:null,id:null, -size_active:1,size_total:1,__next:null,__d_ax:-1,__d_ay:-1,gestureEnabled:false,invalid:true,cached:false,collides:false,collidesAsRect:true,isAA:true,setupCollission:function(a,b){this.collides=a;this.collidesAsRect=!b},invalidate:function(){this.invalid=true},setGestureEnabled:function(a){this.gestureEnabled=!!a},isGestureEnabled:function(){return this.gestureEnabled},getId:function(){return this.id},setId:function(a){this.id=a;return this},setParent:function(a){this.parent=a;return this},setBackgroundImage:function(a, -b){if(a){a instanceof CAAT.SpriteImage||(a=(new CAAT.SpriteImage).initialize(a,1,1));a.setOwner(this);this.backgroundImage=a;if(typeof b==="undefined"||b)this.width=a.getWidth(),this.height=a.getHeight();this.glEnabled=true}else this.backgroundImage=null;return this},setSpriteIndex:function(a){this.backgroundImage&&(this.backgroundImage.setSpriteIndex(a),this.invalidate());return this},setBackgroundImageOffset:function(a,b){this.backgroundImage&&this.backgroundImage.setOffset(a,b);return this},setAnimationImageIndex:function(a){this.backgroundImage&& -this.backgroundImage.setAnimationImageIndex(a);return this},setChangeFPS:function(a){this.backgroundImage&&this.backgroundImage.setChangeFPS(a);return this},setImageTransformation:function(a){this.backgroundImage&&this.backgroundImage.setSpriteTransformation(a);return this},centerOn:function(a,b){this.setLocation(a-this.width/2,b-this.height/2);return this},centerAt:function(a,b){return this.centerOn(a,b)},getTextureGLPage:function(){return this.backgroundImage.image.__texturePage},setVisible:function(a){this.visible= -a;return this},setOutOfFrameTime:function(){this.setFrameTime(-1,0);return this},addListener:function(a){this.lifecycleListenerList.push(a);return this},removeListener:function(a){for(var b=this.lifecycleListenerList.length;b--;)if(this.lifecycleListenerList[b]===a){this.lifecycleListenerList.splice(b,1);break}},setGlobalAlpha:function(a){this.isGlobalAlpha=a;return this},fireEvent:function(a,b){for(var c=0;c=this.start_time+this.duration?(this.expired||this.setExpired(a),false):this.start_time<=a&&a=0&&b>=0&&ae)e=c.x;if(c.yg)g=c.y;c=b[1];if(c.xe)e=c.x;if(c.yg)g=c.y;c=b[2];if(c.xe)e=c.x;if(c.yg)g=c.y;c=b[3];if(c.x< -d)d=c.x;if(c.x>e)e=c.x;if(c.yg)g=c.y;a.x=d;a.y=f;a.x1=e;a.y1=g;a.width=e-d;a.height=g-f;return this},paintActor:function(a,b){if(!this.visible)return true;var c=a.ctx;this.frameAlpha=this.parent?this.parent.frameAlpha*this.alpha:1;c.globalAlpha=this.frameAlpha;a.modelViewMatrix.transformRenderingContextSet(c);this.worldModelViewMatrix.transformRenderingContext(c);this.clip&&(c.beginPath(),this.clipPath?this.clipPath.applyAsPath(a):c.rect(0,0,this.width,this.height),c.clip());this.paint(a, -b);return true},__paintActor:function(a,b){if(!this.visible)return true;var c=a.ctx;this.frameAlpha=this.alpha;var d=this.worldModelViewMatrix.matrix;c.setTransform(d[0],d[3],d[1],d[4],d[2],d[5],this.frameAlpha);this.paint(a,b);return true},paintActorGL:function(a){this.frameAlpha=this.parent.frameAlpha*this.alpha;if(this.glEnabled&&this.visible)if(this.glNeedsFlush(a)){a.glFlush();this.glSetShader(a);if(!this.__uv)this.__uv=new Float32Array(8);if(!this.__vv)this.__vv=new Float32Array(12);this.setGLCoords(this.__vv, -0);this.setUV(this.__uv,0);a.glRender(this.__vv,12,this.__uv)}else{var b=a.coordsIndex;this.setGLCoords(a.coords,b);a.coordsIndex=b+12;this.setUV(a.uv,a.uvIndex);a.uvIndex+=8}},setGLCoords:function(a,b){var c=this.viewVertices;a[b++]=c[0].x;a[b++]=c[0].y;a[b++]=0;a[b++]=c[1].x;a[b++]=c[1].y;a[b++]=0;a[b++]=c[2].x;a[b++]=c[2].y;a[b++]=0;a[b++]=c[3].x;a[b++]=c[3].y;a[b++]=0},setUV:function(a,b){this.backgroundImage.setUV(a,b)},glNeedsFlush:function(a){return this.getTextureGLPage()!==a.currentTexturePage? -true:this.frameAlpha!==a.currentOpacity?true:false},glSetShader:function(a){var b=this.getTextureGLPage();b!==a.currentTexturePage&&a.setGLTexturePage(b);this.frameAlpha!==a.currentOpacity&&a.setGLCurrentOpacity(this.frameAlpha)},endAnimate:function(){return this},initialize:function(a){if(a)for(var b in a)this[b]=a[b];return this},setClip:function(a,b){this.clip=a;this.clipPath=b;return this},cacheAsBitmap:function(a){var a=a||0,b=document.createElement("canvas");b.width=this.width;b.height=this.height; -var c=b.getContext("2d");this.paintActor({ctx:c,crc:c,modelViewMatrix:new CAAT.Matrix},a);this.setBackgroundImage(b);this.cached=true;return this},setAsButton:function(a,b,c,d,e,f){this.setBackgroundImage(a,true);this.iNormal=b||0;this.iOver=c||b;this.iPress=d||b;this.iDisabled=e||b;this.fnOnClick=f;this.enabled=true;this.setSpriteIndex(b);this.setEnabled=function(a){this.enabled=a;this.setSpriteIndex(this.enabled?this.iNormal:this.iDisabled);return this};this.actionPerformed=function(){this.enabled&& -null!==this.fnOnClick&&this.fnOnClick(this)};this.mouseEnter=function(){this.enabled&&(this.dragging?this.setSpriteIndex(this.iPress):this.setSpriteIndex(this.iOver),CAAT.setCursor("pointer"))};this.mouseExit=function(){this.enabled&&(this.setSpriteIndex(this.iNormal),CAAT.setCursor("default"))};this.mouseDown=function(){this.enabled&&this.setSpriteIndex(this.iPress)};this.mouseUp=function(){if(this.enabled)this.setSpriteIndex(this.iNormal),this.dragging=false};this.mouseClick=function(){};this.mouseDrag= -function(){if(this.enabled)this.dragging=true};this.setButtonImageIndex=function(a,b,c,d){this.iNormal=a;this.iOver=b;this.iPress=c;this.iDisabled=d;this.setSpriteIndex(this.iNormal);return this};return this}};if(CAAT.NO_PERF)CAAT.Actor.prototype.paintActor=CAAT.Actor.prototype.__paintActor})(); -(function(){CAAT.ActorContainer=function(a){CAAT.ActorContainer.superclass.constructor.call(this);this.childrenList=[];this.pendingChildrenList=[];if(typeof a!=="undefined")this.addHint=a,this.boundingBox=new CAAT.Rectangle;return this};CAAT.ActorContainer.AddHint={CONFORM:1};CAAT.ActorContainer.prototype={childrenList:null,activeChildren:null,pendingChildrenList:null,addHint:0,boundingBox:null,runion:new CAAT.Rectangle,drawScreenBoundingBox:function(a,b){if(this.inFrame){for(var c=this.childrenList, -d=0;d=this.childrenList.length)b=this.childrenList.length; -a.parent=this;a.dirty=true;this.childrenList.splice(b,0,a);return this},findActorById:function(a){for(var b=this.childrenList,c=0,d=b.length;c=0;b--){var c=this.childrenList[b],d=new CAAT.Point(a.x,a.y,0),c=c.findActorAtPosition(d);if(null!==c)return c}return this},destroy:function(){for(var a=this.childrenList,b=a.length-1;b>=0;b--)a[b].destroy();CAAT.ActorContainer.superclass.destroy.call(this);return this},getNumChildren:function(){return this.childrenList.length},getNumActiveChildren:function(){return this.activeChildren.length}, -getChildAt:function(a){return this.childrenList[a]},setZOrder:function(a,b){var c=this.findChild(a);if(-1!==c){var d=this.childrenList;if(b!==c)if(b>=d.length)d.splice(c,1),d.push(a);else{c=d.splice(c,1);if(b<0)b=0;else if(b>d.length)b=d.length;d.splice(b,0,c[0])}}}};if(CAAT.NO_PERF)CAAT.ActorContainer.prototype.paintActor=CAAT.ActorContainer.prototype.__paintActor;extend(CAAT.ActorContainer,CAAT.Actor,null)})(); -(function(){CAAT.TextActor=function(){CAAT.TextActor.superclass.constructor.call(this);this.font="10px sans-serif";this.textAlign="left";this.textBaseline="top";this.outlineColor="black";this.clip=false;return this};CAAT.TextActor.TRAVERSE_PATH_FORWARD=1;CAAT.TextActor.TRAVERSE_PATH_BACKWARD=-1;CAAT.TextActor.prototype={font:null,textAlign:null,textBaseline:null,fill:true,textFillStyle:"#eee",text:null,textWidth:0,textHeight:0,outline:false,outlineColor:null,path:null,pathInterpolator:null,pathDuration:1E4, -sign:1,setFill:function(a){this.fill=a;return this},setTextFillStyle:function(a){this.textFillStyle=a;return this},setOutline:function(a){this.outline=a;return this},setPathTraverseDirection:function(a){this.sign=a;return this},setOutlineColor:function(a){this.outlineColor=a;return this},setText:function(a){this.text=a;if(null===this.text||this.text==="")this.width=this.height=0;this.calcTextSize(CAAT.director[0]);return this},setTextAlign:function(a){this.textAlign=a;return this},setAlign:function(a){return this.setTextAlign(a)}, -setTextBaseline:function(a){this.textBaseline=a;return this},setBaseline:function(a){return this.setTextBaseline(a)},setFont:function(a){a||(a="10px sans-serif");this.font=a;this.calcTextSize(CAAT.director[0]);return this},calcTextSize:function(a){if(typeof this.text==="undefined"||null===this.text||""===this.text)return this.textHeight=this.textWidth=0,this;if(a.glEnabled)return this;if(this.font instanceof CAAT.SpriteImage)return this.textWidth=this.font.stringWidth(this.text),this.textHeight=this.font.stringHeight(), -this.width=this.textWidth,this.height=this.textHeight,this;a=a.ctx;a.save();a.font=this.font;this.textWidth=a.measureText(this.text).width;if(this.width===0)this.width=this.textWidth;try{var b=this.font.substring(0,this.font.indexOf("px"));this.textHeight=parseInt(b,10);this.textHeight+=this.textHeight/4>>0}catch(c){this.textHeight=20}if(this.height===0)this.height=this.textHeight;a.restore();return this},paint:function(a,b){CAAT.TextActor.superclass.paint.call(this,a,b);if(!this.cached&&null!==this.text){(this.textWidth=== -0||this.textHeight===0)&&this.calcTextSize(a);var c=a.ctx;if(this.font instanceof CAAT.SpriteImage)return this.drawSpriteText(a,b);if(null!==this.font)c.font=this.font;if(null!==this.textAlign)c.textAlign=this.textAlign;if(null!==this.textBaseline)c.textBaseline=this.textBaseline;if(this.fill&&null!==this.textFillStyle)c.fillStyle=this.textFillStyle;if(this.outline&&null!==this.outlineColor)c.strokeStyle=this.outlineColor;if(null===this.path){var d=0;if(this.textAlign==="center")d=this.width/2|0; -else if(this.textAlign==="right")d=this.width;if(this.fill)c.fillText(this.text,d,0),this.outline&&(c.beginPath(),c.strokeText(this.text,d,0));else{if(null!==this.outlineColor)c.strokeStyle=this.outlineColor;c.beginPath();c.strokeText(this.text,d,0)}}else this.drawOnPath(a,b)}},drawOnPath:function(a,b){for(var c=a.ctx,d=this.sign*this.pathInterpolator.getPosition(b%this.pathDuration/this.pathDuration).y*this.path.getLength(),e=new CAAT.Point(0,0,0),f=new CAAT.Point(0,0,0),g=0;g=this.start_time+this.duration?(this.expired||this.setExpired(a),!1):this.start_time<=a&&ae&&(e=c.x);c.yg&&(g=c.y);c=b[1];c.xe&&(e=c.x);c.yg&&(g=c.y);c=b[2];c.xe&&(e=c.x);c.y< +f&&(f=c.y);c.y>g&&(g=c.y);c=b[3];c.xe&&(e=c.x);c.yg&&(g=c.y);a.x=d;a.y=f;a.x1=e;a.y1=g;a.width=e-d;a.height=g-f;return this},paintActor:function(a,b){if(!this.visible)return!0;var c=a.ctx;this.frameAlpha=this.parent?this.parent.frameAlpha*this.alpha:1;c.globalAlpha=this.frameAlpha;a.modelViewMatrix.transformRenderingContextSet(c);this.worldModelViewMatrix.transformRenderingContext(c);this.clip&&(c.beginPath(),this.clipPath?this.clipPath.applyAsPath(a):c.rect(0,0,this.width, +this.height),c.clip());this.paint(a,b);return!0},__paintActor:function(a,b){if(!this.visible)return!0;var c=a.ctx;this.frameAlpha=this.alpha;var d=this.worldModelViewMatrix.matrix;c.setTransform(d[0],d[3],d[1],d[4],d[2],d[5],this.frameAlpha);this.paint(a,b);return!0},paintActorGL:function(a){this.frameAlpha=this.parent.frameAlpha*this.alpha;if(this.glEnabled&&this.visible)if(this.glNeedsFlush(a))a.glFlush(),this.glSetShader(a),this.__uv||(this.__uv=new Float32Array(8)),this.__vv||(this.__vv=new Float32Array(12)), +this.setGLCoords(this.__vv,0),this.setUV(this.__uv,0),a.glRender(this.__vv,12,this.__uv);else{var b=a.coordsIndex;this.setGLCoords(a.coords,b);a.coordsIndex=b+12;this.setUV(a.uv,a.uvIndex);a.uvIndex+=8}},setGLCoords:function(a,b){var c=this.viewVertices;a[b++]=c[0].x;a[b++]=c[0].y;a[b++]=0;a[b++]=c[1].x;a[b++]=c[1].y;a[b++]=0;a[b++]=c[2].x;a[b++]=c[2].y;a[b++]=0;a[b++]=c[3].x;a[b++]=c[3].y;a[b++]=0},setUV:function(a,b){this.backgroundImage.setUV(a,b)},glNeedsFlush:function(a){return this.getTextureGLPage()!== +a.currentTexturePage||this.frameAlpha!==a.currentOpacity?!0:!1},glSetShader:function(a){var b=this.getTextureGLPage();b!==a.currentTexturePage&&a.setGLTexturePage(b);this.frameAlpha!==a.currentOpacity&&a.setGLCurrentOpacity(this.frameAlpha)},endAnimate:function(){return this},initialize:function(a){if(a)for(var b in a)this[b]=a[b];return this},setClip:function(a,b){this.clip=a;this.clipPath=b;return this},cacheAsBitmap:function(a){var a=a||0,b=document.createElement("canvas");b.width=this.width;b.height= +this.height;var c=b.getContext("2d");this.paintActor({ctx:c,crc:c,modelViewMatrix:new CAAT.Matrix},a);this.setBackgroundImage(b);this.cached=!0;return this},setAsButton:function(a,b,c,d,e,f){this.setBackgroundImage(a,!0);this.iNormal=b||0;this.iOver=c||b;this.iPress=d||b;this.iDisabled=e||b;this.fnOnClick=f;this.enabled=!0;this.setSpriteIndex(b);this.setEnabled=function(a){this.enabled=a;this.setSpriteIndex(this.enabled?this.iNormal:this.iDisabled);return this};this.actionPerformed=function(){this.enabled&& +null!==this.fnOnClick&&this.fnOnClick(this)};this.mouseEnter=function(){this.enabled&&(this.dragging?this.setSpriteIndex(this.iPress):this.setSpriteIndex(this.iOver),CAAT.setCursor("pointer"))};this.mouseExit=function(){this.enabled&&(this.setSpriteIndex(this.iNormal),CAAT.setCursor("default"))};this.mouseDown=function(){this.enabled&&this.setSpriteIndex(this.iPress)};this.mouseUp=function(){this.enabled&&(this.setSpriteIndex(this.iNormal),this.dragging=!1)};this.mouseClick=function(){};this.mouseDrag= +function(){this.enabled&&(this.dragging=!0)};this.setButtonImageIndex=function(a,b,c,d){this.iNormal=a;this.iOver=b;this.iPress=c;this.iDisabled=d;this.setSpriteIndex(this.iNormal);return this};return this}};CAAT.NO_PERF&&(CAAT.Actor.prototype.paintActor=CAAT.Actor.prototype.__paintActor)})(); +(function(){CAAT.ActorContainer=function(a){CAAT.ActorContainer.superclass.constructor.call(this);this.childrenList=[];this.pendingChildrenList=[];"undefined"!==typeof a&&(this.addHint=a,this.boundingBox=new CAAT.Rectangle);return this};CAAT.ActorContainer.AddHint={CONFORM:1};CAAT.ActorContainer.prototype={childrenList:null,activeChildren:null,pendingChildrenList:null,addHint:0,boundingBox:null,runion:new CAAT.Rectangle,drawScreenBoundingBox:function(a,b){if(this.inFrame){for(var c=this.childrenList, +d=0;dc.x?0:c.x,0>c.y?0:c.y,c.width,c.height),a.unionRectangle(this.runion);this.setSize(a.x1,a.y1);return this},addChildDelayed:function(a){this.pendingChildrenList.push(a);return this},addChildAt:function(a,b){if(0>=b)return a.parent=this,a.dirty=!0,this.childrenList.splice(0,0,a),this;b>=this.childrenList.length&&(b=this.childrenList.length); +a.parent=this;a.dirty=!0;this.childrenList.splice(b,0,a);return this},findActorById:function(a){for(var b=this.childrenList,c=0,d=b.length;c=d.length?(d.splice(c,1),d.push(a)):(c=d.splice(c,1),0>b?b=0:b>d.length&&(b=d.length),d.splice(b,0,c[0])))}}};CAAT.NO_PERF&&(CAAT.ActorContainer.prototype.paintActor=CAAT.ActorContainer.prototype.__paintActor);extend(CAAT.ActorContainer,CAAT.Actor,null)})(); +(function(){CAAT.TextActor=function(){CAAT.TextActor.superclass.constructor.call(this);this.font="10px sans-serif";this.textAlign="left";this.textBaseline="top";this.outlineColor="black";this.clip=!1;return this};CAAT.TextActor.TRAVERSE_PATH_FORWARD=1;CAAT.TextActor.TRAVERSE_PATH_BACKWARD=-1;CAAT.TextActor.prototype={font:null,textAlign:null,textBaseline:null,fill:!0,textFillStyle:"#eee",text:null,textWidth:0,textHeight:0,outline:!1,outlineColor:null,path:null,pathInterpolator:null,pathDuration:1E4, +sign:1,setFill:function(a){this.fill=a;return this},setTextFillStyle:function(a){this.textFillStyle=a;return this},setOutline:function(a){this.outline=a;return this},setPathTraverseDirection:function(a){this.sign=a;return this},setOutlineColor:function(a){this.outlineColor=a;return this},setText:function(a){this.text=a;if(null===this.text||""===this.text)this.width=this.height=0;this.calcTextSize(CAAT.director[0]);return this},setTextAlign:function(a){this.textAlign=a;return this},setAlign:function(a){return this.setTextAlign(a)}, +setTextBaseline:function(a){this.textBaseline=a;return this},setBaseline:function(a){return this.setTextBaseline(a)},setFont:function(a){a||(a="10px sans-serif");this.font=a;this.calcTextSize(CAAT.director[0]);return this},calcTextSize:function(a){if("undefined"===typeof this.text||null===this.text||""===this.text)return this.textHeight=this.textWidth=0,this;if(a.glEnabled)return this;if(this.font instanceof CAAT.SpriteImage)return this.textWidth=this.font.stringWidth(this.text),this.textHeight=this.font.stringHeight(), +this.width=this.textWidth,this.height=this.textHeight,this;a=a.ctx;a.save();a.font=this.font;this.textWidth=a.measureText(this.text).width;0===this.width&&(this.width=this.textWidth);try{var b=this.font.substring(0,this.font.indexOf("px"));this.textHeight=parseInt(b,10);this.textHeight+=this.textHeight/4>>0}catch(c){this.textHeight=20}0===this.height&&(this.height=this.textHeight);a.restore();return this},paint:function(a,b){CAAT.TextActor.superclass.paint.call(this,a,b);if(!(this.cached||null=== +this.text)){(0===this.textWidth||0===this.textHeight)&&this.calcTextSize(a);var c=a.ctx;if(this.font instanceof CAAT.SpriteImage)return this.drawSpriteText(a,b);null!==this.font&&(c.font=this.font);null!==this.textAlign&&(c.textAlign=this.textAlign);null!==this.textBaseline&&(c.textBaseline=this.textBaseline);this.fill&&null!==this.textFillStyle&&(c.fillStyle=this.textFillStyle);this.outline&&null!==this.outlineColor&&(c.strokeStyle=this.outlineColor);if(null===this.path){var d=0;"center"===this.textAlign? +d=this.width/2|0:"right"===this.textAlign&&(d=this.width);this.fill?(c.fillText(this.text,d,0),this.outline&&(c.beginPath(),c.strokeText(this.text,d,0))):(null!==this.outlineColor&&(c.strokeStyle=this.outlineColor),c.beginPath(),c.strokeText(this.text,d,0))}else this.drawOnPath(a,b)}},drawOnPath:function(a,b){for(var c=a.ctx,d=this.sign*this.pathInterpolator.getPosition(b%this.pathDuration/this.pathDuration).y*this.path.getLength(),e=new CAAT.Point(0,0,0),f=new CAAT.Point(0,0,0),g=0;gthis.changeTime)this.imageProcessor.apply(a,b),this.lastApplicationTime=b;this.imageProcessor.paint(a,b)}};extend(CAAT.IMActor,CAAT.ActorContainer, -null)})();(function(){CAAT.AudioManager=function(){this.browserInfo=new CAAT.BrowserDetect;return this};CAAT.AudioManager.prototype={browserInfo:null,musicEnabled:true,fxEnabled:true,audioCache:null,channels:null,workingChannels:null,loopingChannels:[],audioTypes:{mp3:"audio/mpeg;",ogg:'audio/ogg; codecs="vorbis"',wav:'audio/wav; codecs="1"',mp4:'audio/mp4; codecs="mp4a.40.2"'},initialize:function(a){this.audioCache=[];this.channels=[];this.workingChannels=[];for(var b=0;b -0){var b=this.channels.shift();b.src=a.src;b.load();b.volume=a.volume;b.play();this.workingChannels.push(b)}return this},loop:function(a){if(!this.musicEnabled)return this;a=this.getAudio(a);if(null!==a){var b=document.createElement("audio");if(null!==b)return b.src=a.src,b.preload="auto",this.browserInfo.browser==="Firefox"?b.addEventListener("ended",function(a){a.target.currentTime=0},false):b.loop=true,b.load(),b.play(),this.loopingChannels.push(b),b}return null},endSound:function(){var a;for(a= -0;athis.changeTime&&(this.imageProcessor.apply(a,b),this.lastApplicationTime=b);this.imageProcessor.paint(a,b)}};extend(CAAT.IMActor,CAAT.ActorContainer, +null)})();(function(){CAAT.AudioManager=function(){this.browserInfo=new CAAT.BrowserDetect;return this};CAAT.AudioManager.prototype={browserInfo:null,musicEnabled:!0,fxEnabled:!0,audioCache:null,channels:null,workingChannels:null,loopingChannels:[],audioTypes:{mp3:"audio/mpeg;",ogg:'audio/ogg; codecs="vorbis"',wav:'audio/wav; codecs="1"',mp4:'audio/mp4; codecs="mp4a.40.2"'},initialize:function(a){this.audioCache=[];this.channels=[];this.workingChannels=[];for(var b=0;bd+this.range?this.minSize:a===d?this.maxSize:ad+this.range?this.minSize:a===d?this.maxSize:aa;a++)this.dirtyRects.push(new CAAT.Rectangle);this.dirtyRectsIndex= +0;return this};CAAT.Director.CLEAR_DIRTY_RECTS=1;CAAT.Director.CLEAR_ALL=!0;CAAT.Director.CLEAR_NONE=!1;CAAT.Director.prototype={debug:!1,onRenderStart:null,onRenderEnd:null,mousePoint:null,prevMousePoint:null,screenMousePoint:null,isMouseDown:!1,lastSelectedActor:null,dragging:!1,scenes:null,currentScene:null,canvas:null,crc:null,ctx:null,time:0,timeline:0,imagesCache:null,audioManager:null,clear:!0,transitionScene:null,browserInfo:null,gl:null,glEnabled:!1,glTextureManager:null,glTtextureProgram:null, +glColorProgram:null,pMatrix:null,coords:null,coordsIndex:0,uv:null,uvIndex:0,front_to_back:!1,statistics:{size_total:0,size_active:0,size_dirtyRects:0,draws:0},currentTexturePage:0,currentOpacity:1,intervalId:null,frameCounter:0,RESIZE_NONE:1,RESIZE_WIDTH:2,RESIZE_HEIGHT:4,RESIZE_BOTH:8,RESIZE_PROPORTIONAL:16,resize:1,onResizeCallback:null,__gestureScale:0,__gestureRotation:0,dirtyRects:null,cDirtyRects:null,dirtyRectsIndex:0,dirtyRectsEnabled:!1,nDirtyRects:0,checkDebug:function(){if(CAAT.DEBUG){var a= (new CAAT.Debug).initialize(this.width,60);this.debugInfo=a.debugInfo.bind(a)}},getRenderType:function(){return this.glEnabled?"WEBGL":"CANVAS"},windowResized:function(a,b){switch(this.resize){case this.RESIZE_WIDTH:this.setBounds(0,0,a,this.height);break;case this.RESIZE_HEIGHT:this.setBounds(0,0,this.width,b);break;case this.RESIZE_BOTH:this.setBounds(0,0,a,b);break;case this.RESIZE_PROPORTIONAL:this.setScaleProportional(a,b)}this.glEnabled&&this.glReset();if(this.onResizeCallback)this.onResizeCallback(this, a,b)},setScaleProportional:function(a,b){var c=Math.min(a/this.referenceWidth,b/this.referenceHeight);this.setScaleAnchored(c,c,0,0);this.canvas.width=this.referenceWidth*c;this.canvas.height=this.referenceHeight*c;this.crc=this.ctx=this.canvas.getContext(this.glEnabled?"experimental-webgl":"2d");this.glEnabled&&this.glReset()},enableResizeEvents:function(a,b){a===this.RESIZE_BOTH||a===this.RESIZE_WIDTH||a===this.RESIZE_HEIGHT||a===this.RESIZE_PROPORTIONAL?(this.referenceWidth=this.width,this.referenceHeight= this.height,this.resize=a,CAAT.registerResizeListener(this),this.onResizeCallback=b,this.windowResized(window.innerWidth,window.innerHeight)):(CAAT.unregisterResizeListener(this),this.onResizeCallback=null)},setBounds:function(a,b,c,d){CAAT.Director.superclass.setBounds.call(this,a,b,c,d);this.canvas.width=c;this.canvas.height=d;this.crc=this.ctx=this.canvas.getContext(this.glEnabled?"experimental-webgl":"2d");for(a=0;a=0;b--){var c=this.childrenList[b],d=new CAAT.Point(a.x,a.y,0),c=c.findActorAtPosition(d);if(null!==c)return c}return this},resetStats:function(){this.statistics.size_total=0;this.statistics.size_active=0;this.statistics.draws=0}, +c.width=a;c.height=b;this.referenceWidth=a;this.referenceHeight=b;try{this.gl=c.getContext("experimental-webgl"),this.gl.viewportWidth=a,this.gl.viewportHeight=b,CAAT.GLRENDER=!0}catch(d){}if(this.gl)this.canvas=c,this.create(),this.setBounds(0,0,a,b),this.crc=this.ctx,this.enableEvents(c),this.timeline=(new Date).getTime(),this.glColorProgram=(new CAAT.ColorProgram(this.gl)).create().initialize(),this.glTextureProgram=(new CAAT.TextureProgram(this.gl)).create().initialize(),this.glTextureProgram.useProgram(), +this.glReset(),this.coords=new Float32Array(6144),this.uv=new Float32Array(4096),this.gl.clearColor(0,0,0,255),this.front_to_back?(this.gl.clearDepth(1),this.gl.enable(this.gl.DEPTH_TEST),this.gl.depthFunc(this.gl.LESS)):this.gl.disable(this.gl.DEPTH_TEST),this.gl.enable(this.gl.BLEND),this.gl.blendFunc(this.gl.ONE,this.gl.ONE_MINUS_SRC_ALPHA),this.glEnabled=!0,this.checkDebug();else return this.initialize(a,b,c);return this},createScene:function(){var a=(new CAAT.Scene).create();this.addScene(a); +return a},setImagesCache:function(a,b,c){var d;null!==this.glTextureManager&&(this.glTextureManager.deletePages(),this.glTextureManager=null);if(this.imagesCache){var e=[];for(d=0;d0&&CAAT.DEBUG&&CAAT.DEBUG_DIRTYRECTS){f.beginPath();this.nDirtyRects=0;d=this.cDirtyRects;for(c=0;c=this.dirtyRects.length)for(b=0;b<32;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0, -0,this.width,this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc;this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=true;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null=== -this.currentScene&&this.setScene(0)},getNumScenes:function(){return this.scenes.length},easeInOut:function(a,b,c,d,e,f,g,h,i,j){if(a!==this.getCurrentSceneIndex()){a=this.scenes[a];d=this.scenes[d];if(!this.glEnabled&&!navigator.browser==="iOS")this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene;a.setExpired(false);d.setExpired(false);a.mouseEnabled=false;d.mouseEnabled=false;a.resetTransform();d.resetTransform(); -a.setLocation(0,0);d.setLocation(0,0);a.alpha=1;d.alpha=1;b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i);e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j);this.childrenList=[];this.addChild(d);this.addChild(a)}},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;e< -0.33?(e=CAAT.Scene.prototype.EASE_ROTATION,g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):e<0.66?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;f<0.33?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):f<0.66?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)): -(f=CAAT.Scene.prototype.EASE_TRANSLATE,h=(new CAAT.Interpolator).createBounceOutInterpolator());this.easeInOut(a,e,Math.random()*8.99>>0,b,f,Math.random()*8.99>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=false;a.setExpired(false)}, -setScene:function(a){a=this.scenes[a];this.childrenList=[];this.addChild(a);this.currentScene=a;a.setExpired(false);a.mouseEnabled=true;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===0||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a, -b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===this.getNumScenes()-1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(true);a.mouseEnabled=true;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b500&&(b=500);if(this.onRenderStart)this.onRenderStart(b);this.render(b);this.debugInfo&&this.debugInfo(this.statistics);this.timeline=a;if(this.onRenderEnd)this.onRenderEnd(b)}, -endLoop:function(){},setClear:function(a){this.clear=a;if(this.clear===CAAT.Director.CLEAR_DIRTY_RECTS)this.dirtyRectsEnabled=true;return this},getAudioManager:function(){return this.audioManager},cumulateOffset:function(a,b,c){var d=c+"Left";c+="Top";for(var e=0,f=0,g;navigator.browser!=="iOS"&&a&&a.style;)if(g=a.currentStyle?a.currentStyle.position:(g=(a.ownerDocument.defaultView||a.ownerDocument.parentWindow).getComputedStyle(a,null))?g.getPropertyValue("position"):null,/^(fixed)$/.test(g))break; -else e+=a[d],f+=a[c],a=a[b];return{x:e,y:f,style:g}},getOffset:function(a){var b=this.cumulateOffset(a,"offsetParent","offset");return b.style==="fixed"?(a=this.cumulateOffset(a,a.parentNode?"parentNode":"parentElement","scroll"),{x:b.x+a.x,y:b.y+a.y}):{x:b.x,y:b.y}},getCanvasCoord:function(a,b){var c=0,d=0;if(!b)b=window.event;if(b.pageX||b.pageY)c=b.pageX,d=b.pageY;else if(b.clientX||b.clientY)c=b.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,d=b.clientY+document.body.scrollTop+ -document.documentElement.scrollTop;var e=this.getOffset(b.target);c-=e.x;d-=e.y;d=new CAAT.Point(c,d);if(!this.modelViewMatrixI)this.modelViewMatrixI=this.modelViewMatrix.getInverse();this.modelViewMatrixI.transformCoord(d);c=d.x;d=d.y;a.set(c,d);this.screenMousePoint.set(c,d)},__mouseDownHandler:function(a){if(this.dragging&&this.lastSelectedActor)this.__mouseUpHandler(a);else{this.getCanvasCoord(this.mousePoint,a);this.isMouseDown=true;var b=this.findActorAtPosition(this.mousePoint);if(null!==b){var c= -b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));b.mouseDown((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y)))}this.lastSelectedActor=b}},__mouseUpHandler:function(a){this.isMouseDown=false;this.getCanvasCoord(this.mousePoint,a);var b=null,c=this.lastSelectedActor;null!==c&&(b=c.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),c.actionPerformed&&c.contains(b.x,b.y)&&c.actionPerformed(a), -c.mouseUp((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time)));!this.dragging&&null!==c&&c.contains(b.x,b.y)&&c.mouseClick((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time));this.in_=this.dragging=false},__mouseMoveHandler:function(a){this.getCanvasCoord(this.mousePoint,a);var b,c,d=this.currentScene?this.currentScene.time:0;if(this.isMouseDown&&null!==this.lastSelectedActor){b=this.lastSelectedActor;c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x, -this.screenMousePoint.y,0));this.dragging=true;var e=b.x,f=b.y;b.mouseDrag((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y),d));this.prevMousePoint.x=c.x;this.prevMousePoint.y=c.y;if(e===b.x&&f===b.y){e=b.contains(c.x,c.y);if(this.in_&&!e)b.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,d)),this.in_=false;if(!this.in_&&e)b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,d)),this.in_=true}}else this.in_= -true,b=this.findActorAtPosition(this.mousePoint),b!==this.lastSelectedActor&&(null!==this.lastSelectedActor&&(c=this.lastSelectedActor.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),this.lastSelectedActor.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,this.lastSelectedActor,this.screenMousePoint,d))),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint, -d)))),c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),null!==b&&b.mouseMove((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,d)),this.lastSelectedActor=b},__mouseOutHandler:function(a){if(null!==this.lastSelectedActor){this.getCanvasCoord(this.mousePoint,a);var b=new CAAT.Point(this.mousePoint.x,this.mousePoint.y,0);this.lastSelectedActor.viewToModel(b);a=(new CAAT.MouseEvent).init(b.x,b.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time); -this.lastSelectedActor.mouseExit(a);this.lastSelectedActor.mouseOut(a);if(!this.dragging)this.lastSelectedActor=null}else this.in_=this.isMouseDown=false},__mouseOverHandler:function(a){var b,c;this.getCanvasCoord(this.mousePoint,a);null==this.lastSelectedActor?(b=this.findActorAtPosition(this.mousePoint),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScane?this.currentScene.time: -0),b.mouseOver(a),b.mouseEnter(a)),this.lastSelectedActor=b):(b=this.lastSelectedActor,c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a))},__mouseDBLClickHandler:function(a){this.getCanvasCoord(this.mousePoint,a);null!==this.lastSelectedActor&&this.lastSelectedActor.mouseDblClick((new CAAT.MouseEvent).init(this.mousePoint.x,this.mousePoint.y,a,this.lastSelectedActor, -this.screenMousePoint,this.currentScene.time))},__touchStartHandler:function(a){a.preventDefault();a=a.targetTouches[0];this.__mouseDownHandler(a)},__touchEndHandler:function(a){a.preventDefault();a=a.changedTouches[0];this.__mouseUpHandler(a)},__touchMoveHandler:function(a){a.preventDefault();if(!this.gesturing)for(var b=0;b=this.dirtyRects.length)for(b=0;32>b;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0,0,this.width, +this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc;this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=!0;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null===this.currentScene&& +this.setScene(0)},getNumScenes:function(){return this.scenes.length},easeInOut:function(a,b,c,d,e,f,g,h,i,j){a!==this.getCurrentSceneIndex()&&(a=this.scenes[a],d=this.scenes[d],!this.glEnabled&&"iOS"===!navigator.browser&&(this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene),a.setExpired(!1),d.setExpired(!1),a.mouseEnabled=!1,d.mouseEnabled=!1,a.resetTransform(),d.resetTransform(),a.setLocation(0,0), +d.setLocation(0,0),a.alpha=1,d.alpha=1,b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i),e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j),this.childrenList=[],this.addChild(d),this.addChild(a))},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;0.33>e?(e=CAAT.Scene.prototype.EASE_ROTATION, +g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):0.66>e?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;0.33>f?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):0.66>f?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)):(f=CAAT.Scene.prototype.EASE_TRANSLATE, +h=(new CAAT.Interpolator).createBounceOutInterpolator());this.easeInOut(a,e,8.99*Math.random()>>0,b,f,8.99*Math.random()>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=!1;a.setExpired(!1)},setScene:function(a){a=this.scenes[a];this.childrenList= +[];this.addChild(a);this.currentScene=a;a.setExpired(!1);a.mouseEnabled=!0;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);1>=this.getNumScenes()||0===d||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene); +1>=this.getNumScenes()||d===this.getNumScenes()-1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(!0);a.mouseEnabled=!0;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b>0)*e;var k=i+(d/h>>0)*f,l=g+e,n=k+f;g=(new CAAT.SpriteImageHelper(g,k,l-g,n-k,j.width,j.height)).setGL(g/j.width,k/j.height,l/j.width,n/j.height);this.mapInfo[d]=g}}else for(d=0;d0&&(g-=e);var h=(this.offsetY-this.ownerActor.y)%f;h>0&&(h-=f);var e=((d.width-g)/e>>0)+1,f=((d.height-h)/f>>0)+1,i,j,k=a.ctx;for(i=0;i>0)*e;var k=i+(d/h>>0)*f,m=g+e,n=k+f;g=(new CAAT.SpriteImageHelper(g,k,m-g,n-k,j.width,j.height)).setGL(g/j.width,k/j.height,m/j.width,n/j.height);this.mapInfo[d]=g}}else for(d=0;d>0)+1,f=((d.height-h)/f>>0)+1,i,j,k=a.ctx;for(i=0;i>0,d.y-this.ownerActor.y+h+i*c.height>>0,c.width,c.height)},paintInvertedH:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate((c|0)+b.width,d|0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex]; a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedHV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.translate(b.width,0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this}, paintN:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,b.width,b.height);return this},paintScaled:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,this.ownerActor.width,this.ownerActor.height);return this},getCurrentSpriteImageCSSPosition:function(){var a=this.mapInfo[this.spriteIndex]; return"-"+(a.x-this.offsetX)+"px -"+(a.y-this.offsetY)+"px "+(this.transformation===this.TR_TILE?"":"no-repeat")},getNumImages:function(){return this.rows*this.columns},setUV:function(a,b){var c=this.image;if(c.__texturePage){var d=b,e=this.mapInfo[this.spriteIndex],f=e.u,g=e.v,h=e.u1,e=e.v1;if(this.offsetX||this.offsetY)f=c.__texturePage,g=-this.offsetY/f.height,h=(this.ownerActor.width-this.offsetX)/f.width,e=(this.ownerActor.height-this.offsetY)/f.height,f=-this.offsetX/f.width+c.__u,g+=c.__v, h+=c.__u,e+=c.__v;c.inverted?(a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e,a[d++]=f,a[d++]=g):(a[d++]=f,a[d++]=g,a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e)}},setChangeFPS:function(a){this.changeFPS=a;return this},setSpriteTransformation:function(a){this.transformation=a;switch(a){case this.TR_FLIP_HORIZONTAL:this.paint=this.paintInvertedH;break;case this.TR_FLIP_VERTICAL:this.paint=this.paintInvertedV;break;case this.TR_FLIP_ALL:this.paint=this.paintInvertedHV;break;case this.TR_FIXED_TO_SIZE:this.paint= -this.paintScaled;break;case this.TR_TILE:this.paint=this.paintTiled;break;default:this.paint=this.paintN}return this},setAnimationImageIndex:function(a){this.animationImageIndex=a;this.spriteIndex=a[0];return this},setSpriteIndex:function(a){this.spriteIndex=a;return this},setSpriteIndexAtTime:function(a){if(this.animationImageIndex.length>1)this.prevAnimationTime===-1?(this.prevAnimationTime=a,this.spriteIndex=0):(a-=this.prevAnimationTime,a/=this.changeFPS,a%=this.animationImageIndex.length,this.spriteIndex= -this.animationImageIndex[Math.floor(a)])},getMapInfo:function(a){return this.mapInfo[a]},initializeFromMap:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b)d=b[c],d=new CAAT.SpriteImageHelper(d.x,d.y,d.width,d.height,a.width,a.height),this.mapInfo[c]=d,e||this.setAnimationImageIndex([c]),e++;return this},initializeAsGlyphDesigner:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b){var f=b[c];d=new CAAT.SpriteImageHelper(f.x,f.y,f.width,f.height,a.width,a.height);d.xoffset=typeof f.xoffset=== -"undefined"?0:f.xoffset;d.yoffset=typeof f.yoffset==="undefined"?0:f.yoffset;d.xadvance=typeof f.xadvance==="undefined"?f.width:f.xadvance;this.mapInfo[c]=d;e||this.setAnimationImageIndex([c]);e++}return this},initializeAsFontMap:function(a,b){this.initialize(a,1,1);for(var c,d=0,e=0;e>0,f=0;fa&&(a=c)}return this.fontHeight=a},drawString:function(a,b,c,d){for(var e, -f,g=b.split(""),b=0;b=this.duration?(this.remove=true,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, -b,this);return this},reset:function(a){this.remove=false;this.startTime=a;this.scene.ensureTimerTask(this);return this},cancel:function(){this.remove=true;null!=this.callback_cancel&&this.callback_cancel(this.scene.time,this.scene.time-this.startTime,this);return this}}})();(function(){CAAT.Scene=function(){CAAT.Scene.superclass.constructor.call(this);this.timerList=[];this.fillStyle=null;return this};CAAT.Scene.prototype={easeContainerBehaviour:null,easeContainerBehaviourListener:null,easeIn:false,EASE_ROTATION:1,EASE_SCALE:2,EASE_TRANSLATE:3,timerList:null,timerSequence:0,paused:false,isPaused:function(){return this.paused},setPaused:function(a){this.paused=a},checkTimers:function(a){for(var b=this.timerList,c=b.length-1;c>=0;)b[c].remove||b[c].checkTask(a),c--},ensureTimerTask:function(a){this.hasTimer(a)|| -this.timerList.push(a);return this},hasTimer:function(a){for(var b=this.timerList,c=b.length-1;c>=0;){if(b[c]===a)return true;c--}return false},createTimer:function(a,b,c,d,e){a=(new CAAT.TimerTask).create(a,b,c,d,e);a.taskId=this.timerSequence++;a.sceneTime=this.time;a.scene=this;this.timerList.push(a);return a},removeExpiredTimers:function(){var a,b=this.timerList;for(a=0;a4&&(c=4);switch(c){case CAAT.Actor.prototype.ANCHOR_TOP:d?f.setPath((new CAAT.Path).setLinear(0,-this.height,0,0)):f.setPath((new CAAT.Path).setLinear(0,0,0,-this.height));break;case CAAT.Actor.prototype.ANCHOR_BOTTOM:d?f.setPath((new CAAT.Path).setLinear(0,this.height,0,0)):f.setPath((new CAAT.Path).setLinear(0,0,0,this.height));break;case CAAT.Actor.prototype.ANCHOR_LEFT:d?f.setPath((new CAAT.Path).setLinear(-this.width,0,0,0)):f.setPath((new CAAT.Path).setLinear(0,0,-this.width,0)); -break;case CAAT.Actor.prototype.ANCHOR_RIGHT:d?f.setPath((new CAAT.Path).setLinear(this.width,0,0,0)):f.setPath((new CAAT.Path).setLinear(0,0,this.width,0))}b&&this.createAlphaBehaviour(a,d);this.easeContainerBehaviour.addBehavior(f);this.easeContainerBehaviour.setFrameTime(this.time,a);this.easeContainerBehaviour.addListener(this);this.emptyBehaviorList();CAAT.Scene.superclass.addBehavior.call(this,this.easeContainerBehaviour)},easeScaleIn:function(a,b,c,d,e){this.easeScale(a,b,c,d,true,e);this.easeIn= -true},easeScaleOut:function(a,b,c,d,e){this.easeScale(a,b,c,d,false,e);this.easeIn=false},easeScale:function(a,b,c,d,e,f){this.easeContainerBehaviour=new CAAT.ContainerBehavior;var g=0,h=0,i=0,j=0;switch(d){case CAAT.Actor.prototype.ANCHOR_TOP_LEFT:case CAAT.Actor.prototype.ANCHOR_TOP_RIGHT:case CAAT.Actor.prototype.ANCHOR_BOTTOM_LEFT:case CAAT.Actor.prototype.ANCHOR_BOTTOM_RIGHT:case CAAT.Actor.prototype.ANCHOR_CENTER:j=i=1;break;case CAAT.Actor.prototype.ANCHOR_TOP:case CAAT.Actor.prototype.ANCHOR_BOTTOM:i= +f,g=b.split(""),b=0;b=this.duration?(this.remove=!0,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, +b,this);return this},reset:function(a){this.remove=!1;this.startTime=a;this.scene.ensureTimerTask(this);return this},cancel:function(){this.remove=!0;null!=this.callback_cancel&&this.callback_cancel(this.scene.time,this.scene.time-this.startTime,this);return this}}})();(function(){CAAT.Scene=function(){CAAT.Scene.superclass.constructor.call(this);this.timerList=[];this.fillStyle=null;return this};CAAT.Scene.prototype={easeContainerBehaviour:null,easeContainerBehaviourListener:null,easeIn:!1,EASE_ROTATION:1,EASE_SCALE:2,EASE_TRANSLATE:3,timerList:null,timerSequence:0,paused:!1,name:"CAAT.Scene",isPaused:function(){return this.paused},setPaused:function(a){this.paused=a},checkTimers:function(a){for(var b=this.timerList,c=b.length-1;0<=c;)b[c].remove||b[c].checkTask(a), +c--},ensureTimerTask:function(a){this.hasTimer(a)||this.timerList.push(a);return this},hasTimer:function(a){for(var b=this.timerList,c=b.length-1;0<=c;){if(b[c]===a)return!0;c--}return!1},createTimer:function(a,b,c,d,e){a=(new CAAT.TimerTask).create(a,b,c,d,e);a.taskId=this.timerSequence++;a.sceneTime=this.time;a.scene=this;this.timerList.push(a);return a},removeExpiredTimers:function(){var a,b=this.timerList;for(a=0;ac?c=1:4=this.inputList.length&&(b=this.inputList.length-1);b=this.inputList[b];typeof c==="undefined"||c>=b.length?b.push(a):c<=0?b.unshift(a):b.splice(c,0,a);return this},emptyInputList:function(a){a<0?a=0:a>=this.inputList.length&&(a=this.inputList.length-1);this.inputList[a]=[];return this},removeActorFromInputList:function(a,b){if(typeof b==="undefined"){var c,d;for(c=0;c=this.inputList.length&&(b=this.inputList.length-1);e=this.inputList[b];for(d=0;dMath.random()?1:-1);break;case CAAT.Actor.prototype.ANCHOR_TOP_LEFT:case CAAT.Actor.prototype.ANCHOR_TOP_RIGHT:case CAAT.Actor.prototype.ANCHOR_BOTTOM_LEFT:case CAAT.Actor.prototype.ANCHOR_BOTTOM_RIGHT:f=Math.PI/2*(0.5>Math.random()?1:-1);break;default:alert("rot anchor ?? "+c)}if(!1===d)var h=f,f=g,g=h;b&&this.createAlphaBehaviour(a,d);b=this.getAnchorPercent(c);f=(new CAAT.RotateBehavior).setFrameTime(0,a).setValues(f,g,b.x,b.y);e&&f.setInterpolator(e);this.easeContainerBehaviour.addBehavior(f); +this.easeContainerBehaviour.setFrameTime(this.time,a);this.easeContainerBehaviour.addListener(this);this.emptyBehaviorList();CAAT.Scene.superclass.addBehavior.call(this,this.easeContainerBehaviour)},setEaseListener:function(a){this.easeContainerBehaviourListener=a},behaviorExpired:function(){this.easeContainerBehaviourListener.easeEnd(this,this.easeIn)},activated:function(){},setExpired:function(a){this.expired=a},paint:function(a){this.fillStyle&&(a=a.crc,a.fillStyle=this.fillStyle,a.fillRect(0, +0,this.width,this.height))},findActorAtPosition:function(a){var b,c,d=new CAAT.Point;if(this.inputList){var e=this.inputList;for(b=0;bb?b=0:b>=this.inputList.length&&(b=this.inputList.length-1);b=this.inputList[b];"undefined"===typeof c||c>=b.length?b.push(a):0>=c?b.unshift(a):b.splice(c,0,a);return this},emptyInputList:function(a){0>a?a=0:a>=this.inputList.length&&(a=this.inputList.length-1);this.inputList[a]=[];return this},removeActorFromInputList:function(a,b){if("undefined"===typeof b){var c,d;for(c=0;cb?b= +0:b>=this.inputList.length&&(b=this.inputList.length-1);e=this.inputList[b];for(d=0;dthis.bounds.right)a.position.x=this.bounds.left+e;else if(b&1&&c+fthis.bounds.bottom)a.position.y=this.bounds.top-e;else if(b&4&&d+f=this.bounds.right)a.position.x=a.position.x=this.bounds.right-e;else if(b&8&&c-ethis.bounds.bottom)a.position.y=this.bounds.bottom-e;else if(b&16&&d-ed?e=-1:c=0;a--)this.allCircles[a]===null&&this.allCircles.splice(a,1)},initialize:function(a){if(a)for(var b in a)this[b]=a[b];return this}}})();(function(){CAAT.modules.LocalStorage=function(){return this};CAAT.modules.LocalStorage.prototype={save:function(a,b){try{localStorage.setItem(a,JSON.stringify(b))}catch(c){}return this},load:function(a){try{return JSON.parse(localStorage.getItem(a))}catch(b){return null}},remove:function(a){try{localStorage.removeItem(a)}catch(b){}return this}}})();(function(){CAAT.modules.ImageUtil={};CAAT.modules.ImageUtil.createAlphaSpriteSheet=function(a,b,c,d,e){if(a>=0;var d=true,e=true,f=true,g=true;if(typeof c!=="undefined"){if(typeof c.top!== -"undefined")d=c.top;if(typeof c.bottom!=="undefined")e=c.bottom;if(typeof c.left!=="undefined")f=c.left;if(typeof c.right!=="undefined")g=c.right}c=document.createElement("canvas");c.width=a.width;c.height=a.height;var h=c.getContext("2d");h.fillStyle="rgba(0,0,0,0)";h.fillRect(0,0,a.width,a.height);h.drawImage(a,0,0);var i=h.getImageData(0,0,a.width,a.height).data,j,a=0,k=c.height-1,l=0,n=c.width-1,m=false;if(d){for(d=0;db){m=true;break}if(m)break}a= -d}if(e){m=false;for(d=c.height-1;d>=a;d--){for(j=0;jb){m=true;break}if(m)break}k=d}if(f){m=false;for(j=0;jb){m=true;break}if(m)break}l=j}if(g){m=false;for(j=c.width-1;j>=l;j--){for(d=a;d<=k;d++)if(i[d*c.width*4+3+j*4]>b){m=true;break}if(m)break}n=j}if(0===l&&0===a&&c.width-1===n&&c.height-1===k)return c;b=n-l+1;e=k-a+1;f=h.getImageData(l,a,b,e);c.width=b;c.height=e;h=c.getContext("2d");h.putImageData(f,0,0); -return c};CAAT.modules.ImageUtil.createThumb=function(a,b,c,d){var b=b||24,c=c||24,e=document.createElement("canvas");e.width=b;e.height=c;var f=e.getContext("2d");if(d){var g=Math.max(a.width,a.height),d=a.width/g*b,g=a.height/g*c;f.drawImage(a,(b-d)/2,(c-g)/2,d,g)}else f.drawImage(a,0,0,b,c);return e}})();(function(){CAAT.Font=function(){return this};CAAT.Font.prototype={fontSize:10,fontSizeUnit:"px",font:"Sans-Serif",fontStyle:"",fillStyle:"#fff",strokeStyle:null,padding:0,image:null,charMap:null,height:0,setPadding:function(a){this.padding=a;return this},setFontStyle:function(a){this.fontStyle=a;return this},setFontSize:function(a){this.fontSize=a;this.fontSizeUnit="px";return this},setFont:function(a){this.font=a;return this},setFillStyle:function(a){this.fillStyle=a;return this},setStrokeStyle:function(a){this.strokeStyle= -a;return this},createDefault:function(a){for(var b="",c=32;c<128;c++)b+=String.fromCharCode(c);return this.create(b,a)},create:function(a,b){this.padding=b;var c=document.createElement("canvas");c.width=1;c.height=1;var d=c.getContext("2d");d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;var e=0,f=[],g,h;for(g=0;g>0)+1)+2*b,f.push(h),e+=h;c.width=e;c.height=this.fontSize*1.5>>0;d=c.getContext("2d"); -d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;d.fillStyle=this.fillStyle;d.strokeStyle=this.strokeStyle;this.charMap={};for(g=e=0;gthis.bounds.right?a.position.x=this.bounds.left+e:b&1&&c+fthis.bounds.bottom? +a.position.y=this.bounds.top-e:b&4&&d+f=this.bounds.right?a.position.x=a.position.x=this.bounds.right-e:b&8&&c-ethis.bounds.bottom?a.position.y=this.bounds.bottom-e:b&16&&d-ed?e=-1:c>0,d=!0,e=!0,f=!0,g=!0;"undefined"!==typeof c&&("undefined"!== +typeof c.top&&(d=c.top),"undefined"!==typeof c.bottom&&(e=c.bottom),"undefined"!==typeof c.left&&(f=c.left),"undefined"!==typeof c.right&&(g=c.right));c=document.createElement("canvas");c.width=a.width;c.height=a.height;var h=c.getContext("2d");h.fillStyle="rgba(0,0,0,0)";h.fillRect(0,0,a.width,a.height);h.drawImage(a,0,0);var i=h.getImageData(0,0,a.width,a.height).data,j,a=0,k=c.height-1,m=0,n=c.width-1,l=!1;if(d){for(d=0;db){l=!0;break}if(l)break}a= +d}if(e){l=!1;for(d=c.height-1;d>=a;d--){for(j=0;jb){l=!0;break}if(l)break}k=d}if(f){l=!1;for(j=0;jb){l=!0;break}if(l)break}m=j}if(g){l=!1;for(j=c.width-1;j>=m;j--){for(d=a;d<=k;d++)if(i[4*d*c.width+3+4*j]>b){l=!0;break}if(l)break}n=j}if(0===m&&0===a&&c.width-1===n&&c.height-1===k)return c;b=n-m+1;e=k-a+1;f=h.getImageData(m,a,b,e);c.width=b;c.height=e;h=c.getContext("2d");h.putImageData(f,0,0);return c};CAAT.modules.ImageUtil.createThumb= +function(a,b,c,d){var b=b||24,c=c||24,e=document.createElement("canvas");e.width=b;e.height=c;var f=e.getContext("2d");if(d){var g=Math.max(a.width,a.height),d=a.width/g*b,g=a.height/g*c;f.drawImage(a,(b-d)/2,(c-g)/2,d,g)}else f.drawImage(a,0,0,b,c);return e}})();(function(){CAAT.Font=function(){return this};CAAT.Font.prototype={fontSize:10,fontSizeUnit:"px",font:"Sans-Serif",fontStyle:"",fillStyle:"#fff",strokeStyle:null,padding:0,image:null,charMap:null,height:0,setPadding:function(a){this.padding=a;return this},setFontStyle:function(a){this.fontStyle=a;return this},setFontSize:function(a){this.fontSize=a;this.fontSizeUnit="px";return this},setFont:function(a){this.font=a;return this},setFillStyle:function(a){this.fillStyle=a;return this},setStrokeStyle:function(a){this.strokeStyle= +a;return this},createDefault:function(a){for(var b="",c=32;128>c;c++)b+=String.fromCharCode(c);return this.create(b,a)},create:function(a,b){this.padding=b;var c=document.createElement("canvas");c.width=1;c.height=1;var d=c.getContext("2d");d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;var e=0,f=[],g,h;for(g=0;g>0)+1)+2*b,h=Math.max(1,(d.measureText(a.charAt(g)).width>>0)+1),f.push(h),e+= +h+2*b;c.width=e;c.height=1.5*this.fontSize>>0;d=c.getContext("2d");d.textBaseline="top";d.font=this.fontStyle+" "+this.fontSize+""+this.fontSizeUnit+" "+this.font;d.fillStyle=this.fillStyle;d.strokeStyle=this.strokeStyle;this.charMap={};e=b;for(g=0;g1||a<0)a%=1;a<0&&(a=1+a);this.newPosition.set(this.points[0].x+(this.points[1].x-this.points[0].x)*a,this.points[0].y+(this.points[1].y-this.points[0].y)*a);return this.newPosition},getPositionFromLength:function(a){return this.getPosition(a/this.length)},initialPositionX:function(){return this.points[0].x},finalPositionX:function(){return this.points[1].x},paint:function(a,b){var c=a.ctx;c.save();c.strokeStyle=this.color; -c.beginPath();c.moveTo(this.points[0].x,this.points[0].y);c.lineTo(this.points[1].x,this.points[1].y);c.stroke();if(b)c.globalAlpha=0.5,c.fillStyle="#7f7f00",c.beginPath(),this.drawHandle(c,this.points[0].x,this.points[0].y),this.drawHandle(c,this.points[1].x,this.points[1].y);c.restore()},numControlPoints:function(){return 2},getControlPoint:function(a){if(0===a)return this.points[0];else if(1===a)return this.points[1]},getContour:function(){var a=[];a.push(this.getPosition(0).clone());a.push(this.getPosition(1).clone()); +startCurvePosition:function(){return this.points[0]},getPosition:function(a){if(1a)a%=1;0>a&&(a=1+a);this.newPosition.set(this.points[0].x+(this.points[1].x-this.points[0].x)*a,this.points[0].y+(this.points[1].y-this.points[0].y)*a);return this.newPosition},getPositionFromLength:function(a){return this.getPosition(a/this.length)},initialPositionX:function(){return this.points[0].x},finalPositionX:function(){return this.points[1].x},paint:function(a,b){var c=a.ctx;c.save();c.strokeStyle=this.color; +c.beginPath();c.moveTo(this.points[0].x,this.points[0].y);c.lineTo(this.points[1].x,this.points[1].y);c.stroke();b&&(c.globalAlpha=0.5,c.fillStyle="#7f7f00",c.beginPath(),this.drawHandle(c,this.points[0].x,this.points[0].y),this.drawHandle(c,this.points[1].x,this.points[1].y));c.restore()},numControlPoints:function(){return 2},getControlPoint:function(a){if(0===a)return this.points[0];if(1===a)return this.points[1]},getContour:function(){var a=[];a.push(this.getPosition(0).clone());a.push(this.getPosition(1).clone()); return a}};extend(CAAT.LinearPath,CAAT.PathSegment)})(); (function(){CAAT.CurvePath=function(){CAAT.CurvePath.superclass.constructor.call(this);this.newPosition=new CAAT.Point(0,0,0);return this};CAAT.CurvePath.prototype={curve:null,newPosition:null,applyAsPath:function(a){this.curve.applyAsPath(a);return this},setPoint:function(a,b){this.curve&&this.curve.setPoint(a,b)},setPoints:function(a){var b=new CAAT.Bezier;b.setPoints(a);this.curve=b;return this},setQuadric:function(a,b,c,d,e,f){var g=new CAAT.Bezier;g.setQuadric(a,b,c,d,e,f);this.curve=g;this.updatePath(); -return this},setCubic:function(a,b,c,d,e,f,g,h){var i=new CAAT.Bezier;i.setCubic(a,b,c,d,e,f,g,h);this.curve=i;this.updatePath();return this},updatePath:function(){this.curve.update();this.length=this.curve.getLength();this.curve.getBoundingBox(this.bbox);return this},getPosition:function(a){if(a>1||a<0)a%=1;a<0&&(a=1+a);this.curve.solve(this.newPosition,a);return this.newPosition},getPositionFromLength:function(a){this.curve.solve(this.newPosition,a/this.length);return this.newPosition},initialPositionX:function(){return this.curve.coordlist[0].x}, +return this},setCubic:function(a,b,c,d,e,f,g,h){var i=new CAAT.Bezier;i.setCubic(a,b,c,d,e,f,g,h);this.curve=i;this.updatePath();return this},updatePath:function(){this.curve.update();this.length=this.curve.getLength();this.curve.getBoundingBox(this.bbox);return this},getPosition:function(a){if(1a)a%=1;0>a&&(a=1+a);this.curve.solve(this.newPosition,a);return this.newPosition},getPositionFromLength:function(a){this.curve.solve(this.newPosition,a/this.length);return this.newPosition},initialPositionX:function(){return this.curve.coordlist[0].x}, finalPositionX:function(){return this.curve.coordlist[this.curve.coordlist.length-1].x},paint:function(a,b){this.curve.drawHandles=b;a.ctx.strokeStyle=this.color;this.curve.paint(a,b)},numControlPoints:function(){return this.curve.coordlist.length},getControlPoint:function(a){return this.curve.coordlist[a]},endCurvePosition:function(){return this.curve.endCurvePosition()},startCurvePosition:function(){return this.curve.startCurvePosition()},getContour:function(a){for(var b=[],c=0;c<=a;c++)b.push({x:c/ a,y:this.getPosition(c/a).y});return b}};extend(CAAT.CurvePath,CAAT.PathSegment,null)})(); -(function(){CAAT.ShapePath=function(){CAAT.ShapePath.superclass.constructor.call(this);this.points=[];this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.newPosition=new CAAT.Point;return this};CAAT.ShapePath.prototype={points:null,length:-1,cw:true,bbox:null,newPosition:null,applyAsPath:function(a){a=a.ctx;this.cw?(a.lineTo(this.points[0].x,this.points[0].y),a.lineTo(this.points[1].x, -this.points[1].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[4].x,this.points[4].y)):(a.lineTo(this.points[4].x,this.points[4].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[1].x,this.points[1].y),a.lineTo(this.points[0].x,this.points[0].y));return this},setPoint:function(a,b){b>=0&&b1||a<0)a%=1;a<0&&(a=1+a);if(-1===this.length)this.newPosition.set(0,0);else{var b=this.bbox.width/this.length,c=this.bbox.height/this.length,d=0,e,f=0;this.cw?(e=[0,1,2,3,4],b=[b,c, +(function(){CAAT.ShapePath=function(){CAAT.ShapePath.superclass.constructor.call(this);this.points=[];this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.points.push(new CAAT.Point);this.newPosition=new CAAT.Point;return this};CAAT.ShapePath.prototype={points:null,length:-1,cw:!0,bbox:null,newPosition:null,applyAsPath:function(a){a=a.ctx;this.cw?(a.lineTo(this.points[0].x,this.points[0].y),a.lineTo(this.points[1].x, +this.points[1].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[4].x,this.points[4].y)):(a.lineTo(this.points[4].x,this.points[4].y),a.lineTo(this.points[3].x,this.points[3].y),a.lineTo(this.points[2].x,this.points[2].y),a.lineTo(this.points[1].x,this.points[1].y),a.lineTo(this.points[0].x,this.points[0].y));return this},setPoint:function(a,b){0<=b&&ba)a%=1;0>a&&(a=1+a);if(-1===this.length)this.newPosition.set(0,0);else{var b=this.bbox.width/this.length,c=this.bbox.height/this.length,d=0,e,f=0;this.cw?(e=[0,1,2,3,4],b=[b,c, b,c]):(e=[4,3,2,1,0],b=[c,b,c,b]);for(;fa;a++)this.bbox.union(this.points[a].x,this.points[a].y);this.length=2*this.bbox.width+2*this.bbox.height;this.points[0].x=this.bbox.x;this.points[0].y=this.bbox.y;this.points[1].x=this.bbox.x+this.bbox.width;this.points[1].y=this.bbox.y;this.points[2].x= this.bbox.x+this.bbox.width;this.points[2].y=this.bbox.y+this.bbox.height;this.points[3].x=this.bbox.x;this.points[3].y=this.bbox.y+this.bbox.height;this.points[4].x=this.bbox.x;this.points[4].y=this.bbox.y;return this}};extend(CAAT.ShapePath,CAAT.PathSegment)})(); -(function(){CAAT.Path=function(){CAAT.Path.superclass.constructor.call(this);this.newPosition=new CAAT.Point(0,0,0);this.pathSegments=[];this.behaviorList=[];this.matrix=new CAAT.Matrix;this.tmpMatrix=new CAAT.Matrix;return this};CAAT.Path.prototype={pathSegments:null,pathSegmentDurationTime:null,pathSegmentStartTime:null,newPosition:null,pathLength:-1,beginPathX:-1,beginPathY:-1,trackPathX:-1,trackPathY:-1,ax:-1,ay:-1,point:[],interactive:true,behaviorList:null,rb_angle:0,rb_rotateAnchorX:0.5,rb_rotateAnchorY:0.5, +(function(){CAAT.Path=function(){CAAT.Path.superclass.constructor.call(this);this.newPosition=new CAAT.Point(0,0,0);this.pathSegments=[];this.behaviorList=[];this.matrix=new CAAT.Matrix;this.tmpMatrix=new CAAT.Matrix;return this};CAAT.Path.prototype={pathSegments:null,pathSegmentDurationTime:null,pathSegmentStartTime:null,newPosition:null,pathLength:-1,beginPathX:-1,beginPathY:-1,trackPathX:-1,trackPathY:-1,ax:-1,ay:-1,point:[],interactive:!0,behaviorList:null,rb_angle:0,rb_rotateAnchorX:0.5,rb_rotateAnchorY:0.5, sb_scaleX:1,sb_scaleY:1,sb_scaleAnchorX:0.5,sb_scaleAnchorY:0.5,tAnchorX:0,tAnchorY:0,tb_x:0,tb_y:0,matrix:null,tmpMatrix:null,pathPoints:null,width:0,height:0,clipOffsetX:0,clipOffsetY:0,applyAsPath:function(a){var b=a.ctx;a.modelViewMatrix.transformRenderingContext(b);b.beginPath();b.globalCompositeOperation="source-out";b.moveTo(this.getFirstPathSegment().startCurvePosition().x,this.getFirstPathSegment().startCurvePosition().y);for(var c=0;c1||a<0)a%=1;a<0&&(a=1+a);for(var b=this.pathSegments,c=this.pathSegmentStartTime,d=this.pathSegmentDurationTime,e=0,f=b.length,g,h=this.newPosition,i;e!==f;)if(g=(f+e)/2|0,i=c[g],i<=a&&a<=i+d[g])return a=d[g]?(a-i)/d[g]:0,a=b[g].getPosition(a),h.x=a.x,h.y=a.y,h;else aa)a%=1;0>a&&(a=1+a);for(var b=this.pathSegments,c=this.pathSegmentStartTime,d=this.pathSegmentDurationTime,e=0,f=b.length,g,h=this.newPosition,i;e!==f;){g=(f+e)/2|0;i=c[g];if(i<=a&&a<=i+d[g])return a=d[g]?(a-i)/d[g]:0,a=b[g].getPosition(a),h.x=a.x,h.y=a.y,h;aa&&(a+=this.getLength());for(var b=0,c=0;c0?this.pathSegmentStartTime[c]=this.pathSegmentStartTime[c-1]+this.pathSegmentDurationTime[c-1]:this.pathSegmentStartTime[0]=0,this.pathSegments[c].endPath();this.extractPathPoints();typeof b!=="undefined"&&b(this);return this},press:function(a,b){if(this.interactive){for(var c=CAAT.Curve.prototype.HANDLE_SIZE/2,d=0;d=f.x-c&&b>=f.y-c&&a=f.x-c&&b>=f.y-c&&a=0&&b0.5;this.b2=Math.random()>0.5;this.b3=Math.random()>0.5;this.b4= -Math.random()>0.5;this.spd1=Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1));this.spd2=Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1));this.spd3=Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1));this.spd4=Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1));this.i1=Math.floor((Math.random()*2.4+1)*(Math.random()<0.5?1:-1));this.i2=Math.floor((Math.random()*2.4+1)*(Math.random()<0.5?1:-1));this.i3=Math.floor((Math.random()*2.4+1)*(Math.random()<0.5?1:-1));this.i4=Math.floor((Math.random()* -2.4+1)*(Math.random()<0.5?1:-1))},apply:function(a,b){var c=0;this.tpos1=this.pos1;this.tpos2=this.pos2;for(var d=this.bufferImage,e=this.m_colorMap,f=this.wavetable,g,h=0;ha;a++)this.wavetable.push(Math.floor(32* +(1+Math.cos(2*a*Math.PI/256))));this.pos1=Math.floor(255*Math.random());this.pos2=Math.floor(255*Math.random());this.pos3=Math.floor(255*Math.random());this.pos4=Math.floor(255*Math.random());this.m_colorMap=CAAT.Color.prototype.makeRGBColorRamp(null!==c?c:this.color,256,CAAT.Color.prototype.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY);this.setB();return this},setB:function(){this.b1=0.5Math.random()?1:-1));this.spd2=Math.floor((3*Math.random()+1)*(0.5>Math.random()?1:-1));this.spd3=Math.floor((3*Math.random()+1)*(0.5>Math.random()?1:-1));this.spd4=Math.floor((3*Math.random()+1)*(0.5>Math.random()?1:-1));this.i1=Math.floor((2.4*Math.random()+1)*(0.5>Math.random()?1:-1));this.i2=Math.floor((2.4*Math.random()+1)*(0.5>Math.random()?1:-1));this.i3=Math.floor((2.4*Math.random()+1)*(0.5>Math.random()?1:-1));this.i4=Math.floor((2.4*Math.random()+1)*(0.5>Math.random()? +1:-1))},apply:function(a,b){var c=0;this.tpos1=this.pos1;this.tpos2=this.pos2;for(var d=this.bufferImage,e=this.m_colorMap,f=this.wavetable,g,h=0;h=this.m_radius&&(i=this.m_radius-1);h>=this.m_radius&&(h=this.m_radius-1);var i=this.phong[i][h],j=h=0,k=0;i>=0?(h= -this.m_lightcolor[d][0]*i/128,j=this.m_lightcolor[d][1]*i/128,k=this.m_lightcolor[d][2]*i/128):(i=128+i,h=this.m_lightcolor[d][0],j=this.m_lightcolor[d][1],k=this.m_lightcolor[d][2],h=Math.floor(h+(255-h)*i/128),j=Math.floor(j+(255-j)*i/128),k=Math.floor(k+(255-k)*i/128));e+=h;f+=j;g+=k}e>255&&(e=255);f>255&&(f=255);g>255&&(g=255);d=(c+this.m_tt[b])*4;a[d]=e;a[d+1]=f;a[d+2]=g;a[d+3]=255}},setLightColors:function(a){this.m_lightcolor=a;this.lightPosition=[];for(a=0;ac&&(c=0);this.phong[a][b]=Math.floor(255*c)}},drawColored:function(a){var b,c,d;for(b=0;b=this.m_radius&&(i=this.m_radius-1);h>=this.m_radius&&(h=this.m_radius-1);var i=this.phong[i][h],j=h=0,k=0;0<=i?(h= +this.m_lightcolor[d][0]*i/128,j=this.m_lightcolor[d][1]*i/128,k=this.m_lightcolor[d][2]*i/128):(i=128+i,h=this.m_lightcolor[d][0],j=this.m_lightcolor[d][1],k=this.m_lightcolor[d][2],h=Math.floor(h+(255-h)*i/128),j=Math.floor(j+(255-j)*i/128),k=Math.floor(k+(255-k)*i/128));e+=h;f+=j;g+=k}255> -1;break;case 2:f=this.height-1}switch(this.m_alignv){case 0:g=0;break;case 1:g=this.width>>1;break;case 2:g=this.width-1}for(var c=(this.width>>1<<8)-e*g+b*f&65535,f=(this.height>>1<<8)-b*g-e*f&65535,g=this.sourceImageData.width,h=this.sourceImageData.data,i=this.bufferImage,j,k,l;d>this.shift&this.mask)*g+(k>>this.shift&this.mask),j<<=2,i[d++]=h[j++],i[d++]=h[j++],i[d++]=h[j++],i[d++]=h[j++],k+=e,l+=b;a+=this.distortion;c-=b;f+= -e-a}},apply:function(a,b){null!==this.sourceImageData&&this.rotoZoom(a,b);return CAAT.IMRotoZoom.superclass.apply.call(this,a,b)},setCenter:function(){var a=Math.random();this.m_alignv=a<0.33?0:a<0.66?1:2;a=Math.random();this.m_alignh=a<0.33?0:a<0.66?1:2}};extend(CAAT.IMRotoZoom,CAAT.ImageProcessor,null)})();(function(){CAAT.Program=function(a){this.gl=a;return this};CAAT.Program.prototype={shaderProgram:null,gl:null,setAlpha:function(){},getShader:function(a,b,c){if(b==="x-shader/x-fragment")b=a.createShader(a.FRAGMENT_SHADER);else if(b==="x-shader/x-vertex")b=a.createShader(a.VERTEX_SHADER);else return null;a.shaderSource(b,c);a.compileShader(b);return!a.getShaderParameter(b,a.COMPILE_STATUS)?(alert(a.getShaderInfoLog(b)),null):b},getDomShader:function(a,b){var c=document.getElementById(b);if(!c)return null; -for(var d="",e=c.firstChild;e;)e.nodeType===3&&(d+=e.textContent),e=e.nextSibling;if(c.type==="x-shader/x-fragment")c=a.createShader(a.FRAGMENT_SHADER);else if(c.type==="x-shader/x-vertex")c=a.createShader(a.VERTEX_SHADER);else return null;a.shaderSource(c,d);a.compileShader(c);return!a.getShaderParameter(c,a.COMPILE_STATUS)?(alert(a.getShaderInfoLog(c)),null):c},initialize:function(){return this},getFragmentShader:function(){return null},getVertexShader:function(){return null},create:function(){var a= -this.gl;this.shaderProgram=a.createProgram();a.attachShader(this.shaderProgram,this.getVertexShader());a.attachShader(this.shaderProgram,this.getFragmentShader());a.linkProgram(this.shaderProgram);a.useProgram(this.shaderProgram);return this},setMatrixUniform:function(a){this.gl.uniformMatrix4fv(this.shaderProgram.pMatrixUniform,false,new Float32Array(a.flatten()))},useProgram:function(){this.gl.useProgram(this.shaderProgram);return this}}})(); +255;this.shift=8;break;case 128:this.mask=127;this.shift=7;break;case 64:this.mask=63;this.shift=6;break;case 32:this.mask=31;this.shift=5;break;case 16:this.mask=15;this.shift=4;break;case 8:this.mask=7,this.shift=3}this.setCenter();return this},rotoZoom:function(){var a=(new Date).getTime(),b=2*Math.PI*Math.cos(1.0E-4*a),c=600+550*Math.sin(2.0E-4*a),a=this.distortion,d=0,e=Math.floor(Math.cos(b)*c),b=Math.floor(Math.sin(b)*c),f=0,g=0;switch(this.m_alignh){case 0:f=0;break;case 1:f=this.height>> +1;break;case 2:f=this.height-1}switch(this.m_alignv){case 0:g=0;break;case 1:g=this.width>>1;break;case 2:g=this.width-1}for(var c=(this.width>>1<<8)-e*g+b*f&65535,f=(this.height>>1<<8)-b*g-e*f&65535,g=this.sourceImageData.width,h=this.sourceImageData.data,i=this.bufferImage,j,k,m;d<4*this.width*this.height;){k=c;m=f;for(var n=0;n>this.shift&this.mask)*g+(k>>this.shift&this.mask),j<<=2,i[d++]=h[j++],i[d++]=h[j++],i[d++]=h[j++],i[d++]=h[j++],k+=e,m+=b;a+=this.distortion;c-=b;f+= +e-a}},apply:function(a,b){null!==this.sourceImageData&&this.rotoZoom(a,b);return CAAT.IMRotoZoom.superclass.apply.call(this,a,b)},setCenter:function(){var a=Math.random();this.m_alignv=0.33>a?0:0.66>a?1:2;a=Math.random();this.m_alignh=0.33>a?0:0.66>a?1:2}};extend(CAAT.IMRotoZoom,CAAT.ImageProcessor,null)})();(function(){CAAT.Program=function(a){this.gl=a;return this};CAAT.Program.prototype={shaderProgram:null,gl:null,setAlpha:function(){},getShader:function(a,b,c){if("x-shader/x-fragment"===b)b=a.createShader(a.FRAGMENT_SHADER);else if("x-shader/x-vertex"===b)b=a.createShader(a.VERTEX_SHADER);else return null;a.shaderSource(b,c);a.compileShader(b);return!a.getShaderParameter(b,a.COMPILE_STATUS)?(alert(a.getShaderInfoLog(b)),null):b},getDomShader:function(a,b){var c=document.getElementById(b);if(!c)return null; +for(var d="",e=c.firstChild;e;)3===e.nodeType&&(d+=e.textContent),e=e.nextSibling;if("x-shader/x-fragment"===c.type)c=a.createShader(a.FRAGMENT_SHADER);else if("x-shader/x-vertex"===c.type)c=a.createShader(a.VERTEX_SHADER);else return null;a.shaderSource(c,d);a.compileShader(c);return!a.getShaderParameter(c,a.COMPILE_STATUS)?(alert(a.getShaderInfoLog(c)),null):c},initialize:function(){return this},getFragmentShader:function(){return null},getVertexShader:function(){return null},create:function(){var a= +this.gl;this.shaderProgram=a.createProgram();a.attachShader(this.shaderProgram,this.getVertexShader());a.attachShader(this.shaderProgram,this.getFragmentShader());a.linkProgram(this.shaderProgram);a.useProgram(this.shaderProgram);return this},setMatrixUniform:function(a){this.gl.uniformMatrix4fv(this.shaderProgram.pMatrixUniform,!1,new Float32Array(a.flatten()))},useProgram:function(){this.gl.useProgram(this.shaderProgram);return this}}})(); (function(){CAAT.ColorProgram=function(a){CAAT.ColorProgram.superclass.constructor.call(this,a);return this};CAAT.ColorProgram.prototype={colorBuffer:null,vertexPositionBuffer:null,vertexPositionArray:null,getFragmentShader:function(){return this.getShader(this.gl,"x-shader/x-fragment","#ifdef GL_ES \nprecision highp float; \n#endif \nvarying vec4 color; \nvoid main(void) { \n gl_FragColor = color;\n}\n")},getVertexShader:function(){return this.getShader(this.gl,"x-shader/x-vertex","attribute vec3 aVertexPosition; \nattribute vec4 aColor; \nuniform mat4 uPMatrix; \nvarying vec4 color; \nvoid main(void) { \ngl_Position = uPMatrix * vec4(aVertexPosition, 1.0); \ncolor= aColor; \n}\n")}, initialize:function(){this.shaderProgram.vertexPositionAttribute=this.gl.getAttribLocation(this.shaderProgram,"aVertexPosition");this.gl.enableVertexAttribArray(this.shaderProgram.vertexPositionAttribute);this.shaderProgram.vertexColorAttribute=this.gl.getAttribLocation(this.shaderProgram,"aColor");this.gl.enableVertexAttribArray(this.shaderProgram.vertexColorAttribute);this.shaderProgram.pMatrixUniform=this.gl.getUniformLocation(this.shaderProgram,"uPMatrix");this.useProgram();this.colorBuffer=this.gl.createBuffer(); -this.setColor([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]);this.vertexPositionBuffer=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexPositionBuffer);this.vertexPositionArray=new Float32Array(6144);this.gl.bufferData(this.gl.ARRAY_BUFFER,this.vertexPositionArray,this.gl.DYNAMIC_DRAW);this.gl.vertexAttribPointer(this.shaderProgram.vertexPositionAttribute,3,this.gl.FLOAT,false,0,0);return CAAT.ColorProgram.superclass.initialize.call(this)},setColor:function(a){this.gl.bindBuffer(this.gl.ARRAY_BUFFER, -this.colorBuffer);this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(a),this.gl.STATIC_DRAW);this.gl.vertexAttribPointer(this.shaderProgram.vertexColorAttribute,this.colorBuffer,this.gl.FLOAT,false,0,0)}};extend(CAAT.ColorProgram,CAAT.Program,null)})(); +this.setColor([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]);this.vertexPositionBuffer=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexPositionBuffer);this.vertexPositionArray=new Float32Array(6144);this.gl.bufferData(this.gl.ARRAY_BUFFER,this.vertexPositionArray,this.gl.DYNAMIC_DRAW);this.gl.vertexAttribPointer(this.shaderProgram.vertexPositionAttribute,3,this.gl.FLOAT,!1,0,0);return CAAT.ColorProgram.superclass.initialize.call(this)},setColor:function(a){this.gl.bindBuffer(this.gl.ARRAY_BUFFER, +this.colorBuffer);this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(a),this.gl.STATIC_DRAW);this.gl.vertexAttribPointer(this.shaderProgram.vertexColorAttribute,this.colorBuffer,this.gl.FLOAT,!1,0,0)}};extend(CAAT.ColorProgram,CAAT.Program,null)})(); (function(){CAAT.TextureProgram=function(a){CAAT.TextureProgram.superclass.constructor.call(this,a);return this};CAAT.TextureProgram.prototype={vertexPositionBuffer:null,vertexPositionArray:null,vertexUVBuffer:null,vertexUVArray:null,vertexIndexBuffer:null,linesBuffer:null,prevAlpha:-1,prevR:-1,prevG:-1,prevB:-1,prevA:-1,prevTexture:null,getFragmentShader:function(){return this.getShader(this.gl,"x-shader/x-fragment","#ifdef GL_ES \nprecision highp float; \n#endif \nvarying vec2 vTextureCoord; \nuniform sampler2D uSampler; \nuniform float alpha; \nuniform bool uUseColor;\nuniform vec4 uColor;\nvoid main(void) { \nif ( uUseColor ) {\n gl_FragColor= vec4(uColor.r*alpha, uColor.g*alpha, uColor.b*alpha, uColor.a*alpha);\n} else { \n vec4 textureColor= texture2D(uSampler, vec2(vTextureCoord)); \n gl_FragColor = vec4(textureColor.r*alpha, textureColor.g*alpha, textureColor.b*alpha, textureColor.a * alpha ); \n}\n}\n")}, getVertexShader:function(){return this.getShader(this.gl,"x-shader/x-vertex","attribute vec3 aVertexPosition; \nattribute vec2 aTextureCoord; \nuniform mat4 uPMatrix; \nvarying vec2 vTextureCoord; \nvoid main(void) { \ngl_Position = uPMatrix * vec4(aVertexPosition, 1.0); \nvTextureCoord = aTextureCoord;\n}\n")},useProgram:function(){CAAT.TextureProgram.superclass.useProgram.call(this);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexPositionBuffer);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexUVBuffer); -this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.vertexIndexBuffer)},initialize:function(){var a;this.linesBuffer=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.linesBuffer);var b=[];for(a=0;a<1024;a++)b[a]=a;this.linesBufferArray=new Uint16Array(b);this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,this.linesBufferArray,this.gl.DYNAMIC_DRAW);this.shaderProgram.vertexPositionAttribute=this.gl.getAttribLocation(this.shaderProgram,"aVertexPosition");this.gl.enableVertexAttribArray(this.shaderProgram.vertexPositionAttribute); +this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.vertexIndexBuffer)},initialize:function(){var a;this.linesBuffer=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.linesBuffer);var b=[];for(a=0;1024>a;a++)b[a]=a;this.linesBufferArray=new Uint16Array(b);this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,this.linesBufferArray,this.gl.DYNAMIC_DRAW);this.shaderProgram.vertexPositionAttribute=this.gl.getAttribLocation(this.shaderProgram,"aVertexPosition");this.gl.enableVertexAttribArray(this.shaderProgram.vertexPositionAttribute); this.shaderProgram.textureCoordAttribute=this.gl.getAttribLocation(this.shaderProgram,"aTextureCoord");this.gl.enableVertexAttribArray(this.shaderProgram.textureCoordAttribute);this.shaderProgram.pMatrixUniform=this.gl.getUniformLocation(this.shaderProgram,"uPMatrix");this.shaderProgram.samplerUniform=this.gl.getUniformLocation(this.shaderProgram,"uSampler");this.shaderProgram.alphaUniform=this.gl.getUniformLocation(this.shaderProgram,"alpha");this.shaderProgram.useColor=this.gl.getUniformLocation(this.shaderProgram, -"uUseColor");this.shaderProgram.color=this.gl.getUniformLocation(this.shaderProgram,"uColor");this.setAlpha(1);this.setUseColor(false);this.vertexPositionBuffer=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexPositionBuffer);this.vertexPositionArray=new Float32Array(49152);this.gl.bufferData(this.gl.ARRAY_BUFFER,this.vertexPositionArray,this.gl.DYNAMIC_DRAW);this.gl.vertexAttribPointer(this.shaderProgram.vertexPositionAttribute,3,this.gl.FLOAT,false,0,0);this.vertexUVBuffer= -this.gl.createBuffer();this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexUVBuffer);this.vertexUVArray=new Float32Array(32768);this.gl.bufferData(this.gl.ARRAY_BUFFER,this.vertexUVArray,this.gl.DYNAMIC_DRAW);this.gl.vertexAttribPointer(this.shaderProgram.textureCoordAttribute,2,this.gl.FLOAT,false,0,0);this.vertexIndexBuffer=this.gl.createBuffer();this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.vertexIndexBuffer);b=[];for(a=0;a<4096;a++)b.push(0+a*4),b.push(1+a*4),b.push(2+a*4),b.push(0+a*4), -b.push(2+a*4),b.push(3+a*4);this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(b),this.gl.DYNAMIC_DRAW);return CAAT.TextureProgram.superclass.initialize.call(this)},setUseColor:function(a,b,c,d,e){this.gl.uniform1i(this.shaderProgram.useColor,a?1:0);if(a&&(this.prevA!==e||this.prevR!==b||this.prevG!==c||this.prevB!==d))this.gl.uniform4f(this.shaderProgram.color,b,c,d,e),this.prevA=e,this.prevR=b,this.prevG=c,this.prevB=d},setTexture:function(a){if(this.prevTexture!==a){var b=this.gl; -b.activeTexture(b.TEXTURE0);b.bindTexture(b.TEXTURE_2D,a);b.uniform1i(this.shaderProgram.samplerUniform,0);this.prevTexture=a}return this},updateVertexBuffer:function(a){var b=this.gl;b.bindBuffer(b.ARRAY_BUFFER,this.vertexPositionBuffer);b.bufferSubData(b.ARRAY_BUFFER,0,a);return this},updateUVBuffer:function(a){var b=this.gl;b.bindBuffer(b.ARRAY_BUFFER,this.vertexUVBuffer);b.bufferSubData(b.ARRAY_BUFFER,0,a);return this},setAlpha:function(a){if(this.prevAlpha!==a)this.gl.uniform1f(this.shaderProgram.alphaUniform, -a),this.prevAlpha=a;return this},drawLines:function(a,b,c,d,e,f,g){var h=this.gl;this.setAlpha(f);h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.linesBuffer);h.lineWidth(g);this.updateVertexBuffer(a);this.setUseColor(true,c,d,e,1);h.drawElements(h.LINES,b,h.UNSIGNED_SHORT,0);this.setAlpha(1);this.setUseColor(false);h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.vertexIndexBuffer)},drawPolylines:function(a,b,c,d,e,f,g){var h=this.gl;h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.linesBuffer);h.lineWidth(g);this.setAlpha(f); -this.updateVertexBuffer(a);this.setUseColor(true,c,d,e,1);h.drawElements(h.LINE_STRIP,b,h.UNSIGNED_SHORT,0);this.setAlpha(1);this.setUseColor(false);h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.vertexIndexBuffer)}};extend(CAAT.TextureProgram,CAAT.Program,null)})();function makePerspective(a,b,c,d,e){var a=c*Math.tan(a*Math.PI/360),f=-a;return makeFrustum(f*b,a*b,f,a,c,d,e)}function makeFrustum(a,b,c,d,e,f,g){var h=2*e/(b-a),i=2*e/(d-c),a=(b+a)/(b-a),c=(d+c)/(d-c),d=-(f+e)/(f-e),e=-2*f*e/(f-e);return(new CAAT.Matrix3).initWithMatrix([[h,0,a,-g/2],[0,-i,c,g/2],[0,0,d,e],[0,0,-1,0]])} -function makeOrtho(a,b,c,d,e,f){var g=-(b+a)/(b-a),h=-(d+c)/(d-c),i=-(f+e)/(f-e);return(new CAAT.Matrix3).initWithMatrix([[2/(b-a),0,0,g],[0,2/(d-c),0,h],[0,0,-2/(f-e),i],[0,0,0,1]])};(function(){CAAT.GLTextureElement=function(){return this};CAAT.GLTextureElement.prototype={inverted:false,image:null,u:0,v:0,glTexture:null}})(); -(function(){CAAT.GLTextureScan=function(a){this.freeChunks=[{position:0,size:a||1024}];return this};CAAT.GLTextureScan.prototype={freeChunks:null,findWhereFits:function(a){if(this.freeChunks.length===0)return[];var b=[],c;for(c=0;c0&&this.freeChunks.splice(c++,0,{position:e,size:f});h>0&&this.freeChunks.splice(c,0,{position:g,size:h});return true}}return false},log:function(a){if(0===this.freeChunks.length)CAAT.log("index "+a+" empty");else{for(var a="index "+a,b=0;bthis.width||b>this.height)return null;for(var c,d,e=0;e<=this.scanMapHeight-b;){var f=null;for(c=false;e<=this.scanMapHeight-b;e++)if(f=this.scanMap[e].findWhereFits(a),null!== -f&&f.length>0){c=true;break}if(c){for(d=0;db.width?-1:0;else if(c.criteria==="height")return a.heightb.height?-1:0;return fg?-1:0});for(b=0;ba;a++)b.push(0+4*a),b.push(1+4*a),b.push(2+4*a),b.push(0+4*a),b.push(2+4*a),b.push(3+4* +a);this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(b),this.gl.DYNAMIC_DRAW);return CAAT.TextureProgram.superclass.initialize.call(this)},setUseColor:function(a,b,c,d,e){this.gl.uniform1i(this.shaderProgram.useColor,a?1:0);if(a&&(this.prevA!==e||this.prevR!==b||this.prevG!==c||this.prevB!==d))this.gl.uniform4f(this.shaderProgram.color,b,c,d,e),this.prevA=e,this.prevR=b,this.prevG=c,this.prevB=d},setTexture:function(a){if(this.prevTexture!==a){var b=this.gl;b.activeTexture(b.TEXTURE0); +b.bindTexture(b.TEXTURE_2D,a);b.uniform1i(this.shaderProgram.samplerUniform,0);this.prevTexture=a}return this},updateVertexBuffer:function(a){var b=this.gl;b.bindBuffer(b.ARRAY_BUFFER,this.vertexPositionBuffer);b.bufferSubData(b.ARRAY_BUFFER,0,a);return this},updateUVBuffer:function(a){var b=this.gl;b.bindBuffer(b.ARRAY_BUFFER,this.vertexUVBuffer);b.bufferSubData(b.ARRAY_BUFFER,0,a);return this},setAlpha:function(a){this.prevAlpha!==a&&(this.gl.uniform1f(this.shaderProgram.alphaUniform,a),this.prevAlpha= +a);return this},drawLines:function(a,b,c,d,e,f,g){var h=this.gl;this.setAlpha(f);h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.linesBuffer);h.lineWidth(g);this.updateVertexBuffer(a);this.setUseColor(!0,c,d,e,1);h.drawElements(h.LINES,b,h.UNSIGNED_SHORT,0);this.setAlpha(1);this.setUseColor(!1);h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.vertexIndexBuffer)},drawPolylines:function(a,b,c,d,e,f,g){var h=this.gl;h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.linesBuffer);h.lineWidth(g);this.setAlpha(f);this.updateVertexBuffer(a); +this.setUseColor(!0,c,d,e,1);h.drawElements(h.LINE_STRIP,b,h.UNSIGNED_SHORT,0);this.setAlpha(1);this.setUseColor(!1);h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.vertexIndexBuffer)}};extend(CAAT.TextureProgram,CAAT.Program,null)})();function makePerspective(a,b,c,d,e){var a=c*Math.tan(a*Math.PI/360),f=-a;return makeFrustum(f*b,a*b,f,a,c,d,e)}function makeFrustum(a,b,c,d,e,f,g){var h=2*e/(b-a),i=2*e/(d-c),a=(b+a)/(b-a),c=(d+c)/(d-c),d=-(f+e)/(f-e),e=-2*f*e/(f-e);return(new CAAT.Matrix3).initWithMatrix([[h,0,a,-g/2],[0,-i,c,g/2],[0,0,d,e],[0,0,-1,0]])} +function makeOrtho(a,b,c,d,e,f){var g=-(b+a)/(b-a),h=-(d+c)/(d-c),i=-(f+e)/(f-e);return(new CAAT.Matrix3).initWithMatrix([[2/(b-a),0,0,g],[0,2/(d-c),0,h],[0,0,-2/(f-e),i],[0,0,0,1]])};(function(){CAAT.GLTextureElement=function(){return this};CAAT.GLTextureElement.prototype={inverted:!1,image:null,u:0,v:0,glTexture:null}})(); +(function(){CAAT.GLTextureScan=function(a){this.freeChunks=[{position:0,size:a||1024}];return this};CAAT.GLTextureScan.prototype={freeChunks:null,findWhereFits:function(a){if(0===this.freeChunks.length)return[];var b=[],c;for(c=0;cthis.width||b>this.height)return null;for(var c,d,e=0;e<=this.scanMapHeight-b;){var f=null;for(c=!1;e<=this.scanMapHeight-b;e++)if(f=this.scanMap[e].findWhereFits(a),null!==f&& +0c&&(c=100);100>d&&(d=100);this.width=c;this.height=d;this.createFromImages(this.images)},createFromImages:function(a){var b;this.scan=new CAAT.GLTextureScanMap(this.width,this.height);this.images=[];if(this.allowImagesInvertion)for(b=0;bb.width?-1:0:"height"===c.criteria?a.heightb.height?-1:0:fg?-1:0});for(b=0;b> 8) & 0xFF, + (num ) & 0xFF ); +}; +Array.prototype.push32 = function (num) { + this.push((num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + (num ) & 0xFF ); +}; + +// IE does not support map (even in IE9) +//This prototype is provided by the Mozilla foundation and +//is distributed under the MIT license. +//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license +if (!Array.prototype.map) +{ + Array.prototype.map = function(fun /*, thisp*/) + { + var len = this.length; + if (typeof fun != "function") + throw new TypeError(); + + var res = new Array(len); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + { + if (i in this) + res[i] = fun.call(thisp, this[i], i, this); + } + + return res; + }; +} + +/* + * ------------------------------------------------------ + * Namespaced in Util + * ------------------------------------------------------ + */ + +/* + * Logging/debug routines + */ + +Util._log_level = 'warn'; +Util.init_logging = function (level) { + if (typeof level === 'undefined') { + level = Util._log_level; + } else { + Util._log_level = level; + } + if (typeof window.console === "undefined") { + if (typeof window.opera !== "undefined") { + window.console = { + 'log' : window.opera.postError, + 'warn' : window.opera.postError, + 'error': window.opera.postError }; + } else { + window.console = { + 'log' : function(m) {}, + 'warn' : function(m) {}, + 'error': function(m) {}}; + } + } + + Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; + switch (level) { + case 'debug': Util.Debug = function (msg) { console.log(msg); }; + case 'info': Util.Info = function (msg) { console.log(msg); }; + case 'warn': Util.Warn = function (msg) { console.warn(msg); }; + case 'error': Util.Error = function (msg) { console.error(msg); }; + case 'none': + break; + default: + throw("invalid logging type '" + level + "'"); + } +}; +Util.get_logging = function () { + return Util._log_level; +}; +// Initialize logging level +Util.init_logging(); + + +// Set configuration default for Crockford style function namespaces +Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) { + var getter, setter; + + // Default getter function + getter = function (idx) { + if ((type in {'arr':1, 'array':1}) && + (typeof idx !== 'undefined')) { + return cfg[v][idx]; + } else { + return cfg[v]; + } + }; + + // Default setter function + setter = function (val, idx) { + if (type in {'boolean':1, 'bool':1}) { + if ((!val) || (val in {'0':1, 'no':1, 'false':1})) { + val = false; + } else { + val = true; + } + } else if (type in {'integer':1, 'int':1}) { + val = parseInt(val, 10); + } else if (type === 'func') { + if (!val) { + val = function () {}; + } + } + if (typeof idx !== 'undefined') { + cfg[v][idx] = val; + } else { + cfg[v] = val; + } + }; + + // Set the description + api[v + '_description'] = desc; + + // Set the getter function + if (typeof api['get_' + v] === 'undefined') { + api['get_' + v] = getter; + } + + // Set the setter function with extra sanity checks + if (typeof api['set_' + v] === 'undefined') { + api['set_' + v] = function (val, idx) { + if (mode in {'RO':1, 'ro':1}) { + throw(v + " is read-only"); + } else if ((mode in {'WO':1, 'wo':1}) && + (typeof cfg[v] !== 'undefined')) { + throw(v + " can only be set once"); + } + setter(val, idx); + }; + } + + // Set the default value + if (typeof defaults[v] !== 'undefined') { + defval = defaults[v]; + } else if ((type in {'arr':1, 'array':1}) && + (! (defval instanceof Array))) { + defval = []; + } + // Coerce existing setting to the right type + //Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]); + setter(defval); +}; + +// Set group of configuration defaults +Util.conf_defaults = function(cfg, api, defaults, arr) { + var i; + for (i = 0; i < arr.length; i++) { + Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1], + arr[i][2], arr[i][3], arr[i][4]); + } +}; + + +/* + * Cross-browser routines + */ + +// Get DOM element position on page +Util.getPosition = function (obj) { + var x = 0, y = 0; + if (obj.offsetParent) { + do { + x += obj.offsetLeft; + y += obj.offsetTop; + obj = obj.offsetParent; + } while (obj); + } + return {'x': x, 'y': y}; +}; + +// Get mouse event position in DOM element +Util.getEventPosition = function (e, obj, scale) { + var evt, docX, docY, pos; + //if (!e) evt = window.event; + evt = (e ? e : window.event); + evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt); + if (evt.pageX || evt.pageY) { + docX = evt.pageX; + docY = evt.pageY; + } else if (evt.clientX || evt.clientY) { + docX = evt.clientX + document.body.scrollLeft + + document.documentElement.scrollLeft; + docY = evt.clientY + document.body.scrollTop + + document.documentElement.scrollTop; + } + pos = Util.getPosition(obj); + if (typeof scale === "undefined") { + scale = 1; + } + return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale}; +}; + + +// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events +Util.addEvent = function (obj, evType, fn){ + if (obj.attachEvent){ + var r = obj.attachEvent("on"+evType, fn); + return r; + } else if (obj.addEventListener){ + obj.addEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be attached"); + } +}; + +Util.removeEvent = function(obj, evType, fn){ + if (obj.detachEvent){ + var r = obj.detachEvent("on"+evType, fn); + return r; + } else if (obj.removeEventListener){ + obj.removeEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be removed"); + } +}; + +Util.stopEvent = function(e) { + if (e.stopPropagation) { e.stopPropagation(); } + else { e.cancelBubble = true; } + + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } +}; + + +// Set browser engine versions. Based on mootools. +Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; + +Util.Engine = { + // Version detection break in Opera 11.60 (errors on arguments.callee.caller reference) + //'presto': (function() { + // return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), + 'presto': (function() { return (!window.opera) ? false : true; }()), + + 'trident': (function() { + return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()), + 'webkit': (function() { + try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), + //'webkit': (function() { + // return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()), + 'gecko': (function() { + return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }()) +}; +if (Util.Engine.webkit) { + // Extract actual webkit version if available + Util.Engine.webkit = (function(v) { + var re = new RegExp('WebKit/([0-9\.]*) '); + v = (navigator.userAgent.match(re) || ['', v])[1]; + return parseFloat(v, 10); + })(Util.Engine.webkit); +} + +Util.Flash = (function(){ + var v, version; + try { + v = navigator.plugins['Shockwave Flash'].description; + } catch(err1) { + try { + v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch(err2) { + v = '0 r0'; + } + } + version = v.match(/\d+/g); + return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; +}()); +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2011 Joel Martin + * Licensed under LGPL-2 or any later version (see LICENSE.txt) + */ + +/*jslint browser: true, white: false, bitwise: false */ +/*global window, Util */ + + +// +// Keyboard event handler +// + +function Keyboard(defaults) { +//"use strict"; + +var that = {}, // Public API methods + conf = {}, // Configuration attributes + + keyDownList = []; // List of depressed keys + // (even if they are happy) + +// Configuration attributes +Util.conf_defaults(conf, that, defaults, [ + ['target', 'wo', 'dom', document, 'DOM element that captures keyboard input'], + ['focused', 'rw', 'bool', true, 'Capture and send key events'], + + ['onKeyPress', 'rw', 'func', null, 'Handler for key press/release'] + ]); + + +// +// Private functions +// + +// From the event keyCode return the keysym value for keys that need +// to be suppressed otherwise they may trigger unintended browser +// actions +function getKeysymSpecial(evt) { + var keysym = null; + + switch ( evt.keyCode ) { + // These generate a keyDown and keyPress in Firefox and Opera + case 8 : keysym = 0xFF08; break; // BACKSPACE + case 13 : keysym = 0xFF0D; break; // ENTER + + // This generates a keyDown and keyPress in Opera + case 9 : keysym = 0xFF09; break; // TAB + default : break; + } + + if (evt.type === 'keydown') { + switch ( evt.keyCode ) { + case 27 : keysym = 0xFF1B; break; // ESCAPE + case 46 : keysym = 0xFFFF; break; // DELETE + + case 36 : keysym = 0xFF50; break; // HOME + case 35 : keysym = 0xFF57; break; // END + case 33 : keysym = 0xFF55; break; // PAGE_UP + case 34 : keysym = 0xFF56; break; // PAGE_DOWN + case 45 : keysym = 0xFF63; break; // INSERT + // '-' during keyPress + case 37 : keysym = 0xFF51; break; // LEFT + case 38 : keysym = 0xFF52; break; // UP + case 39 : keysym = 0xFF53; break; // RIGHT + case 40 : keysym = 0xFF54; break; // DOWN + case 16 : keysym = 0xFFE1; break; // SHIFT + case 17 : keysym = 0xFFE3; break; // CONTROL + //case 18 : keysym = 0xFFE7; break; // Left Meta (Mac Option) + case 18 : keysym = 0xFFE9; break; // Left ALT (Mac Command) + + case 112 : keysym = 0xFFBE; break; // F1 + case 113 : keysym = 0xFFBF; break; // F2 + case 114 : keysym = 0xFFC0; break; // F3 + case 115 : keysym = 0xFFC1; break; // F4 + case 116 : keysym = 0xFFC2; break; // F5 + case 117 : keysym = 0xFFC3; break; // F6 + case 118 : keysym = 0xFFC4; break; // F7 + case 119 : keysym = 0xFFC5; break; // F8 + case 120 : keysym = 0xFFC6; break; // F9 + case 121 : keysym = 0xFFC7; break; // F10 + case 122 : keysym = 0xFFC8; break; // F11 + case 123 : keysym = 0xFFC9; break; // F12 + + default : break; + } + } + + if ((!keysym) && (evt.ctrlKey || evt.altKey)) { + if ((typeof(evt.which) !== "undefined") && (evt.which > 0)) { + keysym = evt.which; + } else { + // IE9 always + // Firefox and Opera when ctrl/alt + special + Util.Warn("which not set, using keyCode"); + keysym = evt.keyCode; + } + + /* Remap symbols */ + switch (keysym) { + case 186 : keysym = 59; break; // ; (IE) + case 187 : keysym = 61; break; // = (IE) + case 188 : keysym = 44; break; // , (Mozilla, IE) + case 109 : // - (Mozilla, Opera) + if (Util.Engine.gecko || Util.Engine.presto) { + keysym = 45; } + break; + case 189 : keysym = 45; break; // - (IE) + case 190 : keysym = 46; break; // . (Mozilla, IE) + case 191 : keysym = 47; break; // / (Mozilla, IE) + case 192 : keysym = 96; break; // ` (Mozilla, IE) + case 219 : keysym = 91; break; // [ (Mozilla, IE) + case 220 : keysym = 92; break; // \ (Mozilla, IE) + case 221 : keysym = 93; break; // ] (Mozilla, IE) + case 222 : keysym = 39; break; // ' (Mozilla, IE) + } + + /* Remap shifted and unshifted keys */ + if (!!evt.shiftKey) { + switch (keysym) { + case 48 : keysym = 41 ; break; // ) (shifted 0) + case 49 : keysym = 33 ; break; // ! (shifted 1) + case 50 : keysym = 64 ; break; // @ (shifted 2) + case 51 : keysym = 35 ; break; // # (shifted 3) + case 52 : keysym = 36 ; break; // $ (shifted 4) + case 53 : keysym = 37 ; break; // % (shifted 5) + case 54 : keysym = 94 ; break; // ^ (shifted 6) + case 55 : keysym = 38 ; break; // & (shifted 7) + case 56 : keysym = 42 ; break; // * (shifted 8) + case 57 : keysym = 40 ; break; // ( (shifted 9) + + case 59 : keysym = 58 ; break; // : (shifted `) + case 61 : keysym = 43 ; break; // + (shifted ;) + case 44 : keysym = 60 ; break; // < (shifted ,) + case 45 : keysym = 95 ; break; // _ (shifted -) + case 46 : keysym = 62 ; break; // > (shifted .) + case 47 : keysym = 63 ; break; // ? (shifted /) + case 96 : keysym = 126; break; // ~ (shifted `) + case 91 : keysym = 123; break; // { (shifted [) + case 92 : keysym = 124; break; // | (shifted \) + case 93 : keysym = 125; break; // } (shifted ]) + case 39 : keysym = 34 ; break; // " (shifted ') + } + } else if ((keysym >= 65) && (keysym <=90)) { + /* Remap unshifted A-Z */ + keysym += 32; + } else if (evt.keyLocation === 3) { + // numpad keys + switch (keysym) { + case 96 : keysym = 48; break; // 0 + case 97 : keysym = 49; break; // 1 + case 98 : keysym = 50; break; // 2 + case 99 : keysym = 51; break; // 3 + case 100: keysym = 52; break; // 4 + case 101: keysym = 53; break; // 5 + case 102: keysym = 54; break; // 6 + case 103: keysym = 55; break; // 7 + case 104: keysym = 56; break; // 8 + case 105: keysym = 57; break; // 9 + case 109: keysym = 45; break; // - + case 110: keysym = 46; break; // . + case 111: keysym = 47; break; // / + } + } + } + + return keysym; +} + +/* Translate DOM keyPress event to keysym value */ +function getKeysym(evt) { + var keysym, msg; + + if (typeof(evt.which) !== "undefined") { + // WebKit, Firefox, Opera + keysym = evt.which; + } else { + // IE9 + Util.Warn("which not set, using keyCode"); + keysym = evt.keyCode; + } + + if ((keysym > 255) && (keysym < 0xFF00)) { + msg = "Mapping character code " + keysym; + // Map Unicode outside Latin 1 to X11 keysyms + keysym = unicodeTable[keysym]; + if (typeof(keysym) === 'undefined') { + keysym = 0; + } + Util.Debug(msg + " to " + keysym); + } + + return keysym; +} + +function show_keyDownList(kind) { + var c; + var msg = "keyDownList (" + kind + "):\n"; + for (c = 0; c < keyDownList.length; c++) { + msg = msg + " " + c + " - keyCode: " + keyDownList[c].keyCode + + " - which: " + keyDownList[c].which + "\n"; + } + Util.Debug(msg); +} + +function copyKeyEvent(evt) { + var members = ['type', 'keyCode', 'charCode', 'which', + 'altKey', 'ctrlKey', 'shiftKey', + 'keyLocation', 'keyIdentifier'], i, obj = {}; + for (i = 0; i < members.length; i++) { + if (typeof(evt[members[i]]) !== "undefined") { + obj[members[i]] = evt[members[i]]; + } + } + return obj; +} + +function pushKeyEvent(fevt) { + keyDownList.push(fevt); +} + +function getKeyEvent(keyCode, pop) { + var i, fevt = null; + for (i = keyDownList.length-1; i >= 0; i--) { + if (keyDownList[i].keyCode === keyCode) { + if ((typeof(pop) !== "undefined") && (pop)) { + fevt = keyDownList.splice(i, 1)[0]; + } else { + fevt = keyDownList[i]; + } + break; + } + } + return fevt; +} + +function ignoreKeyEvent(evt) { + // Blarg. Some keys have a different keyCode on keyDown vs keyUp + if (evt.keyCode === 229) { + // French AZERTY keyboard dead key. + // Lame thing is that the respective keyUp is 219 so we can't + // properly ignore the keyUp event + return true; + } + return false; +} + + +// +// Key Event Handling: +// +// There are several challenges when dealing with key events: +// - The meaning and use of keyCode, charCode and which depends on +// both the browser and the event type (keyDown/Up vs keyPress). +// - We cannot automatically determine the keyboard layout +// - The keyDown and keyUp events have a keyCode value that has not +// been translated by modifier keys. +// - The keyPress event has a translated (for layout and modifiers) +// character code but the attribute containing it differs. keyCode +// contains the translated value in WebKit (Chrome/Safari), Opera +// 11 and IE9. charCode contains the value in WebKit and Firefox. +// The which attribute contains the value on WebKit, Firefox and +// Opera 11. +// - The keyDown/Up keyCode value indicates (sort of) the physical +// key was pressed but only for standard US layout. On a US +// keyboard, the '-' and '_' characters are on the same key and +// generate a keyCode value of 189. But on an AZERTY keyboard even +// though they are different physical keys they both still +// generate a keyCode of 189! +// - To prevent a key event from propagating to the browser and +// causing unwanted default actions (such as closing a tab, +// opening a menu, shifting focus, etc) we must suppress this +// event in both keyDown and keyPress because not all key strokes +// generate on a keyPress event. Also, in WebKit and IE9 +// suppressing the keyDown prevents a keyPress but other browsers +// still generated a keyPress even if keyDown is suppressed. +// +// For safe key events, we wait until the keyPress event before +// reporting a key down event. For unsafe key events, we report a key +// down event when the keyDown event fires and we suppress any further +// actions (including keyPress). +// +// In order to report a key up event that matches what we reported +// for the key down event, we keep a list of keys that are currently +// down. When the keyDown event happens, we add the key event to the +// list. If it is a safe key event, then we update the which attribute +// in the most recent item on the list when we received a keyPress +// event (keyPress should immediately follow keyDown). When we +// received a keyUp event we search for the event on the list with +// a matching keyCode and we report the character code using the value +// in the 'which' attribute that was stored with that key. +// + +function onKeyDown(e) { + if (! conf.focused) { + return true; + } + var fevt = null, evt = (e ? e : window.event), + keysym = null, suppress = false; + //Util.Debug("onKeyDown kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + fevt = copyKeyEvent(evt); + + keysym = getKeysymSpecial(evt); + // Save keysym decoding for use in keyUp + fevt.keysym = keysym; + if (keysym) { + // If it is a key or key combination that might trigger + // browser behaviors or it has no corresponding keyPress + // event, then send it immediately + if (conf.onKeyPress && !ignoreKeyEvent(evt)) { + Util.Debug("onKeyPress down, keysym: " + keysym + + " (onKeyDown key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 1, evt); + } + suppress = true; + } + + if (! ignoreKeyEvent(evt)) { + // Add it to the list of depressed keys + pushKeyEvent(fevt); + //show_keyDownList('down'); + } + + if (suppress) { + // Suppress bubbling/default actions + Util.stopEvent(e); + return false; + } else { + // Allow the event to bubble and become a keyPress event which + // will have the character code translated + return true; + } +} + +function onKeyPress(e) { + if (! conf.focused) { + return true; + } + var evt = (e ? e : window.event), + kdlen = keyDownList.length, keysym = null; + //Util.Debug("onKeyPress kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + if (((evt.which !== "undefined") && (evt.which === 0)) || + (getKeysymSpecial(evt))) { + // Firefox and Opera generate a keyPress event even if keyDown + // is suppressed. But the keys we want to suppress will have + // either: + // - the which attribute set to 0 + // - getKeysymSpecial() will identify it + Util.Debug("Ignoring special key in keyPress"); + Util.stopEvent(e); + return false; + } + + keysym = getKeysym(evt); + + // Modify the the which attribute in the depressed keys list so + // that the keyUp event will be able to have the character code + // translation available. + if (kdlen > 0) { + keyDownList[kdlen-1].keysym = keysym; + } else { + Util.Warn("keyDownList empty when keyPress triggered"); + } + + //show_keyDownList('press'); + + // Send the translated keysym + if (conf.onKeyPress && (keysym > 0)) { + Util.Debug("onKeyPress down, keysym: " + keysym + + " (onKeyPress key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 1, evt); + } + + // Stop keypress events just in case + Util.stopEvent(e); + return false; +} + +function onKeyUp(e) { + if (! conf.focused) { + return true; + } + var fevt = null, evt = (e ? e : window.event), keysym; + //Util.Debug("onKeyUp kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + fevt = getKeyEvent(evt.keyCode, true); + + if (fevt) { + keysym = fevt.keysym; + } else { + Util.Warn("Key event (keyCode = " + evt.keyCode + + ") not found on keyDownList"); + keysym = 0; + } + + //show_keyDownList('up'); + + if (conf.onKeyPress && (keysym > 0)) { + //Util.Debug("keyPress up, keysym: " + keysym + + // " (key: " + evt.keyCode + ", which: " + evt.which + ")"); + Util.Debug("onKeyPress up, keysym: " + keysym + + " (onKeyPress key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 0, evt); + } + Util.stopEvent(e); + return false; +} + +// +// Public API interface functions +// + +that.grab = function() { + //Util.Debug(">> Keyboard.grab"); + var c = conf.target; + + Util.addEvent(c, 'keydown', onKeyDown); + Util.addEvent(c, 'keyup', onKeyUp); + Util.addEvent(c, 'keypress', onKeyPress); + + //Util.Debug("<< Keyboard.grab"); +}; + +that.ungrab = function() { + //Util.Debug(">> Keyboard.ungrab"); + var c = conf.target; + + Util.removeEvent(c, 'keydown', onKeyDown); + Util.removeEvent(c, 'keyup', onKeyUp); + Util.removeEvent(c, 'keypress', onKeyPress); + + //Util.Debug(">> Keyboard.ungrab"); +}; + +return that; // Return the public API interface + +} // End of Keyboard() + + +// +// Mouse event handler +// + +function Mouse(defaults) { +//"use strict"; + +var that = {}, // Public API methods + conf = {}; // Configuration attributes + +// Configuration attributes +Util.conf_defaults(conf, that, defaults, [ + ['target', 'ro', 'dom', document, 'DOM element that captures mouse input'], + ['focused', 'rw', 'bool', true, 'Capture and send mouse clicks/movement'], + ['scale', 'rw', 'float', 1.0, 'Viewport scale factor 0.0 - 1.0'], + + ['onMouseButton', 'rw', 'func', null, 'Handler for mouse button click/release'], + ['onMouseMove', 'rw', 'func', null, 'Handler for mouse movement'], + ['touchButton', 'rw', 'int', 1, 'Button mask (1, 2, 4) for touch devices (0 means ignore clicks)'] + ]); + + +// +// Private functions +// + +function onMouseButton(e, down) { + var evt, pos, bmask; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + if (e.touches || e.changedTouches) { + // Touch device + bmask = conf.touchButton; + // If bmask is set + } else if (evt.which) { + /* everything except IE */ + bmask = 1 << evt.button; + } else { + /* IE including 9 */ + bmask = (evt.button & 0x1) + // Left + (evt.button & 0x2) * 2 + // Right + (evt.button & 0x4) / 2; // Middle + } + //Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down + + // " bmask: " + bmask + "(evt.button: " + evt.button + ")"); + if (bmask > 0 && conf.onMouseButton) { + Util.Debug("onMouseButton " + (down ? "down" : "up") + + ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); + conf.onMouseButton(pos.x, pos.y, down, bmask); + } + Util.stopEvent(e); + return false; +} + +function onMouseDown(e) { + onMouseButton(e, 1); +} + +function onMouseUp(e) { + onMouseButton(e, 0); +} + +function onMouseWheel(e) { + var evt, pos, bmask, wheelData; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40; + if (wheelData > 0) { + bmask = 1 << 3; + } else { + bmask = 1 << 4; + } + //Util.Debug('mouse scroll by ' + wheelData + ':' + pos.x + "," + pos.y); + if (conf.onMouseButton) { + conf.onMouseButton(pos.x, pos.y, 1, bmask); + conf.onMouseButton(pos.x, pos.y, 0, bmask); + } + Util.stopEvent(e); + return false; +} + +function onMouseMove(e) { + var evt, pos; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + //Util.Debug('mouse ' + evt.which + '/' + evt.button + ' up:' + pos.x + "," + pos.y); + if (conf.onMouseMove) { + conf.onMouseMove(pos.x, pos.y); + } + Util.stopEvent(e); + return false; +} + +function onMouseDisable(e) { + var evt, pos; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + /* Stop propagation if inside canvas area */ + if ((pos.x >= 0) && (pos.y >= 0) && + (pos.x < conf.target.offsetWidth) && + (pos.y < conf.target.offsetHeight)) { + //Util.Debug("mouse event disabled"); + Util.stopEvent(e); + return false; + } + //Util.Debug("mouse event not disabled"); + return true; +} + +// +// Public API interface functions +// + +that.grab = function() { + //Util.Debug(">> Mouse.grab"); + var c = conf.target; + + if ('ontouchstart' in document.documentElement) { + Util.addEvent(c, 'touchstart', onMouseDown); + Util.addEvent(c, 'touchend', onMouseUp); + Util.addEvent(c, 'touchmove', onMouseMove); + } else { + Util.addEvent(c, 'mousedown', onMouseDown); + Util.addEvent(c, 'mouseup', onMouseUp); + Util.addEvent(c, 'mousemove', onMouseMove); + Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } + + /* Work around right and middle click browser behaviors */ + Util.addEvent(document, 'click', onMouseDisable); + Util.addEvent(document.body, 'contextmenu', onMouseDisable); + + //Util.Debug("<< Mouse.grab"); +}; + +that.ungrab = function() { + //Util.Debug(">> Mouse.ungrab"); + var c = conf.target; + + if ('ontouchstart' in document.documentElement) { + Util.removeEvent(c, 'touchstart', onMouseDown); + Util.removeEvent(c, 'touchend', onMouseUp); + Util.removeEvent(c, 'touchmove', onMouseMove); + } else { + Util.removeEvent(c, 'mousedown', onMouseDown); + Util.removeEvent(c, 'mouseup', onMouseUp); + Util.removeEvent(c, 'mousemove', onMouseMove); + Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } + + /* Work around right and middle click browser behaviors */ + Util.removeEvent(document, 'click', onMouseDisable); + Util.removeEvent(document.body, 'contextmenu', onMouseDisable); + + //Util.Debug(">> Mouse.ungrab"); +}; + +return that; // Return the public API interface + +} // End of Mouse() + + +/* + * Browser keypress to X11 keysym for Unicode characters > U+00FF + */ +unicodeTable = { + 0x0104 : 0x01a1, + 0x02D8 : 0x01a2, + 0x0141 : 0x01a3, + 0x013D : 0x01a5, + 0x015A : 0x01a6, + 0x0160 : 0x01a9, + 0x015E : 0x01aa, + 0x0164 : 0x01ab, + 0x0179 : 0x01ac, + 0x017D : 0x01ae, + 0x017B : 0x01af, + 0x0105 : 0x01b1, + 0x02DB : 0x01b2, + 0x0142 : 0x01b3, + 0x013E : 0x01b5, + 0x015B : 0x01b6, + 0x02C7 : 0x01b7, + 0x0161 : 0x01b9, + 0x015F : 0x01ba, + 0x0165 : 0x01bb, + 0x017A : 0x01bc, + 0x02DD : 0x01bd, + 0x017E : 0x01be, + 0x017C : 0x01bf, + 0x0154 : 0x01c0, + 0x0102 : 0x01c3, + 0x0139 : 0x01c5, + 0x0106 : 0x01c6, + 0x010C : 0x01c8, + 0x0118 : 0x01ca, + 0x011A : 0x01cc, + 0x010E : 0x01cf, + 0x0110 : 0x01d0, + 0x0143 : 0x01d1, + 0x0147 : 0x01d2, + 0x0150 : 0x01d5, + 0x0158 : 0x01d8, + 0x016E : 0x01d9, + 0x0170 : 0x01db, + 0x0162 : 0x01de, + 0x0155 : 0x01e0, + 0x0103 : 0x01e3, + 0x013A : 0x01e5, + 0x0107 : 0x01e6, + 0x010D : 0x01e8, + 0x0119 : 0x01ea, + 0x011B : 0x01ec, + 0x010F : 0x01ef, + 0x0111 : 0x01f0, + 0x0144 : 0x01f1, + 0x0148 : 0x01f2, + 0x0151 : 0x01f5, + 0x0171 : 0x01fb, + 0x0159 : 0x01f8, + 0x016F : 0x01f9, + 0x0163 : 0x01fe, + 0x02D9 : 0x01ff, + 0x0126 : 0x02a1, + 0x0124 : 0x02a6, + 0x0130 : 0x02a9, + 0x011E : 0x02ab, + 0x0134 : 0x02ac, + 0x0127 : 0x02b1, + 0x0125 : 0x02b6, + 0x0131 : 0x02b9, + 0x011F : 0x02bb, + 0x0135 : 0x02bc, + 0x010A : 0x02c5, + 0x0108 : 0x02c6, + 0x0120 : 0x02d5, + 0x011C : 0x02d8, + 0x016C : 0x02dd, + 0x015C : 0x02de, + 0x010B : 0x02e5, + 0x0109 : 0x02e6, + 0x0121 : 0x02f5, + 0x011D : 0x02f8, + 0x016D : 0x02fd, + 0x015D : 0x02fe, + 0x0138 : 0x03a2, + 0x0156 : 0x03a3, + 0x0128 : 0x03a5, + 0x013B : 0x03a6, + 0x0112 : 0x03aa, + 0x0122 : 0x03ab, + 0x0166 : 0x03ac, + 0x0157 : 0x03b3, + 0x0129 : 0x03b5, + 0x013C : 0x03b6, + 0x0113 : 0x03ba, + 0x0123 : 0x03bb, + 0x0167 : 0x03bc, + 0x014A : 0x03bd, + 0x014B : 0x03bf, + 0x0100 : 0x03c0, + 0x012E : 0x03c7, + 0x0116 : 0x03cc, + 0x012A : 0x03cf, + 0x0145 : 0x03d1, + 0x014C : 0x03d2, + 0x0136 : 0x03d3, + 0x0172 : 0x03d9, + 0x0168 : 0x03dd, + 0x016A : 0x03de, + 0x0101 : 0x03e0, + 0x012F : 0x03e7, + 0x0117 : 0x03ec, + 0x012B : 0x03ef, + 0x0146 : 0x03f1, + 0x014D : 0x03f2, + 0x0137 : 0x03f3, + 0x0173 : 0x03f9, + 0x0169 : 0x03fd, + 0x016B : 0x03fe, + 0x1E02 : 0x1001e02, + 0x1E03 : 0x1001e03, + 0x1E0A : 0x1001e0a, + 0x1E80 : 0x1001e80, + 0x1E82 : 0x1001e82, + 0x1E0B : 0x1001e0b, + 0x1EF2 : 0x1001ef2, + 0x1E1E : 0x1001e1e, + 0x1E1F : 0x1001e1f, + 0x1E40 : 0x1001e40, + 0x1E41 : 0x1001e41, + 0x1E56 : 0x1001e56, + 0x1E81 : 0x1001e81, + 0x1E57 : 0x1001e57, + 0x1E83 : 0x1001e83, + 0x1E60 : 0x1001e60, + 0x1EF3 : 0x1001ef3, + 0x1E84 : 0x1001e84, + 0x1E85 : 0x1001e85, + 0x1E61 : 0x1001e61, + 0x0174 : 0x1000174, + 0x1E6A : 0x1001e6a, + 0x0176 : 0x1000176, + 0x0175 : 0x1000175, + 0x1E6B : 0x1001e6b, + 0x0177 : 0x1000177, + 0x0152 : 0x13bc, + 0x0153 : 0x13bd, + 0x0178 : 0x13be, + 0x203E : 0x047e, + 0x3002 : 0x04a1, + 0x300C : 0x04a2, + 0x300D : 0x04a3, + 0x3001 : 0x04a4, + 0x30FB : 0x04a5, + 0x30F2 : 0x04a6, + 0x30A1 : 0x04a7, + 0x30A3 : 0x04a8, + 0x30A5 : 0x04a9, + 0x30A7 : 0x04aa, + 0x30A9 : 0x04ab, + 0x30E3 : 0x04ac, + 0x30E5 : 0x04ad, + 0x30E7 : 0x04ae, + 0x30C3 : 0x04af, + 0x30FC : 0x04b0, + 0x30A2 : 0x04b1, + 0x30A4 : 0x04b2, + 0x30A6 : 0x04b3, + 0x30A8 : 0x04b4, + 0x30AA : 0x04b5, + 0x30AB : 0x04b6, + 0x30AD : 0x04b7, + 0x30AF : 0x04b8, + 0x30B1 : 0x04b9, + 0x30B3 : 0x04ba, + 0x30B5 : 0x04bb, + 0x30B7 : 0x04bc, + 0x30B9 : 0x04bd, + 0x30BB : 0x04be, + 0x30BD : 0x04bf, + 0x30BF : 0x04c0, + 0x30C1 : 0x04c1, + 0x30C4 : 0x04c2, + 0x30C6 : 0x04c3, + 0x30C8 : 0x04c4, + 0x30CA : 0x04c5, + 0x30CB : 0x04c6, + 0x30CC : 0x04c7, + 0x30CD : 0x04c8, + 0x30CE : 0x04c9, + 0x30CF : 0x04ca, + 0x30D2 : 0x04cb, + 0x30D5 : 0x04cc, + 0x30D8 : 0x04cd, + 0x30DB : 0x04ce, + 0x30DE : 0x04cf, + 0x30DF : 0x04d0, + 0x30E0 : 0x04d1, + 0x30E1 : 0x04d2, + 0x30E2 : 0x04d3, + 0x30E4 : 0x04d4, + 0x30E6 : 0x04d5, + 0x30E8 : 0x04d6, + 0x30E9 : 0x04d7, + 0x30EA : 0x04d8, + 0x30EB : 0x04d9, + 0x30EC : 0x04da, + 0x30ED : 0x04db, + 0x30EF : 0x04dc, + 0x30F3 : 0x04dd, + 0x309B : 0x04de, + 0x309C : 0x04df, + 0x06F0 : 0x10006f0, + 0x06F1 : 0x10006f1, + 0x06F2 : 0x10006f2, + 0x06F3 : 0x10006f3, + 0x06F4 : 0x10006f4, + 0x06F5 : 0x10006f5, + 0x06F6 : 0x10006f6, + 0x06F7 : 0x10006f7, + 0x06F8 : 0x10006f8, + 0x06F9 : 0x10006f9, + 0x066A : 0x100066a, + 0x0670 : 0x1000670, + 0x0679 : 0x1000679, + 0x067E : 0x100067e, + 0x0686 : 0x1000686, + 0x0688 : 0x1000688, + 0x0691 : 0x1000691, + 0x060C : 0x05ac, + 0x06D4 : 0x10006d4, + 0x0660 : 0x1000660, + 0x0661 : 0x1000661, + 0x0662 : 0x1000662, + 0x0663 : 0x1000663, + 0x0664 : 0x1000664, + 0x0665 : 0x1000665, + 0x0666 : 0x1000666, + 0x0667 : 0x1000667, + 0x0668 : 0x1000668, + 0x0669 : 0x1000669, + 0x061B : 0x05bb, + 0x061F : 0x05bf, + 0x0621 : 0x05c1, + 0x0622 : 0x05c2, + 0x0623 : 0x05c3, + 0x0624 : 0x05c4, + 0x0625 : 0x05c5, + 0x0626 : 0x05c6, + 0x0627 : 0x05c7, + 0x0628 : 0x05c8, + 0x0629 : 0x05c9, + 0x062A : 0x05ca, + 0x062B : 0x05cb, + 0x062C : 0x05cc, + 0x062D : 0x05cd, + 0x062E : 0x05ce, + 0x062F : 0x05cf, + 0x0630 : 0x05d0, + 0x0631 : 0x05d1, + 0x0632 : 0x05d2, + 0x0633 : 0x05d3, + 0x0634 : 0x05d4, + 0x0635 : 0x05d5, + 0x0636 : 0x05d6, + 0x0637 : 0x05d7, + 0x0638 : 0x05d8, + 0x0639 : 0x05d9, + 0x063A : 0x05da, + 0x0640 : 0x05e0, + 0x0641 : 0x05e1, + 0x0642 : 0x05e2, + 0x0643 : 0x05e3, + 0x0644 : 0x05e4, + 0x0645 : 0x05e5, + 0x0646 : 0x05e6, + 0x0647 : 0x05e7, + 0x0648 : 0x05e8, + 0x0649 : 0x05e9, + 0x064A : 0x05ea, + 0x064B : 0x05eb, + 0x064C : 0x05ec, + 0x064D : 0x05ed, + 0x064E : 0x05ee, + 0x064F : 0x05ef, + 0x0650 : 0x05f0, + 0x0651 : 0x05f1, + 0x0652 : 0x05f2, + 0x0653 : 0x1000653, + 0x0654 : 0x1000654, + 0x0655 : 0x1000655, + 0x0698 : 0x1000698, + 0x06A4 : 0x10006a4, + 0x06A9 : 0x10006a9, + 0x06AF : 0x10006af, + 0x06BA : 0x10006ba, + 0x06BE : 0x10006be, + 0x06CC : 0x10006cc, + 0x06D2 : 0x10006d2, + 0x06C1 : 0x10006c1, + 0x0492 : 0x1000492, + 0x0493 : 0x1000493, + 0x0496 : 0x1000496, + 0x0497 : 0x1000497, + 0x049A : 0x100049a, + 0x049B : 0x100049b, + 0x049C : 0x100049c, + 0x049D : 0x100049d, + 0x04A2 : 0x10004a2, + 0x04A3 : 0x10004a3, + 0x04AE : 0x10004ae, + 0x04AF : 0x10004af, + 0x04B0 : 0x10004b0, + 0x04B1 : 0x10004b1, + 0x04B2 : 0x10004b2, + 0x04B3 : 0x10004b3, + 0x04B6 : 0x10004b6, + 0x04B7 : 0x10004b7, + 0x04B8 : 0x10004b8, + 0x04B9 : 0x10004b9, + 0x04BA : 0x10004ba, + 0x04BB : 0x10004bb, + 0x04D8 : 0x10004d8, + 0x04D9 : 0x10004d9, + 0x04E2 : 0x10004e2, + 0x04E3 : 0x10004e3, + 0x04E8 : 0x10004e8, + 0x04E9 : 0x10004e9, + 0x04EE : 0x10004ee, + 0x04EF : 0x10004ef, + 0x0452 : 0x06a1, + 0x0453 : 0x06a2, + 0x0451 : 0x06a3, + 0x0454 : 0x06a4, + 0x0455 : 0x06a5, + 0x0456 : 0x06a6, + 0x0457 : 0x06a7, + 0x0458 : 0x06a8, + 0x0459 : 0x06a9, + 0x045A : 0x06aa, + 0x045B : 0x06ab, + 0x045C : 0x06ac, + 0x0491 : 0x06ad, + 0x045E : 0x06ae, + 0x045F : 0x06af, + 0x2116 : 0x06b0, + 0x0402 : 0x06b1, + 0x0403 : 0x06b2, + 0x0401 : 0x06b3, + 0x0404 : 0x06b4, + 0x0405 : 0x06b5, + 0x0406 : 0x06b6, + 0x0407 : 0x06b7, + 0x0408 : 0x06b8, + 0x0409 : 0x06b9, + 0x040A : 0x06ba, + 0x040B : 0x06bb, + 0x040C : 0x06bc, + 0x0490 : 0x06bd, + 0x040E : 0x06be, + 0x040F : 0x06bf, + 0x044E : 0x06c0, + 0x0430 : 0x06c1, + 0x0431 : 0x06c2, + 0x0446 : 0x06c3, + 0x0434 : 0x06c4, + 0x0435 : 0x06c5, + 0x0444 : 0x06c6, + 0x0433 : 0x06c7, + 0x0445 : 0x06c8, + 0x0438 : 0x06c9, + 0x0439 : 0x06ca, + 0x043A : 0x06cb, + 0x043B : 0x06cc, + 0x043C : 0x06cd, + 0x043D : 0x06ce, + 0x043E : 0x06cf, + 0x043F : 0x06d0, + 0x044F : 0x06d1, + 0x0440 : 0x06d2, + 0x0441 : 0x06d3, + 0x0442 : 0x06d4, + 0x0443 : 0x06d5, + 0x0436 : 0x06d6, + 0x0432 : 0x06d7, + 0x044C : 0x06d8, + 0x044B : 0x06d9, + 0x0437 : 0x06da, + 0x0448 : 0x06db, + 0x044D : 0x06dc, + 0x0449 : 0x06dd, + 0x0447 : 0x06de, + 0x044A : 0x06df, + 0x042E : 0x06e0, + 0x0410 : 0x06e1, + 0x0411 : 0x06e2, + 0x0426 : 0x06e3, + 0x0414 : 0x06e4, + 0x0415 : 0x06e5, + 0x0424 : 0x06e6, + 0x0413 : 0x06e7, + 0x0425 : 0x06e8, + 0x0418 : 0x06e9, + 0x0419 : 0x06ea, + 0x041A : 0x06eb, + 0x041B : 0x06ec, + 0x041C : 0x06ed, + 0x041D : 0x06ee, + 0x041E : 0x06ef, + 0x041F : 0x06f0, + 0x042F : 0x06f1, + 0x0420 : 0x06f2, + 0x0421 : 0x06f3, + 0x0422 : 0x06f4, + 0x0423 : 0x06f5, + 0x0416 : 0x06f6, + 0x0412 : 0x06f7, + 0x042C : 0x06f8, + 0x042B : 0x06f9, + 0x0417 : 0x06fa, + 0x0428 : 0x06fb, + 0x042D : 0x06fc, + 0x0429 : 0x06fd, + 0x0427 : 0x06fe, + 0x042A : 0x06ff, + 0x0386 : 0x07a1, + 0x0388 : 0x07a2, + 0x0389 : 0x07a3, + 0x038A : 0x07a4, + 0x03AA : 0x07a5, + 0x038C : 0x07a7, + 0x038E : 0x07a8, + 0x03AB : 0x07a9, + 0x038F : 0x07ab, + 0x0385 : 0x07ae, + 0x2015 : 0x07af, + 0x03AC : 0x07b1, + 0x03AD : 0x07b2, + 0x03AE : 0x07b3, + 0x03AF : 0x07b4, + 0x03CA : 0x07b5, + 0x0390 : 0x07b6, + 0x03CC : 0x07b7, + 0x03CD : 0x07b8, + 0x03CB : 0x07b9, + 0x03B0 : 0x07ba, + 0x03CE : 0x07bb, + 0x0391 : 0x07c1, + 0x0392 : 0x07c2, + 0x0393 : 0x07c3, + 0x0394 : 0x07c4, + 0x0395 : 0x07c5, + 0x0396 : 0x07c6, + 0x0397 : 0x07c7, + 0x0398 : 0x07c8, + 0x0399 : 0x07c9, + 0x039A : 0x07ca, + 0x039B : 0x07cb, + 0x039C : 0x07cc, + 0x039D : 0x07cd, + 0x039E : 0x07ce, + 0x039F : 0x07cf, + 0x03A0 : 0x07d0, + 0x03A1 : 0x07d1, + 0x03A3 : 0x07d2, + 0x03A4 : 0x07d4, + 0x03A5 : 0x07d5, + 0x03A6 : 0x07d6, + 0x03A7 : 0x07d7, + 0x03A8 : 0x07d8, + 0x03A9 : 0x07d9, + 0x03B1 : 0x07e1, + 0x03B2 : 0x07e2, + 0x03B3 : 0x07e3, + 0x03B4 : 0x07e4, + 0x03B5 : 0x07e5, + 0x03B6 : 0x07e6, + 0x03B7 : 0x07e7, + 0x03B8 : 0x07e8, + 0x03B9 : 0x07e9, + 0x03BA : 0x07ea, + 0x03BB : 0x07eb, + 0x03BC : 0x07ec, + 0x03BD : 0x07ed, + 0x03BE : 0x07ee, + 0x03BF : 0x07ef, + 0x03C0 : 0x07f0, + 0x03C1 : 0x07f1, + 0x03C3 : 0x07f2, + 0x03C2 : 0x07f3, + 0x03C4 : 0x07f4, + 0x03C5 : 0x07f5, + 0x03C6 : 0x07f6, + 0x03C7 : 0x07f7, + 0x03C8 : 0x07f8, + 0x03C9 : 0x07f9, + 0x23B7 : 0x08a1, + 0x2320 : 0x08a4, + 0x2321 : 0x08a5, + 0x23A1 : 0x08a7, + 0x23A3 : 0x08a8, + 0x23A4 : 0x08a9, + 0x23A6 : 0x08aa, + 0x239B : 0x08ab, + 0x239D : 0x08ac, + 0x239E : 0x08ad, + 0x23A0 : 0x08ae, + 0x23A8 : 0x08af, + 0x23AC : 0x08b0, + 0x2264 : 0x08bc, + 0x2260 : 0x08bd, + 0x2265 : 0x08be, + 0x222B : 0x08bf, + 0x2234 : 0x08c0, + 0x221D : 0x08c1, + 0x221E : 0x08c2, + 0x2207 : 0x08c5, + 0x223C : 0x08c8, + 0x2243 : 0x08c9, + 0x21D4 : 0x08cd, + 0x21D2 : 0x08ce, + 0x2261 : 0x08cf, + 0x221A : 0x08d6, + 0x2282 : 0x08da, + 0x2283 : 0x08db, + 0x2229 : 0x08dc, + 0x222A : 0x08dd, + 0x2227 : 0x08de, + 0x2228 : 0x08df, + 0x2202 : 0x08ef, + 0x0192 : 0x08f6, + 0x2190 : 0x08fb, + 0x2191 : 0x08fc, + 0x2192 : 0x08fd, + 0x2193 : 0x08fe, + 0x25C6 : 0x09e0, + 0x2592 : 0x09e1, + 0x2409 : 0x09e2, + 0x240C : 0x09e3, + 0x240D : 0x09e4, + 0x240A : 0x09e5, + 0x2424 : 0x09e8, + 0x240B : 0x09e9, + 0x2518 : 0x09ea, + 0x2510 : 0x09eb, + 0x250C : 0x09ec, + 0x2514 : 0x09ed, + 0x253C : 0x09ee, + 0x23BA : 0x09ef, + 0x23BB : 0x09f0, + 0x2500 : 0x09f1, + 0x23BC : 0x09f2, + 0x23BD : 0x09f3, + 0x251C : 0x09f4, + 0x2524 : 0x09f5, + 0x2534 : 0x09f6, + 0x252C : 0x09f7, + 0x2502 : 0x09f8, + 0x2003 : 0x0aa1, + 0x2002 : 0x0aa2, + 0x2004 : 0x0aa3, + 0x2005 : 0x0aa4, + 0x2007 : 0x0aa5, + 0x2008 : 0x0aa6, + 0x2009 : 0x0aa7, + 0x200A : 0x0aa8, + 0x2014 : 0x0aa9, + 0x2013 : 0x0aaa, + 0x2026 : 0x0aae, + 0x2025 : 0x0aaf, + 0x2153 : 0x0ab0, + 0x2154 : 0x0ab1, + 0x2155 : 0x0ab2, + 0x2156 : 0x0ab3, + 0x2157 : 0x0ab4, + 0x2158 : 0x0ab5, + 0x2159 : 0x0ab6, + 0x215A : 0x0ab7, + 0x2105 : 0x0ab8, + 0x2012 : 0x0abb, + 0x215B : 0x0ac3, + 0x215C : 0x0ac4, + 0x215D : 0x0ac5, + 0x215E : 0x0ac6, + 0x2122 : 0x0ac9, + 0x2018 : 0x0ad0, + 0x2019 : 0x0ad1, + 0x201C : 0x0ad2, + 0x201D : 0x0ad3, + 0x211E : 0x0ad4, + 0x2032 : 0x0ad6, + 0x2033 : 0x0ad7, + 0x271D : 0x0ad9, + 0x2663 : 0x0aec, + 0x2666 : 0x0aed, + 0x2665 : 0x0aee, + 0x2720 : 0x0af0, + 0x2020 : 0x0af1, + 0x2021 : 0x0af2, + 0x2713 : 0x0af3, + 0x2717 : 0x0af4, + 0x266F : 0x0af5, + 0x266D : 0x0af6, + 0x2642 : 0x0af7, + 0x2640 : 0x0af8, + 0x260E : 0x0af9, + 0x2315 : 0x0afa, + 0x2117 : 0x0afb, + 0x2038 : 0x0afc, + 0x201A : 0x0afd, + 0x201E : 0x0afe, + 0x22A4 : 0x0bc2, + 0x230A : 0x0bc4, + 0x2218 : 0x0bca, + 0x2395 : 0x0bcc, + 0x22A5 : 0x0bce, + 0x25CB : 0x0bcf, + 0x2308 : 0x0bd3, + 0x22A3 : 0x0bdc, + 0x22A2 : 0x0bfc, + 0x2017 : 0x0cdf, + 0x05D0 : 0x0ce0, + 0x05D1 : 0x0ce1, + 0x05D2 : 0x0ce2, + 0x05D3 : 0x0ce3, + 0x05D4 : 0x0ce4, + 0x05D5 : 0x0ce5, + 0x05D6 : 0x0ce6, + 0x05D7 : 0x0ce7, + 0x05D8 : 0x0ce8, + 0x05D9 : 0x0ce9, + 0x05DA : 0x0cea, + 0x05DB : 0x0ceb, + 0x05DC : 0x0cec, + 0x05DD : 0x0ced, + 0x05DE : 0x0cee, + 0x05DF : 0x0cef, + 0x05E0 : 0x0cf0, + 0x05E1 : 0x0cf1, + 0x05E2 : 0x0cf2, + 0x05E3 : 0x0cf3, + 0x05E4 : 0x0cf4, + 0x05E5 : 0x0cf5, + 0x05E6 : 0x0cf6, + 0x05E7 : 0x0cf7, + 0x05E8 : 0x0cf8, + 0x05E9 : 0x0cf9, + 0x05EA : 0x0cfa, + 0x0E01 : 0x0da1, + 0x0E02 : 0x0da2, + 0x0E03 : 0x0da3, + 0x0E04 : 0x0da4, + 0x0E05 : 0x0da5, + 0x0E06 : 0x0da6, + 0x0E07 : 0x0da7, + 0x0E08 : 0x0da8, + 0x0E09 : 0x0da9, + 0x0E0A : 0x0daa, + 0x0E0B : 0x0dab, + 0x0E0C : 0x0dac, + 0x0E0D : 0x0dad, + 0x0E0E : 0x0dae, + 0x0E0F : 0x0daf, + 0x0E10 : 0x0db0, + 0x0E11 : 0x0db1, + 0x0E12 : 0x0db2, + 0x0E13 : 0x0db3, + 0x0E14 : 0x0db4, + 0x0E15 : 0x0db5, + 0x0E16 : 0x0db6, + 0x0E17 : 0x0db7, + 0x0E18 : 0x0db8, + 0x0E19 : 0x0db9, + 0x0E1A : 0x0dba, + 0x0E1B : 0x0dbb, + 0x0E1C : 0x0dbc, + 0x0E1D : 0x0dbd, + 0x0E1E : 0x0dbe, + 0x0E1F : 0x0dbf, + 0x0E20 : 0x0dc0, + 0x0E21 : 0x0dc1, + 0x0E22 : 0x0dc2, + 0x0E23 : 0x0dc3, + 0x0E24 : 0x0dc4, + 0x0E25 : 0x0dc5, + 0x0E26 : 0x0dc6, + 0x0E27 : 0x0dc7, + 0x0E28 : 0x0dc8, + 0x0E29 : 0x0dc9, + 0x0E2A : 0x0dca, + 0x0E2B : 0x0dcb, + 0x0E2C : 0x0dcc, + 0x0E2D : 0x0dcd, + 0x0E2E : 0x0dce, + 0x0E2F : 0x0dcf, + 0x0E30 : 0x0dd0, + 0x0E31 : 0x0dd1, + 0x0E32 : 0x0dd2, + 0x0E33 : 0x0dd3, + 0x0E34 : 0x0dd4, + 0x0E35 : 0x0dd5, + 0x0E36 : 0x0dd6, + 0x0E37 : 0x0dd7, + 0x0E38 : 0x0dd8, + 0x0E39 : 0x0dd9, + 0x0E3A : 0x0dda, + 0x0E3F : 0x0ddf, + 0x0E40 : 0x0de0, + 0x0E41 : 0x0de1, + 0x0E42 : 0x0de2, + 0x0E43 : 0x0de3, + 0x0E44 : 0x0de4, + 0x0E45 : 0x0de5, + 0x0E46 : 0x0de6, + 0x0E47 : 0x0de7, + 0x0E48 : 0x0de8, + 0x0E49 : 0x0de9, + 0x0E4A : 0x0dea, + 0x0E4B : 0x0deb, + 0x0E4C : 0x0dec, + 0x0E4D : 0x0ded, + 0x0E50 : 0x0df0, + 0x0E51 : 0x0df1, + 0x0E52 : 0x0df2, + 0x0E53 : 0x0df3, + 0x0E54 : 0x0df4, + 0x0E55 : 0x0df5, + 0x0E56 : 0x0df6, + 0x0E57 : 0x0df7, + 0x0E58 : 0x0df8, + 0x0E59 : 0x0df9, + 0x0587 : 0x1000587, + 0x0589 : 0x1000589, + 0x055D : 0x100055d, + 0x058A : 0x100058a, + 0x055C : 0x100055c, + 0x055B : 0x100055b, + 0x055E : 0x100055e, + 0x0531 : 0x1000531, + 0x0561 : 0x1000561, + 0x0532 : 0x1000532, + 0x0562 : 0x1000562, + 0x0533 : 0x1000533, + 0x0563 : 0x1000563, + 0x0534 : 0x1000534, + 0x0564 : 0x1000564, + 0x0535 : 0x1000535, + 0x0565 : 0x1000565, + 0x0536 : 0x1000536, + 0x0566 : 0x1000566, + 0x0537 : 0x1000537, + 0x0567 : 0x1000567, + 0x0538 : 0x1000538, + 0x0568 : 0x1000568, + 0x0539 : 0x1000539, + 0x0569 : 0x1000569, + 0x053A : 0x100053a, + 0x056A : 0x100056a, + 0x053B : 0x100053b, + 0x056B : 0x100056b, + 0x053C : 0x100053c, + 0x056C : 0x100056c, + 0x053D : 0x100053d, + 0x056D : 0x100056d, + 0x053E : 0x100053e, + 0x056E : 0x100056e, + 0x053F : 0x100053f, + 0x056F : 0x100056f, + 0x0540 : 0x1000540, + 0x0570 : 0x1000570, + 0x0541 : 0x1000541, + 0x0571 : 0x1000571, + 0x0542 : 0x1000542, + 0x0572 : 0x1000572, + 0x0543 : 0x1000543, + 0x0573 : 0x1000573, + 0x0544 : 0x1000544, + 0x0574 : 0x1000574, + 0x0545 : 0x1000545, + 0x0575 : 0x1000575, + 0x0546 : 0x1000546, + 0x0576 : 0x1000576, + 0x0547 : 0x1000547, + 0x0577 : 0x1000577, + 0x0548 : 0x1000548, + 0x0578 : 0x1000578, + 0x0549 : 0x1000549, + 0x0579 : 0x1000579, + 0x054A : 0x100054a, + 0x057A : 0x100057a, + 0x054B : 0x100054b, + 0x057B : 0x100057b, + 0x054C : 0x100054c, + 0x057C : 0x100057c, + 0x054D : 0x100054d, + 0x057D : 0x100057d, + 0x054E : 0x100054e, + 0x057E : 0x100057e, + 0x054F : 0x100054f, + 0x057F : 0x100057f, + 0x0550 : 0x1000550, + 0x0580 : 0x1000580, + 0x0551 : 0x1000551, + 0x0581 : 0x1000581, + 0x0552 : 0x1000552, + 0x0582 : 0x1000582, + 0x0553 : 0x1000553, + 0x0583 : 0x1000583, + 0x0554 : 0x1000554, + 0x0584 : 0x1000584, + 0x0555 : 0x1000555, + 0x0585 : 0x1000585, + 0x0556 : 0x1000556, + 0x0586 : 0x1000586, + 0x055A : 0x100055a, + 0x10D0 : 0x10010d0, + 0x10D1 : 0x10010d1, + 0x10D2 : 0x10010d2, + 0x10D3 : 0x10010d3, + 0x10D4 : 0x10010d4, + 0x10D5 : 0x10010d5, + 0x10D6 : 0x10010d6, + 0x10D7 : 0x10010d7, + 0x10D8 : 0x10010d8, + 0x10D9 : 0x10010d9, + 0x10DA : 0x10010da, + 0x10DB : 0x10010db, + 0x10DC : 0x10010dc, + 0x10DD : 0x10010dd, + 0x10DE : 0x10010de, + 0x10DF : 0x10010df, + 0x10E0 : 0x10010e0, + 0x10E1 : 0x10010e1, + 0x10E2 : 0x10010e2, + 0x10E3 : 0x10010e3, + 0x10E4 : 0x10010e4, + 0x10E5 : 0x10010e5, + 0x10E6 : 0x10010e6, + 0x10E7 : 0x10010e7, + 0x10E8 : 0x10010e8, + 0x10E9 : 0x10010e9, + 0x10EA : 0x10010ea, + 0x10EB : 0x10010eb, + 0x10EC : 0x10010ec, + 0x10ED : 0x10010ed, + 0x10EE : 0x10010ee, + 0x10EF : 0x10010ef, + 0x10F0 : 0x10010f0, + 0x10F1 : 0x10010f1, + 0x10F2 : 0x10010f2, + 0x10F3 : 0x10010f3, + 0x10F4 : 0x10010f4, + 0x10F5 : 0x10010f5, + 0x10F6 : 0x10010f6, + 0x1E8A : 0x1001e8a, + 0x012C : 0x100012c, + 0x01B5 : 0x10001b5, + 0x01E6 : 0x10001e6, + 0x01D2 : 0x10001d1, + 0x019F : 0x100019f, + 0x1E8B : 0x1001e8b, + 0x012D : 0x100012d, + 0x01B6 : 0x10001b6, + 0x01E7 : 0x10001e7, + 0x01D2 : 0x10001d2, + 0x0275 : 0x1000275, + 0x018F : 0x100018f, + 0x0259 : 0x1000259, + 0x1E36 : 0x1001e36, + 0x1E37 : 0x1001e37, + 0x1EA0 : 0x1001ea0, + 0x1EA1 : 0x1001ea1, + 0x1EA2 : 0x1001ea2, + 0x1EA3 : 0x1001ea3, + 0x1EA4 : 0x1001ea4, + 0x1EA5 : 0x1001ea5, + 0x1EA6 : 0x1001ea6, + 0x1EA7 : 0x1001ea7, + 0x1EA8 : 0x1001ea8, + 0x1EA9 : 0x1001ea9, + 0x1EAA : 0x1001eaa, + 0x1EAB : 0x1001eab, + 0x1EAC : 0x1001eac, + 0x1EAD : 0x1001ead, + 0x1EAE : 0x1001eae, + 0x1EAF : 0x1001eaf, + 0x1EB0 : 0x1001eb0, + 0x1EB1 : 0x1001eb1, + 0x1EB2 : 0x1001eb2, + 0x1EB3 : 0x1001eb3, + 0x1EB4 : 0x1001eb4, + 0x1EB5 : 0x1001eb5, + 0x1EB6 : 0x1001eb6, + 0x1EB7 : 0x1001eb7, + 0x1EB8 : 0x1001eb8, + 0x1EB9 : 0x1001eb9, + 0x1EBA : 0x1001eba, + 0x1EBB : 0x1001ebb, + 0x1EBC : 0x1001ebc, + 0x1EBD : 0x1001ebd, + 0x1EBE : 0x1001ebe, + 0x1EBF : 0x1001ebf, + 0x1EC0 : 0x1001ec0, + 0x1EC1 : 0x1001ec1, + 0x1EC2 : 0x1001ec2, + 0x1EC3 : 0x1001ec3, + 0x1EC4 : 0x1001ec4, + 0x1EC5 : 0x1001ec5, + 0x1EC6 : 0x1001ec6, + 0x1EC7 : 0x1001ec7, + 0x1EC8 : 0x1001ec8, + 0x1EC9 : 0x1001ec9, + 0x1ECA : 0x1001eca, + 0x1ECB : 0x1001ecb, + 0x1ECC : 0x1001ecc, + 0x1ECD : 0x1001ecd, + 0x1ECE : 0x1001ece, + 0x1ECF : 0x1001ecf, + 0x1ED0 : 0x1001ed0, + 0x1ED1 : 0x1001ed1, + 0x1ED2 : 0x1001ed2, + 0x1ED3 : 0x1001ed3, + 0x1ED4 : 0x1001ed4, + 0x1ED5 : 0x1001ed5, + 0x1ED6 : 0x1001ed6, + 0x1ED7 : 0x1001ed7, + 0x1ED8 : 0x1001ed8, + 0x1ED9 : 0x1001ed9, + 0x1EDA : 0x1001eda, + 0x1EDB : 0x1001edb, + 0x1EDC : 0x1001edc, + 0x1EDD : 0x1001edd, + 0x1EDE : 0x1001ede, + 0x1EDF : 0x1001edf, + 0x1EE0 : 0x1001ee0, + 0x1EE1 : 0x1001ee1, + 0x1EE2 : 0x1001ee2, + 0x1EE3 : 0x1001ee3, + 0x1EE4 : 0x1001ee4, + 0x1EE5 : 0x1001ee5, + 0x1EE6 : 0x1001ee6, + 0x1EE7 : 0x1001ee7, + 0x1EE8 : 0x1001ee8, + 0x1EE9 : 0x1001ee9, + 0x1EEA : 0x1001eea, + 0x1EEB : 0x1001eeb, + 0x1EEC : 0x1001eec, + 0x1EED : 0x1001eed, + 0x1EEE : 0x1001eee, + 0x1EEF : 0x1001eef, + 0x1EF0 : 0x1001ef0, + 0x1EF1 : 0x1001ef1, + 0x1EF4 : 0x1001ef4, + 0x1EF5 : 0x1001ef5, + 0x1EF6 : 0x1001ef6, + 0x1EF7 : 0x1001ef7, + 0x1EF8 : 0x1001ef8, + 0x1EF9 : 0x1001ef9, + 0x01A0 : 0x10001a0, + 0x01A1 : 0x10001a1, + 0x01AF : 0x10001af, + 0x01B0 : 0x10001b0, + 0x20A0 : 0x10020a0, + 0x20A1 : 0x10020a1, + 0x20A2 : 0x10020a2, + 0x20A3 : 0x10020a3, + 0x20A4 : 0x10020a4, + 0x20A5 : 0x10020a5, + 0x20A6 : 0x10020a6, + 0x20A7 : 0x10020a7, + 0x20A8 : 0x10020a8, + 0x20A9 : 0x10020a9, + 0x20AA : 0x10020aa, + 0x20AB : 0x10020ab, + 0x20AC : 0x20ac, + 0x2070 : 0x1002070, + 0x2074 : 0x1002074, + 0x2075 : 0x1002075, + 0x2076 : 0x1002076, + 0x2077 : 0x1002077, + 0x2078 : 0x1002078, + 0x2079 : 0x1002079, + 0x2080 : 0x1002080, + 0x2081 : 0x1002081, + 0x2082 : 0x1002082, + 0x2083 : 0x1002083, + 0x2084 : 0x1002084, + 0x2085 : 0x1002085, + 0x2086 : 0x1002086, + 0x2087 : 0x1002087, + 0x2088 : 0x1002088, + 0x2089 : 0x1002089, + 0x2202 : 0x1002202, + 0x2205 : 0x1002205, + 0x2208 : 0x1002208, + 0x2209 : 0x1002209, + 0x220B : 0x100220B, + 0x221A : 0x100221A, + 0x221B : 0x100221B, + 0x221C : 0x100221C, + 0x222C : 0x100222C, + 0x222D : 0x100222D, + 0x2235 : 0x1002235, + 0x2245 : 0x1002248, + 0x2247 : 0x1002247, + 0x2262 : 0x1002262, + 0x2263 : 0x1002263, + 0x2800 : 0x1002800, + 0x2801 : 0x1002801, + 0x2802 : 0x1002802, + 0x2803 : 0x1002803, + 0x2804 : 0x1002804, + 0x2805 : 0x1002805, + 0x2806 : 0x1002806, + 0x2807 : 0x1002807, + 0x2808 : 0x1002808, + 0x2809 : 0x1002809, + 0x280a : 0x100280a, + 0x280b : 0x100280b, + 0x280c : 0x100280c, + 0x280d : 0x100280d, + 0x280e : 0x100280e, + 0x280f : 0x100280f, + 0x2810 : 0x1002810, + 0x2811 : 0x1002811, + 0x2812 : 0x1002812, + 0x2813 : 0x1002813, + 0x2814 : 0x1002814, + 0x2815 : 0x1002815, + 0x2816 : 0x1002816, + 0x2817 : 0x1002817, + 0x2818 : 0x1002818, + 0x2819 : 0x1002819, + 0x281a : 0x100281a, + 0x281b : 0x100281b, + 0x281c : 0x100281c, + 0x281d : 0x100281d, + 0x281e : 0x100281e, + 0x281f : 0x100281f, + 0x2820 : 0x1002820, + 0x2821 : 0x1002821, + 0x2822 : 0x1002822, + 0x2823 : 0x1002823, + 0x2824 : 0x1002824, + 0x2825 : 0x1002825, + 0x2826 : 0x1002826, + 0x2827 : 0x1002827, + 0x2828 : 0x1002828, + 0x2829 : 0x1002829, + 0x282a : 0x100282a, + 0x282b : 0x100282b, + 0x282c : 0x100282c, + 0x282d : 0x100282d, + 0x282e : 0x100282e, + 0x282f : 0x100282f, + 0x2830 : 0x1002830, + 0x2831 : 0x1002831, + 0x2832 : 0x1002832, + 0x2833 : 0x1002833, + 0x2834 : 0x1002834, + 0x2835 : 0x1002835, + 0x2836 : 0x1002836, + 0x2837 : 0x1002837, + 0x2838 : 0x1002838, + 0x2839 : 0x1002839, + 0x283a : 0x100283a, + 0x283b : 0x100283b, + 0x283c : 0x100283c, + 0x283d : 0x100283d, + 0x283e : 0x100283e, + 0x283f : 0x100283f, + 0x2840 : 0x1002840, + 0x2841 : 0x1002841, + 0x2842 : 0x1002842, + 0x2843 : 0x1002843, + 0x2844 : 0x1002844, + 0x2845 : 0x1002845, + 0x2846 : 0x1002846, + 0x2847 : 0x1002847, + 0x2848 : 0x1002848, + 0x2849 : 0x1002849, + 0x284a : 0x100284a, + 0x284b : 0x100284b, + 0x284c : 0x100284c, + 0x284d : 0x100284d, + 0x284e : 0x100284e, + 0x284f : 0x100284f, + 0x2850 : 0x1002850, + 0x2851 : 0x1002851, + 0x2852 : 0x1002852, + 0x2853 : 0x1002853, + 0x2854 : 0x1002854, + 0x2855 : 0x1002855, + 0x2856 : 0x1002856, + 0x2857 : 0x1002857, + 0x2858 : 0x1002858, + 0x2859 : 0x1002859, + 0x285a : 0x100285a, + 0x285b : 0x100285b, + 0x285c : 0x100285c, + 0x285d : 0x100285d, + 0x285e : 0x100285e, + 0x285f : 0x100285f, + 0x2860 : 0x1002860, + 0x2861 : 0x1002861, + 0x2862 : 0x1002862, + 0x2863 : 0x1002863, + 0x2864 : 0x1002864, + 0x2865 : 0x1002865, + 0x2866 : 0x1002866, + 0x2867 : 0x1002867, + 0x2868 : 0x1002868, + 0x2869 : 0x1002869, + 0x286a : 0x100286a, + 0x286b : 0x100286b, + 0x286c : 0x100286c, + 0x286d : 0x100286d, + 0x286e : 0x100286e, + 0x286f : 0x100286f, + 0x2870 : 0x1002870, + 0x2871 : 0x1002871, + 0x2872 : 0x1002872, + 0x2873 : 0x1002873, + 0x2874 : 0x1002874, + 0x2875 : 0x1002875, + 0x2876 : 0x1002876, + 0x2877 : 0x1002877, + 0x2878 : 0x1002878, + 0x2879 : 0x1002879, + 0x287a : 0x100287a, + 0x287b : 0x100287b, + 0x287c : 0x100287c, + 0x287d : 0x100287d, + 0x287e : 0x100287e, + 0x287f : 0x100287f, + 0x2880 : 0x1002880, + 0x2881 : 0x1002881, + 0x2882 : 0x1002882, + 0x2883 : 0x1002883, + 0x2884 : 0x1002884, + 0x2885 : 0x1002885, + 0x2886 : 0x1002886, + 0x2887 : 0x1002887, + 0x2888 : 0x1002888, + 0x2889 : 0x1002889, + 0x288a : 0x100288a, + 0x288b : 0x100288b, + 0x288c : 0x100288c, + 0x288d : 0x100288d, + 0x288e : 0x100288e, + 0x288f : 0x100288f, + 0x2890 : 0x1002890, + 0x2891 : 0x1002891, + 0x2892 : 0x1002892, + 0x2893 : 0x1002893, + 0x2894 : 0x1002894, + 0x2895 : 0x1002895, + 0x2896 : 0x1002896, + 0x2897 : 0x1002897, + 0x2898 : 0x1002898, + 0x2899 : 0x1002899, + 0x289a : 0x100289a, + 0x289b : 0x100289b, + 0x289c : 0x100289c, + 0x289d : 0x100289d, + 0x289e : 0x100289e, + 0x289f : 0x100289f, + 0x28a0 : 0x10028a0, + 0x28a1 : 0x10028a1, + 0x28a2 : 0x10028a2, + 0x28a3 : 0x10028a3, + 0x28a4 : 0x10028a4, + 0x28a5 : 0x10028a5, + 0x28a6 : 0x10028a6, + 0x28a7 : 0x10028a7, + 0x28a8 : 0x10028a8, + 0x28a9 : 0x10028a9, + 0x28aa : 0x10028aa, + 0x28ab : 0x10028ab, + 0x28ac : 0x10028ac, + 0x28ad : 0x10028ad, + 0x28ae : 0x10028ae, + 0x28af : 0x10028af, + 0x28b0 : 0x10028b0, + 0x28b1 : 0x10028b1, + 0x28b2 : 0x10028b2, + 0x28b3 : 0x10028b3, + 0x28b4 : 0x10028b4, + 0x28b5 : 0x10028b5, + 0x28b6 : 0x10028b6, + 0x28b7 : 0x10028b7, + 0x28b8 : 0x10028b8, + 0x28b9 : 0x10028b9, + 0x28ba : 0x10028ba, + 0x28bb : 0x10028bb, + 0x28bc : 0x10028bc, + 0x28bd : 0x10028bd, + 0x28be : 0x10028be, + 0x28bf : 0x10028bf, + 0x28c0 : 0x10028c0, + 0x28c1 : 0x10028c1, + 0x28c2 : 0x10028c2, + 0x28c3 : 0x10028c3, + 0x28c4 : 0x10028c4, + 0x28c5 : 0x10028c5, + 0x28c6 : 0x10028c6, + 0x28c7 : 0x10028c7, + 0x28c8 : 0x10028c8, + 0x28c9 : 0x10028c9, + 0x28ca : 0x10028ca, + 0x28cb : 0x10028cb, + 0x28cc : 0x10028cc, + 0x28cd : 0x10028cd, + 0x28ce : 0x10028ce, + 0x28cf : 0x10028cf, + 0x28d0 : 0x10028d0, + 0x28d1 : 0x10028d1, + 0x28d2 : 0x10028d2, + 0x28d3 : 0x10028d3, + 0x28d4 : 0x10028d4, + 0x28d5 : 0x10028d5, + 0x28d6 : 0x10028d6, + 0x28d7 : 0x10028d7, + 0x28d8 : 0x10028d8, + 0x28d9 : 0x10028d9, + 0x28da : 0x10028da, + 0x28db : 0x10028db, + 0x28dc : 0x10028dc, + 0x28dd : 0x10028dd, + 0x28de : 0x10028de, + 0x28df : 0x10028df, + 0x28e0 : 0x10028e0, + 0x28e1 : 0x10028e1, + 0x28e2 : 0x10028e2, + 0x28e3 : 0x10028e3, + 0x28e4 : 0x10028e4, + 0x28e5 : 0x10028e5, + 0x28e6 : 0x10028e6, + 0x28e7 : 0x10028e7, + 0x28e8 : 0x10028e8, + 0x28e9 : 0x10028e9, + 0x28ea : 0x10028ea, + 0x28eb : 0x10028eb, + 0x28ec : 0x10028ec, + 0x28ed : 0x10028ed, + 0x28ee : 0x10028ee, + 0x28ef : 0x10028ef, + 0x28f0 : 0x10028f0, + 0x28f1 : 0x10028f1, + 0x28f2 : 0x10028f2, + 0x28f3 : 0x10028f3, + 0x28f4 : 0x10028f4, + 0x28f5 : 0x10028f5, + 0x28f6 : 0x10028f6, + 0x28f7 : 0x10028f7, + 0x28f8 : 0x10028f8, + 0x28f9 : 0x10028f9, + 0x28fa : 0x10028fa, + 0x28fb : 0x10028fb, + 0x28fc : 0x10028fc, + 0x28fd : 0x10028fd, + 0x28fe : 0x10028fe, + 0x28ff : 0x10028ff +}; +/** + * See LICENSE file. + * + * Library namespace. + * CAAT stands for: Canvas Advanced Animation Tookit. + */ + +/** + * @namespace + */ +var CAAT= CAAT || {}; + +/** + * Common bind function. Allows to set an object's function as callback. Set for every function in the + * javascript context. + */ +Function.prototype.bind= Function.prototype.bind || function() { + var fn= this; // the function + var args= Array.prototype.slice.call(arguments); // copy the arguments. + var obj= args.shift(); // first parameter will be context 'this' + return function() { + return fn.apply( + obj, + args.concat(Array.prototype.slice.call(arguments))); + } +}; +/** + * See LICENSE file. + * + * Extend a prototype with another to form a classical OOP inheritance procedure. + * + * @param subc {object} Prototype to define the base class + * @param superc {object} Prototype to be extended (derived class). + */ +function extend(subc, superc) { + var subcp = subc.prototype; + + // Class pattern. + var F = function() { + }; + F.prototype = superc.prototype; + + subc.prototype = new F(); // chain prototypes. + subc.superclass = superc.prototype; + subc.prototype.constructor = subc; + + // Reset constructor. See Object Oriented Javascript for an in-depth explanation of this. + if (superc.prototype.constructor === Object.prototype.constructor) { + superc.prototype.constructor = superc; + } + + // los metodos de superc, que no esten en esta clase, crear un metodo que + // llama al metodo de superc. + for (var method in subcp) { + if (subcp.hasOwnProperty(method)) { + subc.prototype[method] = subcp[method]; + +/** + * Sintactic sugar to add a __super attribute on every overriden method. + * Despite comvenient, it slows things down by 5fps. + * + * Uncomment at your own risk. + * + // tenemos en super un metodo con igual nombre. + if ( superc.prototype[method]) { + subc.prototype[method]= (function(fn, fnsuper) { + return function() { + var prevMethod= this.__super; + + this.__super= fnsuper; + + var retValue= fn.apply( + this, + Array.prototype.slice.call(arguments) ); + + this.__super= prevMethod; + + return retValue; + }; + })(subc.prototype[method], superc.prototype[method]); + } + */ + } + } +} + +/** + * Dynamic Proxy for an object or wrap/decorate a function. + * + * @param object + * @param preMethod + * @param postMethod + * @param errorMethod + */ +function proxy(object, preMethod, postMethod, errorMethod) { + + // proxy a function + if ( typeof object==='function' ) { + + if ( object.__isProxy ) { + return object; + } + + return (function(fn) { + var proxyfn= function() { + if ( preMethod ) { + preMethod({ + fn: fn, + arguments: Array.prototype.slice.call(arguments)} ); + } + var retValue= null; + try { + // apply original function call with itself as context + retValue= fn.apply(fn, Array.prototype.slice.call(arguments)); + // everything went right on function call, then call + // post-method hook if present + if ( postMethod ) { + postMethod({ + fn: fn, + arguments: Array.prototype.slice.call(arguments)} ); + } + } catch(e) { + // an exeception was thrown, call exception-method hook if + // present and return its result as execution result. + if( errorMethod ) { + retValue= errorMethod({ + fn: fn, + arguments: Array.prototype.slice.call(arguments), + exception: e} ); + } else { + // since there's no error hook, just throw the exception + throw e; + } + } + + // return original returned value to the caller. + return retValue; + }; + proxyfn.__isProxy= true; + return proxyfn; + + })(object); + } + + /** + * If not a function then only non privitive objects can be proxied. + * If it is a previously created proxy, return the proxy itself. + */ + if ( !typeof object==='object' || + object.constructor===Array || + object.constructor===String || + object.__isProxy ) { + + return object; + } + + // Our proxy object class. + var cproxy= function() {}; + // A new proxy instance. + var proxy= new cproxy(); + // hold the proxied object as member. Needed to assign proper + // context on proxy method call. + proxy.__object= object; + proxy.__isProxy= true; + + // For every element in the object to be proxied + for( var method in object ) { + // only function members + if ( typeof object[method]==='function' ) { + // add to the proxy object a method of equal signature to the + // method present at the object to be proxied. + // cache references of object, function and function name. + proxy[method]= (function(proxy,fn,method) { + return function() { + // call pre-method hook if present. + if ( preMethod ) { + preMethod({ + object: proxy.__object, + method: method, + arguments: Array.prototype.slice.call(arguments)} ); + } + var retValue= null; + try { + // apply original object call with proxied object as + // function context. + retValue= fn.apply( proxy.__object, arguments ); + // everything went right on function call, the call + // post-method hook if present + if ( postMethod ) { + postMethod({ + object: proxy.__object, + method: method, + arguments: Array.prototype.slice.call(arguments)} ); + } + } catch(e) { + // an exeception was thrown, call exception-method hook if + // present and return its result as execution result. + if( errorMethod ) { + retValue= errorMethod({ + object: proxy.__object, + method: method, + arguments: Array.prototype.slice.call(arguments), + exception: e} ); + } else { + // since there's no error hook, just throw the exception + throw e; + } + } + + // return original returned value to the caller. + return retValue; + }; + })(proxy,object[method],method); + } + } + + // return our newly created and populated of functions proxy object. + return proxy; +} + +/** proxy sample usage + +var c0= new Meetup.C1(5); + +var cp1= proxy( + c1, + function() { + console.log('pre method on object: ', + arguments[0].object.toString(), + arguments[0].method, + arguments[0].arguments ); + }, + function() { + console.log('post method on object: ', + arguments[0].object.toString(), + arguments[0].method, + arguments[0].arguments ); + + }, + function() { + console.log('exception on object: ', + arguments[0].object.toString(), + arguments[0].method, + arguments[0].arguments, + arguments[0].exception); + + return -1; + }); + **//** + * See LICENSE file. + * + * Manages every Actor affine transformations. + * Take into account that Canvas' renderingContext computes postive rotation clockwise, so hacks + * to handle it properly are hardcoded. + * + * Contained classes are CAAT.Matrix and CAAT.MatrixStack. + * + **/ + +(function() { + + /** + * + * Define a matrix to hold three dimensional affine transforms. + * + * @constructor + */ + CAAT.Matrix3= function() { + this.matrix= [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + + this.fmatrix= [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; + + return this; + }; + + CAAT.Matrix3.prototype= { + matrix: null, + fmatrix:null, + + transformCoord : function(point) { + var x= point.x; + var y= point.y; + var z= point.z; + + point.x= x*this.matrix[0][0] + y*this.matrix[0][1] + z*this.matrix[0][2] + this.matrix[0][3]; + point.y= x*this.matrix[1][0] + y*this.matrix[1][1] + z*this.matrix[1][2] + this.matrix[1][3]; + point.z= x*this.matrix[2][0] + y*this.matrix[2][1] + z*this.matrix[2][2] + this.matrix[2][3]; + + return point; + }, + initialize : function( x0,y0,z0, x1,y1,z1, x2,y2,z2 ) { + this.identity( ); + this.matrix[0][0]= x0; + this.matrix[0][1]= y0; + this.matrix[0][2]= z0; + + this.matrix[1][0]= x1; + this.matrix[1][1]= y1; + this.matrix[1][2]= z1; + + this.matrix[2][0]= x2; + this.matrix[2][1]= y2; + this.matrix[2][2]= z2; + + return this; + }, + initWithMatrix : function(matrixData) { + this.matrix= matrixData; + return this; + }, + flatten : function() { + var d= this.fmatrix; + var s= this.matrix; + d[ 0]= s[0][0]; + d[ 1]= s[1][0]; + d[ 2]= s[2][0]; + d[ 3]= s[3][0]; + + d[ 4]= s[0][1]; + d[ 5]= s[1][1]; + d[ 6]= s[2][1]; + d[ 7]= s[2][1]; + + d[ 8]= s[0][2]; + d[ 9]= s[1][2]; + d[10]= s[2][2]; + d[11]= s[3][2]; + + d[12]= s[0][3]; + d[13]= s[1][3]; + d[14]= s[2][3]; + d[15]= s[3][3]; + + return this.fmatrix; + }, + + /** + * Set this matrix to identity matrix. + * @return this + */ + identity : function() { + for( var i=0; i<4; i++ ) { + for( var j=0; j<4; j++ ) { + this.matrix[i][j]= (i===j) ? 1.0 : 0.0; + } + } + + return this; + }, + /** + * Get this matri'x internal representation data. The bakced structure is a 4x4 array of number. + */ + getMatrix : function() { + return this.matrix; + }, + /** + * Multiply this matrix by a created rotation matrix. The rotation matrix is set up to rotate around + * xy axis. + * + * @param xy {Number} radians to rotate. + * + * @return this + */ + rotateXY : function( xy ) { + return this.rotate( xy, 0, 0 ); + }, + /** + * Multiply this matrix by a created rotation matrix. The rotation matrix is set up to rotate around + * xz axis. + * + * @param xz {Number} radians to rotate. + * + * @return this + */ + rotateXZ : function( xz ) { + return this.rotate( 0, xz, 0 ); + }, + /** + * Multiply this matrix by a created rotation matrix. The rotation matrix is set up to rotate aroind + * yz axis. + * + * @param yz {Number} radians to rotate. + * + * @return this + */ + rotateYZ : function( yz ) { + return this.rotate( 0, 0, yz ); + }, + /** + * + * @param xy + * @param xz + * @param yz + */ + setRotate : function( xy, xz, yz ) { + var m= this.rotate(xy,xz,yz); + this.copy(m); + return this; + }, + /** + * Creates a matrix to represent arbitrary rotations around the given planes. + * @param xy {number} radians to rotate around xy plane. + * @param xz {number} radians to rotate around xz plane. + * @param yz {number} radians to rotate around yz plane. + * + * @return {CAAT.Matrix3} a newly allocated matrix. + * @static + */ + rotate : function( xy, xz, yz ) { + var res=new CAAT.Matrix3(); + var s,c,m; + + if (xy!==0) { + m =new CAAT.Matrix3( ); + s=Math.sin(xy); + c=Math.cos(xy); + m.matrix[1][1]=c; + m.matrix[1][2]=-s; + m.matrix[2][1]=s; + m.matrix[2][2]=c; + res.multiply(m); + } + + if (xz!==0) { + m =new CAAT.Matrix3( ); + s=Math.sin(xz); + c=Math.cos(xz); + m.matrix[0][0]=c; + m.matrix[0][2]=-s; + m.matrix[2][0]=s; + m.matrix[2][2]=c; + res.multiply(m); + } + + if (yz!==0) { + m =new CAAT.Matrix3( ); + s=Math.sin(yz); + c=Math.cos(yz); + m.matrix[0][0]=c; + m.matrix[0][1]=-s; + m.matrix[1][0]=s; + m.matrix[1][1]=c; + res.multiply(m); + } + + return res; + }, + /** + * Creates a new matrix being a copy of this matrix. + * @return {CAAT.Matrix3} a newly allocated matrix object. + */ + getClone : function() { + var m= new CAAT.Matrix3( ); + m.copy(this); + return m; + }, + /** + * Multiplies this matrix by another matrix. + * + * @param n {CAAT.Matrix3} a CAAT.Matrix3 object. + * @return this + */ + multiply : function( m ) { + var n= this.getClone( ); + + var nm= n.matrix; + var n00= nm[0][0]; + var n01= nm[0][1]; + var n02= nm[0][2]; + var n03= nm[0][3]; + + var n10= nm[1][0]; + var n11= nm[1][1]; + var n12= nm[1][2]; + var n13= nm[1][3]; + + var n20= nm[2][0]; + var n21= nm[2][1]; + var n22= nm[2][2]; + var n23= nm[2][3]; + + var n30= nm[3][0]; + var n31= nm[3][1]; + var n32= nm[3][2]; + var n33= nm[3][3]; + + var mm= m.matrix; + var m00= mm[0][0]; + var m01= mm[0][1]; + var m02= mm[0][2]; + var m03= mm[0][3]; + + var m10= mm[1][0]; + var m11= mm[1][1]; + var m12= mm[1][2]; + var m13= mm[1][3]; + + var m20= mm[2][0]; + var m21= mm[2][1]; + var m22= mm[2][2]; + var m23= mm[2][3]; + + var m30= mm[3][0]; + var m31= mm[3][1]; + var m32= mm[3][2]; + var m33= mm[3][3]; + + this.matrix[0][0] = n00*m00 + n01*m10 + n02*m20 + n03*m30; + this.matrix[0][1] = n00*m01 + n01*m11 + n02*m21 + n03*m31; + this.matrix[0][2] = n00*m02 + n01*m12 + n02*m22 + n03*m32; + this.matrix[0][3] = n00*m03 + n01*m13 + n02*m23 + n03*m33; + + this.matrix[1][0] = n10*m00 + n11*m10 + n12*m20 + n13*m30; + this.matrix[1][1] = n10*m01 + n11*m11 + n12*m21 + n13*m31; + this.matrix[1][2] = n10*m02 + n11*m12 + n12*m22 + n13*m32; + this.matrix[1][3] = n10*m03 + n11*m13 + n12*m23 + n13*m33; + + this.matrix[2][0] = n20*m00 + n21*m10 + n22*m20 + n23*m30; + this.matrix[2][1] = n20*m01 + n21*m11 + n22*m21 + n23*m31; + this.matrix[2][2] = n20*m02 + n21*m12 + n22*m22 + n23*m32; + this.matrix[2][3] = n20*m03 + n21*m13 + n22*m23 + n23*m33; + + return this; + }, + /** + * Pre multiplies this matrix by a given matrix. + * + * @param m {CAAT.Matrix3} a CAAT.Matrix3 object. + * + * @return this + */ + premultiply : function(m) { + var n= this.getClone( ); + + var nm= n.matrix; + var n00= nm[0][0]; + var n01= nm[0][1]; + var n02= nm[0][2]; + var n03= nm[0][3]; + + var n10= nm[1][0]; + var n11= nm[1][1]; + var n12= nm[1][2]; + var n13= nm[1][3]; + + var n20= nm[2][0]; + var n21= nm[2][1]; + var n22= nm[2][2]; + var n23= nm[2][3]; + + var n30= nm[3][0]; + var n31= nm[3][1]; + var n32= nm[3][2]; + var n33= nm[3][3]; + + var mm= m.matrix; + var m00= mm[0][0]; + var m01= mm[0][1]; + var m02= mm[0][2]; + var m03= mm[0][3]; + + var m10= mm[1][0]; + var m11= mm[1][1]; + var m12= mm[1][2]; + var m13= mm[1][3]; + + var m20= mm[2][0]; + var m21= mm[2][1]; + var m22= mm[2][2]; + var m23= mm[2][3]; + + var m30= mm[3][0]; + var m31= mm[3][1]; + var m32= mm[3][2]; + var m33= mm[3][3]; + + this.matrix[0][0] = n00*m00 + n01*m10 + n02*m20; + this.matrix[0][1] = n00*m01 + n01*m11 + n02*m21; + this.matrix[0][2] = n00*m02 + n01*m12 + n02*m22; + this.matrix[0][3] = n00*m03 + n01*m13 + n02*m23 + n03; + this.matrix[1][0] = n10*m00 + n11*m10 + n12*m20; + this.matrix[1][1] = n10*m01 + n11*m11 + n12*m21; + this.matrix[1][2] = n10*m02 + n11*m12 + n12*m22; + this.matrix[1][3] = n10*m03 + n11*m13 + n12*m23 + n13; + this.matrix[2][0] = n20*m00 + n21*m10 + n22*m20; + this.matrix[2][1] = n20*m01 + n21*m11 + n22*m21; + this.matrix[2][2] = n20*m02 + n21*m12 + n22*m22; + this.matrix[2][3] = n20*m03 + n21*m13 + n22*m23 + n23; + + return this; + }, + /** + * Set this matrix translation values to be the given parameters. + * + * @param x {number} x component of translation point. + * @param y {number} y component of translation point. + * @param z {number} z component of translation point. + * + * @return this + */ + setTranslate : function(x,y,z) { + this.identity(); + this.matrix[0][3]=x; + this.matrix[1][3]=y; + this.matrix[2][3]=z; + return this; + }, + /** + * Create a translation matrix. + * @param x {number} + * @param y {number} + * @param z {number} + * @return {CAAT.Matrix3} a new matrix. + */ + translate : function( x,y,z ) { + var m= new CAAT.Matrix3(); + m.setTranslate( x,y,z ); + return m; + }, + setScale : function( sx, sy, sz ) { + this.identity(); + this.matrix[0][0]= sx; + this.matrix[1][1]= sy; + this.matrix[2][2]= sz; + return this; + }, + scale : function( sx, sy, sz ) { + var m= new CAAT.Matrix3(); + m.setScale(sx,sy,sz); + return m; + }, + /** + * Set this matrix as the rotation matrix around the given axes. + * @param xy {number} radians of rotation around z axis. + * @param xz {number} radians of rotation around y axis. + * @param yz {number} radians of rotation around x axis. + * + * @return this + */ + rotateModelView : function( xy, xz, yz ) { + var sxy= Math.sin( xy ); + var sxz= Math.sin( xz ); + var syz= Math.sin( yz ); + var cxy= Math.cos( xy ); + var cxz= Math.cos( xz ); + var cyz= Math.cos( yz ); + + this.matrix[0][0]= cxz*cxy; + this.matrix[0][1]= -cxz*sxy; + this.matrix[0][2]= sxz; + this.matrix[0][3]= 0; + this.matrix[1][0]= syz*sxz*cxy+sxy*cyz; + this.matrix[1][1]= cyz*cxy-syz*sxz*sxy; + this.matrix[1][2]= -syz*cxz; + this.matrix[1][3]= 0; + this.matrix[2][0]= syz*sxy-cyz*sxz*cxy; + this.matrix[2][1]= cyz*sxz*sxy+syz*cxy; + this.matrix[2][2]= cyz*cxz; + this.matrix[2][3]= 0; + this.matrix[3][0]= 0; + this.matrix[3][1]= 0; + this.matrix[3][2]= 0; + this.matrix[3][3]= 1; + + return this; + }, + /** + * Copy a given matrix values into this one's. + * @param m {CAAT.Matrix} a matrix + * + * @return this + */ + copy : function( m ) { + for( var i=0; i<4; i++ ) { + for( var j=0; j<4; j++ ) { + this.matrix[i][j]= m.matrix[i][j]; + } + } + + return this; + }, + /** + * Calculate this matrix's determinant. + * @return {number} matrix determinant. + */ + calculateDeterminant: function () { + + var mm= this.matrix; + var m11= mm[0][0], m12= mm[0][1], m13= mm[0][2], m14= mm[0][3], + m21= mm[1][0], m22= mm[1][1], m23= mm[1][2], m24= mm[1][3], + m31= mm[2][0], m32= mm[2][1], m33= mm[2][2], m34= mm[2][3], + m41= mm[3][0], m42= mm[3][1], m43= mm[3][2], m44= mm[3][3]; + + return m14 * m22 * m33 * m41 + + m12 * m24 * m33 * m41 + + m14 * m23 * m31 * m42 + + m13 * m24 * m31 * m42 + + + m13 * m21 * m34 * m42 + + m11 * m23 * m34 * m42 + + m14 * m21 * m32 * m43 + + m11 * m24 * m32 * m43 + + + m13 * m22 * m31 * m44 + + m12 * m23 * m31 * m44 + + m12 * m21 * m33 * m44 + + m11 * m22 * m33 * m44 + + + m14 * m23 * m32 * m41 - + m13 * m24 * m32 * m41 - + m13 * m22 * m34 * m41 - + m12 * m23 * m34 * m41 - + + m14 * m21 * m33 * m42 - + m11 * m24 * m33 * m42 - + m14 * m22 * m31 * m43 - + m12 * m24 * m31 * m43 - + + m12 * m21 * m34 * m43 - + m11 * m22 * m34 * m43 - + m13 * m21 * m32 * m44 - + m11 * m23 * m32 * m44; + }, + /** + * Return a new matrix which is this matrix's inverse matrix. + * @return {CAAT.Matrix3} a new matrix. + */ + getInverse : function() { + var mm= this.matrix; + var m11 = mm[0][0], m12 = mm[0][1], m13 = mm[0][2], m14 = mm[0][3], + m21 = mm[1][0], m22 = mm[1][1], m23 = mm[1][2], m24 = mm[1][3], + m31 = mm[2][0], m32 = mm[2][1], m33 = mm[2][2], m34 = mm[2][3], + m41 = mm[3][0], m42 = mm[3][1], m43 = mm[3][2], m44 = mm[3][3]; + + var m2= new CAAT.Matrix3(); + m2.matrix[0][0]= m23*m34*m42 + m24*m32*m43 + m22*m33*m44 - m24*m33*m42 - m22*m34*m43 - m23*m32*m44; + m2.matrix[0][1]= m14*m33*m42 + m12*m34*m43 + m13*m32*m44 - m12*m33*m44 - m13*m34*m42 - m14*m32*m43; + m2.matrix[0][2]= m13*m24*m42 + m12*m23*m44 + m14*m22*m43 - m12*m24*m43 - m13*m22*m44 - m14*m23*m42; + m2.matrix[0][3]= m14*m23*m32 + m12*m24*m33 + m13*m22*m34 - m13*m24*m32 - m14*m22*m33 - m12*m23*m34; + + m2.matrix[1][0]= m24*m33*m41 + m21*m34*m43 + m23*m31*m44 - m23*m34*m41 - m24*m31*m43 - m21*m33*m44; + m2.matrix[1][1]= m13*m34*m41 + m14*m31*m43 + m11*m33*m44 - m14*m33*m41 - m11*m34*m43 - m13*m31*m44; + m2.matrix[1][2]= m14*m23*m41 + m11*m24*m43 + m13*m21*m44 - m13*m24*m41 - m14*m21*m43 - m11*m23*m44; + m2.matrix[1][3]= m13*m24*m31 + m14*m21*m33 + m11*m23*m34 - m14*m23*m31 - m11*m24*m33 - m13*m21*m34; + + m2.matrix[2][0]= m22*m34*m41 + m24*m31*m42 + m21*m32*m44 - m24*m32*m41 - m21*m34*m42 - m22*m31*m44; + m2.matrix[2][1]= m14*m32*m41 + m11*m34*m42 + m12*m31*m44 - m11*m32*m44 - m12*m34*m41 - m14*m31*m42; + m2.matrix[2][2]= m13*m24*m41 + m14*m21*m42 + m11*m22*m44 - m14*m22*m41 - m11*m24*m42 - m12*m21*m44; + m2.matrix[2][3]= m14*m22*m31 + m11*m24*m32 + m12*m21*m34 - m11*m22*m34 - m12*m24*m31 - m14*m21*m32; + + m2.matrix[3][0]= m23*m32*m41 + m21*m33*m42 + m22*m31*m43 - m22*m33*m41 - m23*m31*m42 - m21*m32*m43; + m2.matrix[3][1]= m12*m33*m41 + m13*m31*m42 + m11*m32*m43 - m13*m32*m41 - m11*m33*m42 - m12*m31*m43; + m2.matrix[3][2]= m13*m22*m41 + m11*m23*m42 + m12*m21*m43 - m11*m22*m43 - m12*m23*m41 - m13*m21*m42; + m2.matrix[3][3]= m12*m23*m31 + m13*m21*m32 + m11*m22*m33 - m13*m22*m31 - m11*m23*m32 - m12*m21*m33; + + return m2.multiplyScalar( 1/this.calculateDeterminant() ); + }, + /** + * Multiply this matrix by a scalar. + * @param scalar {number} scalar value + * + * @return this + */ + multiplyScalar : function( scalar ) { + var i,j; + + for( i=0; i<4; i++ ) { + for( j=0; j<4; j++ ) { + this.matrix[i][j]*=scalar; + } + } + + return this; + } + + }; + +})(); + +(function() { + + /** + * 2D affinetransform matrix represeantation. + * It includes matrices for + *
    + *
  • Rotation by any anchor point + *
  • translation + *
  • scale by any anchor point + *
+ * + */ + CAAT.Matrix = function() { + this.matrix= [ + 1.0,0.0,0.0, + 0.0,1.0,0.0, 0.0,0.0,1.0 ]; + return this; + }; + + CAAT.Matrix.prototype= { + matrix: null, + + /** + * Transform a point by this matrix. The parameter point will be modified with the transformation values. + * @param point {CAAT.Point}. + * @return {CAAT.Point} the parameter point. + */ + transformCoord : function(point) { + var x= point.x; + var y= point.y; + + var tm= this.matrix; + + point.x= x*tm[0] + y*tm[1] + tm[2]; + point.y= x*tm[3] + y*tm[4] + tm[5]; + + return point; + }, + /** + * Create a new rotation matrix and set it up for the specified angle in radians. + * @param angle {number} + * @return {CAAT.Matrix} a matrix object. + * + * @static + */ + rotate : function(angle) { + var m= new CAAT.Matrix(); + m.setRotation(angle); + return m; + }, + setRotation : function( angle ) { + + this.identity(); + + var tm= this.matrix; + var c= Math.cos( angle ); + var s= Math.sin( angle ); + tm[0]= c; + tm[1]= -s; + tm[3]= s; + tm[4]= c; + + return this; + }, + /** + * Create a scale matrix. + * @param scalex {number} x scale magnitude. + * @param scaley {number} y scale magnitude. + * + * @return {CAAT.Matrix} a matrix object. + * + * @static + */ + scale : function(scalex, scaley) { + var m= new CAAT.Matrix(); + + m.matrix[0]= scalex; + m.matrix[4]= scaley; + + return m; + }, + setScale : function(scalex, scaley) { + this.identity(); + + this.matrix[0]= scalex; + this.matrix[4]= scaley; + + return this; + }, + /** + * Create a translation matrix. + * @param x {number} x translation magnitude. + * @param y {number} y translation magnitude. + * + * @return {CAAT.Matrix} a matrix object. + * @static + * + */ + translate : function( x, y ) { + var m= new CAAT.Matrix(); + + m.matrix[2]= x; + m.matrix[5]= y; + + return m; + }, + /** + * Sets this matrix as a translation matrix. + * @param x + * @param y + */ + setTranslate : function( x, y ) { + this.identity(); + + this.matrix[2]= x; + this.matrix[5]= y; + + return this; + }, + /** + * Copy into this matrix the given matrix values. + * @param matrix {CAAT.Matrix} + * @return this + */ + copy : function( matrix ) { + matrix= matrix.matrix; + + var tmatrix= this.matrix; + tmatrix[0]= matrix[0]; + tmatrix[1]= matrix[1]; + tmatrix[2]= matrix[2]; + tmatrix[3]= matrix[3]; + tmatrix[4]= matrix[4]; + tmatrix[5]= matrix[5]; + tmatrix[6]= matrix[6]; + tmatrix[7]= matrix[7]; + tmatrix[8]= matrix[8]; + + return this; + }, + /** + * Set this matrix to the identity matrix. + * @return this + */ + identity : function() { + + var m= this.matrix; + m[0]= 1.0; + m[1]= 0.0; + m[2]= 0.0; + + m[3]= 0.0; + m[4]= 1.0; + m[5]= 0.0; + + m[6]= 0.0; + m[7]= 0.0; + m[8]= 1.0; + + return this; + }, + /** + * Multiply this matrix by a given matrix. + * @param m {CAAT.Matrix} + * @return this + */ + multiply : function( m ) { + + var tm= this.matrix; + var mm= m.matrix; + + var tm0= tm[0]; + var tm1= tm[1]; + var tm2= tm[2]; + var tm3= tm[3]; + var tm4= tm[4]; + var tm5= tm[5]; + var tm6= tm[6]; + var tm7= tm[7]; + var tm8= tm[8]; + + var mm0= mm[0]; + var mm1= mm[1]; + var mm2= mm[2]; + var mm3= mm[3]; + var mm4= mm[4]; + var mm5= mm[5]; + var mm6= mm[6]; + var mm7= mm[7]; + var mm8= mm[8]; + + tm[0]= tm0*mm0 + tm1*mm3 + tm2*mm6; + tm[1]= tm0*mm1 + tm1*mm4 + tm2*mm7; + tm[2]= tm0*mm2 + tm1*mm5 + tm2*mm8; + tm[3]= tm3*mm0 + tm4*mm3 + tm5*mm6; + tm[4]= tm3*mm1 + tm4*mm4 + tm5*mm7; + tm[5]= tm3*mm2 + tm4*mm5 + tm5*mm8; + tm[6]= tm6*mm0 + tm7*mm3 + tm8*mm6; + tm[7]= tm6*mm1 + tm7*mm4 + tm8*mm7; + tm[8]= tm6*mm2 + tm7*mm5 + tm8*mm8; + + return this; + }, + /** + * Premultiply this matrix by a given matrix. + * @param m {CAAT.Matrix} + * @return this + */ + premultiply : function(m) { + + var m00= m.matrix[0]*this.matrix[0] + m.matrix[1]*this.matrix[3] + m.matrix[2]*this.matrix[6]; + var m01= m.matrix[0]*this.matrix[1] + m.matrix[1]*this.matrix[4] + m.matrix[2]*this.matrix[7]; + var m02= m.matrix[0]*this.matrix[2] + m.matrix[1]*this.matrix[5] + m.matrix[2]*this.matrix[8]; + + var m10= m.matrix[3]*this.matrix[0] + m.matrix[4]*this.matrix[3] + m.matrix[5]*this.matrix[6]; + var m11= m.matrix[3]*this.matrix[1] + m.matrix[4]*this.matrix[4] + m.matrix[5]*this.matrix[7]; + var m12= m.matrix[3]*this.matrix[2] + m.matrix[4]*this.matrix[5] + m.matrix[5]*this.matrix[8]; + + var m20= m.matrix[6]*this.matrix[0] + m.matrix[7]*this.matrix[3] + m.matrix[8]*this.matrix[6]; + var m21= m.matrix[6]*this.matrix[1] + m.matrix[7]*this.matrix[4] + m.matrix[8]*this.matrix[7]; + var m22= m.matrix[6]*this.matrix[2] + m.matrix[7]*this.matrix[5] + m.matrix[8]*this.matrix[8]; + + this.matrix[0]= m00; + this.matrix[1]= m01; + this.matrix[2]= m02; + + this.matrix[3]= m10; + this.matrix[4]= m11; + this.matrix[5]= m12; + + this.matrix[6]= m20; + this.matrix[7]= m21; + this.matrix[8]= m22; + + + return this; + }, + /** + * Creates a new inverse matrix from this matrix. + * @return {CAAT.Matrix} an inverse matrix. + */ + getInverse : function() { + var tm= this.matrix; + + var m00= tm[0]; + var m01= tm[1]; + var m02= tm[2]; + var m10= tm[3]; + var m11= tm[4]; + var m12= tm[5]; + var m20= tm[6]; + var m21= tm[7]; + var m22= tm[8]; + + var newMatrix= new CAAT.Matrix(); + + var determinant= m00* (m11*m22 - m21*m12) - m10*(m01*m22 - m21*m02) + m20 * (m01*m12 - m11*m02); + if ( determinant===0 ) { + return null; + } + + var m= newMatrix.matrix; + + m[0]= m11*m22-m12*m21; + m[1]= m02*m21-m01*m22; + m[2]= m01*m12-m02*m11; + + m[3]= m12*m20-m10*m22; + m[4]= m00*m22-m02*m20; + m[5]= m02*m10-m00*m12; + + m[6]= m10*m21-m11*m20; + m[7]= m01*m20-m00*m21; + m[8]= m00*m11-m01*m10; + + newMatrix.multiplyScalar( 1/determinant ); + + return newMatrix; + }, + /** + * Multiply this matrix by a scalar. + * @param scalar {number} scalar value + * + * @return this + */ + multiplyScalar : function( scalar ) { + var i; + + for( i=0; i<9; i++ ) { + this.matrix[i]*=scalar; + } + + return this; + }, + + transformRenderingContextSet : null, + + transformRenderingContext : null, + + /** + * + * @param ctx + */ + transformRenderingContextSet_NoClamp : function(ctx) { + var m= this.matrix; + ctx.setTransform( m[0], m[3], m[1], m[4], m[2], m[5] ); + return this; + }, + + /** + * + * @param ctx + */ + transformRenderingContext_NoClamp : function(ctx) { + var m= this.matrix; + ctx.transform( m[0], m[3], m[1], m[4], m[2], m[5] ); + return this; + }, + + /** + * + * @param ctx + */ + transformRenderingContextSet_Clamp : function(ctx) { + var m= this.matrix; + ctx.setTransform( m[0], m[3], m[1], m[4], m[2]>>0, m[5]>>0 ); + return this; + }, + + /** + * + * @param ctx + */ + transformRenderingContext_Clamp : function(ctx) { + var m= this.matrix; + ctx.transform( m[0], m[3], m[1], m[4], m[2]>>0, m[5]>>0 ); + return this; + } + + }; + + CAAT.Matrix.prototype.transformRenderingContext= CAAT.Matrix.prototype.transformRenderingContext_Clamp; + CAAT.Matrix.prototype.transformRenderingContextSet= CAAT.Matrix.prototype.transformRenderingContextSet_Clamp; + +})(); + +(function() { + /** + * Implementation of a matrix stack. Each CAAT.Actor instance contains a MatrixStack to hold of its affine + * transformations. The Canvas rendering context will be fed with this matrix stack values to keep a homogeneous + * transformation process. + * + * @constructor + */ + CAAT.MatrixStack= function() { + this.stack= []; + this.saved= []; + return this; + }; + + CAAT.MatrixStack.prototype= { + stack: null, + saved: null, + + /** + * Add a matrix to the transformation stack. + * @return this + */ + pushMatrix : function(matrix) { + this.stack.push(matrix); + return this; + }, + /** + * Remove the last matrix from this stack. + * @return {CAAT.Matrix} the poped matrix. + */ + popMatrix : function() { + return this.stack.pop(); + }, + /** + * Create a restoration point of pushed matrices. + * @return this + */ + save : function() { + this.saved.push(this.stack.length); + return this; + }, + /** + * Restore from the last restoration point set. + * @return this + */ + restore : function() { + var pos= this.saved.pop(); + while( this.stack.length!==pos ) { + this.popMatrix(); + } + return this; + }, + /** + * Return the concatenation (multiplication) matrix of all the matrices contained in this stack. + * @return {CAAT.Matrix} a new matrix. + */ + getMatrix : function() { + var matrix= new CAAT.Matrix(); + + for( var i=0; i + * H runs from 0 to 360 degrees
+ * S and V run from 0 to 100 + *

+ * Ported from the excellent java algorithm by Eugene Vishnevsky at: + * http://www.cs.rit.edu/~ncs/color/t_convert.html + * + * @static + */ + hsvToRgb: function(h, s, v) + { + var r, g, b; + var i; + var f, p, q, t; + + // Make sure our arguments stay in-range + h = Math.max(0, Math.min(360, h)); + s = Math.max(0, Math.min(100, s)); + v = Math.max(0, Math.min(100, v)); + + // We accept saturation and value arguments from 0 to 100 because that's + // how Photoshop represents those values. Internally, however, the + // saturation and value are calculated from a range of 0 to 1. We make + // That conversion here. + s /= 100; + v /= 100; + + if(s === 0) { + // Achromatic (grey) + r = g = b = v; + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + } + + h /= 60; // sector 0 to 5 + i = Math.floor(h); + f = h - i; // factorial part of h + p = v * (1 - s); + q = v * (1 - s * f); + t = v * (1 - s * (1 - f)); + + switch(i) { + case 0: + r = v; + g = t; + b = p; + break; + + case 1: + r = q; + g = v; + b = p; + break; + + case 2: + r = p; + g = v; + b = t; + break; + + case 3: + r = p; + g = q; + b = v; + break; + + case 4: + r = t; + g = p; + b = v; + break; + + default: // case 5: + r = v; + g = p; + b = q; + } + + return new CAAT.Color.RGB(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)); + }, + /** + * Enumeration to define types of color ramps. + * @enum {number} + */ + RampEnumeration : { + RAMP_RGBA: 0, + RAMP_RGB: 1, + RAMP_CHANNEL_RGB: 2, + RAMP_CHANNEL_RGBA: 3, + RAMP_CHANNEL_RGB_ARRAY: 4, + RAMP_CHANNEL_RGBA_ARRAY:5 + }, + + /** + * Interpolate the color between two given colors. The return value will be a calculated color + * among the two given initial colors which corresponds to the 'step'th color of the 'nsteps' + * calculated colors. + * @param r0 {number} initial color red component. + * @param g0 {number} initial color green component. + * @param b0 {number} initial color blue component. + * @param r1 {number} final color red component. + * @param g1 {number} final color green component. + * @param b1 {number} final color blue component. + * @param nsteps {number} number of colors to calculate including the two given colors. If 16 is passed as value, + * 14 colors plus the two initial ones will be calculated. + * @param step {number} return this color index of all the calculated colors. + * + * @return { r{number}, g{number}, b{number} } return an object with the new calculated color components. + * @static + */ + interpolate : function( r0, g0, b0, r1, g1, b1, nsteps, step) { + if ( step<=0 ) { + return { + r:r0, + g:g0, + b:b0 + }; + } else if ( step>=nsteps ) { + return { + r:r1, + g:g1, + b:b1 + }; + } + + var r= (r0+ (r1-r0)/nsteps*step)>>0; + var g= (g0+ (g1-g0)/nsteps*step)>>0; + var b= (b0+ (b1-b0)/nsteps*step)>>0; + + if ( r>255 ) {r=255;} else if (r<0) {r=0;} + if ( g>255 ) {g=255;} else if (g<0) {g=0;} + if ( b>255 ) {b=255;} else if (b<0) {b=0;} + + return { + r:r, + g:g, + b:b + }; + }, + /** + * Generate a ramp of colors from an array of given colors. + * @param fromColorsArray {[number]} an array of colors. each color is defined by an integer number from which + * color components will be extracted. Be aware of the alpha component since it will also be interpolated for + * new colors. + * @param rampSize {number} number of colors to produce. + * @param returnType {CAAT.ColorUtils.RampEnumeration} a value of CAAT.ColorUtils.RampEnumeration enumeration. + * + * @return { [{number},{number},{number},{number}] } an array of integers each of which represents a color of + * the calculated color ramp. + * + * @static + */ + makeRGBColorRamp : function( fromColorsArray, rampSize, returnType ) { + + var ramp= []; + var nc= fromColorsArray.length-1; + var chunk= rampSize/nc; + + for( var i=0; i>24)&0xff; + var r0= (c&0xff0000)>>16; + var g0= (c&0xff00)>>8; + var b0= c&0xff; + + var c1= fromColorsArray[i+1]; + var a1= (c1>>24)&0xff; + var r1= (c1&0xff0000)>>16; + var g1= (c1&0xff00)>>8; + var b1= c1&0xff; + + var da= (a1-a0)/chunk; + var dr= (r1-r0)/chunk; + var dg= (g1-g0)/chunk; + var db= (b1-b0)/chunk; + + for( var j=0; j>0; + var nr= (r0+dr*j)>>0; + var ng= (g0+dg*j)>>0; + var nb= (b0+db*j)>>0; + + switch( returnType ) { + case this.RampEnumeration.RAMP_RGBA: + ramp.push( 'argb('+na+','+nr+','+ng+','+nb+')' ); + break; + case this.RampEnumeration.RAMP_RGB: + ramp.push( 'rgb('+nr+','+ng+','+nb+')' ); + break; + case this.RampEnumeration.RAMP_CHANNEL_RGB: + ramp.push( 0xff000000 | nr<<16 | ng<<8 | nb ); + break; + case this.RampEnumeration.RAMP_CHANNEL_RGBA: + ramp.push( na<<24 | nr<<16 | ng<<8 | nb ); + break; + case this.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY: + ramp.push([ nr, ng, nb, na ]); + break; + case this.RampEnumeration.RAMP_CHANNEL_RGB_ARRAY: + ramp.push([ nr, ng, nb ]); + break; + } + } + } + + return ramp; + + } + }; +})(); + +(function() { + /** + * RGB color implementation + * @param r {number} an integer in the range 0..255 + * @param g {number} an integer in the range 0..255 + * @param b {number} an integer in the range 0..255 + * + * @constructor + */ + CAAT.Color.RGB = function(r, g, b) { + this.r = r || 255; + this.g = g || 255; + this.b = b || 255; + return this; + }; + CAAT.Color.RGB.prototype= { + r: 255, + g: 255, + b: 255, + + /** + * Get color hexadecimal representation. + * @return {string} a string with color hexadecimal representation. + */ + toHex: function() { + // See: http://jsperf.com/rgb-decimal-to-hex/5 + return ('000000' + ((this.r << 16) + (this.g << 8) + this.b).toString(16)).slice(-6); + } + }; +})(); +/** + * See LICENSE file. + * + * Rectangle Class. + * Needed to compute Curve bounding box. + * Needed to compute Actor affected area on change. + * + **/ + + +(function() { + /** + * A Rectangle implementation, which defines an area positioned somewhere. + * + * @constructor + */ + CAAT.Rectangle= function() { + return this; + }; + + CAAT.Rectangle.prototype= { + x: 0, + y: 0, + x1: 0, + y1: 0, + width: -1, + height: -1, + + setEmpty : function() { + this.width= -1; + this.height= -1; + this.x= 0; + this.y= 0; + this.x1= 0; + this.y1= 0; + return this; + }, + /** + * Set this rectangle's location. + * @param x {number} + * @param y {number} + */ + setLocation: function( x,y ) { + this.x= x; + this.y= y; + this.x1= this.x+this.width; + this.y1= this.y+this.height; + return this; + }, + /** + * Set this rectangle's dimension. + * @param w {number} + * @param h {number} + */ + setDimension : function( w,h ) { + this.width= w; + this.height= h; + this.x1= this.x+this.width; + this.y1= this.y+this.height; + return this; + }, + setBounds : function( x,y,w,h ) { + this.setLocation( x, y ) + this.setDimension( w, h ); + return this; + }, + /** + * Return whether the coordinate is inside this rectangle. + * @param px {number} + * @param py {number} + * + * @return {boolean} + */ + contains : function(px,py) { + return px>=0 && px=0 && pythis.y1 ) { + this.y1= py; + } + if ( px>this.x1 ){ + this.x1= px; + } + + this.width= this.x1-this.x; + this.height= this.y1-this.y; + }, + unionRectangle : function( rectangle ) { + this.union( rectangle.x , rectangle.y ); + this.union( rectangle.x1, rectangle.y ); + this.union( rectangle.x, rectangle.y1 ); + this.union( rectangle.x1, rectangle.y1 ); + return this; + }, + intersects : function( r ) { + if ( r.isEmpty() || this.isEmpty() ) { + return false; + } + + if ( r.x1< this.x ) { + return false; + } + if ( r.x > this.x1 ) { + return false; + } + if ( r.y1< this.y ) { + return false; + } + if ( r.y> this.y1 ) { + return false; + } + + return true; + }, + + intersectsRect : function( x,y,w,h ) { + if ( -1===w || -1===h ) { + return false; + } + + var x1= x+w-1; + var y1= y+h-1; + + if ( x1< this.x ) { + return false; + } + if ( x > this.x1 ) { + return false; + } + if ( y1< this.y ) { + return false; + } + if ( y> this.y1 ) { + return false; + } + + return true; + }, + + intersect : function( i, r ) { + if ( typeof r==='undefined' ) { + r= new CAAT.Rectangle(); + } + + r.x= Math.max( this.x, i.x ); + r.y= Math.max( this.y, i.y ); + r.x1=Math.min( this.x1, i.x1 ); + r.y1=Math.min( this.y1, i.y1 ); + r.width= r.x1-r.x; + r.height=r.y1-r.y; + + return r; + } + }; +})();/** + * See LICENSE file. + * + * Classes to solve and draw curves. + * Curve is the superclass of + * + Bezier (quadric and cubic) + * + TODO: Catmull Rom + * + * + **/ + +(function() { + /** + * + * Curve class is the base for all curve solvers available in CAAT. + * + * @constructor + */ + CAAT.Curve= function() { + return this; + }; + + CAAT.Curve.prototype= { + coordlist: null, + k: 0.05, + length: -1, + interpolator: false, + HANDLE_SIZE: 20, + drawHandles: true, + + /** + * Paint the curve control points. + * @param director {CAAT.Director} + */ + paint: function(director) { + if ( false===this.drawHandles ) { + return; + } + + var ctx= director.ctx; + + // control points + ctx.save(); + ctx.beginPath(); + + ctx.strokeStyle='#a0a0a0'; + ctx.moveTo( this.coordlist[0].x, this.coordlist[0].y ); + ctx.lineTo( this.coordlist[1].x, this.coordlist[1].y ); + ctx.stroke(); + if ( this.cubic ) { + ctx.moveTo( this.coordlist[2].x, this.coordlist[2].y ); + ctx.lineTo( this.coordlist[3].x, this.coordlist[3].y ); + ctx.stroke(); + } + + + ctx.globalAlpha=0.5; + for( var i=0; i=0 && index + * This object manages one single catmull rom segment, that is 4 points. + * A complete spline should be managed with CAAT.Path.setCatmullRom with a complete list of points. + * + * @constructor + * @extends CAAT.Curve + */ + CAAT.CatmullRom = function() { + CAAT.CatmullRom.superclass.constructor.call(this); + return this; + }; + + CAAT.CatmullRom.prototype= { + + /** + * Set curve control points. + * @param points Array + */ + setCurve : function( p0, p1, p2, p3 ) { + + this.coordlist= []; + this.coordlist.push( p0 ); + this.coordlist.push( p1 ); + this.coordlist.push( p2 ); + this.coordlist.push( p3 ); + + this.update(); + + return this; + }, + /** + * Paint the contour by solving again the entire curve. + * @param director {CAAT.Director} + */ + paint: function(director) { + + var x1,y1; + + // Catmull rom solves from point 1 !!! + + x1 = this.coordlist[1].x; + y1 = this.coordlist[1].y; + + var ctx= director.ctx; + + ctx.save(); + ctx.beginPath(); + ctx.moveTo(x1,y1); + + var point= new CAAT.Point(); + + for(var t=this.k;t<=1+this.k;t+=this.k){ + this.solve(point,t); + ctx.lineTo(point.x,point.y); + } + + ctx.stroke(); + ctx.restore(); + + CAAT.CatmullRom.superclass.paint.call(this,director); + }, + /** + * Solves the curve for any given parameter t. + * @param point {CAAT.Point} the point to store the solved value on the curve. + * @param t {number} a number in the range 0..1 + */ + solve: function(point,t) { + var c= this.coordlist; + + // Handy from CAKE. Thanks. + var af = ((-t+2)*t-1)*t*0.5 + var bf = (((3*t-5)*t)*t+2)*0.5 + var cf = ((-3*t+4)*t+1)*t*0.5 + var df = ((t-1)*t*t)*0.5 + + point.x= c[0].x * af + c[1].x * bf + c[2].x * cf + c[3].x * df; + point.y= c[0].y * af + c[1].y * bf + c[2].y * cf + c[3].y * df; + + return point; + + } + }; + + extend(CAAT.CatmullRom, CAAT.Curve, null); +})();/** + * See LICENSE file. + * + * Hold a 2D point information. + * Think about the possibility of turning CAAT.Point into {x:,y:}. + * + **/ +(function() { + + /** + * + * A point defined by two coordinates. + * + * @param xpos {number} + * @param ypos {number} + * + * @constructor + */ + CAAT.Point= function(xpos, ypos, zpos) { + this.x= xpos; + this.y= ypos; + this.z= zpos||0; + return this; + }; + + CAAT.Point.prototype= { + x: 0, + y: 0, + z: 0, + + /** + * Sets this point coordinates. + * @param x {number} + * @param y {number} + * + * @return this + */ + set : function(x,y,z) { + this.x= x; + this.y= y; + this.z= z||0; + return this; + }, + /** + * Create a new CAAT.Point equal to this one. + * @return {CAAT.Point} + */ + clone : function() { + var p= new CAAT.Point(this.x, this.y, this.z ); + return p; + }, + /** + * Translate this point to another position. The final point will be (point.x+x, point.y+y) + * @param x {number} + * @param y {number} + * + * @return this + */ + translate : function(x,y,z) { + this.x+= x; + this.y+= y; + this.z+= z; + + return this; + }, + /** + * Translate this point to another point. + * @param aPoint {CAAT.Point} + * @return this + */ + translatePoint: function(aPoint) { + this.x += aPoint.x; + this.y += aPoint.y; + this.z += aPoint.z; + return this; + }, + /** + * Substract a point from this one. + * @param aPoint {CAAT.Point} + * @return this + */ + subtract: function(aPoint) { + this.x -= aPoint.x; + this.y -= aPoint.y; + this.z -= aPoint.z; + return this; + }, + /** + * Multiply this point by a scalar. + * @param factor {number} + * @return this + */ + multiply: function(factor) { + this.x *= factor; + this.y *= factor; + this.z *= factor; + return this; + }, + /** + * Rotate this point by an angle. The rotation is held by (0,0) coordinate as center. + * @param angle {number} + * @return this + */ + rotate: function(angle) { + var x = this.x, y = this.y; + this.x = x * Math.cos(angle) - Math.sin(angle) * y; + this.y = x * Math.sin(angle) + Math.cos(angle) * y; + this.z = 0; + return this; + }, + /** + * + * @param angle {number} + * @return this + */ + setAngle: function(angle) { + var len = this.getLength(); + this.x = Math.cos(angle) * len; + this.y = Math.sin(angle) * len; + this.z = 0; + return this; + }, + /** + * + * @param length {number} + * @return this + */ + setLength: function(length) { + var len = this.getLength(); + if (len)this.multiply(length / len); + else this.x = this.y = this.z = length; + return this; + }, + /** + * Normalize this point, that is, both set coordinates proportionally to values raning 0..1 + * @return this + */ + normalize: function() { + var len = this.getLength(); + this.x /= len; + this.y /= len; + this.z /= len; + return this; + }, + /** + * Return the angle from -Pi to Pi of this point. + * @return {number} + */ + getAngle: function() { + return Math.atan2(this.y, this.x); + }, + /** + * Set this point coordinates proportinally to a maximum value. + * @param max {number} + * @return this + */ + limit: function(max) { + var aLenthSquared = this.getLengthSquared(); + if(aLenthSquared+0.01 > max*max) + { + var aLength = Math.sqrt(aLenthSquared); + this.x= (this.x/aLength) * max; + this.y= (this.y/aLength) * max; + this.z= (this.z/aLength) * max; + } + return this; + }, + /** + * Get this point's lenght. + * @return {number} + */ + getLength: function() { + var length = Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z); + if ( length < 0.005 && length > -0.005) return 0.000001; + return length; + + }, + /** + * Get this point's squared length. + * @return {number} + */ + getLengthSquared: function() { + var lengthSquared = this.x*this.x + this.y*this.y + this.z*this.z; + if ( lengthSquared < 0.005 && lengthSquared > -0.005) return 0; + return lengthSquared; + }, + /** + * Get the distance between two points. + * @param point {CAAT.Point} + * @return {number} + */ + getDistance: function(point) { + var deltaX = this.x - point.x; + var deltaY = this.y - point.y; + var deltaZ = this.z - point.z; + return Math.sqrt( deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ ); + }, + /** + * Get the squared distance between two points. + * @param point {CAAT.Point} + * @return {number} + */ + getDistanceSquared: function(point) { + var deltaX = this.x - point.x; + var deltaY = this.y - point.y; + var deltaZ = this.z - point.z; + return deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ; + }, + /** + * Get a string representation. + * @return {string} + */ + toString: function() { + return "(CAAT.Point)" + + " x:" + String(Math.round(Math.floor(this.x*10))/10) + + " y:" + String(Math.round(Math.floor(this.y*10))/10) + + " z:" + String(Math.round(Math.floor(this.z*10))/10); + } + }; +})();/** + * Created by Ibon Tolosana - @hyperandroid + * User: ibon + * Date: 02/02/12 + * Time: 19:29 + */ + +(function() { + + CAAT.QuadTree= function() { + return this; + }; + + var QT_MAX_ELEMENTS= 1; + var QT_MIN_WIDTH= 32; + + CAAT.QuadTree.prototype= { + + bgActors : null, + + quadData : null, + + create : function( l,t, r,b, backgroundElements, minWidth, maxElements ) { + + if ( typeof minWidth==='undefined' ) { + minWidth= QT_MIN_WIDTH; + } + if ( typeof maxElements==='undefined' ) { + maxElements= QT_MAX_ELEMENTS; + } + + var cx= (l+r)/2; + var cy= (t+b)/2; + + this.x= l; + this.y= t; + this.x1= r; + this.y1= b; + this.width= r-l; + this.height= b-t; + + this.bgActors= this.__getOverlappingActorList( backgroundElements ); + + if ( this.bgActors.length <= maxElements || this.width <= minWidth ) { + return this; + } + + this.quadData= new Array(4); + this.quadData[0]= new CAAT.QuadTree().create( l,t,cx,cy, this.bgActors ); // TL + this.quadData[1]= new CAAT.QuadTree().create( cx,t,r,cy, this.bgActors ); // TR + this.quadData[2]= new CAAT.QuadTree().create( l,cy,cx,b, this.bgActors ); // BL + this.quadData[3]= new CAAT.QuadTree().create( cx,cy,r,b, this.bgActors ); + + return this; + }, + + __getOverlappingActorList : function( actorList ) { + var tmpList= []; + for( var i=0, l=actorList.length; i>0 ); + } + + this.ycache= []; + for( i=0; i>0 ); + } + + this.xycache=[]; + for( i=0; i + *

  • The input values must be between 0 and 1. + *
  • Output values will be between 0 and 1. + *
  • Every Interpolator has at least an entering boolean parameter called pingpong. if set to true, the Interpolator + * will set values from 0..1 and back from 1..0. So half the time for each range. + * + * + *

    + * CAAt.Interpolator is defined by a createXXXX method which sets up an internal getPosition(time) + * function. You could set as an Interpolator up any object which exposes a method getPosition(time) + * and returns a CAAT.Point or an object of the form {x:{number}, y:{number}}. + *

    + * In the return value, the x attribute's value will be the same value as that of the time parameter, + * and y attribute will hold a value between 0 and 1 with the resulting value of applying the + * interpolation function for the time parameter. + * + *

    + * For am exponential interpolation, the getPosition function would look like this: + * function getPosition(time) { return { x:time, y: Math.pow(time,2) }Ê}. + * meaning that for time=0.5, a value of 0,5*0,5 should use instead. + * + *

    + * For a visual understanding of interpolators see tutorial 4 interpolators, or play with technical + * demo 1 where a SpriteActor moves along a path and the way it does can be modified by every + * out-of-the-box interpolator. + * + * @constructor + * + */ + CAAT.Interpolator = function() { + this.interpolated= new CAAT.Point(0,0,0); + return this; + }; + + CAAT.Interpolator.prototype= { + + interpolated: null, // a coordinate holder for not building a new CAAT.Point for each interpolation call. + paintScale: 90, // the size of the interpolation draw on screen in pixels. + + /** + * Set a linear interpolation function. + * + * @param bPingPong {boolean} + * @param bInverse {boolean} will values will be from 1 to 0 instead of 0 to 1 ?. + */ + createLinearInterpolator : function(bPingPong, bInverse) { + /** + * Linear and inverse linear interpolation function. + * @param time {number} + */ + this.getPosition= function getPosition(time) { + + var orgTime= time; + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + if ( bInverse!==null && bInverse ) { + time= 1-time; + } + + return this.interpolated.set(orgTime,time); + }; + + return this; + }, + createBackOutInterpolator : function(bPingPong) { + this.getPosition= function getPosition(time) { + var orgTime= time; + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + time = time - 1; + var overshoot= 1.70158; + + return this.interpolated.set( + orgTime, + time * time * ((overshoot + 1) * time + overshoot) + 1); + }; + + return this; + }, + /** + * Set an exponential interpolator function. The function to apply will be Math.pow(time,exponent). + * This function starts with 0 and ends in values of 1. + * + * @param exponent {number} exponent of the function. + * @param bPingPong {boolean} + */ + createExponentialInInterpolator : function(exponent, bPingPong) { + this.getPosition= function getPosition(time) { + var orgTime= time; + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + return this.interpolated.set(orgTime,Math.pow(time,exponent)); + }; + + return this; + }, + /** + * Set an exponential interpolator function. The function to apply will be 1-Math.pow(time,exponent). + * This function starts with 1 and ends in values of 0. + * + * @param exponent {number} exponent of the function. + * @param bPingPong {boolean} + */ + createExponentialOutInterpolator : function(exponent, bPingPong) { + this.getPosition= function getPosition(time) { + var orgTime= time; + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + return this.interpolated.set(orgTime,1-Math.pow(1-time,exponent)); + }; + + return this; + }, + /** + * Set an exponential interpolator function. Two functions will apply: + * Math.pow(time*2,exponent)/2 for the first half of the function (t<0.5) and + * 1-Math.abs(Math.pow(time*2-2,exponent))/2 for the second half (t>=.5) + * This function starts with 0 and goes to values of 1 and ends with values of 0. + * + * @param exponent {number} exponent of the function. + * @param bPingPong {boolean} + */ + createExponentialInOutInterpolator : function(exponent, bPingPong) { + this.getPosition= function getPosition(time) { + var orgTime= time; + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + if ( time*2<1 ) { + return this.interpolated.set(orgTime,Math.pow(time*2,exponent)/2); + } + + return this.interpolated.set(orgTime,1-Math.abs(Math.pow(time*2-2,exponent))/2); + }; + + return this; + }, + /** + * Creates a Quadric bezier curbe as interpolator. + * + * @param p0 {CAAT.Point} a CAAT.Point instance. + * @param p1 {CAAT.Point} a CAAT.Point instance. + * @param p2 {CAAT.Point} a CAAT.Point instance. + * @param bPingPong {boolean} a boolean indicating if the interpolator must ping-pong. + */ + createQuadricBezierInterpolator : function(p0,p1,p2,bPingPong) { + this.getPosition= function getPosition(time) { + var orgTime= time; + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + time= (1-time)*(1-time)*p0.y + 2*(1-time)*time*p1.y + time*time*p2.y; + + return this.interpolated.set( orgTime, time ); + }; + + return this; + }, + /** + * Creates a Cubic bezier curbe as interpolator. + * + * @param p0 {CAAT.Point} a CAAT.Point instance. + * @param p1 {CAAT.Point} a CAAT.Point instance. + * @param p2 {CAAT.Point} a CAAT.Point instance. + * @param p3 {CAAT.Point} a CAAT.Point instance. + * @param bPingPong {boolean} a boolean indicating if the interpolator must ping-pong. + */ + createCubicBezierInterpolator : function(p0,p1,p2,p3,bPingPong) { + this.getPosition= function getPosition(time) { + var orgTime= time; + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + var t2= time*time; + var t3= time*t2; + + time = (p0.y + time * (-p0.y * 3 + time * (3 * p0.y - + p0.y * time))) + time * (3 * p1.y + time * (-6 * p1.y + + p1.y * 3 * time)) + t2 * (p2.y * 3 - p2.y * 3 * time) + + p3.y * t3; + + return this.interpolated.set( orgTime, time ); + }; + + return this; + }, + createElasticOutInterpolator : function(amplitude,p,bPingPong) { + this.getPosition= function getPosition(time) { + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + if (time === 0) { + return {x:0,y:0}; + } + if (time === 1) { + return {x:1,y:1}; + } + + var s = p/(2*Math.PI) * Math.asin (1/amplitude); + return this.interpolated.set( + time, + (amplitude*Math.pow(2,-10*time) * Math.sin( (time-s)*(2*Math.PI)/p ) + 1 ) ); + }; + return this; + }, + createElasticInInterpolator : function(amplitude,p,bPingPong) { + this.getPosition= function getPosition(time) { + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + if (time === 0) { + return {x:0,y:0}; + } + if (time === 1) { + return {x:1,y:1}; + } + + var s = p/(2*Math.PI) * Math.asin (1/amplitude); + return this.interpolated.set( + time, + -(amplitude*Math.pow(2,10*(time-=1)) * Math.sin( (time-s)*(2*Math.PI)/p ) ) ); + }; + + return this; + }, + createElasticInOutInterpolator : function(amplitude,p,bPingPong) { + this.getPosition= function getPosition(time) { + + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + var s = p/(2*Math.PI) * Math.asin (1/amplitude); + time*=2; + if ( time<=1 ) { + return this.interpolated.set( + time, + -0.5*(amplitude*Math.pow(2,10*(time-=1)) * Math.sin( (time-s)*(2*Math.PI)/p ))); + } + + return this.interpolated.set( + time, + 1+0.5*(amplitude*Math.pow(2,-10*(time-=1)) * Math.sin( (time-s)*(2*Math.PI)/p ))); + }; + + return this; + }, + /** + * @param time {number} + * @private + */ + bounce : function(time) { + if ((time /= 1) < (1 / 2.75)) { + return {x:time, y:7.5625 * time * time}; + } else if (time < (2 / 2.75)) { + return {x:time, y:7.5625 * (time -= (1.5 / 2.75)) * time + 0.75}; + } else if (time < (2.5 / 2.75)) { + return {x:time, y:7.5625 * (time -= (2.25 / 2.75)) * time + 0.9375}; + } else { + return {x:time, y:7.5625*(time-=(2.625/2.75))*time+0.984375}; + } + }, + createBounceOutInterpolator : function(bPingPong) { + this.getPosition= function getPosition(time) { + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + return this.bounce(time); + }; + + return this; + }, + createBounceInInterpolator : function(bPingPong) { + + this.getPosition= function getPosition(time) { + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + var r= this.bounce(1-time); + r.y= 1-r.y; + return r; + }; + + return this; + }, + createBounceInOutInterpolator : function(bPingPong) { + + this.getPosition= function getPosition(time) { + if ( bPingPong ) { + if ( time<0.5 ) { + time*=2; + } else { + time= 1-(time-0.5)*2; + } + } + + var r; + if (time < 0.5) { + r= this.bounce(1 - time * 2); + r.y= (1 - r.y)* 0.5; + return r; + } + r= this.bounce(time * 2 - 1,bPingPong); + r.y= r.y* 0.5 + 0.5; + return r; + }; + + return this; + }, + /** + * Paints an interpolator on screen. + * @param director {CAAT.Director} a CAAT.Director instance. + * @param time {number} an integer indicating the scene time the Interpolator will be drawn at. This value is useless. + */ + paint : function(director,time) { + + var canvas= director.crc; + canvas.save(); + canvas.beginPath(); + + canvas.moveTo( 0, this.getPosition(0).y * this.paintScale ); + + for( var i=0; i<=this.paintScale; i++ ) { + canvas.lineTo( i, this.getPosition(i/this.paintScale).y * this.paintScale ); + } + + canvas.strokeStyle='black'; + canvas.stroke(); + canvas.restore(); + }, + /** + * Gets an array of coordinates which define the polyline of the intepolator's curve contour. + * Values for both coordinates range from 0 to 1. + * @param iSize {number} an integer indicating the number of contour segments. + * @return array {[CAAT.Point]} of object of the form {x:float, y:float}. + */ + getContour : function(iSize) { + var contour=[]; + for( var i=0; i<=iSize; i++ ) { + contour.push( {x: i/iSize, y: this.getPosition(i/iSize).y} ); + } + + return contour; + }, + /** + * + */ + enumerateInterpolators : function() { + return [ + new CAAT.Interpolator().createLinearInterpolator(false, false), 'Linear pingpong=false, inverse=false', + new CAAT.Interpolator().createLinearInterpolator(true, false), 'Linear pingpong=true, inverse=false', + + new CAAT.Interpolator().createLinearInterpolator(false, true), 'Linear pingpong=false, inverse=true', + new CAAT.Interpolator().createLinearInterpolator(true, true), 'Linear pingpong=true, inverse=true', + + new CAAT.Interpolator().createExponentialInInterpolator( 2, false), 'ExponentialIn pingpong=false, exponent=2', + new CAAT.Interpolator().createExponentialOutInterpolator( 2, false), 'ExponentialOut pingpong=false, exponent=2', + new CAAT.Interpolator().createExponentialInOutInterpolator( 2, false), 'ExponentialInOut pingpong=false, exponent=2', + new CAAT.Interpolator().createExponentialInInterpolator( 2, true), 'ExponentialIn pingpong=true, exponent=2', + new CAAT.Interpolator().createExponentialOutInterpolator( 2, true), 'ExponentialOut pingpong=true, exponent=2', + new CAAT.Interpolator().createExponentialInOutInterpolator( 2, true), 'ExponentialInOut pingpong=true, exponent=2', + + new CAAT.Interpolator().createExponentialInInterpolator( 4, false), 'ExponentialIn pingpong=false, exponent=4', + new CAAT.Interpolator().createExponentialOutInterpolator( 4, false), 'ExponentialOut pingpong=false, exponent=4', + new CAAT.Interpolator().createExponentialInOutInterpolator( 4, false), 'ExponentialInOut pingpong=false, exponent=4', + new CAAT.Interpolator().createExponentialInInterpolator( 4, true), 'ExponentialIn pingpong=true, exponent=4', + new CAAT.Interpolator().createExponentialOutInterpolator( 4, true), 'ExponentialOut pingpong=true, exponent=4', + new CAAT.Interpolator().createExponentialInOutInterpolator( 4, true), 'ExponentialInOut pingpong=true, exponent=4', + + new CAAT.Interpolator().createExponentialInInterpolator( 6, false), 'ExponentialIn pingpong=false, exponent=6', + new CAAT.Interpolator().createExponentialOutInterpolator( 6, false), 'ExponentialOut pingpong=false, exponent=6', + new CAAT.Interpolator().createExponentialInOutInterpolator( 6, false), 'ExponentialInOut pingpong=false, exponent=6', + new CAAT.Interpolator().createExponentialInInterpolator( 6, true), 'ExponentialIn pingpong=true, exponent=6', + new CAAT.Interpolator().createExponentialOutInterpolator( 6, true), 'ExponentialOut pingpong=true, exponent=6', + new CAAT.Interpolator().createExponentialInOutInterpolator( 6, true), 'ExponentialInOut pingpong=true, exponent=6', + + new CAAT.Interpolator().createBounceInInterpolator(false), 'BounceIn pingpong=false', + new CAAT.Interpolator().createBounceOutInterpolator(false), 'BounceOut pingpong=false', + new CAAT.Interpolator().createBounceInOutInterpolator(false), 'BounceInOut pingpong=false', + new CAAT.Interpolator().createBounceInInterpolator(true), 'BounceIn pingpong=true', + new CAAT.Interpolator().createBounceOutInterpolator(true), 'BounceOut pingpong=true', + new CAAT.Interpolator().createBounceInOutInterpolator(true), 'BounceInOut pingpong=true', + + new CAAT.Interpolator().createElasticInInterpolator( 1.1, 0.4, false), 'ElasticIn pingpong=false, amp=1.1, d=.4', + new CAAT.Interpolator().createElasticOutInterpolator( 1.1, 0.4, false), 'ElasticOut pingpong=false, amp=1.1, d=.4', + new CAAT.Interpolator().createElasticInOutInterpolator( 1.1, 0.4, false), 'ElasticInOut pingpong=false, amp=1.1, d=.4', + new CAAT.Interpolator().createElasticInInterpolator( 1.1, 0.4, true), 'ElasticIn pingpong=true, amp=1.1, d=.4', + new CAAT.Interpolator().createElasticOutInterpolator( 1.1, 0.4, true), 'ElasticOut pingpong=true, amp=1.1, d=.4', + new CAAT.Interpolator().createElasticInOutInterpolator( 1.1, 0.4, true), 'ElasticInOut pingpong=true, amp=1.1, d=.4', + + new CAAT.Interpolator().createElasticInInterpolator( 1.0, 0.2, false), 'ElasticIn pingpong=false, amp=1.0, d=.2', + new CAAT.Interpolator().createElasticOutInterpolator( 1.0, 0.2, false), 'ElasticOut pingpong=false, amp=1.0, d=.2', + new CAAT.Interpolator().createElasticInOutInterpolator( 1.0, 0.2, false), 'ElasticInOut pingpong=false, amp=1.0, d=.2', + new CAAT.Interpolator().createElasticInInterpolator( 1.0, 0.2, true), 'ElasticIn pingpong=true, amp=1.0, d=.2', + new CAAT.Interpolator().createElasticOutInterpolator( 1.0, 0.2, true), 'ElasticOut pingpong=true, amp=1.0, d=.2', + new CAAT.Interpolator().createElasticInOutInterpolator( 1.0, 0.2, true), 'ElasticInOut pingpong=true, amp=1.0, d=.2' + ]; + } + + }; +})(); + +/** + * See LICENSE file. + * + * Behaviors are keyframing elements. + * By using a BehaviorContainer, you can specify different actions on any animation Actor. + * An undefined number of Behaviors can be defined for each Actor. + * + * There're the following Behaviors: + * + AlphaBehavior: controls container/actor global alpha. + * + RotateBehavior: takes control of rotation affine transform. + * + ScaleBehavior: takes control of scaling on x/y axis affine transform. + * + PathBehavior: takes control of translating an Actor/ActorContainer across a path [ie. pathSegment collection]. + * + GenericBehavior: applies a behavior to any given target object's property, or notifies a callback. + * + * + **/ + +(function() { + /** + * Behavior base class. + * + *

    + * A behavior is defined by a frame time (behavior duration) and a behavior application function called interpolator. + * In its default form, a behaviour is applied linearly, that is, the same amount of behavior is applied every same + * time interval. + *

    + * A concrete Behavior, a rotateBehavior in example, will change a concrete Actor's rotationAngle during the specified + * period. + *

    + * A behavior is guaranteed to notify (if any observer is registered) on behavior expiration. + *

    + * A behavior can keep an unlimited observers. Observers are objects of the form: + *

    + * + * { + * behaviorExpired : function( behavior, time, actor); + * behaviorApplied : function( behavior, time, normalizedTime, actor, value); + * } + * + *

    + * behaviorExpired: function( behavior, time, actor). This method will be called for any registered observer when + * the scene time is greater than behavior's startTime+duration. This method will be called regardless of the time + * granurality. + *

    + * behaviorApplied : function( behavior, time, normalizedTime, actor, value). This method will be called once per + * frame while the behavior is not expired and is in frame time (behavior startTime>=scene time). This method can be + * called multiple times. + *

    + * Every behavior is applied to a concrete Actor. + * Every actor must at least define an start and end value. The behavior will set start-value at behaviorStartTime and + * is guaranteed to apply end-value when scene time= behaviorStartTime+behaviorDuration. + *

    + * You can set behaviors to apply forever that is cyclically. When a behavior is cycle=true, won't notify + * behaviorExpired to its registered observers. + *

    + * Other Behaviors simply must supply with the method setForTime(time, actor) overriden. + * + * @constructor + */ + CAAT.Behavior= function() { + this.lifecycleListenerList=[]; + this.setDefaultInterpolator(); + return this; + }; + + /** + * @enum + */ + CAAT.Behavior.Status= { + NOT_STARTED: 0, + STARTED: 1, + EXPIRED: 2 + }; + + var DefaultInterpolator= new CAAT.Interpolator().createLinearInterpolator(false); + var DefaultPPInterpolator= new CAAT.Interpolator().createLinearInterpolator(true); + + CAAT.Behavior.prototype= { + + lifecycleListenerList: null, // observer list. + behaviorStartTime: -1, // scene time to start applying the behavior + behaviorDuration: -1, // behavior duration in ms. + cycleBehavior: false, // apply forever ? + + status: CAAT.Behavior.NOT_STARTED, + + interpolator: null, // behavior application function. linear by default. + actor: null, // actor the Behavior acts on. + id: 0, // an integer id suitable to identify this behavior by number. + + timeOffset: 0, + + doValueApplication: true, + + solved : true, + + setValueApplication : function( apply ) { + this.doValueApplication= apply; + return this; + }, + + setTimeOffset : function( offset ) { + this.timeOffset= offset; + return this; + }, + + /** + * Sets this behavior id. + * @param id an integer. + * + */ + setId : function( id ) { + this.id= id; + return this; + }, + /** + * Sets the default interpolator to a linear ramp, that is, behavior will be applied linearly. + * @return this + */ + setDefaultInterpolator : function() { + this.interpolator= DefaultInterpolator; + return this; + }, + /** + * Sets default interpolator to be linear from 0..1 and from 1..0. + * @return this + */ + setPingPong : function() { + this.interpolator= DefaultPPInterpolator; + return this; + }, + + /** + * + * @param status {CAAT.Behavior.Status} + */ + setStatus : function(status) { + this.status= status; + }, + + /** + * Sets behavior start time and duration. + * Scene time will be the time of the scene the behavior actor is bound to. + * @param startTime {number} an integer indicating behavior start time in scene time in ms.. + * @param duration {number} an integer indicating behavior duration in ms. + */ + setFrameTime : function( startTime, duration ) { + this.behaviorStartTime= startTime; + this.behaviorDuration= duration; + this.setStatus( CAAT.Behavior.Status.NOT_STARTED ); + + return this; + }, + /** + * Sets behavior start time and duration but instead as setFrameTime which sets initial time as absolute time + * regarding scene's time, it uses a relative time offset from current scene time. + * a call to + * setFrameTime( scene.time, duration ) is equivalent to + * setDelayTime( 0, duration ) + * @param delay {number} + * @param duration {number} + */ + setDelayTime : function( delay, duration ) { + this.behaviorStartTime= delay; + this.behaviorDuration= duration; + this.setStatus( CAAT.Behavior.Status.NOT_STARTED ); + this.solved= false; + + return this; + + }, + setOutOfFrameTime : function() { + this.setStatus( CAAT.Behavior.Status.EXPIRED ); + this.behaviorStartTime= Number.MAX_VALUE; + this.behaviorDuration= 0; + return this; + }, + /** + * Changes behavior default interpolator to another instance of CAAT.Interpolator. + * If the behavior is not defined by CAAT.Interpolator factory methods, the interpolation function must return + * its values in the range 0..1. The behavior will only apply for such value range. + * @param interpolator a CAAT.Interpolator instance. + */ + setInterpolator : function(interpolator) { + this.interpolator= interpolator; + return this; + }, + /** + * This method must no be called directly. + * The director loop will call this method in orther to apply actor behaviors. + * @param time the scene time the behaviro is being applied at. + * @param actor a CAAT.Actor instance the behavior is being applied to. + */ + apply : function( time, actor ) { + + if ( !this.solved ) { + this.behaviorStartTime+= time; + this.solved= true; + } + + time+= this.timeOffset*this.behaviorDuration; + + var orgTime= time; + if ( this.isBehaviorInTime(time,actor) ) { + time= this.normalizeTime(time); + this.fireBehaviorAppliedEvent( + actor, + orgTime, + time, + this.setForTime( time, actor ) ); + } + }, + + /** + * Sets the behavior to cycle, ie apply forever. + * @param bool a boolean indicating whether the behavior is cycle. + */ + setCycle : function(bool) { + this.cycleBehavior= bool; + return this; + }, + /** + * Adds an observer to this behavior. + * @param behaviorListener an observer instance. + */ + addListener : function( behaviorListener ) { + this.lifecycleListenerList.push(behaviorListener); + return this; + }, + /** + * Remove all registered listeners to the behavior. + */ + emptyListenerList : function() { + this.lifecycleListenerList= []; + return this; + }, + /** + * @return an integer indicating the behavior start time in ms.. + */ + getStartTime : function() { + return this.behaviorStartTime; + }, + /** + * @return an integer indicating the behavior duration time in ms. + */ + getDuration : function() { + return this.behaviorDuration; + + }, + /** + * Chekcs whether the behaviour is in scene time. + * In case it gets out of scene time, and has not been tagged as expired, the behavior is expired and observers + * are notified about that fact. + * @param time the scene time to check the behavior against. + * @param actor the actor the behavior is being applied to. + * @return a boolean indicating whether the behavior is in scene time. + */ + isBehaviorInTime : function(time,actor) { + + var S= CAAT.Behavior.Status; + + if ( this.status===S.EXPIRED || this.behaviorStartTime<0 ) { + return false; + } + + if ( this.cycleBehavior ) { + if ( time>=this.behaviorStartTime ) { + time= (time-this.behaviorStartTime)%this.behaviorDuration + this.behaviorStartTime; + } + } + + if ( time>this.behaviorStartTime+this.behaviorDuration ) { + if ( this.status!==S.EXPIRED ) { + this.setExpired(actor,time); + } + + return false; + } + + if ( this.status===S.NOT_STARTED ) { + this.status=S.STARTED; + this.fireBehaviorStartedEvent(actor,time); + } + + return this.behaviorStartTime<=time; // && time + * A ContainerBehavior is a holder to sum up different behaviors. + *

    + * It imposes some constraints to contained Behaviors: + *

      + *
    • The time of every contained behavior will be zero based, so the frame time set for each behavior will + * be referred to the container's behaviorStartTime and not scene time as usual. + *
    • Cycling a ContainerBehavior means cycling every contained behavior. + *
    • The container will not impose any Interpolator, so calling the method setInterpolator(CAAT.Interpolator) + * will be useless. + *
    • The Behavior application time will be bounded to the Container's frame time. I.E. if we set a container duration + * to 10 seconds, setting a contained behavior's duration to 15 seconds will be useless since the container will stop + * applying the behavior after 10 seconds have elapsed. + *
    • Every ContainerBehavior adds itself as an observer for its contained Behaviors. The main reason is because + * ContainerBehaviors modify cycling properties of its contained Behaviors. When a contained + * Behavior is expired, if the Container has isCycle=true, will unexpire the contained Behavior, otherwise, it won't be + * applied in the next frame. It is left up to the developer to manage correctly the logic of other posible contained + * behaviors observers. + *
    + * + *

    + * A ContainerBehavior can contain other ContainerBehaviors at will. + *

    + * A ContainerBehavior will not apply any CAAT.Actor property change by itself, but will instrument its contained + * Behaviors to do so. + * + * @constructor + * @extends CAAT.Behavior + */ + CAAT.ContainerBehavior= function() { + CAAT.ContainerBehavior.superclass.constructor.call(this); + this.behaviors= []; + return this; + }; + + CAAT.ContainerBehavior.prototype= { + + behaviors: null, // contained behaviors array + + /** + * Proportionally change this container duration to its children. + * @param duration {number} new duration in ms. + * @return this; + */ + conformToDuration : function( duration ) { + this.duration= duration; + + var f= duration/this.duration; + var bh; + for( var i=0; i=time ) { + // 3.- renormalizar tiempo reltivo a comportamiento. + time= (time-bh.behaviorStartTime)/bh.behaviorDuration; + + // 4.- obtener valor de comportamiento para tiempo normalizado relativo a contenedor + cssRuleValue= bh.calculateKeyFrameData(time); + cssProperty= bh.getPropertyName(prefix); + + if ( typeof retValue[cssProperty] ==='undefined' ) { + retValue[cssProperty]= ""; + } + + // 5.- asignar a objeto, par de propiedad/valor css + retValue[cssProperty]+= cssRuleValue+" "; + } + + } + } + + + var tr=""; + var pv; + function xx(pr) { + if ( retValue[pr] ) { + tr+= retValue[pr]; + } else { + if ( prevValues ) { + pv= prevValues[pr]; + if ( pv ) { + tr+= pv; + retValue[pr]= pv; + } + } + } + + } + + xx('translate'); + xx('rotate'); + xx('scale'); + + var keyFrameRule= ""; + + if ( tr ) { + keyFrameRule='-'+prefix+'-transform: '+tr+';'; + } + + tr=""; + xx('opacity'); + if( tr ) { + keyFrameRule+= ' opacity: '+tr+';'; + } + + return { + rules: keyFrameRule, + ret: retValue + }; + + }, + + /** + * + * @param prefix + * @param name + * @param keyframessize + */ + calculateKeyFramesData : function(prefix, name, keyframessize) { + + if ( this.duration===Number.MAX_VALUE ) { + return ""; + } + + if ( typeof keyframessize==='undefined' ) { + keyframessize=100; + } + + var i; + var prevValues= null; + var kfd= "@-"+prefix+"-keyframes "+name+" {"; + var ret; + var time; + var kfr; + + for( i=0; i<=keyframessize; i++ ) { + time= this.interpolator.getPosition(i/keyframessize).y; + ret= this.calculateKeyFrameData(time, prefix, prevValues); + kfr= "" + + (i/keyframessize*100) + "%" + // percentage + "{" + ret.rules + "}\n"; + + prevValues= ret.ret; + kfd+= kfr; + } + + kfd+= "}"; + + return kfd; + } + + }; + + extend( CAAT.ContainerBehavior, CAAT.Behavior, null ); +})(); + +(function() { + /** + * This class applies a rotation to a CAAt.Actor instance. + * StartAngle, EndAngle must be supplied. Angles are in radians. + * The RotationAnchor, if not supplied, will be ANCHOR_CENTER. + * + * An example os use will be + * + * var rb= new CAAT.RotateBehavior(). + * setValues(0,2*Math.PI). + * setFrameTime(0,2500); + * + * @see CAAT.Actor. + * + * @constructor + * @extends CAAT.Behavior + * + */ + CAAT.RotateBehavior= function() { + CAAT.RotateBehavior.superclass.constructor.call(this); + this.anchor= CAAT.Actor.prototype.ANCHOR_CENTER; + return this; + }; + + CAAT.RotateBehavior.prototype= { + + startAngle: 0, // behavior start angle + endAngle: 0, // behavior end angle + anchorX: .50, // rotation center x. + anchorY: .50, // rotation center y. + + getPropertyName : function() { + return "rotate"; + }, + + /** + * Behavior application function. + * Do not call directly. + * @param time an integer indicating the application time. + * @param actor a CAAT.Actor the behavior will be applied to. + * @return the set angle. + */ + setForTime : function(time,actor) { + var angle= this.startAngle + time*(this.endAngle-this.startAngle); + + if ( this.doValueApplication ) { + actor.setRotationAnchored(angle, this.anchorX, this.anchorY); + } + + return angle; + + }, + /** + * Set behavior bound values. + * if no anchorx,anchory values are supplied, the behavior will assume + * 50% for both values, that is, the actor's center. + * + * Be aware the anchor values are supplied in RELATIVE PERCENT to + * actor's size. + * + * @param startAngle {float} indicating the starting angle. + * @param endAngle {float} indicating the ending angle. + * @param anchorx {float} the percent position for anchorX + * @param anchory {float} the percent position for anchorY + */ + setValues : function( startAngle, endAngle, anchorx, anchory ) { + this.startAngle= startAngle; + this.endAngle= endAngle; + if ( typeof anchorx!=='undefined' && typeof anchory!=='undefined' ) { + this.anchorX= anchorx; + this.anchorY= anchory; + } + return this; + }, + /** + * @deprecated + * Use setValues instead + * @param start + * @param end + */ + setAngles : function( start, end ) { + return this.setValues(start,end); + }, + /** + * Set the behavior rotation anchor. Use this method when setting an exact percent + * by calling setValues is complicated. + * @see CAAT.Actor + * @param anchor any of CAAT.Actor.prototype.ANCHOR_* constants. + * + * These parameters are to set a custom rotation anchor point. if anchor==CAAT.Actor.prototype.ANCHOR_CUSTOM + * the custom rotation point is set. + * @param rx + * @param ry + * + */ + setAnchor : function( actor, rx, ry ) { + this.anchorX= rx/actor.width; + this.anchorY= ry/actor.height; + return this; + }, + + + calculateKeyFrameData : function( time ) { + time= this.interpolator.getPosition(time).y; + return "rotate(" + (this.startAngle + time*(this.endAngle-this.startAngle)) +"rad)"; + }, + + /** + * @param prefix {string} browser vendor prefix + * @param name {string} keyframes animation name + * @param keyframessize {integer} number of keyframes to generate + * @override + */ + calculateKeyFramesData : function(prefix, name, keyframessize) { + + if ( typeof keyframessize==='undefined' ) { + keyframessize= 100; + } + keyframessize>>=0; + + var i; + var kfr; + var kfd= "@-"+prefix+"-keyframes "+name+" {"; + + for( i=0; i<=keyframessize; i++ ) { + kfr= "" + + (i/keyframessize*100) + "%" + // percentage + "{" + + "-"+prefix+"-transform:" + this.calculateKeyFrameData(i/keyframessize) + + "}\n"; + + kfd+= kfr; + } + + kfd+="}"; + + return kfd; + } + + }; + + extend( CAAT.RotateBehavior, CAAT.Behavior, null); + +})(); + +(function() { + /** + *

    + * A generic behavior is supposed to be extended to create new behaviors when the out-of-the-box + * ones are not sufficient. It applies the behavior result to a given target object in two ways: + * + *

      + *
    1. defining the property parameter: the toolkit will perform target_object[property]= calculated_value_for_time. + *
    2. defining a callback function. Sometimes setting of a property is not enough. In example, + * for a give property in a DOM element, it is needed to set object.style['left']= '70px'; + * With the property approach, you won't be able to add de 'px' suffix to the value, and hence won't + * work correctly. The function callback will allow to take control by receiving as parameters the + * target object, and the calculated value to apply by the behavior for the given time. + *
    + * + *

    + * For example, this code will move a dom element from 0 to 400 px on x during 1 second: + * + *

    + * var enterBehavior= new CAAT.GenericBehavior().
    + *   setFrameTime( scene.time, 1000 ).
    + *   setValues(
    + *     0,
    + *     400,
    + *     domElement,
    + *     null,
    + *     function( currentValue, target ) {
    + *       target.style['left']= currentValue+'px';
    + *     }
    + *   );
    + *
    + * + * @constructor + * @extends CAAT.Behavior + * + */ + CAAT.GenericBehavior= function() { + CAAT.GenericBehavior.superclass.constructor.call(this); + return this; + }; + + CAAT.GenericBehavior.prototype= { + + start: 0, + end: 0, + target: null, + property: null, + callback: null, + + /** + * Sets the target objects property to the corresponding value for the given time. + * If a callback function is defined, it is called as well. + * + * @param time {number} the scene time to apply the behavior at. + * @param actor {CAAT.Actor} a CAAT.Actor object instance. + */ + setForTime : function(time, actor) { + var value= this.start+ time*(this.end-this.start); + if ( this.callback ) { + this.callback( value, this.target, actor ); + } + + if ( this.property ) { + this.target[this.property]= value; + } + }, + /** + * Defines the values to apply this behavior. + * + * @param start {number} initial behavior value. + * @param end {number} final behavior value. + * @param target {object} an object. Usually a CAAT.Actor. + * @param property {string} target object's property to set value to. + * @param callback {function} a function of the form function( target, value ). + */ + setValues : function( start, end, target, property, callback ) { + this.start= start; + this.end= end; + this.target= target; + this.property= property; + this.callback= callback; + return this; + } + }; + + extend( CAAT.GenericBehavior, CAAT.Behavior, null); +})(); + +(function() { + + /** + * ScaleBehavior applies scale affine transforms in both axis. + * StartScale and EndScale must be supplied for each axis. This method takes care of a FF bug in which if a Scale is + * set to 0, the animation will fail playing. + * + * This behavior specifies anchors in values ranges 0..1 + * + * @constructor + * @extends CAAT.Behavior + * + */ + CAAT.ScaleBehavior= function() { + CAAT.ScaleBehavior.superclass.constructor.call(this); + this.anchor= CAAT.Actor.prototype.ANCHOR_CENTER; + return this; + }; + + CAAT.ScaleBehavior.prototype= { + startScaleX: 1, + endScaleX: 1, + startScaleY: 1, + endScaleY: 1, + anchorX: .50, + anchorY: .50, + + getPropertyName : function() { + return "scale"; + }, + + /** + * Applies corresponding scale values for a given time. + * + * @param time the time to apply the scale for. + * @param actor the target actor to Scale. + * @return {object} an object of the form { scaleX: {float}, scaleY: {float}Ê} + */ + setForTime : function(time,actor) { + + var scaleX= this.startScaleX + time*(this.endScaleX-this.startScaleX); + var scaleY= this.startScaleY + time*(this.endScaleY-this.startScaleY); + + // Firefox 3.x & 4, will crash animation if either scaleX or scaleY equals 0. + if (0===scaleX ) { + scaleX=0.01; + } + if (0===scaleY ) { + scaleY=0.01; + } + + if ( this.doValueApplication ) { + actor.setScaleAnchored( scaleX, scaleY, this.anchorX, this.anchorY ); + } + + return { scaleX: scaleX, scaleY: scaleY }; + }, + /** + * Define this scale behaviors values. + * + * Be aware the anchor values are supplied in RELATIVE PERCENT to + * actor's size. + * + * @param startX {number} initial X axis scale value. + * @param endX {number} final X axis scale value. + * @param startY {number} initial Y axis scale value. + * @param endY {number} final Y axis scale value. + * @param anchorx {float} the percent position for anchorX + * @param anchory {float} the percent position for anchorY + * + * @return this. + */ + setValues : function( startX, endX, startY, endY, anchorx, anchory ) { + this.startScaleX= startX; + this.endScaleX= endX; + this.startScaleY= startY; + this.endScaleY= endY; + + if ( typeof anchorx!=='undefined' && typeof anchory!=='undefined' ) { + this.anchorX= anchorx; + this.anchorY= anchory; + } + + return this; + }, + /** + * Set an exact position scale anchor. Use this method when it is hard to + * set a thorough anchor position expressed in percentage. + * @param actor + * @param x + * @param y + */ + setAnchor : function( actor, x, y ) { + this.anchorX= x/actor.width; + this.anchorY= y/actor.height; + + return this; + }, + + calculateKeyFrameData : function( time ) { + var scaleX; + var scaleY; + + time= this.interpolator.getPosition(time).y; + scaleX= this.startScaleX + time*(this.endScaleX-this.startScaleX); + scaleY= this.startScaleY + time*(this.endScaleY-this.startScaleY); + + return "scaleX("+scaleX+") scaleY("+scaleY+")"; + }, + + calculateKeyFramesData : function(prefix, name, keyframessize) { + + if ( typeof keyframessize==='undefined' ) { + keyframessize= 100; + } + keyframessize>>=0; + + var i; + var kfr; + var kfd= "@-"+prefix+"-keyframes "+name+" {"; + + for( i=0; i<=keyframessize; i++ ) { + kfr= "" + + (i/keyframessize*100) + "%" + // percentage + "{" + + "-"+prefix+"-transform:" + this.calculateKeyFrameData(i/keyframessize) + + "}"; + + kfd+= kfr; + } + + kfd+="}"; + + return kfd; + } + }; + + extend( CAAT.ScaleBehavior, CAAT.Behavior, null); +})(); + +(function() { + /** + * AlphaBehavior modifies alpha composition property for an actor. + * + * @constructor + * @extends CAAT.Behavior + */ + CAAT.AlphaBehavior= function() { + CAAT.AlphaBehavior.superclass.constructor.call(this); + return this; + }; + + CAAT.AlphaBehavior.prototype= { + startAlpha: 0, + endAlpha: 0, + + getPropertyName : function() { + return "opacity"; + }, + + /** + * Applies corresponding alpha transparency value for a given time. + * + * @param time the time to apply the scale for. + * @param actor the target actor to set transparency for. + * @return {number} the alpha value set. Normalized from 0 (total transparency) to 1 (total opacity) + */ + setForTime : function(time,actor) { + var alpha= (this.startAlpha+time*(this.endAlpha-this.startAlpha)); + if ( this.doValueApplication ) { + actor.setAlpha( alpha ); + } + return alpha; + }, + /** + * Set alpha transparency minimum and maximum value. + * This value can be coerced by Actor's property isGloblAlpha. + * + * @param start {number} a float indicating the starting alpha value. + * @param end {number} a float indicating the ending alpha value. + */ + setValues : function( start, end ) { + this.startAlpha= start; + this.endAlpha= end; + return this; + }, + + calculateKeyFrameData : function( time ) { + time= this.interpolator.getPosition(time).y; + return (this.startAlpha+time*(this.endAlpha-this.startAlpha)); + }, + + /** + * @param prefix {string} browser vendor prefix + * @param name {string} keyframes animation name + * @param keyframessize {integer} number of keyframes to generate + * @override + */ + calculateKeyFramesData : function(prefix, name, keyframessize) { + + if ( typeof keyframessize==='undefined' ) { + keyframessize= 100; + } + keyframessize>>=0; + + var i; + var kfr; + var kfd= "@-"+prefix+"-keyframes "+name+" {"; + + for( i=0; i<=keyframessize; i++ ) { + kfr= "" + + (i/keyframessize*100) + "%" + // percentage + "{" + + "opacity: " + this.calculateKeyFrameData( i / keyframessize ) + + "}"; + + kfd+= kfr; + } + + kfd+="}"; + + return kfd; + } + }; + + extend( CAAT.AlphaBehavior, CAAT.Behavior, null); +})(); + +(function() { + /** + * CAAT.PathBehavior modifies the position of a CAAT.Actor along the path represented by an + * instance of CAAT.Path. + * + * @constructor + * @extends CAAT.Behavior + * + */ + CAAT.PathBehavior= function() { + CAAT.PathBehavior.superclass.constructor.call(this); + return this; + }; + + /** + * @enum + */ + CAAT.PathBehavior.autorotate = { + LEFT_TO_RIGHT: 0, // fix left_to_right direction + RIGHT_TO_LEFT: 1, // fix right_to_left + FREE: 2 // do not apply correction + }; + + CAAT.PathBehavior.prototype= { + path: null, // the path to traverse + autoRotate : false, // set whether the actor must be rotated tangentially to the path. + prevX: -1, // private, do not use. + prevY: -1, // private, do not use. + + autoRotateOp: CAAT.PathBehavior.autorotate.FREE, + + getPropertyName : function() { + return "translate"; + }, + + /** + * Sets an actor rotation to be heading from past to current path's point. + * Take into account that this will be incompatible with rotation Behaviors + * since they will set their own rotation configuration. + * @param autorotate {boolean} + * @param autorotateOp {CAAT.PathBehavior.autorotate} whether the sprite is drawn heading to the right. + * @return this. + */ + setAutoRotate : function( autorotate, autorotateOp ) { + this.autoRotate= autorotate; + if (autorotateOp!==undefined) { + this.autoRotateOp= autorotateOp; + } + return this; + }, + /** + * Set the behavior path. + * The path can be any length, and will take behaviorDuration time to be traversed. + * @param {CAAT.Path} + * + * @deprecated + */ + setPath : function(path) { + this.path= path; + return this; + }, + + /** + * Set the behavior path. + * The path can be any length, and will take behaviorDuration time to be traversed. + * @param {CAAT.Path} + * @return this + */ + setValues : function(path) { + return this.setPath(path); + }, + + /** + * @see Acotr.setPositionAcchor + * @deprecated + * @param tx a float with xoffset. + * @param ty a float with yoffset. + */ + setTranslation : function( tx, ty ) { + return this; + }, + + calculateKeyFrameData : function( time ) { + time= this.interpolator.getPosition(time).y; + var point= this.path.getPosition(time); + return "translateX("+point.x+"px) translateY("+point.y+"px)" ; + }, + + calculateKeyFramesData : function(prefix, name, keyframessize) { + + if ( typeof keyframessize==='undefined' ) { + keyframessize= 100; + } + keyframessize>>=0; + + var i; + var kfr; + var time; + var kfd= "@-"+prefix+"-keyframes "+name+" {"; + + for( i=0; i<=keyframessize; i++ ) { + kfr= "" + + (i/keyframessize*100) + "%" + // percentage + "{" + + "-"+prefix+"-transform:" + this.calculateKeyFrameData(i/keyframessize) + + "}"; + + kfd+= kfr; + } + + kfd+="}"; + + return kfd; + }, + + /** + * Translates the Actor to the corresponding time path position. + * If autoRotate=true, the actor is rotated as well. The rotation anchor will (if set) always be ANCHOR_CENTER. + * @param time an integer indicating the time the behavior is being applied at. + * @param actor a CAAT.Actor instance to be translated. + * @return {object} an object of the form { x: {float}, y: {float}Ê}. + */ + setForTime : function(time,actor) { + + if ( !this.path ) { + return { + x: actor.x, + y: actor.y + }; + } + + var point= this.path.getPosition(time); + + if ( this.autoRotate ) { + + if ( -1===this.prevX && -1===this.prevY ) { + this.prevX= point.x; + this.prevY= point.y; + } + + var ax= point.x-this.prevX; + var ay= point.y-this.prevY; + + if ( ax===0 && ay===0 ) { + actor.setLocation( point.x, point.y ); + return { x: actor.x, y: actor.y }; + } + + var angle= Math.atan2( ay, ax ); + var si= CAAT.SpriteImage.prototype; + var pba= CAAT.PathBehavior.autorotate; + + // actor is heading left to right + if ( this.autoRotateOp===pba.LEFT_TO_RIGHT ) { + if ( this.prevX<=point.x ) { + actor.setImageTransformation( si.TR_NONE ); + } + else { + actor.setImageTransformation( si.TR_FLIP_HORIZONTAL ); + angle+=Math.PI; + } + } else if ( this.autoRotateOp===pba.RIGHT_TO_LEFT ) { + if ( this.prevX<=point.x ) { + actor.setImageTransformation( si.TR_FLIP_HORIZONTAL ); + } + else { + actor.setImageTransformation( si.TR_NONE ); + angle-=Math.PI; + } + } + + actor.setRotation(angle); + + this.prevX= point.x; + this.prevY= point.y; + + var modulo= Math.sqrt(ax*ax+ay*ay); + ax/=modulo; + ay/=modulo; + } + + if ( this.doValueApplication ) { + actor.setLocation( point.x, point.y ); + return { x: actor.x, y: actor.y }; + } else { + return { + x: point.x, + y: point.y + }; + } + + + }, + /** + * Get a point on the path. + * If the time to get the point at is in behaviors frame time, a point on the path will be returned, otherwise + * a default {x:-1, y:-1} point will be returned. + * + * @param time {number} the time at which the point will be taken from the path. + * @return {object} an object of the form {x:float y:float} + */ + positionOnTime : function(time) { + if ( this.isBehaviorInTime(time,null) ) { + time= this.normalizeTime(time); + return this.path.getPosition( time ); + } + + return {x:-1, y:-1}; + + } + }; + + extend( CAAT.PathBehavior, CAAT.Behavior ); +})(); + +(function() { + + /** + * ColorBehavior interpolates between two given colors. + * @constructor + */ + CAAT.ColorBehavior= function() { + return this; + }; + + CAAT.ColorBehavior.prototype= { + + }; + + extend( CAAT.ColorBehavior, CAAT.Behavior ); + +})(); + +(function() { + + /** + * + * Scale only X or Y axis, instead both at the same time as ScaleBehavior. + * + * @constructor + */ + CAAT.Scale1Behavior= function() { + CAAT.Scale1Behavior.superclass.constructor.call(this); + this.anchor= CAAT.Actor.prototype.ANCHOR_CENTER; + return this; + }; + + CAAT.Scale1Behavior.prototype= { + startScale: 1, + endScale: 1, + anchorX: .50, + anchorY: .50, + + sx : 1, + sy : 1, + + applyOnX : true, + + getPropertyName : function() { + return "scale"; + }, + + /** + * Applies corresponding scale values for a given time. + * + * @param time the time to apply the scale for. + * @param actor the target actor to Scale. + * @return {object} an object of the form { scaleX: {float}, scaleY: {float}Ê} + */ + setForTime : function(time,actor) { + + var scale= this.startScale + time*(this.endScale-this.startScale); + + // Firefox 3.x & 4, will crash animation if either scaleX or scaleY equals 0. + if (0===scale ) { + scale=0.01; + } + + if ( this.doValueApplication ) { + if ( this.applyOnX ) { + actor.setScaleAnchored( scale, actor.scaleY, this.anchorX, this.anchorY ); + } else { + actor.setScaleAnchored( actor.scaleX, scale, this.anchorX, this.anchorY ); + } + } + + return scale; + }, + /** + * Define this scale behaviors values. + * + * Be aware the anchor values are supplied in RELATIVE PERCENT to + * actor's size. + * + * @param start {number} initial X axis scale value. + * @param end {number} final X axis scale value. + * @param anchorx {float} the percent position for anchorX + * @param anchory {float} the percent position for anchorY + * + * @return this. + */ + setValues : function( start, end, applyOnX, anchorx, anchory ) { + this.startScale= start; + this.endScale= end; + this.applyOnX= !!applyOnX; + + if ( typeof anchorx!=='undefined' && typeof anchory!=='undefined' ) { + this.anchorX= anchorx; + this.anchorY= anchory; + } + + return this; + }, + /** + * Set an exact position scale anchor. Use this method when it is hard to + * set a thorough anchor position expressed in percentage. + * @param actor + * @param x + * @param y + */ + setAnchor : function( actor, x, y ) { + this.anchorX= x/actor.width; + this.anchorY= y/actor.height; + + return this; + }, + + calculateKeyFrameData : function( time ) { + var scale; + + time= this.interpolator.getPosition(time).y; + scale= this.startScale + time*(this.endScale-this.startScale); + + return this.applyOnX ? "scaleX("+scale+")" : "scaleY("+scale+")"; + }, + + calculateKeyFramesData : function(prefix, name, keyframessize) { + + if ( typeof keyframessize==='undefined' ) { + keyframessize= 100; + } + keyframessize>>=0; + + var i; + var kfr; + var kfd= "@-"+prefix+"-keyframes "+name+" {"; + + for( i=0; i<=keyframessize; i++ ) { + kfr= "" + + (i/keyframessize*100) + "%" + // percentage + "{" + + "-"+prefix+"-transform:" + this.calculateKeyFrameData(i/keyframessize) + + "}"; + + kfd+= kfr; + } + + kfd+="}"; + + return kfd; + } + }; + + extend( CAAT.Scale1Behavior, CAAT.Behavior ); +})();/** + * See LICENSE file. + * + * This object manages CSS3 transitions reflecting applying behaviors. + * + **/ + +(function() { + + CAAT.CSS= {}; + + CAAT.CSS.PREFIX= (function() { + + var prefix = ""; + var prefixes = ['WebKit', 'Moz', 'O']; + var keyframes= ""; + + // guess this browser vendor prefix. + for (var i = 0; i < prefixes.length; i++) { + if (window[prefixes[i] + 'CSSKeyframeRule']) { + prefix = prefixes[i].toLowerCase(); + break; + } + } + + CAAT.CSS.PROP_ANIMATION= '-'+prefix+'-animation'; + + return prefix; + })(); + + CAAT.CSS.applyKeyframe= function( domElement, name, secs, forever ) { + domElement.style[CAAT.CSS.PROP_ANIMATION]= name+' '+(secs/1000)+'s linear both '+(forever ? 'infinite' : '') ; + }; + + CAAT.CSS.unregisterKeyframes= function( name ) { + var index= CAAT.CSS.getCSSKeyframesIndex(name); + if ( -1!==index ) { + document.styleSheets[0].deleteRule( index ); + } + }; + + /** + * + * @param kfDescriptor {object{ name{string}, behavior{CAAT.Behavior}, size{!number}, overwrite{boolean}} + */ + CAAT.CSS.registerKeyframes= function( kfDescriptor ) { + + var name= kfDescriptor.name; + var behavior= kfDescriptor.behavior; + var size= kfDescriptor.size; + var overwrite= kfDescriptor.overwrite; + + if ( typeof name==='undefined' || typeof behavior==='undefined' ) { + throw 'Keyframes must be defined by a name and a CAAT.Behavior instance.'; + } + + if ( typeof size==='undefined' ) { + size= 100; + } + if ( typeof overwrite==='undefined' ) { + overwrite= false; + } + + // find if keyframes has already a name set. + var cssRulesIndex= CAAT.CSS.getCSSKeyframesIndex(name); + if (-1!==cssRulesIndex && !overwrite) { + return; + } + + var keyframesRule= behavior.calculateKeyframesData(CAAT.CSS.PREFIX, name, size ); + + if (document.styleSheets) { + if ( !document.styleSheets.length) { + var s = document.createElement('style'); + s.type="text/css"; + + document.getElementsByTagName('head')[ 0 ].appendChild(s); + } + + if ( -1!==cssRulesIndex ) { + document.styleSheets[0].deleteRule( cssRulesIndex ); + } + + document.styleSheets[0].insertRule( keyframesRule, 0 ); + } + + }; + + CAAT.CSS.getCSSKeyframesIndex= function(name) { + var ss = document.styleSheets; + for (var i = ss.length - 1; i >= 0; i--) { + try { + var s = ss[i], + rs = s.cssRules ? s.cssRules : + s.rules ? s.rules : + []; + + for (var j = rs.length - 1; j >= 0; j--) { + if ( ( rs[j].type === window.CSSRule.WEBKIT_KEYFRAMES_RULE || + rs[j].type === window.CSSRule.MOZ_KEYFRAMES_RULE ) && rs[j].name === name) { + + return j; + } + } + } catch(e) { + } + } + + return -1; + }; + + CAAT.CSS.getCSSKeyframes= function(name) { + + var ss = document.styleSheets; + for (var i = ss.length - 1; i >= 0; i--) { + try { + var s = ss[i], + rs = s.cssRules ? s.cssRules : + s.rules ? s.rules : + []; + + for (var j = rs.length - 1; j >= 0; j--) { + if ( ( rs[j].type === window.CSSRule.WEBKIT_KEYFRAMES_RULE || + rs[j].type === window.CSSRule.MOZ_KEYFRAMES_RULE ) && rs[j].name === name) { + + return rs[j]; + } + } + } + catch(e) { + } + } + return null; + }; + + + +})();/** + * + * taken from: http://www.quirksmode.org/js/detect.html + * + * 20101008 Hyperandroid. IE9 seems to identify himself as Explorer and stopped calling himself MSIE. + * Added Explorer description to browser list. Thanks @alteredq for this tip. + * + */ +(function() { + + CAAT.BrowserDetect = function() { + this.init(); + return this; + }; + + CAAT.BrowserDetect.prototype = { + browser: '', + version: 0, + OS: '', + init: function() + { + this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; + this.version = this.searchVersion(navigator.userAgent) || + this.searchVersion(navigator.appVersion) || + "an unknown version"; + this.OS = this.searchString(this.dataOS) || "an unknown OS"; + }, + + searchString: function (data) { + for (var i=0;i"+ + " #caat-debug {"+ + " z-index: 10000;"+ + " position:fixed;"+ + " bottom:0;"+ + " left:0;"+ + " width:100%;"+ + " background-color: rgba(0,0,0,0.8);"+ + " }"+ + " #caat-debug.caat_debug_max {"+ + " margin-bottom: 0px;"+ + " }"+ + " .caat_debug_bullet {"+ + " display:inline-block;"+ + " background-color:#f00;"+ + " width:8px;"+ + " height:8px;"+ + " border-radius: 4px;"+ + " margin-left:10px;"+ + " margin-right:2px;"+ + " }"+ + " .caat_debug_description {"+ + " font-size:11px;"+ + " font-family: helvetica, arial;"+ + " color: #aaa;"+ + " display: inline-block;"+ + " }"+ + " .caat_debug_value {"+ + " font-size:11px;"+ + " font-family: helvetica, arial;"+ + " color: #fff;"+ + " width:25px;"+ + " text-align: right;"+ + " display: inline-block;"+ + " margin-right: .3em;"+ + " }"+ + " .caat_debug_indicator {"+ + " float: right;"+ + " }"+ + " #debug_tabs {"+ + " border-top: 1px solid #888;"+ + " height:25px;"+ + " }"+ + " .tab_max_min {"+ + " font-family: helvetica, arial;"+ + " font-size: 12px;"+ + " font-weight: bold;"+ + " color: #888;"+ + " border-right: 1px solid #888;"+ + " float: left;"+ + " cursor: pointer;"+ + " padding-left: 5px;"+ + " padding-right: 5px;"+ + " padding-top: 5px;"+ + " height: 20px;"+ + " }"+ + " .debug_tabs_content_hidden {"+ + " display: none;"+ + " width: 100%;"+ + " }"+ + " .debug_tabs_content_visible {"+ + " display: block;"+ + " width: 100%;"+ + " }"+ + " .checkbox_enabled {"+ + " display:inline-block;"+ + " background-color:#eee;"+ + " border: 1px solid #eee;"+ + " width:6px;"+ + " height:8px;"+ + " margin-left:12px;"+ + " margin-right:2px;"+ + " cursor: pointer;"+ + " }"+ + " .checkbox_disabled {"+ + " display:inline-block;"+ + " width:6px;"+ + " height:8px;"+ + " background-color: #333;"+ + " border: 1px solid #eee;"+ + " margin-left:12px;"+ + " margin-right:2px;"+ + " cursor: pointer;"+ + " }"+ + " .checkbox_description {"+ + " font-size:11px;"+ + " font-family: helvetica, arial;"+ + " color: #fff;"+ + " }"+ + " .debug_tab {"+ + " font-family: helvetica, arial;"+ + " font-size: 12px;"+ + " color: #fff;"+ + " border-right: 1px solid #888;"+ + " float: left;"+ + " padding-left: 5px;"+ + " padding-right: 5px;"+ + " height: 20px;"+ + " padding-top: 5px;"+ + " cursor: default;"+ + " }"+ + " .debug_tab_selected {"+ + " background-color: #444;"+ + " cursor: default;"+ + " }"+ + " .debug_tab_not_selected {"+ + " background-color: #000;"+ + " cursor: pointer;"+ + " }"+ + " "+ + "

    "+ + "
    "+ + " CAAT Debug panel "+ + " Performance"+ + " Controls"+ + " "+ + " "+ + " Draw Time: "+ + " 5.46"+ + " ms."+ + " "+ + " "+ + " "+ + " FPS: "+ + " 48"+ + " "+ + "
    "+ + "
    "+ + "
    "+ + " "+ + "
    "+ + " "+ + " "+ + " RAF Time:"+ + " 20.76"+ + " ms."+ + " "+ + " "+ + " "+ + " Entities Total: "+ + " 41"+ + " "+ + " "+ + " "+ + " Entities Active: "+ + " 37"+ + " "+ + " "+ + " "+ + " Draws: "+ + " 0"+ + " "+ + " "+ + " "+ + " DirtyRects: "+ + " 0"+ + " "+ + "
    "+ + "
    "+ + "
    "+ + "
    "+ + "
    "+ + " "+ + " Sound"+ + "
    "+ + "
    "+ + " "+ + " Music"+ + "
    "+ + "
    "+ + " "+ + " AA Bounding Boxes"+ + "
    "+ + "
    "+ + " "+ + " Bounding Boxes"+ + "
    "+ + "
    "+ + " "+ + " Dirty Rects"+ + "
    "+ + "
    "+ + "
    "+ + "
    "+ + "
    ", + + + setScale : function(s) { + this.scale= s; + return this; + }, + + initialize: function(w,h) { + w= window.innerWidth; + + this.width= w; + this.height= h; + + this.framerate = { + refreshInterval: CAAT.FPS_REFRESH || 500, // refresh every ? ms, updating too quickly gives too large rounding errors + frames: 0, // number offrames since last refresh + timeLastRefresh: 0, // When was the framerate counter refreshed last + fps: 0, // current framerate + prevFps: -1, // previously drawn FPS + fpsMin: 1000, // minimum measured framerate + fpsMax: 0 // maximum measured framerate + }; + + var debugContainer= document.getElementById('caat-debug'); + if (!debugContainer) { + var wrap = document.createElement('div'); + wrap.innerHTML=this.debugTpl; + document.body.appendChild(wrap); + + eval( ""+ + " function initCheck( name, bool, callback ) {"+ + " var elem= document.getElementById(name);"+ + " if ( elem ) {"+ + " elem.className= (bool) ? \"checkbox_enabled\" : \"checkbox_disabled\";"+ + " if ( callback ) {"+ + " elem.addEventListener( \"click\", (function(elem, callback) {"+ + " return function(e) {"+ + " elem.__value= !elem.__value;"+ + " elem.className= (elem.__value) ? \"checkbox_enabled\" : \"checkbox_disabled\";"+ + " callback(e,elem.__value);"+ + " }"+ + " })(elem, callback), false );"+ + " }"+ + " elem.__value= bool;"+ + " }"+ + " }"+ + " function setupTabs() {"+ + " var numTabs=0;"+ + " var elem;"+ + " var elemContent;"+ + " do {"+ + " elem= document.getElementById(\"caat-debug-tab\"+numTabs);"+ + " if ( elem ) {"+ + " elemContent= document.getElementById(\"caat-debug-tab\"+numTabs+\"-content\");"+ + " if ( elemContent ) {"+ + " elemContent.style.display= numTabs===0 ? 'block' : 'none';"+ + " elem.className= numTabs===0 ? \"debug_tab debug_tab_selected\" : \"debug_tab debug_tab_not_selected\";"+ + " elem.addEventListener( \"click\", (function(tabIndex) {"+ + " return function(e) {"+ + " for( var i=0; i this.framerate.timeLastRefresh + this.framerate.refreshInterval ) { + this.framerate.fps = ( ( this.framerate.frames * 1000 ) / ( CAAT.RAF - this.framerate.timeLastRefresh ) ) | 0; + this.framerate.fpsMin = this.framerate.frames > 0 ? Math.min( this.framerate.fpsMin, this.framerate.fps ) : this.framerate.fpsMin; + this.framerate.fpsMax = Math.max( this.framerate.fpsMax, this.framerate.fps ); + + this.textFPS.innerHTML= this.framerate.fps; + + var value= ((this.frameTimeAcc*100/this.framerate.frames)|0)/100; + this.frameTimeAcc=0; + this.textDrawTime.innerHTML= value; + + var value2= ((this.frameRAFAcc*100/this.framerate.frames)|0)/100; + this.frameRAFAcc=0; + this.textRAFTime.innerHTML= value2; + + this.framerate.timeLastRefresh = CAAT.RAF; + this.framerate.frames = 0; + + this.paint(value2); + } + + this.textEntitiesTotal.innerHTML= this.statistics.size_total; + this.textEntitiesActive.innerHTML= this.statistics.size_active; + this.textDirtyRects.innerHTML= this.statistics.size_dirtyRects; + this.textDraws.innerHTML= this.statistics.draws; + }, + + paint : function( rafValue ) { + var ctx= this.ctx; + var t=0; + + ctx.drawImage( + this.canvas, + 1, 0, this.width-1, this.height, + 0, 0, this.width-1, this.height ); + + ctx.strokeStyle= 'black'; + ctx.beginPath(); + ctx.moveTo( this.width-.5, 0 ); + ctx.lineTo( this.width-.5, this.height ); + ctx.stroke(); + + ctx.strokeStyle= '#a22'; + ctx.beginPath(); + t= this.height-((20/this.SCALE*this.height)>>0)-.5; + ctx.moveTo( .5, t ); + ctx.lineTo( this.width+.5, t ); + ctx.stroke(); + + ctx.strokeStyle= '#aa2'; + ctx.beginPath(); + t= this.height-((30/this.SCALE*this.height)>>0)-.5; + ctx.moveTo( .5, t ); + ctx.lineTo( this.width+.5, t ); + ctx.stroke(); + + var fps = Math.min( this.height-(this.framerate.fps/this.SCALE*this.height), 59 ); + if (-1===this.framerate.prevFps) { + this.framerate.prevFps= fps|0; + } + + ctx.strokeStyle= '#0ff';//this.framerate.fps<15 ? 'red' : this.framerate.fps<30 ? 'yellow' : 'green'; + ctx.beginPath(); + ctx.moveTo( this.width, (fps|0)-.5 ); + ctx.lineTo( this.width, this.framerate.prevFps-.5 ); + ctx.stroke(); + + this.framerate.prevFps= fps; + + + var t1= ((this.height-(rafValue/this.SCALE*this.height))>>0)-.5; + ctx.strokeStyle= '#ff0'; + ctx.beginPath(); + ctx.moveTo( this.width, t1 ); + ctx.lineTo( this.width, t1 ); + ctx.stroke(); + } + }; +})();/** + * See LICENSE file. + * + * Classes to define animable elements. + * Actor is the superclass of every animable element in the scene graph. It handles the whole + * affine transformation MatrixStack, rotation, translation, globalAlpha and Behaviours. It also + * defines input methods. + * TODO: add text presentation/animation effects. + **/ + +(function() { + + /** + * This class is the base for all animable entities in CAAT. + * It defines an entity able to: + * + *
      + *
    • Position itself on screen. + *
    • Able to modify its presentation aspect via affine transforms. + *
    • Take control of parent/child relationship. + *
    • Take track of behaviors (@see CAAT.Behavior). + *
    • Define a region on screen. + *
    • Define alpha composition scope. + *
    • Expose lifecycle. + *
    • Manage itself in/out scene time. + *
    • etc. + *
    + * + * @constructor + */ + CAAT.Actor = function() { + this.behaviorList= []; +// this.keyframesList= []; + this.lifecycleListenerList= []; + this.AABB= new CAAT.Rectangle(); + this.viewVertices= [ + new CAAT.Point(0,0,0), + new CAAT.Point(0,0,0), + new CAAT.Point(0,0,0), + new CAAT.Point(0,0,0) + ]; + + this.scaleAnchor= this.ANCHOR_CENTER; + + this.modelViewMatrix= new CAAT.Matrix(); + this.worldModelViewMatrix= new CAAT.Matrix(); + + this.resetTransform(); + this.setScale(1,1); + this.setRotation(0); + + return this; + }; + + CAAT.Actor.ANCHOR_CENTER= 0; // constant values to determine different affine transform + CAAT.Actor.ANCHOR_TOP= 1; // anchors. + CAAT.Actor.ANCHOR_BOTTOM= 2; + CAAT.Actor.ANCHOR_LEFT= 3; + CAAT.Actor.ANCHOR_RIGHT= 4; + CAAT.Actor.ANCHOR_TOP_LEFT= 5; + CAAT.Actor.ANCHOR_TOP_RIGHT= 6; + CAAT.Actor.ANCHOR_BOTTOM_LEFT= 7; + CAAT.Actor.ANCHOR_BOTTOM_RIGHT= 8; + CAAT.Actor.ANCHOR_CUSTOM= 9; + + CAAT.Actor.prototype= { + + lifecycleListenerList: null, // Array of life cycle listener + + behaviorList: null, // Array of behaviors to apply to the Actor + parent: null, // Parent of this Actor. May be Scene. + x: 0, // x position on parent. In parent's local coord. system. + y: 0, // y position on parent. In parent's local coord. system. + width: 0, // Actor's width. In parent's local coord. system. + height: 0, // Actor's height. In parent's local coord. system. + start_time: 0, // Start time in Scene time. + duration: Number.MAX_VALUE, // Actor duration in Scene time + clip: false, // should clip the Actor's content against its contour. + clipPath: null, + + tAnchorX : 0, + tAnchorY : 0, + + scaleX: 0, // transformation. width scale parameter + scaleY: 0, // transformation. height scale parameter + scaleTX: .50, // transformation. scale anchor x position + scaleTY: .50, // transformation. scale anchor y position + scaleAnchor: 0, // transformation. scale anchor + rotationAngle: 0, // transformation. rotation angle in radians + rotationY: .50, // transformation. rotation center y + alpha: 1, // alpha transparency value + rotationX: .50, // transformation. rotation center x + isGlobalAlpha: false, // is this a global alpha + frameAlpha: 1, // hierarchically calculated alpha for this Actor. + expired: false, // set when the actor has been expired + discardable: false, // set when you want this actor to be removed if expired + pointed: false, // is the mouse pointer inside this actor + mouseEnabled: true, // events enabled ? + + visible: true, + + ANCHOR_CENTER: 0, // constant values to determine different affine transform + ANCHOR_TOP: 1, // anchors. + ANCHOR_BOTTOM: 2, + ANCHOR_LEFT: 3, + ANCHOR_RIGHT: 4, + ANCHOR_TOP_LEFT: 5, + ANCHOR_TOP_RIGHT: 6, + ANCHOR_BOTTOM_LEFT: 7, + ANCHOR_BOTTOM_RIGHT: 8, + ANCHOR_CUSTOM: 9, + + fillStyle: null, // any canvas rendering valid fill style. + strokeStyle: null, // any canvas rendering valid stroke style. + time: 0, // Cache Scene time. + AABB: null, // CAAT.Rectangle + viewVertices: null, // model to view transformed vertices. + inFrame: false, // boolean indicating whether this Actor was present on last frame. + + dirty: true, // model view is dirty ? + wdirty: true, // world model view is dirty ? + oldX: -1, + oldY: -1, + + modelViewMatrix: null, // model view matrix. + worldModelViewMatrix: null, // world model view matrix. + modelViewMatrixI: null, // model view matrix. + worldModelViewMatrixI: null, // world model view matrix. + + glEnabled: false, + + backgroundImage: null, + id: null, + + size_active: 1, // number of animated children + size_total: 1, + + __next: null, + + __d_ax: -1, // for drag-enabled actors. + __d_ay: -1, + gestureEnabled: false, + + invalid : true, + cached : false, // has cacheAsBitmap been called ? + + collides : false, + collidesAsRect : true, + + isAA : true, // is this actor/container Axis aligned ? if so, much faster inverse matrices + // can be calculated. + + setupCollission : function( collides, isCircular ) { + this.collides= collides; + this.collidesAsRect= !isCircular; + }, + invalidate : function() { + this.invalid= true; + }, + setGestureEnabled : function( enable ) { + this.gestureEnabled= !!enable; + }, + isGestureEnabled : function() { + return this.gestureEnabled; + }, + getId : function() { + return this.id; + }, + setId : function(id) { + this.id= id; + return this; + }, + /** + * Set this actor's parent. + * @param parent {CAAT.ActorContainer} + * @return this + */ + setParent : function(parent) { + this.parent= parent; + return this; + }, + + getScene : function() { + if ( typeof this.parent ==='undefined' || this.parent === null) { + return null; + } + if (this.parent.name === 'CAAT.Scene') { + return this.parent; + } + return this.parent.getScene(); + }, + + /** + * Set this actor's background image. + * The need of a background image is to kept compatibility with the new CSSDirector class. + * The image parameter can be either an Image/Canvas or a CAAT.SpriteImage instance. If an image + * is supplied, it will be wrapped into a CAAT.SriteImage instance of 1 row by 1 column. + * If the actor has set an image in the background, the paint method will draw the image, otherwise + * and if set, will fill its background with a solid color. + * If adjust_size_to_image is true, the host actor will be redimensioned to the size of one + * single image from the SpriteImage (either supplied or generated because of passing an Image or + * Canvas to the function). That means the size will be set to [width:SpriteImage.singleWidth, + * height:singleHeight]. + * + * WARN: if using a CSS renderer, the image supplied MUST be a HTMLImageElement instance. + * + * @see CAAT.SpriteImage + * + * @param image {Image|HTMLCanvasElement|CAAT.SpriteImage} + * @param adjust_size_to_image {boolean} whether to set this actor's size based on image parameter. + * + * @return this + */ + setBackgroundImage : function(image, adjust_size_to_image ) { + if ( image ) { + if ( !(image instanceof CAAT.SpriteImage) ) { + image= new CAAT.SpriteImage().initialize(image,1,1); + } + + image.setOwner(this); + this.backgroundImage= image; + if ( typeof adjust_size_to_image==='undefined' || adjust_size_to_image ) { + this.width= image.getWidth(); + this.height= image.getHeight(); + } + + this.glEnabled= true; + } else { + this.backgroundImage= null; + } + + return this; + }, + /** + * Set the actor's SpriteImage index from animation sheet. + * @see CAAT.SpriteImage + * @param index {number} + * + * @return this + */ + setSpriteIndex: function(index) { + if ( this.backgroundImage ) { + this.backgroundImage.setSpriteIndex(index); + this.invalidate(); + } + + return this; + + }, + /** + * Set this actor's background SpriteImage offset displacement. + * The values can be either positive or negative meaning the texture space of this background + * image does not start at (0,0) but at the desired position. + * @see CAAT.SpriteImage + * @param ox {number} horizontal offset + * @param oy {number} vertical offset + * + * @return this + */ + setBackgroundImageOffset : function( ox, oy ) { + if ( this.backgroundImage ) { + this.backgroundImage.setOffset(ox,oy); + } + + return this; + }, + /** + * Set this actor's background SpriteImage its animation sequence. + * In its simplet's form a SpriteImage treats a given image as an array of rows by columns + * subimages. If you define d Sprite Image of 2x2, you'll be able to draw any of the 4 subimages. + * This method defines the animation sequence so that it could be set [0,2,1,3,2,1] as the + * animation sequence + * @param ii {Array} an array of integers. + */ + setAnimationImageIndex : function( ii ) { + if ( this.backgroundImage ) { + this.backgroundImage.setAnimationImageIndex(ii); + } + return this; + }, + setChangeFPS : function(time) { + if ( this.backgroundImage ) { + this.backgroundImage.setChangeFPS(time); + } + return this; + + }, + /** + * Set this background image transformation. + * If GL is enabled, this parameter has no effect. + * @param it any value from CAAT.SpriteImage.TR_* + * @return this + */ + setImageTransformation : function( it ) { + if ( this.backgroundImage ) { + this.backgroundImage.setSpriteTransformation(it); + } + return this; + }, + /** + * Center this actor at position (x,y). + * @param x {number} x position + * @param y {number} y position + * + * @return this + * @deprecated + */ + centerOn : function( x,y ) { + this.setLocation( x-this.width/2, y-this.height/2 ); + return this; + }, + /** + * Center this actor at position (x,y). + * @param x {number} x position + * @param y {number} y position + * + * @return this + */ + centerAt : function(x,y) { + return this.centerOn(x,y); + }, + /** + * If GL is enables, get this background image's texture page, otherwise it will fail. + * @return {CAAT.GLTexturePage} + */ + getTextureGLPage : function() { + return this.backgroundImage.image.__texturePage; + }, + /** + * Set this actor invisible. + * The actor is animated but not visible. + * A container won't show any of its children if set visible to false. + * + * @param visible {boolean} set this actor visible or not. + * @return this + */ + setVisible : function(visible) { + this.visible= visible; + return this; + }, + /** + * Puts an Actor out of time line, that is, won't be transformed nor rendered. + * @return this + */ + setOutOfFrameTime : function() { + this.setFrameTime(-1,0); + return this; + }, + /** + * Adds an Actor's life cycle listener. + * The developer must ensure the actorListener is not already a listener, otherwise + * it will notified more than once. + * @param actorListener {object} an object with at least a method of the form: + * actorLyfeCycleEvent( actor, string_event_type, long_time ) + */ + addListener : function( actorListener ) { + this.lifecycleListenerList.push(actorListener); + return this; + }, + /** + * Removes an Actor's life cycle listener. + * It will only remove the first occurrence of the given actorListener. + * @param actorListener {object} an Actor's life cycle listener. + */ + removeListener : function( actorListener ) { + var n= this.lifecycleListenerList.length; + while(n--) { + if ( this.lifecycleListenerList[n]===actorListener ) { + // remove the nth element. + this.lifecycleListenerList.splice(n,1); + return; + } + } + }, + /** + * Set alpha composition scope. global will mean this alpha value will be its children maximum. + * If set to false, only this actor will have this alpha value. + * @param global {boolean} whether the alpha value should be propagated to children. + */ + setGlobalAlpha : function( global ) { + this.isGlobalAlpha= global; + return this; + }, + /** + * Notifies the registered Actor's life cycle listener about some event. + * @param sEventType an string indicating the type of event being notified. + * @param time an integer indicating the time related to Scene's timeline when the event + * is being notified. + */ + fireEvent : function(sEventType, time) { + for( var i=0; i=this.start_time+this.duration ) { + if ( !this.expired ) { + this.setExpired(time); + } + + return false; + } + + return this.start_time<=time && time=0 && y>=0 && x + * WARNING: every call to this method calculates + * actor's world model view matrix. + * + * @param point {CAAT.Point} a point in screen space to be transformed to model space. + * + * @return the source point object + * + * + */ + viewToModel : function(point) { + this.worldModelViewMatrixI= this.worldModelViewMatrix.getInverse(); + this.worldModelViewMatrixI.transformCoord(point); + return point; + }, + /** + * Private + * This method does the needed point transformations across an Actor hierarchy to devise + * whether the parameter point coordinate lies inside the Actor. + * @param point {CAAT.Point} + * + * @return null if the point is not inside the Actor. The Actor otherwise. + */ + findActorAtPosition : function(point) { + if ( !this.visible || !this.mouseEnabled || !this.isInAnimationFrame(this.time) ) { + return null; + } + + this.modelViewMatrixI= this.modelViewMatrix.getInverse(); + this.modelViewMatrixI.transformCoord(point); + return this.contains(point.x, point.y) ? this :null; + }, + /** + * Enables a default dragging routine for the Actor. + * This default dragging routine allows to: + *
  • scale the Actor by pressing shift+drag + *
  • rotate the Actor by pressing control+drag + *
  • scale non uniformly by pressing alt+shift+drag + * + * @return this + */ + enableDrag : function() { + + var me= this; + + this.ax= 0; + this.ay= 0; + this.mx= 0; + this.my= 0; + this.asx=1; + this.asy=1; + this.ara=0; + this.screenx=0; + this.screeny=0; + + /** + * Mouse enter handler for default drag behavior. + * @param mouseEvent {CAAT.MouseEvent} + * + * @ignore + */ + this.mouseEnter= function(mouseEvent) { + this.__d_ax= -1; + this.__d_ay= -1; + this.pointed= true; + CAAT.setCursor('move'); + }; + + /** + * Mouse exit handler for default drag behavior. + * @param mouseEvent {CAAT.MouseEvent} + * + * @ignore + */ + this.mouseExit = function(mouseEvent) { + this.__d_ax = -1; + this.__d_ay = -1; + this.pointed = false; + CAAT.setCursor('default'); + }; + + /** + * Mouse move handler for default drag behavior. + * @param mouseEvent {CAAT.MouseEvent} + * + * @ignore + */ + this.mouseMove = function(mouseEvent) { + }; + + /** + * Mouse up handler for default drag behavior. + * @param mouseEvent {CAAT.MouseEvent} + * + * @ignore + */ + this.mouseUp = function(mouseEvent) { + this.__d_ax = -1; + this.__d_ay = -1; + }; + + /** + * Mouse drag handler for default drag behavior. + * @param mouseEvent {CAAT.MouseEvent} + * + * @ignore + */ + this.mouseDrag = function(mouseEvent) { + + var pt; + + pt= this.modelToView( new CAAT.Point(mouseEvent.x, mouseEvent.y ) ); + this.parent.viewToModel( pt ); + + if (this.__d_ax === -1 || this.__d_ay === -1) { + this.__d_ax = pt.x; + this.__d_ay = pt.y; + this.__d_asx = this.scaleX; + this.__d_asy = this.scaleY; + this.__d_ara = this.rotationAngle; + this.__d_screenx = mouseEvent.screenPoint.x; + this.__d_screeny = mouseEvent.screenPoint.y; + } + + if (mouseEvent.isShiftDown()) { + var scx = (mouseEvent.screenPoint.x - this.__d_screenx) / 100; + var scy = (mouseEvent.screenPoint.y - this.__d_screeny) / 100; + if (!mouseEvent.isAltDown()) { + var sc = Math.max(scx, scy); + scx = sc; + scy = sc; + } + this.setScale(scx + this.__d_asx, scy + this.__d_asy); + + } else if (mouseEvent.isControlDown()) { + var vx = mouseEvent.screenPoint.x - this.__d_screenx; + var vy = mouseEvent.screenPoint.y - this.__d_screeny; + this.setRotation(-Math.atan2(vx, vy) + this.__d_ara); + } else { + this.x += pt.x-this.__d_ax; + this.y += pt.y-this.__d_ay; + } + + this.__d_ax= pt.x; + this.__d_ay= pt.y; + }; + + return this; + }, + /** + * Default mouseClick handler. + * Mouse click events are received after a call to mouseUp method if no dragging was in progress. + * + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseClick : function(mouseEvent) { + }, + /** + * Default double click handler + * + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseDblClick : function(mouseEvent) { + }, + /** + * Default mouse enter on Actor handler. + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseEnter : function(mouseEvent) { + this.pointed= true; + }, + /** + * Default mouse exit on Actor handler. + * + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseExit : function(mouseEvent) { + this.pointed= false; + }, + /** + * Default mouse move inside Actor handler. + * + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseMove : function(mouseEvent) { + }, + /** + * default mouse press in Actor handler. + * + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseDown : function(mouseEvent) { + }, + /** + * default mouse release in Actor handler. + * + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseUp : function(mouseEvent) { + }, + mouseOut : function(mouseEvent) { + }, + mouseOver : function(mouseEvent) { + }, + /** + * default Actor mouse drag handler. + * + * @param mouseEvent {CAAT.MouseEvent} + */ + mouseDrag : function(mouseEvent) { + }, + /** + * Draw a bounding box with on-screen coordinates regardless of the transformations + * applied to the Actor. + * + * @param director {CAAT.Director} object instance that contains the Scene the Actor is in. + * @param time {number} integer indicating the Scene time when the bounding box is to be drawn. + */ + drawScreenBoundingBox : function( director, time ) { + if ( null!==this.AABB && this.inFrame ) { + var s= this.AABB; + var ctx= director.ctx; + ctx.strokeStyle= CAAT.DEBUGAABBCOLOR; + ctx.strokeRect( .5+(s.x|0), .5+(s.y|0), s.width|0, s.height|0 ); + if ( CAAT.DEBUGBB ) { + var vv= this.viewVertices; + ctx.beginPath( ); + ctx.lineTo( vv[0].x, vv[0].y ); + ctx.lineTo( vv[1].x, vv[1].y ); + ctx.lineTo( vv[2].x, vv[2].y ); + ctx.lineTo( vv[3].x, vv[3].y ); + ctx.closePath(); + ctx.strokeStyle= CAAT.DEBUGBBCOLOR; + ctx.stroke(); + } + } + }, + /** + * Private + * This method is called by the Director instance. + * It applies the list of behaviors the Actor has registered. + * + * @param director the CAAT.Director object instance that contains the Scene the Actor is in. + * @param time an integer indicating the Scene time when the bounding box is to be drawn. + */ + animate : function(director, time) { + + var i; + + if ( !this.isInAnimationFrame(time) ) { + this.inFrame= false; + this.dirty= true; + return false; + } + + if ( this.x!==this.oldX || this.y!==this.oldY ) { + this.dirty= true; + this.oldX= this.x; + this.oldY= this.y; + } + + for( i=0; i xmax ) { + xmax=vvv.x; + } + if ( vvv.y < ymin ) { + ymin=vvv.y; + } + if ( vvv.y > ymax ) { + ymax=vvv.y; + } + var vvv= vv[1]; + if ( vvv.x < xmin ) { + xmin=vvv.x; + } + if ( vvv.x > xmax ) { + xmax=vvv.x; + } + if ( vvv.y < ymin ) { + ymin=vvv.y; + } + if ( vvv.y > ymax ) { + ymax=vvv.y; + } + var vvv= vv[2]; + if ( vvv.x < xmin ) { + xmin=vvv.x; + } + if ( vvv.x > xmax ) { + xmax=vvv.x; + } + if ( vvv.y < ymin ) { + ymin=vvv.y; + } + if ( vvv.y > ymax ) { + ymax=vvv.y; + } + var vvv= vv[3]; + if ( vvv.x < xmin ) { + xmin=vvv.x; + } + if ( vvv.x > xmax ) { + xmax=vvv.x; + } + if ( vvv.y < ymin ) { + ymin=vvv.y; + } + if ( vvv.y > ymax ) { + ymax=vvv.y; + } + + AABB.x= xmin; + AABB.y= ymin; + AABB.x1= xmax; + AABB.y1= ymax; + AABB.width= (xmax-xmin); + AABB.height= (ymax-ymin); + + return this; + }, + /** + * @private. + * This method will be called by the Director to set the whole Actor pre-render process. + * + * @param director the CAAT.Director object instance that contains the Scene the Actor is in. + * @param time an integer indicating the Scene time when the bounding box is to be drawn. + * + * @return boolean indicating whether the Actor isInFrameTime + */ + paintActor : function(director, time) { + + if (!this.visible) { + return true; + } + + var ctx= director.ctx; + + this.frameAlpha= this.parent ? this.parent.frameAlpha*this.alpha : 1; + ctx.globalAlpha= this.frameAlpha; + + director.modelViewMatrix.transformRenderingContextSet( ctx ); + this.worldModelViewMatrix.transformRenderingContext(ctx); + + if ( this.clip ) { + ctx.beginPath(); + if (!this.clipPath ) { + ctx.rect(0,0,this.width,this.height); + } else { + this.clipPath.applyAsPath(director); + } + ctx.clip(); + } + + this.paint(director, time); + + return true; + }, + /** + * for js2native + * @param director + * @param time + */ + __paintActor : function(director, time) { + if (!this.visible) { + return true; + } + var ctx= director.ctx; + + // global opt: set alpha as owns alpha, not take globalAlpha procedure. + this.frameAlpha= this.alpha; + + var m= this.worldModelViewMatrix.matrix; + ctx.setTransform( m[0], m[3], m[1], m[4], m[2], m[5], this.frameAlpha ); + this.paint(director, time); + return true; + }, + + /** + * Set coordinates and uv values for this actor. + * This function uses Director's coords and indexCoords values. + * @param director + * @param time + */ + paintActorGL : function(director,time) { + + this.frameAlpha= this.parent.frameAlpha*this.alpha; + + if ( !this.glEnabled || !this.visible) { + return; + } + + if ( this.glNeedsFlush(director) ) { + director.glFlush(); + this.glSetShader(director); + + if ( !this.__uv ) { + this.__uv= new Float32Array(8); + } + if ( !this.__vv ) { + this.__vv= new Float32Array(12); + } + + this.setGLCoords( this.__vv, 0 ); + this.setUV( this.__uv, 0 ); + director.glRender(this.__vv, 12, this.__uv); + + return; + } + + var glCoords= director.coords; + var glCoordsIndex= director.coordsIndex; + + ////////////////// XYZ + this.setGLCoords(glCoords, glCoordsIndex); + director.coordsIndex= glCoordsIndex+12; + + ////////////////// UV + this.setUV( director.uv, director.uvIndex ); + director.uvIndex+= 8; + }, + /** + * TODO: set GLcoords for different image transformations. + * @param glCoords + * @param glCoordsIndex + * @param z + */ + setGLCoords : function( glCoords, glCoordsIndex ) { + + var vv= this.viewVertices; + glCoords[glCoordsIndex++]= vv[0].x; + glCoords[glCoordsIndex++]= vv[0].y; + glCoords[glCoordsIndex++]= 0; + + glCoords[glCoordsIndex++]= vv[1].x; + glCoords[glCoordsIndex++]= vv[1].y; + glCoords[glCoordsIndex++]= 0; + + glCoords[glCoordsIndex++]= vv[2].x; + glCoords[glCoordsIndex++]= vv[2].y; + glCoords[glCoordsIndex++]= 0; + + glCoords[glCoordsIndex++]= vv[3].x; + glCoords[glCoordsIndex++]= vv[3].y; + glCoords[glCoordsIndex++]= 0; + + }, + /** + * Set UV for this actor's quad. + * + * @param uvBuffer {Float32Array} + * @param uvIndex {number} + */ + setUV : function( uvBuffer, uvIndex ) { + this.backgroundImage.setUV(uvBuffer, uvIndex); + }, + /** + * Test for compulsory gl flushing: + * 1.- opacity has changed. + * 2.- texture page has changed. + * + */ + glNeedsFlush : function(director) { + if ( this.getTextureGLPage()!==director.currentTexturePage ) { + return true; + } + if ( this.frameAlpha!==director.currentOpacity ) { + return true; + } + return false; + }, + /** + * Change texture shader program parameters. + * @param director + */ + glSetShader : function(director) { + + var tp= this.getTextureGLPage(); + if ( tp!==director.currentTexturePage ) { + director.setGLTexturePage(tp); + } + + if ( this.frameAlpha!==director.currentOpacity ) { + director.setGLCurrentOpacity(this.frameAlpha); + } + }, + /** + * @private. + * This method is called after the Director has transformed and drawn a whole frame. + * + * @param director the CAAT.Director object instance that contains the Scene the Actor is in. + * @param time an integer indicating the Scene time when the bounding box is to be drawn. + * @return this + * + * @deprecated + */ + endAnimate : function(director,time) { + return this; + }, + initialize : function(overrides) { + if (overrides) { + for (var i in overrides) { + this[i] = overrides[i]; + } + } + + return this; + }, + /** + * Set this Actor's clipping area. + * @param enable {boolean} enable clip area. + * @param clipPath {CAAT.Path=} An optional path to apply clip with. If enabled and clipPath is not set, + * a rectangle will be used. + */ + setClip : function( enable, clipPath ) { + this.clip= enable; + this.clipPath= clipPath; + return this; + }, + /** + * + * @param time {Number=} + * @return this + */ + cacheAsBitmap : function(time) { + time= time||0; + var canvas= document.createElement('canvas'); + canvas.width= this.width; + canvas.height= this.height; + var ctx= canvas.getContext('2d'); + var director= { + ctx: ctx, + crc: ctx, + modelViewMatrix: new CAAT.Matrix() + }; + + this.paintActor(director,time); + this.setBackgroundImage(canvas); + + this.cached= true; + + return this; + }, + /** + * Set this actor behavior as if it were a Button. The actor size will be set as SpriteImage's + * single size. + * + * @param buttonImage {CAAT.SpriteImage} sprite image with button's state images. + * @param _iNormal {number} button's normal state image index + * @param _iOver {number} button's mouse over state image index + * @param _iPress {number} button's pressed state image index + * @param _iDisabled {number} button's disabled state image index + * @param fn {function(button{CAAT.Actor})} callback function + */ + setAsButton : function( buttonImage, iNormal, iOver, iPress, iDisabled, fn ) { + + var me= this; + + this.setBackgroundImage(buttonImage, true); + + this.iNormal= iNormal || 0; + this.iOver= iOver || iNormal; + this.iPress= iPress || iNormal; + this.iDisabled= iDisabled || iNormal; + this.fnOnClick= fn; + this.enabled= true; + + this.setSpriteIndex( iNormal ); + + /** + * Enable or disable the button. + * @param enabled {boolean} + * @ignore + */ + this.setEnabled= function( enabled ) { + this.enabled= enabled; + this.setSpriteIndex( this.enabled ? this.iNormal : this.iDisabled ); + return this; + }; + + /** + * This method will be called by CAAT *before* the mouseUp event is fired. + * @param event {CAAT.MouseEvent} + * @ignore + */ + this.actionPerformed= function(event) { + if ( this.enabled && null!==this.fnOnClick ) { + this.fnOnClick(this); + } + }; + + /** + * Button's mouse enter handler. It makes the button provide visual feedback + * @param mouseEvent {CAAT.MouseEvent} + * @ignore + */ + this.mouseEnter= function(mouseEvent) { + if ( !this.enabled ) { + return; + } + + if ( this.dragging ) { + this.setSpriteIndex( this.iPress ); + } else { + this.setSpriteIndex( this.iOver ); + } + CAAT.setCursor('pointer'); + }; + + /** + * Button's mouse exit handler. Release visual apperance. + * @param mouseEvent {CAAT.MouseEvent} + * @ignore + */ + this.mouseExit= function(mouseEvent) { + if ( !this.enabled ) { + return; + } + + this.setSpriteIndex( this.iNormal ); + CAAT.setCursor('default'); + }; + + /** + * Button's mouse down handler. + * @param mouseEvent {CAAT.MouseEvent} + * @ignore + */ + this.mouseDown= function(mouseEvent) { + if ( !this.enabled ) { + return; + } + + this.setSpriteIndex( this.iPress ); + }; + + /** + * Button's mouse up handler. + * @param mouseEvent {CAAT.MouseEvent} + * @ignore + */ + this.mouseUp= function(mouseEvent) { + if ( !this.enabled ) { + return; + } + + this.setSpriteIndex( this.iNormal ); + this.dragging= false; + }; + + /** + * Button's mouse click handler. Do nothing by default. This event handler will be + * called ONLY if it has not been drag on the button. + * @param mouseEvent {CAAT.MouseEvent} + * @ignore + */ + this.mouseClick= function(mouseEvent) { + }; + + /** + * Button's mouse drag handler. + * @param mouseEvent {CAAT.MouseEvent} + * @ignore + */ + this.mouseDrag= function(mouseEvent) { + if ( !this.enabled ) { + return; + } + + this.dragging= true; + }; + + this.setButtonImageIndex= function(_normal, _over, _press, _disabled ) { + this.iNormal= _normal; + this.iOver= _over; + this.iPress= _press; + this.iDisabled= _disabled; + this.setSpriteIndex( this.iNormal ); + return this; + }; + + return this; + } + }; + + if ( CAAT.NO_PERF ) { + CAAT.Actor.prototype.paintActor= CAAT.Actor.prototype.__paintActor; + } + +})(); + +(function() { + + /** + * This class is a general container of CAAT.Actor instances. It extends the concept of an Actor + * from a single entity on screen to a set of entities with a parent/children relationship among + * them. + *

    + * This mainly overrides default behavior of a single entity and exposes methods to manage its children + * collection. + * + * @constructor + * @extends CAAT.Actor + */ + CAAT.ActorContainer= function(hint) { + + CAAT.ActorContainer.superclass.constructor.call(this); + this.childrenList= []; + this.pendingChildrenList= []; + if ( typeof hint!=='undefined' ) { + this.addHint= hint; + this.boundingBox= new CAAT.Rectangle(); + } + return this; + }; + + CAAT.ActorContainer.AddHint= { + CONFORM : 1 + }; + + CAAT.ActorContainer.prototype= { + + childrenList : null, // the list of children contained. + activeChildren : null, + pendingChildrenList : null, + + addHint : 0, + boundingBox : null, + runion : new CAAT.Rectangle(), // Watch out. one for every container. + + /** + * Draws this ActorContainer and all of its children screen bounding box. + * + * @param director the CAAT.Director object instance that contains the Scene the Actor is in. + * @param time an integer indicating the Scene time when the bounding box is to be drawn. + */ + drawScreenBoundingBox : function( director, time ) { + + if (!this.inFrame) { + return; + } + + var cl= this.childrenList; + for( var i=0; i=this.childrenList.length ) { + index= this.childrenList.length; + } + } + + child.parent= this; + child.dirty= true; + this.childrenList.splice(index, 0, child); + + return this; + }, + /** + * Find the first actor with the supplied ID. + * This method is not recommended to be used since executes a linear search. + * @param id + */ + findActorById : function(id) { + var cl= this.childrenList; + for( var i=0, l=cl.length; i=0; i-- ) { + var child= this.childrenList[i]; + + var np= new CAAT.Point( point.x, point.y, 0 ); + var contained= child.findActorAtPosition( np ); + if ( null!==contained ) { + return contained; + } + } + + return this; + }, + /** + * Destroys this ActorContainer. + * The process falls down recursively for each contained Actor into this ActorContainer. + * + * @return this + */ + destroy : function() { + var cl= this.childrenList; + for( var i=cl.length-1; i>=0; i-- ) { + cl[i].destroy(); + } + CAAT.ActorContainer.superclass.destroy.call(this); + + return this; + }, + /** + * Get number of Actors into this container. + * @return integer indicating the number of children. + */ + getNumChildren : function() { + return this.childrenList.length; + }, + getNumActiveChildren : function() { + return this.activeChildren.length; + }, + /** + * Returns the Actor at the iPosition(th) position. + * @param iPosition an integer indicating the position array. + * @return the CAAT.Actor object at position. + */ + getChildAt : function( iPosition ) { + return this.childrenList[ iPosition ]; + }, + /** + * Changes an actor's ZOrder. + * @param actor the actor to change ZOrder for + * @param index an integer indicating the new ZOrder. a value greater than children list size means to be the + * last ZOrder Actor. + */ + setZOrder : function( actor, index ) { + var actorPos= this.findChild(actor); + // the actor is present + if ( -1!==actorPos ) { + var cl= this.childrenList; + // trivial reject. + if ( index===actorPos ) { + return; + } + + if ( index>=cl.length ) { + cl.splice(actorPos,1); + cl.push(actor); + } else { + var nActor= cl.splice(actorPos,1); + if ( index<0 ) { + index=0; + } else if ( index>cl.length ) { + index= cl.length; + } + + //cl.splice( index, 1, nActor ); + cl.splice( index, 0, nActor[0] ); + } + } + } + }; + + if ( CAAT.NO_PERF ) { + CAAT.ActorContainer.prototype.paintActor= CAAT.ActorContainer.prototype.__paintActor; + } + + extend( CAAT.ActorContainer, CAAT.Actor, null); + +})(); + + +(function() { + + /** + * TextActor draws text on screen. The text can be drawn directly on screen or make if follow a + * path defined by an instance of CAAT.Path. + * + * @constructor + * @extends CAAT.ActorContainer + * + */ + CAAT.TextActor = function() { + CAAT.TextActor.superclass.constructor.call(this); + this.font= "10px sans-serif"; + this.textAlign= "left"; + this.textBaseline= "top"; + this.outlineColor= "black"; + this.clip= false; + + return this; + }; + + CAAT.TextActor.TRAVERSE_PATH_FORWARD= 1; + CAAT.TextActor.TRAVERSE_PATH_BACKWARD= -1; + + CAAT.TextActor.prototype= { + font: null, // a valid canvas rendering context font description. Default font + // will be "10px sans-serif". + textAlign: null, // a valid canvas rendering context textAlign string. Any of: + // start, end, left, right, center. + // defaults to "left". + textBaseline: null, // a valid canvas rendering context textBaseLine string. Any of: + // top, hanging, middle, alphabetic, ideographic, bottom. + // defaults to "top". + fill: true, // a boolean indicating whether the text should be filled. + textFillStyle : '#eee', // text fill color + text: null, // a string with the text to draw. + textWidth: 0, // an integer indicating text width in pixels. + textHeight: 0, // an integer indicating text height in pixels. + outline: false, // a boolean indicating whether the text should be outlined. + // not all browsers support it. + outlineColor: null, // a valid color description string. + + path: null, // a CAAT.Path which will be traversed by the text. [Optional] + pathInterpolator: null, // a CAAT.Interpolator to apply to the path traversing. + pathDuration: 10000, // an integer indicating the time to be taken to traverse the path. ms. + sign: 1, // traverse the path forward or backwards. + + /** + * Set the text to be filled. The default Filling style will be set by calling setFillStyle method. + * Default value is true. + * @param fill {boolean} a boolean indicating whether the text will be filled. + * @return this; + */ + setFill : function( fill ) { + this.fill= fill; + return this; + }, + setTextFillStyle : function( style ) { + this.textFillStyle= style; + return this; + }, + /** + * Sets whether the text will be outlined. + * @param outline {boolean} a boolean indicating whether the text will be outlined. + * @return this; + */ + setOutline : function( outline ) { + this.outline= outline; + return this; + }, + setPathTraverseDirection : function(direction) { + this.sign= direction; + return this; + }, + /** + * Defines text's outline color. + * + * @param color {string} sets a valid canvas context color. + * @return this. + */ + setOutlineColor : function( color ) { + this.outlineColor= color; + return this; + }, + /** + * Set the text to be shown by the actor. + * @param sText a string with the text to be shwon. + * @return this + */ + setText : function( sText ) { + this.text= sText; + if ( null===this.text || this.text==="" ) { + this.width= this.height= 0; + } + this.calcTextSize( CAAT.director[0] ); + + return this; + }, + setTextAlign : function( align ) { + this.textAlign= align; + return this; + }, + /** + * Sets text alignment + * @param align + * @deprecated use setTextAlign + */ + setAlign : function( align ) { + return this.setTextAlign(align); + }, + /** + * Set text baseline. + * @param baseline + */ + setTextBaseline : function( baseline ) { + this.textBaseline= baseline; + return this; + + }, + setBaseline : function( baseline ) { + return this.setTextBaseline(baseline); + }, + /** + * Sets the font to be applied for the text. + * @param font a string with a valid canvas rendering context font description. + * @return this + */ + setFont : function(font) { + + if ( !font ) { + font= "10px sans-serif"; + } + + this.font= font; + this.calcTextSize( CAAT.director[0] ); + + return this; + }, + + /** + * Calculates the text dimension in pixels and stores the values in textWidth and textHeight + * attributes. + * If Actor's width and height were not set, the Actor's dimension will be set to these values. + * @param director a CAAT.Director instance. + * @return this + */ + calcTextSize : function(director) { + + if ( typeof this.text==='undefined' || null===this.text || ""===this.text ) { + this.textWidth= 0; + this.textHeight= 0; + return this; + } + + if ( director.glEnabled ) { + return this; + } + + if ( this.font instanceof CAAT.SpriteImage ) { + this.textWidth= this.font.stringWidth( this.text ); + this.textHeight=this.font.stringHeight(); + this.width= this.textWidth; + this.height= this.textHeight; + return this; + } + + var ctx= director.ctx; + + ctx.save(); + ctx.font= this.font; + + this.textWidth= ctx.measureText( this.text ).width; + if (this.width===0) { + this.width= this.textWidth; + } + + try { + var pos= this.font.indexOf("px"); + var s = this.font.substring(0, pos ); + this.textHeight= parseInt(s,10); + + // needed to calculate the descent. + // no context.getDescent(font) WTF !!! + this.textHeight+= (this.textHeight/4)>>0; + } catch(e) { + this.textHeight=20; // default height; + } + + if ( this.height===0 ) { + this.height= this.textHeight; + } + + ctx.restore(); + + return this; + }, + /** + * Custom paint method for TextActor instances. + * If the path attribute is set, the text will be drawn traversing the path. + * + * @param director a valid CAAT.Director instance. + * @param time an integer with the Scene time the Actor is being drawn. + */ + paint : function(director, time) { + + CAAT.TextActor.superclass.paint.call(this, director, time ); + + if ( this.cached ) { + // cacheAsBitmap sets this actor's background image as a representation of itself. + // So if after drawing the background it was cached, we're done. + return; + } + + if ( null===this.text) { + return; + } + + if ( this.textWidth===0 || this.textHeight===0 ) { + this.calcTextSize(director); + } + + var ctx= director.ctx; + + if ( this.font instanceof CAAT.SpriteImage ) { + return this.drawSpriteText(director,time); + } + + if( null!==this.font ) { + ctx.font= this.font; + } + if ( null!==this.textAlign ) { + ctx.textAlign= this.textAlign; + } + if ( null!==this.textBaseline ) { + ctx.textBaseline= this.textBaseline; + } + if ( this.fill && null!==this.textFillStyle ) { + ctx.fillStyle= this.textFillStyle; + } + if ( this.outline && null!==this.outlineColor ) { + ctx.strokeStyle= this.outlineColor; + } + + if (null===this.path) { + + var tx=0; + if ( this.textAlign==='center') { + tx= (this.width/2)|0; + } else if ( this.textAlign==='right' ) { + tx= this.width; + } + + if ( this.fill ) { + ctx.fillText( this.text, tx, 0 ); + if ( this.outline ) { + + // firefox necesita beginPath, si no, dibujara ademas el cuadrado del + // contenedor de los textos. +// if ( null!==this.outlineColor ) { +// ctx.strokeStyle= this.outlineColor; +// } + ctx.beginPath(); + ctx.strokeText( this.text, tx, 0 ); + } + } else { + if ( null!==this.outlineColor ) { + ctx.strokeStyle= this.outlineColor; + } + ctx.beginPath(); + ctx.strokeText( this.text, tx, 0 ); + } + } + else { + this.drawOnPath(director,time); + } + }, + /** + * Private. + * Draw the text traversing a path. + * @param director a valid CAAT.Director instance. + * @param time an integer with the Scene time the Actor is being drawn. + */ + drawOnPath : function(director, time) { + + var ctx= director.ctx; + + var textWidth=this.sign * this.pathInterpolator.getPosition( + (time%this.pathDuration)/this.pathDuration ).y * this.path.getLength() ; + var p0= new CAAT.Point(0,0,0); + var p1= new CAAT.Point(0,0,0); + + for( var i=0; i0} + */ + setLineWidth : function(l) { + this.lineWidth= l; + return this; + }, + /** + * + * @param lc {string{butt|round|square}} + */ + setLineCap : function(lc) { + this.lineCap= lc; + return this; + }, + /** + * + * @param lj {string{bevel|round|miter}} + */ + setLineJoin : function(lj) { + this.lineJoin= lj; + return this; + }, + /** + * + * @param ml {integer>0} + */ + setMiterLimit : function(ml) { + this.miterLimit= ml; + return this; + }, + getLineCap : function() { + return this.lineCap; + }, + getLineJoin : function() { + return this.lineJoin; + }, + getMiterLimit : function() { + return this.miterLimit; + }, + getLineWidth : function() { + return this.lineWidth; + }, + /** + * Sets shape type. + * No check for parameter validity is performed. + * Set paint method according to the shape. + * @param iShape an integer with any of the SHAPE_* constants. + * @return this + */ + setShape : function(iShape) { + this.shape= iShape; + this.paint= this.shape===this.SHAPE_CIRCLE ? + this.paintCircle : + this.paintRectangle; + return this; + }, + /** + * Sets the composite operation to apply on shape drawing. + * @param compositeOp an string with a valid canvas rendering context string describing compositeOps. + * @return this + */ + setCompositeOp : function(compositeOp){ + this.compositeOp= compositeOp; + return this; + }, + /** + * Draws the shape. + * Applies the values of fillStype, strokeStyle, compositeOp, etc. + * + * @param director a valid CAAT.Director instance. + * @param time an integer with the Scene time the Actor is being drawn. + */ + paint : function(director,time) { + }, + /** + * @private + * Draws a circle. + * @param director a valid CAAT.Director instance. + * @param time an integer with the Scene time the Actor is being drawn. + */ + paintCircle : function(director,time) { + var ctx= director.crc; + + ctx.lineWidth= this.lineWidth; + + ctx.globalCompositeOperation= this.compositeOp; + if ( null!==this.fillStyle ) { + ctx.fillStyle= this.fillStyle; + ctx.beginPath(); + ctx.arc( this.width/2, this.height/2, Math.min(this.width,this.height)/2, 0, 2*Math.PI, false ); + ctx.fill(); + } + + if ( null!==this.strokeStyle ) { + ctx.strokeStyle= this.strokeStyle; + ctx.beginPath(); + ctx.arc( this.width/2, this.height/2, Math.min(this.width,this.height)/2, 0, 2*Math.PI, false ); + ctx.stroke(); + } + }, + /** + * + * Private + * Draws a Rectangle. + * + * @param director a valid CAAT.Director instance. + * @param time an integer with the Scene time the Actor is being drawn. + */ + paintRectangle : function(director,time) { + var ctx= director.crc; + + ctx.lineWidth= this.lineWidth; + + if ( this.lineCap ) { + ctx.lineCap= this.lineCap; + } + if ( this.lineJoin ) { + ctx.lineJoin= this.lineJoin; + } + if ( this.miterLimit ) { + ctx.miterLimit= this.miterLimit; + } + + ctx.globalCompositeOperation= this.compositeOp; + if ( null!==this.fillStyle ) { + ctx.fillStyle= this.fillStyle; + ctx.beginPath(); + ctx.fillRect(0,0,this.width,this.height); + ctx.fill(); + } + + if ( null!==this.strokeStyle ) { + ctx.strokeStyle= this.strokeStyle; + ctx.beginPath(); + ctx.strokeRect(0,0,this.width,this.height); + ctx.stroke(); + } + } + }; + + extend( CAAT.ShapeActor, CAAT.ActorContainer, null); +})(); + +(function() { + + /** + * This actor draws stars. + * + * @constructor + * @extends CAAT.ActorContainer + */ + CAAT.StarActor= function() { + CAAT.StarActor.superclass.constructor.call(this); + this.compositeOp= 'source-over'; + return this; + }; + + CAAT.StarActor.prototype= { + nPeaks: 0, + maxRadius: 0, + minRadius: 0, + initialAngle: 0, + compositeOp: null, + lineWidth: 1, + lineCap: null, + lineJoin: null, + miterLimit: null, + + /** + * + * @param l {number>0} + */ + setLineWidth : function(l) { + this.lineWidth= l; + return this; + }, + /** + * + * @param lc {string{butt|round|square}} + */ + setLineCap : function(lc) { + this.lineCap= lc; + return this; + }, + /** + * + * @param lj {string{bevel|round|miter}} + */ + setLineJoin : function(lj) { + this.lineJoin= lj; + return this; + }, + /** + * + * @param ml {integer>0} + */ + setMiterLimit : function(ml) { + this.miterLimit= ml; + return this; + }, + getLineCap : function() { + return this.lineCap; + }, + getLineJoin : function() { + return this.lineJoin; + }, + getMiterLimit : function() { + return this.miterLimit; + }, + getLineWidth : function() { + return this.lineWidth; + }, + /** + * Sets whether the star will be color filled. + * @param filled {boolean} + * @deprecated + */ + setFilled : function( filled ) { + return this; + }, + /** + * Sets whether the star will be outlined. + * @param outlined {boolean} + * @deprecated + */ + setOutlined : function( outlined ) { + return this; + }, + /** + * Sets the composite operation to apply on shape drawing. + * @param compositeOp an string with a valid canvas rendering context string describing compositeOps. + * @return this + */ + setCompositeOp : function(compositeOp){ + this.compositeOp= compositeOp; + return this; + }, + /** + * + * @param angle {number} number in radians. + */ + setInitialAngle : function(angle) { + this.initialAngle= angle; + return this; + }, + /** + * Initialize the star values. + *

    + * The star actor will be of size 2*maxRadius. + * + * @param nPeaks {number} number of star points. + * @param maxRadius {number} maximum star radius + * @param minRadius {number} minimum star radius + * + * @return this + */ + initialize : function(nPeaks, maxRadius, minRadius) { + this.setSize( 2*maxRadius, 2*maxRadius ); + + this.nPeaks= nPeaks; + this.maxRadius= maxRadius; + this.minRadius= minRadius; + + return this; + }, + /** + * Paint the star. + * + * @param director {CAAT.Director} + * @param timer {number} + */ + paint : function(director, timer) { + + var ctx= director.ctx; + var centerX= this.width/2; + var centerY= this.height/2; + var r1= this.maxRadius; + var r2= this.minRadius; + var ix= centerX + r1*Math.cos(this.initialAngle); + var iy= centerY + r1*Math.sin(this.initialAngle); + + ctx.lineWidth= this.lineWidth; + if ( this.lineCap ) { + ctx.lineCap= this.lineCap; + } + if ( this.lineJoin ) { + ctx.lineJoin= this.lineJoin; + } + if ( this.miterLimit ) { + ctx.miterLimit= this.miterLimit; + } + + ctx.globalCompositeOperation= this.compositeOp; + + ctx.beginPath(); + ctx.moveTo(ix,iy); + + for( var i=1; ithis.changeTime ) { + this.imageProcessor.apply( director, time ); + this.lastApplicationTime= time; + } + + var ctx= director.ctx; + this.imageProcessor.paint( director, time ); + } + }; + + extend( CAAT.IMActor, CAAT.ActorContainer, null); +})(); +/** + * See LICENSE file. + * + * Sound implementation. + */ + +(function() { + + /** + * This class is a sound manager implementation which can play at least 'numChannels' sounds at the same time. + * By default, CAAT.Director instances will set eight channels to play sound. + *

    + * If more than 'numChannels' sounds want to be played at the same time the requests will be dropped, + * so no more than 'numChannels' sounds can be concurrently played. + *

    + * Available sounds to be played must be supplied to every CAAT.Director instance by calling addSound + * method. The default implementation will accept a URL/URI or a HTMLAudioElement as source. + *

    + * The cached elements can be played, or looped. The loop method will return a handler to + * give the opportunity of cancelling the sound. + *

    + * Be aware of Audio.canPlay, is able to return 'yes', 'no', 'maybe', ..., so anything different from + * '' and 'no' will do. + * + * @constructor + * + */ + CAAT.AudioManager= function() { + this.browserInfo= new CAAT.BrowserDetect(); + return this; + }; + + CAAT.AudioManager.prototype= { + + browserInfo: null, + musicEnabled: true, + fxEnabled: true, + audioCache: null, // audio elements. + channels: null, // available playing channels. + workingChannels: null, // currently playing channels. + loopingChannels: [], + audioTypes: { // supported audio formats. Don't remember where i took them from :S + 'mp3': 'audio/mpeg;', + 'ogg': 'audio/ogg; codecs="vorbis"', + 'wav': 'audio/wav; codecs="1"', + 'mp4': 'audio/mp4; codecs="mp4a.40.2"' + }, + + /** + * Initializes the sound subsystem by creating a fixed number of Audio channels. + * Every channel registers a handler for sound playing finalization. If a callback is set, the + * callback function will be called with the associated sound id in the cache. + * + * @param numChannels {number} number of channels to pre-create. 8 by default. + * + * @return this. + */ + initialize : function(numChannels) { + + this.audioCache= []; + this.channels= []; + this.workingChannels= []; + + for( var i=0; i + * The audio element can be one of the two forms: + * + *

      + *
    1. Either an HTMLAudioElement/Audio object or a string url. + *
    2. An array of elements of the previous form. + *
    + * + *

    + * When the audio attribute is an array, this function will iterate throught the array elements + * until a suitable audio element to be played is found. When this is the case, the other array + * elements won't be taken into account. The valid form of using this addAudio method will be: + * + *

    + * 1.
    + * addAudio( id, url } ). In this case, if the resource pointed by url is + * not suitable to be played (i.e. a call to the Audio element's canPlayType method return 'no') + * no resource will be added under such id, so no sound will be played when invoking the play(id) + * method. + *

    + * 2.
    + * addAudio( id, dom_audio_tag ). In this case, the same logic than previous case is applied, but + * this time, the parameter url is expected to be an audio tag present in the html file. + *

    + * 3.
    + * addAudio( id, [array_of_url_or_domaudiotag] ). In this case, the function tries to locate a valid + * resource to be played in any of the elements contained in the array. The array element's can + * be any type of case 1 and 2. As soon as a valid resource is found, it will be associated to the + * id in the valid audio resources to be played list. + * + * @return this + */ + addAudio : function( id, array_of_url_or_domnodes, endplaying_callback ) { + + if ( array_of_url_or_domnodes instanceof Array ) { + /* + iterate throught array elements until we can safely add an audio element. + */ + for( var i=0; i0 ) { + var channel= this.channels.shift(); + channel.src= audio.src; + channel.load(); + channel.volume= audio.volume; + channel.play(); + this.workingChannels.push(channel); + } + + return this; + }, + /** + * This method creates a new AudioChannel to loop the sound with. + * It returns an Audio object so that the developer can cancel the sound loop at will. + * The user must call pause() method to stop playing a loop. + *

    + * Firefox does not honor the loop property, so looping is performed by attending end playing + * event on audio elements. + * + * @return {HTMLElement} an Audio instance if a valid sound id is supplied. Null otherwise + */ + loop : function( id ) { + + if (!this.musicEnabled) { + return this; + } + + var audio_in_cache= this.getAudio(id); + // existe el audio, y ademas hay un canal de audio disponible. + if ( null!==audio_in_cache ) { + var audio= document.createElement('audio'); + if ( null!==audio ) { + audio.src= audio_in_cache.src; + audio.preload = "auto"; + + if ( this.browserInfo.browser==='Firefox') { + audio.addEventListener( + 'ended', + // on sound end, set channel to available channels list. + function(audioEvent) { + var target= audioEvent.target; + target.currentTime=0; + }, + false + ); + } else { + audio.loop= true; + } + audio.load(); + audio.play(); + this.loopingChannels.push(audio); + return audio; + } + } + + return null; + }, + /** + * Cancel all playing audio channels + * Get back the playing channels to available channel list. + * + * @return this + */ + endSound : function() { + var i; + for( i=0; i + *

  • CAAT.Dock.prototype.OP_LAYOUT_BOTTOM + *
  • CAAT.Dock.prototype.OP_LAYOUT_TOP + *
  • CAAT.Dock.prototype.OP_LAYOUT_BOTTOM + *
  • CAAT.Dock.prototype.OP_LAYOUT_RIGHT + * + * By default, the layou operation is OP_LAYOUT_BOTTOM, that is, elements zoom bottom anchored. + * + * @param lo {number} one of CAAT.Dock.OP_LAYOUT_BOTTOM, CAAT.Dock.OP_LAYOUT_TOP, + * CAAT.Dock.OP_LAYOUT_BOTTOM, CAAT.Dock.OP_LAYOUT_RIGHT. + * + * @return this + */ + setLayoutOp : function( lo ) { + this.layoutOp= lo; + return this; + }, + /** + * + * Set maximum and minimum size of docked elements. By default, every contained actor will be + * of 'min' size, and will be scaled up to 'max' size. + * + * @param min {number} + * @param max {number} + * @return this + */ + setSizes : function( min, max ) { + this.minSize= min; + this.maxSize= max; + + for( var i=0; isetLayoutOp. + * + * @private + */ + layout : function() { + var i,actor; + + if ( this.layoutOp===this.OP_LAYOUT_BOTTOM || this.layoutOp===this.OP_LAYOUT_TOP ) { + + var currentWidth=0, currentX=0; + + for( i=0; i index + this.range) { + wwidth = this.minSize; + } else if (i === index) { + wwidth = this.maxSize; + } else if (i < index) { + wwidth= + this.minSize + + (this.maxSize-this.minSize) * + (Math.cos((i - index - across + 1) / this.range * Math.PI) + 1) / + 2; + } else { + wwidth= + this.minSize + + (this.maxSize-this.minSize)* + (Math.cos( (i - index - across) / this.range * Math.PI) + 1) / + 2; + } + + actor.height= wwidth; + actor.width= wwidth; + } + + this.layout(); + }, + /** + * Perform the process of exiting the docking element, that is, animate elements to the minimum + * size. + * + * @param mouseEvent {CAAT.MouseEvent} a CAAT.MouseEvent object. + * + * @private + */ + actorMouseExit : function(mouseEvent) { + if ( null!==this.ttask ) { + this.ttask.cancel(); + } + + var me= this; + this.ttask= this.scene.createTimer( + this.scene.time, + 100, + function timeout(sceneTime, time, timerTask) { + me.actorNotPointed(); + }, + null, + null); + }, + /** + * Perform the beginning of docking elements. + * @param mouseEvent {CAAT.MouseEvent} a CAAT.MouseEvent object. + * + * @private + */ + actorMouseEnter : function(mouseEvent) { + if ( null!==this.ttask ) { + this.ttask.cancel(); + this.ttask= null; + } + }, + /** + * Adds an actor to Dock. + *

    + * Be aware that actor mouse functions must be set prior to calling this method. The Dock actor + * needs set his own actor input events functions for mouseEnter, mouseExit and mouseMove and + * will then chain to the original methods set by the developer. + * + * @param actor {CAAT.Actor} a CAAT.Actor instance. + * + * @return this + */ + addChild : function(actor) { + var me= this; + + actor.__Dock_mouseEnter= actor.mouseEnter; + actor.__Dock_mouseExit= actor.mouseExit; + actor.__Dock_mouseMove= actor.mouseMove; + + /** + * @ignore + * @param mouseEvent + */ + actor.mouseEnter= function(mouseEvent) { + me.actorMouseEnter(mouseEvent); + this.__Dock_mouseEnter(mouseEvent); + }; + /** + * @ignore + * @param mouseEvent + */ + actor.mouseExit= function(mouseEvent) { + me.actorMouseExit(mouseEvent); + this.__Dock_mouseExit(mouseEvent); + }; + /** + * @ignore + * @param mouseEvent + */ + actor.mouseMove= function(mouseEvent) { + me.actorPointed( mouseEvent.point.x, mouseEvent.point.y, mouseEvent.source ); + this.__Dock_mouseMove(mouseEvent); + }; + + actor.width= this.minSize; + actor.height= this.minSize; + + return CAAT.Dock.superclass.addChild.call(this,actor); + } + }; + + extend( CAAT.Dock, CAAT.ActorContainer, null); + +})(); +/** + * See LICENSE file. + * + **/ + + +(function() { + /** + * Director is the animator scene graph manager. + *

    + * The director elements is an ActorContainer itself with the main responsibility of managing + * different Scenes. + *

    + * It is responsible for: + *

      + *
    • scene changes. + *
    • route input to the appropriate scene graph actor. + *
    • be the central point for resource caching. + *
    • manage the timeline. + *
    • manage frame rate. + *
    • etc. + *
    + * + *

    + * One document can contain different CAAT.Director instances which will be kept together in CAAT + * function. + * + * @constructor + * @extends CAAT.ActorContainer + */ + CAAT.Director = function() { + CAAT.Director.superclass.constructor.call(this); + + this.browserInfo = new CAAT.BrowserDetect(); + this.audioManager = new CAAT.AudioManager().initialize(8); + this.scenes = []; + + // input related variables initialization + this.mousePoint = new CAAT.Point(0, 0, 0); + this.prevMousePoint = new CAAT.Point(0, 0, 0); + this.screenMousePoint = new CAAT.Point(0, 0, 0); + this.isMouseDown = false; + this.lastSelectedActor = null; + this.dragging = false; + + this.cDirtyRects= []; + this.dirtyRects= []; + for( var i=0; i<64; i++ ) { + this.dirtyRects.push( new CAAT.Rectangle() ); + } + this.dirtyRectsIndex= 0; + + return this; + }; + + + CAAT.Director.CLEAR_DIRTY_RECTS= 1; + CAAT.Director.CLEAR_ALL= true; + CAAT.Director.CLEAR_NONE= false; + + CAAT.Director.prototype = { + + debug: false, // flag indicating debug mode. It will draw affedted screen areas. + + onRenderStart: null, + onRenderEnd: null, + + // input related attributes + mousePoint: null, // mouse coordinate related to canvas 0,0 coord. + prevMousePoint: null, // previous mouse position cache. Needed for drag events. + screenMousePoint: null, // screen mouse coordinates. + isMouseDown: false, // is the left mouse button pressed ? + lastSelectedActor: null, // director's last actor receiving input. + dragging: false, // is in drag mode ? + + // other attributes + + scenes: null, // Scenes collection. An array. + currentScene: null, // The current Scene. This and only this will receive events. + canvas: null, // The canvas the Director draws on. + crc: null, // @deprecated. canvas rendering context + ctx: null, // refactoring crc for a more convenient name + time: 0, // virtual actor time. + timeline: 0, // global director timeline. + imagesCache: null, // An array of JSON elements of the form { id:string, image:Image } + audioManager: null, + clear: true, // clear background before drawing scenes ?? + + transitionScene: null, + + browserInfo: null, + + gl: null, + glEnabled: false, + glTextureManager: null, + glTtextureProgram: null, + glColorProgram: null, + + pMatrix: null, // projection matrix + coords: null, // Float32Array + coordsIndex: 0, + uv: null, + uvIndex: 0, + + front_to_back: false, + + statistics: { + size_total: 0, + size_active: 0, + size_dirtyRects: 0, + draws: 0 + }, + currentTexturePage: 0, + currentOpacity: 1, + + intervalId: null, + + frameCounter: 0, + + RESIZE_NONE: 1, + RESIZE_WIDTH: 2, + RESIZE_HEIGHT: 4, + RESIZE_BOTH: 8, + RESIZE_PROPORTIONAL:16, + resize: 1, + onResizeCallback : null, + + __gestureScale : 0, + __gestureRotation : 0, + + dirtyRects : null, + cDirtyRects : null, + dirtyRectsIndex : 0, + dirtyRectsEnabled : false, + nDirtyRects : 0, + + checkDebug : function() { + if ( CAAT.DEBUG ) { + var dd= new CAAT.Debug().initialize( this.width, 60 ); + this.debugInfo= dd.debugInfo.bind(dd); + } + }, + getRenderType : function() { + return this.glEnabled ? 'WEBGL' : 'CANVAS'; + }, + windowResized : function(w, h) { + switch (this.resize) { + case this.RESIZE_WIDTH: + this.setBounds(0, 0, w, this.height); + break; + case this.RESIZE_HEIGHT: + this.setBounds(0, 0, this.width, h); + break; + case this.RESIZE_BOTH: + this.setBounds(0, 0, w, h); + break; + case this.RESIZE_PROPORTIONAL: + this.setScaleProportional(w,h); + break; + } + + if ( this.glEnabled ) { + this.glReset(); + } + + if ( this.onResizeCallback ) { + this.onResizeCallback( this, w, h ); + } + + }, + setScaleProportional : function(w,h) { + + var factor= Math.min(w/this.referenceWidth, h/this.referenceHeight); + + this.setScaleAnchored( factor, factor, 0, 0 ); + + this.canvas.width = this.referenceWidth*factor; + this.canvas.height = this.referenceHeight*factor; + this.ctx = this.canvas.getContext(this.glEnabled ? 'experimental-webgl' : '2d' ); + this.crc = this.ctx; + + if ( this.glEnabled ) { + this.glReset(); + } + }, + /** + * Enable window resize events and set redimension policy. A callback functio could be supplied + * to be notified on a Director redimension event. This is necessary in the case you set a redim + * policy not equal to RESIZE_PROPORTIONAL. In those redimension modes, director's area and their + * children scenes are resized to fit the new area. But scenes content is not resized, and have + * no option of knowing so uless an onResizeCallback function is supplied. + * + * @param mode {number} RESIZE_BOTH, RESIZE_WIDTH, RESIZE_HEIGHT, RESIZE_NONE. + * @param onResizeCallback {function(director{CAAT.Director}, width{integer}, height{integer})} a callback + * to notify on canvas resize. + */ + enableResizeEvents : function(mode, onResizeCallback) { + if (mode === this.RESIZE_BOTH || mode === this.RESIZE_WIDTH || mode === this.RESIZE_HEIGHT || mode===this.RESIZE_PROPORTIONAL) { + this.referenceWidth= this.width; + this.referenceHeight=this.height; + this.resize = mode; + CAAT.registerResizeListener(this); + this.onResizeCallback= onResizeCallback; + this.windowResized( window.innerWidth, window.innerHeight ); + } else { + CAAT.unregisterResizeListener(this); + this.onResizeCallback= null; + } + }, + /** + * Set this director's bounds as well as its contained scenes. + * @param x {number} ignored, will be 0. + * @param y {number} ignored, will be 0. + * @param w {number} director width. + * @param h {number} director height. + * + * @return this + */ + setBounds : function(x, y, w, h) { + CAAT.Director.superclass.setBounds.call(this, x, y, w, h); + + this.canvas.width = w; + this.canvas.height = h; + this.ctx = this.canvas.getContext(this.glEnabled ? 'experimental-webgl' : '2d'); + this.crc = this.ctx; + + for (var i = 0; i < this.scenes.length; i++) { + this.scenes[i].setBounds(0, 0, w, h); + } + + if ( this.glEnabled ) { + this.glReset(); + } + + return this; + }, + /** + * This method performs Director initialization. Must be called once. + * If the canvas parameter is not set, it will create a Canvas itself, + * and the developer must explicitly add the canvas to the desired DOM position. + * This method will also set the Canvas dimension to the specified values + * by width and height parameters. + * + * @param width {number} a canvas width + * @param height {number} a canvas height + * @param canvas {HTMLCanvasElement=} An optional Canvas object. + * @param proxy {HTMLElement} this object can be an event proxy in case you'd like to layer different elements + * and want events delivered to the correct element. + * + * @return this + */ + initialize : function(width, height, canvas, proxy) { + if ( !canvas ) { + canvas= document.createElement('canvas'); + document.body.appendChild(canvas); + } + this.canvas = canvas; + + if ( typeof proxy==='undefined' ) { + proxy= canvas; + } + + this.setBounds(0, 0, width, height); + this.create(); + this.enableEvents(proxy); + + this.timeline = new Date().getTime(); + + // transition scene + this.transitionScene = new CAAT.Scene().create().setBounds(0, 0, width, height); + var transitionCanvas = document.createElement('canvas'); + transitionCanvas.width = width; + transitionCanvas.height = height; + var transitionImageActor = new CAAT.Actor().create().setBackgroundImage(transitionCanvas); + this.transitionScene.ctx = transitionCanvas.getContext('2d'); + this.transitionScene.addChildImmediately(transitionImageActor); + this.transitionScene.setEaseListener(this); + + this.checkDebug(); + + return this; + }, + glReset : function() { + this.pMatrix= makeOrtho( 0, this.referenceWidth, this.referenceHeight, 0, -1, 1 ); + this.gl.viewport(0,0,this.canvas.width,this.canvas.height); + this.glColorProgram.setMatrixUniform(this.pMatrix); + this.glTextureProgram.setMatrixUniform(this.pMatrix); + this.gl.viewportWidth = this.canvas.width; + this.gl.viewportHeight = this.canvas.height; + }, + /** + * Experimental. + * Initialize a gl enabled director. + * @param width + * @param height + * @param canvas + */ + initializeGL : function(width, height, canvas, proxy) { + + if ( !canvas ) { + canvas= document.createElement('canvas'); + document.body.appendChild(canvas); + } + + canvas.width = width; + canvas.height = height; + + if ( typeof proxy==='undefined' ) { + proxy= canvas; + } + + this.referenceWidth= width; + this.referenceHeight=height; + + var i; + + try { + this.gl = canvas.getContext("experimental-webgl"/*, {antialias: false}*/); + this.gl.viewportWidth = width; + this.gl.viewportHeight = height; + CAAT.GLRENDER= true; + } catch(e) { + } + + if (this.gl) { + this.canvas = canvas; + this.create(); + this.setBounds(0, 0, width, height); + + this.crc = this.ctx; + this.enableEvents(canvas); + this.timeline = new Date().getTime(); + + this.glColorProgram = new CAAT.ColorProgram(this.gl).create().initialize(); + this.glTextureProgram = new CAAT.TextureProgram(this.gl).create().initialize(); + this.glTextureProgram.useProgram(); + this.glReset(); + + + var maxTris = 512; + this.coords = new Float32Array(maxTris * 12); + this.uv = new Float32Array(maxTris * 8); + + this.gl.clearColor(0.0, 0.0, 0.0, 255); + + if (this.front_to_back) { + this.gl.clearDepth(1.0); + this.gl.enable(this.gl.DEPTH_TEST); + this.gl.depthFunc(this.gl.LESS); + } else { + this.gl.disable(this.gl.DEPTH_TEST); + } + + this.gl.enable(this.gl.BLEND); +// Fix FF this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA); + this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA); + this.glEnabled = true; + + this.checkDebug(); + } else { + // fallback to non gl enabled canvas. + return this.initialize(width, height, canvas); + } + + return this; + }, + /** + * Creates an initializes a Scene object. + * @return {CAAT.Scene} + */ + createScene : function() { + var scene = new CAAT.Scene().create(); + this.addScene(scene); + return scene; + }, + setImagesCache : function(imagesCache, tpW, tpH) { + + var i; + + if (null !== this.glTextureManager) { + this.glTextureManager.deletePages(); + this.glTextureManager = null; + } + + // delete previous image identifiers + if ( this.imagesCache ) { + var ids= []; + for ( i = 0; i < this.imagesCache.length; i++) { + ids.push( this.imagesCache[i].id ); + } + + for( i=0; idirector.addImage(id,image,false) many times and a final call with + * director.addImage(id,image,true) to finally command the director to create texture pages. + * + * @param id {string|object} an identitifier to retrieve the image with + * @param image {Image|HTMLCanvasElement} image to add to cache + * @param noUpdateGL {!boolean} unless otherwise stated, the director will + * try to recreate the texture pages. + */ + addImage : function( id, image, noUpdateGL ) { + if ( this.getImage(id) ) { + for (var i = 0; i < this.imagesCache.length; i++) { + if (this.imagesCache[i].id === id) { + this.imagesCache[i].image = image; + break; + } + } + this.imagesCache[ id ] = image; + } else { + this.imagesCache.push( { id: id, image: image } ); + this.imagesCache[id]= image; + } + + if ( !!!noUpdateGL ) { + this.updateGLPages( ); + } + }, + deleteImage : function( id, noUpdateGL ) { + for (var i = 0; i < this.imagesCache.length; i++) { + if (this.imagesCache[i].id === id) { + delete this.imagesCache[id]; + this.imagesCache.splice(i,1); + break; + } + } + if ( !!!noUpdateGL ) { + this.updateGLPages(); + } + }, + setGLCurrentOpacity : function(opacity) { + this.currentOpacity = opacity; + this.glTextureProgram.setAlpha(opacity); + }, + /** + * Render buffered elements. + * @param vertex + * @param coordsIndex + * @param uv + */ + glRender : function(vertex, coordsIndex, uv) { + + vertex = vertex || this.coords; + uv = uv || this.uv; + coordsIndex = coordsIndex || this.coordsIndex; + + var gl = this.gl; + + var numTris = coordsIndex / 12 * 2; + var numVertices = coordsIndex / 3; + + this.glTextureProgram.updateVertexBuffer(vertex); + this.glTextureProgram.updateUVBuffer(uv); + + gl.drawElements(gl.TRIANGLES, 3 * numTris, gl.UNSIGNED_SHORT, 0); + + }, + glFlush : function() { + if (this.coordsIndex !== 0) { + this.glRender(this.coords, this.coordsIndex, this.uv); + } + this.coordsIndex = 0; + this.uvIndex = 0; + + this.statistics.draws++; + }, + + findActorAtPosition : function(point) { + + // z-order + var cl= this.childrenList; + for( var i=cl.length-1; i>=0; i-- ) { + var child= this.childrenList[i]; + + var np= new CAAT.Point( point.x, point.y, 0 ); + var contained= child.findActorAtPosition( np ); + if ( null!==contained ) { + return contained; + } + } + + return this; + }, + + /** + * + * Reset statistics information. + * + * @private + */ + resetStats : function() { + this.statistics.size_total= 0; + this.statistics.size_active=0; + this.statistics.draws= 0; + }, + + /** + * This is the entry point for the animation system of the Director. + * The director is fed with the elapsed time value to maintain a virtual timeline. + * This virtual timeline will provide each Scene with its own virtual timeline, and will only + * feed time when the Scene is the current Scene, or is being switched. + * + * If dirty rectangles are enabled and canvas is used for rendering, the dirty rectangles will be + * set up as a single clip area. + * + * @param time {number} integer indicating the elapsed time between two consecutive frames of the + * Director. + */ + render : function(time) { + + this.time += time; + + this.animate(this,time); + + if ( CAAT.DEBUG ) { + this.resetStats(); + } + + /** + * draw director active scenes. + */ + var ne = this.childrenList.length; + var i, tt, c; + var ctx= this.ctx; + + if (this.glEnabled) { + + this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); + this.coordsIndex = 0; + this.uvIndex = 0; + + for (i = 0; i < ne; i++) { + c = this.childrenList[i]; + if (c.isInAnimationFrame(this.time)) { + tt = c.time - c.start_time; + if ( c.onRenderStart ) { + c.onRenderStart(tt); + } + c.paintActorGL(this, tt); + if ( c.onRenderEnd ) { + c.onRenderEnd(tt); + } + + if ( !c.isPaused() ) { + c.time += time; + } + + if ( CAAT.DEBUG ) { + this.statistics.size_total+= c.size_total; + this.statistics.size_active+= c.size_active; + } + + } + } + + this.glFlush(); + + } else { + ctx.globalAlpha = 1; + ctx.globalCompositeOperation = 'source-over'; + + ctx.save(); + if ( this.dirtyRectsEnabled ) { + this.modelViewMatrix.transformRenderingContext( ctx ); + + if ( !CAAT.DEBUG_DIRTYRECTS ) { + ctx.beginPath(); + this.nDirtyRects=0; + var dr= this.cDirtyRects; + for( i=0; i0 && CAAT.DEBUG && CAAT.DEBUG_DIRTYRECTS ) { + ctx.beginPath(); + this.nDirtyRects=0; + var dr= this.cDirtyRects; + for( i=0; i=this.dirtyRects.length ) { + for( i=0; i<32; i++ ) { + this.dirtyRects.push( new CAAT.Rectangle() ); + } + } + + var r= this.dirtyRects[ this.dirtyRectsIndex ]; + + r.x= rectangle.x; + r.y= rectangle.y; + r.x1= rectangle.x1; + r.y1= rectangle.y1; + r.width= rectangle.width; + r.height= rectangle.height; + + this.cDirtyRects.push( r ); + + }, + /** + * This method draws an Scene to an offscreen canvas. This offscreen canvas is also a child of + * another Scene (transitionScene). So instead of drawing two scenes while transitioning from + * one to another, first of all an scene is drawn to offscreen, and that image is translated. + *

    + * Until the creation of this method, both scenes where drawn while transitioning with + * its performance penalty since drawing two scenes could be twice as expensive than drawing + * only one. + *

    + * Though a high performance increase, we should keep an eye on memory consumption. + * + * @param ctx a canvas.getContext('2d') instnce. + * @param scene {CAAT.Scene} the scene to draw offscreen. + */ + renderToContext : function(ctx, scene) { + /** + * draw actors on scene. + */ + if (scene.isInAnimationFrame(this.time)) { + ctx.globalAlpha = 1; + ctx.globalCompositeOperation = 'source-over'; + ctx.clearRect(0, 0, this.width, this.height); + ctx.setTransform(1,0,0, 0,1,0); + + var octx = this.ctx; + var ocrc = this.crc; + + this.ctx = this.crc = ctx; + ctx.save(); + + /** + * to draw an scene to an offscreen canvas, we have to: + * 1.- save diector's world model view matrix + * 2.- set no transformation on director since we want the offscreen to + * be drawn 1:1. + * 3.- set world dirty flag, so that the scene will recalculate its matrices + * 4.- animate the scene + * 5.- paint the scene + * 6.- restore world model view matrix. + */ + var matwmv= this.worldModelViewMatrix; + this.worldModelViewMatrix= new CAAT.Matrix(); + this.wdirty= true; + scene.animate(this, scene.time); + if ( scene.onRenderStart ) { + scene.onRenderStart(scene.time); + } + scene.paintActor(this, scene.time); + if ( scene.onRenderEnd ) { + scene.onRenderEnd(scene.time); + } + this.worldModelViewMatrix = matwmv; + + ctx.restore(); + + this.ctx = octx; + this.crc = ocrc; + } + }, + /** + * Add a new Scene to Director's Scene list. By adding a Scene to the Director + * does not mean it will be immediately visible, you should explicitly call either + *

      + *
    • easeIn + *
    • easeInOut + *
    • easeInOutRandom + *
    • setScene + *
    • or any of the scene switching methods + *
    + * + * @param scene {CAAT.Scene} an CAAT.Scene object. + */ + addScene : function(scene) { + scene.setBounds(0, 0, this.width, this.height); + this.scenes.push(scene); + scene.setEaseListener(this); + if (null === this.currentScene) { + this.setScene(0); + } + }, + /** + * Get the number of scenes contained in the Director. + * @return {number} the number of scenes contained in the Director. + */ + getNumScenes : function() { + return this.scenes.length; + }, + /** + * This method offers full control over the process of switching between any given two Scenes. + * To apply this method, you must specify the type of transition to apply for each Scene and + * the anchor to keep the Scene pinned at. + *

    + * The type of transition will be one of the following values defined in CAAT.Scene.prototype: + *

      + *
    • EASE_ROTATION + *
    • EASE_SCALE + *
    • EASE_TRANSLATION + *
    + * + *

    + * The anchor will be any of these values defined in CAAT.Actor.prototype: + *

      + *
    • ANCHOR_CENTER + *
    • ANCHOR_TOP + *
    • ANCHOR_BOTTOM + *
    • ANCHOR_LEFT + *
    • ANCHOR_RIGHT + *
    • ANCHOR_TOP_LEFT + *
    • ANCHOR_TOP_RIGHT + *
    • ANCHOR_BOTTOM_LEFT + *
    • ANCHOR_BOTTOM_RIGHT + *
    + * + *

    + * In example, for an entering scene performing a EASE_SCALE transition, the anchor is the + * point by which the scene will scaled. + * + * @param inSceneIndex integer indicating the Scene index to bring in to the Director. + * @param typein integer indicating the type of transition to apply to the bringing in Scene. + * @param anchorin integer indicating the anchor of the bringing in Scene. + * @param outSceneIndex integer indicating the Scene index to take away from the Director. + * @param typeout integer indicating the type of transition to apply to the taking away in Scene. + * @param anchorout integer indicating the anchor of the taking away Scene. + * @param time inteter indicating the time to perform the process of switchihg between Scene object + * in milliseconds. + * @param alpha boolean boolean indicating whether alpha transparency fading will be applied to + * the scenes. + * @param interpolatorIn CAAT.Interpolator object to apply to entering scene. + * @param interpolatorOut CAAT.Interpolator object to apply to exiting scene. + */ + easeInOut : function(inSceneIndex, typein, anchorin, outSceneIndex, typeout, anchorout, time, alpha, interpolatorIn, interpolatorOut) { + + if (inSceneIndex === this.getCurrentSceneIndex()) { + return; + } + + var ssin = this.scenes[ inSceneIndex ]; + var sout = this.scenes[ outSceneIndex ]; + + if (!this.glEnabled && !navigator.browser==='iOS') { + this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx); + this.renderToContext(this.transitionScene.ctx, sout); + sout = this.transitionScene; + } + + ssin.setExpired(false); + sout.setExpired(false); + + ssin.mouseEnabled = false; + sout.mouseEnabled = false; + + ssin.resetTransform(); + sout.resetTransform(); + + ssin.setLocation(0, 0); + sout.setLocation(0, 0); + + ssin.alpha = 1; + sout.alpha = 1; + + if (typein === CAAT.Scene.prototype.EASE_ROTATION) { + ssin.easeRotationIn(time, alpha, anchorin, interpolatorIn); + } else if (typein === CAAT.Scene.prototype.EASE_SCALE) { + ssin.easeScaleIn(0, time, alpha, anchorin, interpolatorIn); + } else { + ssin.easeTranslationIn(time, alpha, anchorin, interpolatorIn); + } + + if (typeout === CAAT.Scene.prototype.EASE_ROTATION) { + sout.easeRotationOut(time, alpha, anchorout, interpolatorOut); + } else if (typeout === CAAT.Scene.prototype.EASE_SCALE) { + sout.easeScaleOut(0, time, alpha, anchorout, interpolatorOut); + } else { + sout.easeTranslationOut(time, alpha, anchorout, interpolatorOut); + } + + this.childrenList = []; + + this.addChild(sout); + this.addChild(ssin); + }, + /** + * This method will switch between two given Scene indexes (ie, take away scene number 2, + * and bring in scene number 5). + *

    + * It will randomly choose for each Scene the type of transition to apply and the anchor + * point of each transition type. + *

    + * It will also set for different kind of transitions the following interpolators: + *

      + *
    • EASE_ROTATION -> ExponentialInOutInterpolator, exponent 4. + *
    • EASE_SCALE -> ElasticOutInterpolator, 1.1 and .4 + *
    • EASE_TRANSLATION -> BounceOutInterpolator + *
    + * + *

    + * These are the default values, and could not be changed by now. + * This method in final instance delegates the process to easeInOutMethod. + * + * @see easeInOutMethod. + * + * @param inIndex integer indicating the entering scene index. + * @param outIndex integer indicating the exiting scene index. + * @param time integer indicating the time to take for the process of Scene in/out in milliseconds. + * @param alpha boolean indicating whether alpha transparency fading should be applied to transitions. + */ + easeInOutRandom : function(inIndex, outIndex, time, alpha) { + + var pin = Math.random(); + var pout = Math.random(); + + var typeIn; + var interpolatorIn; + + if (pin < 0.33) { + typeIn = CAAT.Scene.prototype.EASE_ROTATION; + interpolatorIn = new CAAT.Interpolator().createExponentialInOutInterpolator(4); + } else if (pin < 0.66) { + typeIn = CAAT.Scene.prototype.EASE_SCALE; + interpolatorIn = new CAAT.Interpolator().createElasticOutInterpolator(1.1, 0.4); + } else { + typeIn = CAAT.Scene.prototype.EASE_TRANSLATE; + interpolatorIn = new CAAT.Interpolator().createBounceOutInterpolator(); + } + + var typeOut; + var interpolatorOut; + + if (pout < 0.33) { + typeOut = CAAT.Scene.prototype.EASE_ROTATION; + interpolatorOut = new CAAT.Interpolator().createExponentialInOutInterpolator(4); + } else if (pout < 0.66) { + typeOut = CAAT.Scene.prototype.EASE_SCALE; + interpolatorOut = new CAAT.Interpolator().createExponentialOutInterpolator(4); + } else { + typeOut = CAAT.Scene.prototype.EASE_TRANSLATE; + interpolatorOut = new CAAT.Interpolator().createBounceOutInterpolator(); + } + + this.easeInOut( + inIndex, + typeIn, + (Math.random() * 8.99) >> 0, + + outIndex, + typeOut, + (Math.random() * 8.99) >> 0, + + time, + alpha, + + interpolatorIn, + interpolatorOut); + + }, + /** + * This method changes Director's current Scene to the scene index indicated by + * inSceneIndex parameter. The Scene running in the director won't be eased out. + * + * @see {CAAT.Interpolator} + * @see {CAAT.Actor} + * @see {CAAT.Scene} + * + * @param inSceneIndex integer indicating the new Scene to set as current. + * @param type integer indicating the type of transition to apply to bring the new current + * Scene to the Director. The values will be one of: CAAT.Scene.prototype.EASE_ROTATION, + * CAAT.Scene.prototype.EASE_SCALE, CAAT.Scene.prototype.EASE_TRANSLATION. + * @param time integer indicating how much time in milliseconds the Scene entrance will take. + * @param alpha boolean indicating whether alpha transparency fading will be applied to the + * entereing Scene. + * @param anchor integer indicating the anchor to fix for Scene transition. It will be any of + * CAAT.Actor.prototype.ANCHOR_* values. + * @param interpolator an CAAT.Interpolator object indicating the interpolation function to + * apply. + */ + easeIn : function(inSceneIndex, type, time, alpha, anchor, interpolator) { + var sin = this.scenes[ inSceneIndex ]; + if (type === CAAT.Scene.prototype.EASE_ROTATION) { + sin.easeRotationIn(time, alpha, anchor, interpolator); + } else if (type === CAAT.Scene.prototype.EASE_SCALE) { + sin.easeScaleIn(0, time, alpha, anchor, interpolator); + } else { + sin.easeTranslationIn(time, alpha, anchor, interpolator); + } + this.childrenList = []; + this.addChild(sin); + + sin.resetTransform(); + sin.setLocation(0, 0); + sin.alpha = 1; + sin.mouseEnabled = false; + sin.setExpired(false); + }, + /** + * Changes (or sets) the current Director scene to the index + * parameter. There will be no transition on scene change. + * @param sceneIndex {number} an integer indicating the index of the target Scene + * to be shown. + */ + setScene : function(sceneIndex) { + var sin = this.scenes[ sceneIndex ]; + this.childrenList = []; + this.addChild(sin); + this.currentScene = sin; + + sin.setExpired(false); + sin.mouseEnabled = true; + sin.resetTransform(); + sin.setLocation(0, 0); + sin.alpha = 1; + + sin.activated(); + }, + /** + * This method will change the current Scene by the Scene indicated as parameter. + * It will apply random values for anchor and transition type. + * @see easeInOutRandom + * + * @param iNewSceneIndex {number} an integer indicating the index of the new scene to run on the Director. + * @param time {number} an integer indicating the time the Scene transition will take. + * @param alpha {boolean} a boolean indicating whether Scene transition should be fading. + * @param transition {boolean} a boolean indicating whether the scene change must smoothly animated. + */ + switchToScene : function(iNewSceneIndex, time, alpha, transition) { + var currentSceneIndex = this.getSceneIndex(this.currentScene); + + if (!transition) { + this.setScene(iNewSceneIndex); + } + else { + this.easeInOutRandom(iNewSceneIndex, currentSceneIndex, time, alpha); + } + }, + /** + * Sets the previous Scene in sequence as the current Scene. + * @see switchToScene. + * + * @param time {number} integer indicating the time the Scene transition will take. + * @param alpha {boolean} a boolean indicating whether Scene transition should be fading. + * @param transition {boolean} a boolean indicating whether the scene change must smoothly animated. + */ + switchToPrevScene : function(time, alpha, transition) { + + var currentSceneIndex = this.getSceneIndex(this.currentScene); + + if (this.getNumScenes() <= 1 || currentSceneIndex === 0) { + return; + } + + if (!transition) { + this.setScene(currentSceneIndex - 1); + } + else { + this.easeInOutRandom(currentSceneIndex - 1, currentSceneIndex, time, alpha); + } + }, + /** + * Sets the previous Scene in sequence as the current Scene. + * @see switchToScene. + * + * @param time {number} integer indicating the time the Scene transition will take. + * @param alpha {boolean} a boolean indicating whether Scene transition should be fading. + * @param transition {boolean} a boolean indicating whether the scene change must smoothly animated. + */ + switchToNextScene: function(time, alpha, transition) { + + var currentSceneIndex = this.getSceneIndex(this.currentScene); + + if (this.getNumScenes() <= 1 || currentSceneIndex === this.getNumScenes() - 1) { + return; + } + + if (!transition) { + this.setScene(currentSceneIndex + 1); + } + else { + this.easeInOutRandom(currentSceneIndex + 1, currentSceneIndex, time, alpha); + } + }, + mouseEnter : function(mouseEvent) { + }, + mouseExit : function(mouseEvent) { + }, + mouseMove : function(mouseEvent) { + }, + mouseDown : function(mouseEvent) { + }, + mouseUp : function(mouseEvent) { + }, + mouseDrag : function(mouseEvent) { + }, + /** + * Scene easing listener. Notifies scenes when they're about to be activated (set as current + * director's scene). + * + * @param scene {CAAT.Scene} the scene that has just been brought in or taken out of the director. + * @param b_easeIn {boolean} scene enters or exits ? + */ + easeEnd : function(scene, b_easeIn) { + // scene is going out + if (!b_easeIn) { + + scene.setExpired(true); + } else { + this.currentScene = scene; + this.currentScene.activated(); + } + + scene.mouseEnabled = true; + scene.emptyBehaviorList(); + }, + /** + * Return the index for a given Scene object contained in the Director. + * @param scene {CAAT.Scene} + */ + getSceneIndex : function(scene) { + for (var i = 0; i < this.scenes.length; i++) { + if (this.scenes[i] === scene) { + return i; + } + } + return -1; + }, + /** + * Get a concrete director's scene. + * @param index {number} an integer indicating the scene index. + * @return {CAAT.Scene} a CAAT.Scene object instance or null if the index is oob. + */ + getScene : function(index) { + return this.scenes[index]; + }, + /** + * Return the index of the current scene in the Director's scene list. + * @return {number} the current scene's index. + */ + getCurrentSceneIndex : function() { + return this.getSceneIndex(this.currentScene); + }, + /** + * Return the running browser name. + * @return {string} the browser name. + */ + getBrowserName : function() { + return this.browserInfo.browser; + }, + /** + * Return the running browser version. + * @return {string} the browser version. + */ + getBrowserVersion : function() { + return this.browserInfo.version; + }, + /** + * Return the operating system name. + * @return {string} the os name. + */ + getOSName : function() { + return this.browserInfo.OS; + }, + /** + * Gets the resource with the specified resource name. + * The Director holds a collection called imagesCache + * where you can store a JSON of the form + * [ { id: imageId, image: imageObject } ]. + * This structure will be used as a resources cache. + * There's a CAAT.ImagePreloader class to preload resources and + * generate this structure on loading finalization. + * + * @param sId {object} an String identifying a resource. + */ + getImage : function(sId) { + var ret = this.imagesCache[sId]; + if (ret) { + return ret; + } + + for (var i = 0; i < this.imagesCache.length; i++) { + if (this.imagesCache[i].id === sId) { + return this.imagesCache[i].image; + } + } + + return null; + }, + /** + * Adds an audio to the cache. + * + * @see CAAT.AudioManager.addAudio + * @return this + */ + addAudio : function(id, url) { + this.audioManager.addAudio(id, url); + return this; + }, + /** + * Plays the audio instance identified by the id. + * @param id {object} the object used to store a sound in the audioCache. + */ + audioPlay : function(id) { + this.audioManager.play(id); + }, + /** + * Loops an audio instance identified by the id. + * @param id {object} the object used to store a sound in the audioCache. + * + * @return {HTMLElement|null} the value from audioManager.loop + */ + audioLoop : function(id) { + return this.audioManager.loop(id); + }, + endSound : function() { + return this.audioManager.endSound(); + }, + setSoundEffectsEnabled : function(enabled) { + return this.audioManager.setSoundEffectsEnabled(enabled); + }, + setMusicEnabled : function(enabled) { + return this.audioManager.setMusicEnabled(enabled); + }, + isMusicEnabled : function() { + return this.audioManager.isMusicEnabled(); + }, + isSoundEffectsEnabled : function() { + return this.audioManager.isSoundEffectsEnabled(); + }, + setVolume : function( id, volume ) { + return this.audioManager.setVolume( id, volume ); + }, + /** + * Removes Director's scenes. + */ + emptyScenes : function() { + this.scenes = []; + }, + /** + * Adds an scene to this Director. + * @param scene {CAAT.Scene} a scene object. + */ + addChild : function(scene) { + scene.parent = this; + this.childrenList.push(scene); + }, + /** + * @Deprecated use CAAT.loop instead. + * @param fps + * @param callback + * @param callback2 + */ + loop : function(fps,callback,callback2) { + if ( callback2 ) { + this.onRenderStart= callback; + this.onRenderEnd= callback2; + } else if (callback) { + this.onRenderEnd= callback; + } + CAAT.loop(); + }, + /** + * Starts the director animation.If no scene is explicitly selected, the current Scene will + * be the first scene added to the Director. + *

    + * The fps parameter will set the animation quality. Higher values, + * means CAAT will try to render more frames in the same second (at the + * expense of cpu power at least until hardware accelerated canvas rendering + * context are available). A value of 60 is a high frame rate and should not be exceeded. + * + * @param fps {number} integer value indicating the target frames per second to run + * the animation at. + */ + renderFrame : function(fps, callback) { + var t = new Date().getTime(), + delta = t - this.timeline; + + /* + check for massive frame time. if for example the current browser tab is minified or taken out of + foreground, the system will account for a bit time interval. minify that impact by lowering down + the elapsed time (virtual timelines FTW) + */ + if ( delta > 500 ) { + delta= 500; + } + + if ( this.onRenderStart ) { + this.onRenderStart(delta); + } + + this.render(delta); + + if ( this.debugInfo ) { + this.debugInfo(this.statistics); + } + + this.timeline = t; + + if (this.onRenderEnd) { + this.onRenderEnd(delta); + } + }, + endLoop : function () { + }, + /** + * This method states whether the director must clear background before rendering + * each frame. + * + * The clearing method could be: + * + CAAT.Director.CLEAR_ALL. previous to draw anything on screen the canvas will have clearRect called on it. + * + CAAT.Director.CLEAR_DIRTY_RECTS. Actors marked as invalid, or which have been moved, rotated or scaled + * will have their areas redrawn. + * + CAAT.Director.CLEAR_NONE. clears nothing. + * + * @param clear {CAAT.Director.CLEAR_ALL |ÊCAAT.Director.CLEAR_NONE | CAAT.Director.CLEAR_DIRTY_RECTS} + * @return this. + */ + setClear : function(clear) { + this.clear = clear; + if ( this.clear===CAAT.Director.CLEAR_DIRTY_RECTS ) { + this.dirtyRectsEnabled= true; + } + return this; + }, + /** + * Get this Director's AudioManager instance. + * @return {CAAT.AudioManager} the AudioManager instance. + */ + getAudioManager : function() { + return this.audioManager; + }, + /** + * Acculumate dom elements position to properly offset on-screen mouse/touch events. + * @param node + */ + cumulateOffset : function(node, parent, prop) { + var left= prop+'Left'; + var top= prop+'Top'; + var x=0, y=0, style; + + while( navigator.browser!=='iOS' && node && node.style ) { + if ( node.currentStyle ) { + style= node.currentStyle['position']; + } else { + style= (node.ownerDocument.defaultView || node.ownerDocument.parentWindow).getComputedStyle(node, null); + style= style ? style.getPropertyValue('position') : null; + } + +// if (!/^(relative|absolute|fixed)$/.test(style)) { + if (!/^(fixed)$/.test(style)) { + x += node[left]; + y+= node[top]; + node = node[parent]; + } else { + break; + } + } + + return { + x: x, + y: y, + style: style + }; + }, + getOffset : function( node ) { + var res= this.cumulateOffset(node, 'offsetParent', 'offset'); + if ( res.style==='fixed' ) { + var res2= this.cumulateOffset(node, node.parentNode ? 'parentNode' : 'parentElement', 'scroll'); + return { + x: res.x + res2.x, + y: res.y + res2.y + }; + } + + return { + x: res.x, + y: res.y + }; + }, + /** + * Normalize input event coordinates to be related to (0,0) canvas position. + * @param point {CAAT.Point} a CAAT.Point instance to hold the canvas coordinate. + * @param e {MouseEvent} a mouse event from an input event. + */ + getCanvasCoord : function(point, e) { + + var posx = 0; + var posy = 0; + if (!e) e = window.event; + + if (e.pageX || e.pageY) { + posx = e.pageX; + posy = e.pageY; + } + else if (e.clientX || e.clientY) { + posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + + var offset= this.getOffset(e.target); + + posx-= offset.x; + posy-= offset.y; + + ////////////// + // transformar coordenada inversamente con affine transform de director. + + var pt= new CAAT.Point( posx, posy ); + if ( !this.modelViewMatrixI ) { + this.modelViewMatrixI= this.modelViewMatrix.getInverse(); + } + this.modelViewMatrixI.transformCoord(pt); + posx= pt.x; + posy= pt.y + + point.set(posx, posy); + this.screenMousePoint.set(posx, posy); + + }, + + __mouseDownHandler : function(e) { + + /* + was dragging and mousedown detected, can only mean a mouseOut's been performed and on mouseOver, no + button was presses. Then, send a mouseUp for the previos actor, and return; + */ + if ( this.dragging && this.lastSelectedActor ) { + this.__mouseUpHandler(e); + return; + } + + this.getCanvasCoord(this.mousePoint, e); + this.isMouseDown = true; + var lactor = this.findActorAtPosition(this.mousePoint); + + if (null !== lactor) { + + var pos = lactor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); + + lactor.mouseDown( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + new CAAT.Point( + this.screenMousePoint.x, + this.screenMousePoint.y ))); + } + + this.lastSelectedActor= lactor; + }, + + __mouseUpHandler : function(e) { + + this.isMouseDown = false; + this.getCanvasCoord(this.mousePoint, e); + + var pos= null; + var lactor= this.lastSelectedActor; + + if (null !== lactor) { + pos = lactor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); + if ( lactor.actionPerformed && lactor.contains(pos.x, pos.y) ) { + lactor.actionPerformed(e) + } + + lactor.mouseUp( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + this.currentScene.time)); + } + + if (!this.dragging && null !== lactor) { + if (lactor.contains(pos.x, pos.y)) { + lactor.mouseClick( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + this.currentScene.time)); + } + } + + this.dragging = false; + this.in_= false; +// CAAT.setCursor('default'); + }, + + __mouseMoveHandler : function(e) { + this.getCanvasCoord(this.mousePoint, e); + + var lactor; + var pos; + + var ct= this.currentScene ? this.currentScene.time : 0; + + // drag + + if (this.isMouseDown && null !== this.lastSelectedActor) { +/* + // check for mouse move threshold. + if (!this.dragging) { + if (Math.abs(this.prevMousePoint.x - this.mousePoint.x) < CAAT.DRAG_THRESHOLD_X && + Math.abs(this.prevMousePoint.y - this.mousePoint.y) < CAAT.DRAG_THRESHOLD_Y) { + return; + } + } +*/ + + + lactor = this.lastSelectedActor; + pos = lactor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); + + this.dragging = true; + + var px= lactor.x; + var py= lactor.y; + lactor.mouseDrag( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + new CAAT.Point( + this.screenMousePoint.x, + this.screenMousePoint.y), + ct)); + + this.prevMousePoint.x= pos.x; + this.prevMousePoint.y= pos.y; + + /** + * Element has not moved after drag, so treat it as a button. + */ + if ( px===lactor.x && py===lactor.y ) { + + var contains= lactor.contains(pos.x, pos.y); + + if (this.in_ && !contains) { + lactor.mouseExit( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + ct)); + this.in_ = false; + } + + if (!this.in_ && contains ) { + lactor.mouseEnter( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + ct)); + this.in_ = true; + } + } + + return; + } + + // mouse move. + this.in_= true; + + lactor = this.findActorAtPosition(this.mousePoint); + + // cambiamos de actor. + if (lactor !== this.lastSelectedActor) { + if (null !== this.lastSelectedActor) { + + pos = this.lastSelectedActor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); + + this.lastSelectedActor.mouseExit( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + this.lastSelectedActor, + this.screenMousePoint, + ct)); + } + + if (null !== lactor) { + pos = lactor.viewToModel( + new CAAT.Point( this.screenMousePoint.x, this.screenMousePoint.y, 0)); + + lactor.mouseEnter( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + ct)); + } + } + + pos = lactor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); + + if (null !== lactor) { + + lactor.mouseMove( + new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + ct)); + } + + this.lastSelectedActor = lactor; + }, + + __mouseOutHandler : function(e) { + + if (null !== this.lastSelectedActor ) { + + this.getCanvasCoord(this.mousePoint, e); + var pos = new CAAT.Point(this.mousePoint.x, this.mousePoint.y, 0); + this.lastSelectedActor.viewToModel(pos); + + var ev= new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + this.lastSelectedActor, + this.screenMousePoint, + this.currentScene.time); + + this.lastSelectedActor.mouseExit(ev); + this.lastSelectedActor.mouseOut(ev); + + if ( !this.dragging ) { + this.lastSelectedActor = null; + } + } else { + this.isMouseDown = false; + this.in_ = false; + } + + }, + + __mouseOverHandler : function(e) { + + var lactor; + var pos, ev; + this.getCanvasCoord(this.mousePoint, e); + + if ( null==this.lastSelectedActor ) { + lactor= this.findActorAtPosition( this.mousePoint ); + + if (null !== lactor) { + + pos = lactor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); + + ev= new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + this.currentScane ? this.currentScene.time : 0); + + lactor.mouseOver(ev); + lactor.mouseEnter(ev); + } + + this.lastSelectedActor= lactor; + } else { + lactor= this.lastSelectedActor; + pos = lactor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); + + ev= new CAAT.MouseEvent().init( + pos.x, + pos.y, + e, + lactor, + this.screenMousePoint, + this.currentScene.time); + + lactor.mouseOver(ev); + lactor.mouseEnter(ev); + + } + }, + + __mouseDBLClickHandler : function(e) { + + this.getCanvasCoord(this.mousePoint, e); + if (null !== this.lastSelectedActor) { +/* + var pos = this.lastSelectedActor.viewToModel( + new CAAT.Point(this.screenMousePoint.x, this.screenMousePoint.y, 0)); +*/ + this.lastSelectedActor.mouseDblClick( + new CAAT.MouseEvent().init( + this.mousePoint.x, + this.mousePoint.y, + e, + this.lastSelectedActor, + this.screenMousePoint, + this.currentScene.time)); + } + }, + + /** + * Same as mouseDown but not preventing event. + * Will only take care of first touch. + * @param e + */ + __touchStartHandler : function(e) { + + e.preventDefault(); + e= e.targetTouches[0] + this.__mouseDownHandler(e); + }, + + __touchEndHandler : function(e) { + + e.preventDefault(); + e= e.changedTouches[0]; + this.__mouseUpHandler(e); + }, + + __touchMoveHandler : function(e) { + + e.preventDefault(); + + if ( this.gesturing ) { + return; + } + + for( var i=0; i + * var si= new CAAT.SpriteImage(). + * initialize( an_image_instance, rows, columns ). + * setAnimationImageIndex( [2,1,0,1] ). // cycle throwout image with these indexes + * setChangeFPS( 200 ). // change sprite every 200 ms. + * setSpriteTransformation( CAAT.SpriteImage.TR_xx); // optionally draw images inverted, ... + * + * + * A SpriteImage is an sprite sheet. It encapsulates an Image and treates and references it as a two + * dimensional array of row by columns sub-images. The access form will be sequential so if defined a + * CompoundImage of more than one row, the subimages will be referenced by an index ranging from 0 to + * rows*columns-1. Each sumimage will be of size (image.width/columns) by (image.height/rows). + * + *

    + * It is able to draw its sub-images in the following ways: + *

      + *
    • no transformed (default) + *
    • flipped horizontally + *
    • flipped vertically + *
    • flipped both vertical and horizontally + *
    + * + *

    + * It is supposed to be used in conjunction with CAAT.SpriteActor instances. + * + * @constructor + * + */ + CAAT.SpriteImage = function() { + this.paint= this.paintN; + this.setAnimationImageIndex([0]); + this.mapInfo= {}; + return this; + }; + + CAAT.SpriteImage.prototype = { + + animationImageIndex: null, // an Array defining the sprite frame sequence + prevAnimationTime: -1, + changeFPS: 1000, // how much Scene time to take before changing an Sprite frame. + transformation: 0, // any of the TR_* constants. + spriteIndex: 0, // the current sprite frame + + TR_NONE: 0, // constants used to determine how to draw the sprite image, + TR_FLIP_HORIZONTAL: 1, + TR_FLIP_VERTICAL: 2, + TR_FLIP_ALL: 3, + TR_FIXED_TO_SIZE: 4, + TR_TILE: 5, + + image: null, + rows: 1, + columns: 1, + width: 0, + height: 0, + singleWidth: 0, + singleHeight: 0, + + scaleX: 1, + scaleY: 1, + + offsetX: 0, + offsetY: 0, + + ownerActor: null, + + mapInfo : null, + map : null, + + setOwner : function(actor) { + this.ownerActor= actor; + return this; + }, + getRows: function() { + return this.rows; + }, + getColumns : function() { + return this.columns; + }, + + getWidth : function() { + var el= this.mapInfo[this.spriteIndex]; + return el.width; + }, + + getHeight : function() { + var el= this.mapInfo[this.spriteIndex]; + return el.height; + }, + + /** + * Get a reference to the same image information (rows, columns, image and uv cache) of this + * SpriteImage. This means that re-initializing this objects image info (that is, calling initialize + * method) will change all reference's image information at the same time. + */ + getRef : function() { + var ret= new CAAT.SpriteImage(); + ret.image= this.image; + ret.rows= this.rows; + ret.columns= this.columns; + ret.width= this.width; + ret.height= this.height; + ret.singleWidth= this.singleWidth; + ret.singleHeight= this.singleHeight; + ret.mapInfo= this.mapInfo; + ret.offsetX= this.offsetX; + ret.offsetY= this.offsetY; + ret.scaleX= this.scaleX; + ret.scaleY= this.scaleY; + return ret; + }, + /** + * Set horizontal displacement to draw image. Positive values means drawing the image more to the + * right. + * @param x {number} + * @return this + */ + setOffsetX : function(x) { + this.offsetX= x; + return this; + }, + /** + * Set vertical displacement to draw image. Positive values means drawing the image more to the + * bottom. + * @param y {number} + * @return this + */ + setOffsetY : function(y) { + this.offsetY= y; + return this; + }, + setOffset : function( x,y ) { + this.offsetX= x; + this.offsetY= y; + return this; + }, + /** + * Initialize a grid of subimages out of a given image. + * @param image {HTMLImageElement|Image} an image object. + * @param rows {number} number of rows. + * @param columns {number} number of columns + * + * @return this + */ + initialize : function(image, rows, columns) { + this.image = image; + this.rows = rows; + this.columns = columns; + this.width = image.width; + this.height = image.height; + this.singleWidth = Math.floor(this.width / columns); + this.singleHeight = Math.floor(this.height / rows); + this.mapInfo= {}; + + var i,sx0,sy0; + var helper; + + if (image.__texturePage) { + image.__du = this.singleWidth / image.__texturePage.width; + image.__dv = this.singleHeight / image.__texturePage.height; + + + var w = this.singleWidth; + var h = this.singleHeight; + var mod = this.columns; + if (image.inverted) { + var t = w; + w = h; + h = t; + mod = this.rows; + } + + var xt = this.image.__tx; + var yt = this.image.__ty; + + var tp = this.image.__texturePage; + + for (i = 0; i < rows * columns; i++) { + + + var c = ((i % mod) >> 0); + var r = ((i / mod) >> 0); + + var u = xt + c * w; // esquina izq x + var v = yt + r * h; + + var u1 = u + w; + var v1 = v + h; + + helper= new CAAT.SpriteImageHelper(u,v,(u1-u),(v1-v),tp.width,tp.height).setGL( + u / tp.width, + v / tp.height, + u1 / tp.width, + v1 / tp.height ); + + this.mapInfo[i]= helper; + } + + } else { + for (i = 0; i < rows * columns; i++) { + sx0 = ((i % this.columns) | 0) * this.singleWidth; + sy0 = ((i / this.columns) | 0) * this.singleHeight; + + helper= new CAAT.SpriteImageHelper( sx0, sy0, this.singleWidth, this.singleHeight, image.width, image.height ); + this.mapInfo[i]= helper; + } + } + + return this; + }, + + /** + * Must be used to draw actor background and the actor should have setClip(true) so that the image tiles + * properly. + * @param director + * @param time + * @param x + * @param y + */ + paintTiled : function( director, time, x, y ) { + this.setSpriteIndexAtTime(time); + var el= this.mapInfo[this.spriteIndex]; + + var r= new CAAT.Rectangle(); + this.ownerActor.AABB.intersect( director.AABB, r ); + + var w= this.getWidth(); + var h= this.getHeight(); + var xoff= (this.offsetX-this.ownerActor.x) % w; + if ( xoff> 0 ) { + xoff= xoff-w; + } + var yoff= (this.offsetY-this.ownerActor.y) % h; + if ( yoff> 0 ) { + yoff= yoff-h; + } + + var nw= (((r.width-xoff)/w)>>0)+1; + var nh= (((r.height-yoff)/h)>>0)+1; + var i,j; + var ctx= director.ctx; + + for( i=0; i>0, (r.y-this.ownerActor.y+yoff+i*el.height)>>0, + el.width, el.height); + } + } + }, + + /** + * Draws the subimage pointed by imageIndex horizontally inverted. + * @param canvas a canvas context. + * @param imageIndex {number} a subimage index. + * @param x {number} x position in canvas to draw the image. + * @param y {number} y position in canvas to draw the image. + * + * @return this + */ + paintInvertedH : function(director, time, x, y) { + + this.setSpriteIndexAtTime(time); + + var el= this.mapInfo[this.spriteIndex]; + + var ctx= director.ctx; + ctx.save(); + //ctx.translate(((0.5 + x) | 0) + el.width, (0.5 + y) | 0); + ctx.translate( (x|0) + el.width, y|0 ); + ctx.scale(-1, 1); + + + ctx.drawImage( + this.image, + el.x, el.y, + el.width, el.height, + this.offsetX>>0, this.offsetY>>0, + el.width, el.height ); + + ctx.restore(); + + return this; + }, + /** + * Draws the subimage pointed by imageIndex vertically inverted. + * @param canvas a canvas context. + * @param imageIndex {number} a subimage index. + * @param x {number} x position in canvas to draw the image. + * @param y {number} y position in canvas to draw the image. + * + * @return this + */ + paintInvertedV : function(director, time, x, y) { + + this.setSpriteIndexAtTime(time); + var el= this.mapInfo[this.spriteIndex]; + + var ctx= director.ctx; + ctx.save(); + //ctx.translate((x + 0.5) | 0, (0.5 + y + el.height) | 0); + ctx.translate( x|0, (y + el.height) | 0); + ctx.scale(1, -1); + + ctx.drawImage( + this.image, + el.x, el.y, + el.width, el.height, + this.offsetX>>0,this.offsetY>>0, + el.width, el.height); + + ctx.restore(); + + return this; + }, + /** + * Draws the subimage pointed by imageIndex both horizontal and vertically inverted. + * @param canvas a canvas context. + * @param imageIndex {number} a subimage index. + * @param x {number} x position in canvas to draw the image. + * @param y {number} y position in canvas to draw the image. + * + * @return this + */ + paintInvertedHV : function(director, time, x, y) { + + this.setSpriteIndexAtTime(time); + var el= this.mapInfo[this.spriteIndex]; + + var ctx= director.ctx; + ctx.save(); + //ctx.translate((x + 0.5) | 0, (0.5 + y + el.height) | 0); + ctx.translate( x | 0, (y + el.height) | 0); + ctx.scale(1, -1); + ctx.translate(el.width, 0); + ctx.scale(-1, 1); + + ctx.drawImage( + this.image, + el.x, el.y, + el.width, el.height, + this.offsetX>>0, this.offsetY>>0, + el.width, el.height); + + ctx.restore(); + + return this; + }, + /** + * Draws the subimage pointed by imageIndex. + * @param canvas a canvas context. + * @param imageIndex {number} a subimage index. + * @param x {number} x position in canvas to draw the image. + * @param y {number} y position in canvas to draw the image. + * + * @return this + */ + paintN : function(director, time, x, y) { + this.setSpriteIndexAtTime(time); + var el= this.mapInfo[this.spriteIndex]; + + director.ctx.drawImage( + this.image, + el.x, el.y, + el.width, el.height, + (this.offsetX+x)>>0, (this.offsetY+y)>>0, + el.width, el.height); + + return this; + }, + /** + * Draws the subimage pointed by imageIndex scaled to the size of w and h. + * @param canvas a canvas context. + * @param imageIndex {number} a subimage index. + * @param x {number} x position in canvas to draw the image. + * @param y {number} y position in canvas to draw the image. + * @param w {number} new width of the subimage. + * @param h {number} new height of the subimage. + * + * @return this + */ + paintScaled : function(director, time, x, y) { + this.setSpriteIndexAtTime(time); + var el= this.mapInfo[this.spriteIndex]; + + director.ctx.drawImage( + this.image, + el.x, el.y, + el.width, el.height, + (this.offsetX+x)>>0, (this.offsetY+y)>>0, + this.ownerActor.width, this.ownerActor.height ); + + return this; + }, + getCurrentSpriteImageCSSPosition : function() { + var el= this.mapInfo[this.spriteIndex]; + + return '-'+(el.x-this.offsetX)+'px '+ + '-'+(el.y-this.offsetY)+'px '+ + (this.transformation===this.TR_TILE ? '' : 'no-repeat'); + }, + /** + * Get the number of subimages in this compoundImage + * @return {number} + */ + getNumImages : function() { + return this.rows * this.columns; + }, + /** + * TODO: set mapping coordinates for different transformations. + * @param imageIndex + * @param uvBuffer + * @param uvIndex + */ + setUV : function(uvBuffer, uvIndex) { + var im = this.image; + + if (!im.__texturePage) { + return; + } + + var index = uvIndex; + var sIndex= this.spriteIndex; + var el= this.mapInfo[this.spriteIndex]; + + var u= el.u; + var v= el.v; + var u1= el.u1; + var v1= el.v1; + if ( this.offsetX || this.offsetY ) { + var w= this.ownerActor.width; + var h= this.ownerActor.height; + + var tp= im.__texturePage; + + var _u= -this.offsetX / tp.width; + var _v= -this.offsetY / tp.height; + var _u1=(w-this.offsetX) / tp.width; + var _v1=(h-this.offsetY) / tp.height; + + u= _u + im.__u; + v= _v + im.__v; + u1= _u1 + im.__u; + v1= _v1 + im.__v; + } + + if (im.inverted) { + uvBuffer[index++] = u1; + uvBuffer[index++] = v; + + uvBuffer[index++] = u1; + uvBuffer[index++] = v1; + + uvBuffer[index++] = u; + uvBuffer[index++] = v1; + + uvBuffer[index++] = u; + uvBuffer[index++] = v; + } else { + uvBuffer[index++] = u; + uvBuffer[index++] = v; + + uvBuffer[index++] = u1; + uvBuffer[index++] = v; + + uvBuffer[index++] = u1; + uvBuffer[index++] = v1; + + uvBuffer[index++] = u; + uvBuffer[index++] = v1; + } + }, + /** + * Set the elapsed time needed to change the image index. + * @param fps an integer indicating the time in milliseconds to change. + * @return this + */ + setChangeFPS : function(fps) { + this.changeFPS= fps; + return this; + }, + /** + * Set the transformation to apply to the Sprite image. + * Any value of + *

  • TR_NONE + *
  • TR_FLIP_HORIZONTAL + *
  • TR_FLIP_VERTICAL + *
  • TR_FLIP_ALL + * + * @param transformation an integer indicating one of the previous values. + * @return this + */ + setSpriteTransformation : function( transformation ) { + this.transformation= transformation; + switch(transformation) { + case this.TR_FLIP_HORIZONTAL: + this.paint= this.paintInvertedH; + break; + case this.TR_FLIP_VERTICAL: + this.paint= this.paintInvertedV; + break; + case this.TR_FLIP_ALL: + this.paint= this.paintInvertedHV; + break; + case this.TR_FIXED_TO_SIZE: + this.paint= this.paintScaled; + break; + case this.TR_TILE: + this.paint= this.paintTiled; + break; + default: + this.paint= this.paintN; + } + return this; + }, + + /** + * Set the sprite animation images index. This method accepts an array of objects which define indexes to + * subimages inside this sprite image. + * If the SpriteImage is instantiated by calling the method initialize( image, rows, cols ), the value of + * aAnimationImageIndex should be an array of numbers, which define the indexes into an array of subimages + * with size rows*columns. + * If the method InitializeFromMap( image, map ) is called, the value for aAnimationImageIndex is expected + * to be an array of strings which are the names of the subobjects contained in the map object. + * + * @param aAnimationImageIndex an array indicating the Sprite's frames. + */ + setAnimationImageIndex : function( aAnimationImageIndex ) { + this.animationImageIndex= aAnimationImageIndex; + this.spriteIndex= aAnimationImageIndex[0]; + + return this; + }, + setSpriteIndex : function(index) { + this.spriteIndex= index; + return this; + }, + + /** + * Draws the sprite image calculated and stored in spriteIndex. + * + * @param director the CAAT.Director object instance that contains the Scene the Actor is in. + * @param time an integer indicating the Scene time when the bounding box is to be drawn. + */ + setSpriteIndexAtTime : function(time) { + + if ( this.animationImageIndex.length>1 ) { + if ( this.prevAnimationTime===-1 ) { + this.prevAnimationTime= time; + this.spriteIndex=0; + } + else { + var ttime= time; + ttime-= this.prevAnimationTime; + ttime/= this.changeFPS; + ttime%= this.animationImageIndex.length; + this.spriteIndex= this.animationImageIndex[Math.floor(ttime)]; + } + } + }, + + getMapInfo : function( index ) { + return this.mapInfo[ index ]; + }, + + /** + * This method takes the output generated from the tool at http://labs.hyperandroid.com/static/texture/spriter.html + * and creates a map into that image. + * @param image {Image|HTMLImageElement|Canvas} an image + * @param map {object} the map into the image to define subimages. + */ + initializeFromMap : function( image, map ) { + this.initialize( image, 1, 1 ); + + var key; + var helper; + var count=0; + + for( key in map ) { + var value= map[key]; + + helper= new CAAT.SpriteImageHelper( + value.x, + value.y, + value.width, + value.height, + image.width, + image.height + ); + + this.mapInfo[key]= helper; + + // set a default spriteIndex + if ( !count ) { + this.setAnimationImageIndex( [key] ); + } + + count++; + } + + return this; + }, + + /** + * + * @param image {Image|HTMLImageElement|Canvas} + * @param map object with pairs "" : { + * id : {number}, + * height : {number}, + * xoffset : {number}, + * letter : {string}, + * yoffset : {number}, + * width : {number}, + * xadvance: {number}, + * y : {number}, + * x : {number} + * } + */ + initializeAsGlyphDesigner : function( image, map ) { + this.initialize( image, 1, 1 ); + + var key; + var helper; + var count=0; + + for( key in map ) { + var value= map[key]; + + helper= new CAAT.SpriteImageHelper( + value.x, + value.y, + value.width, + value.height, + image.width, + image.height + ); + + helper.xoffset= typeof value.xoffset==='undefined' ? 0 : value.xoffset; + helper.yoffset= typeof value.yoffset==='undefined' ? 0 : value.yoffset; + helper.xadvance= typeof value.xadvance==='undefined' ? value.width : value.xadvance; + + this.mapInfo[key]= helper; + + // set a default spriteIndex + if ( !count ) { + this.setAnimationImageIndex( [key] ); + } + + count++; + } + + return this; + + }, + + /** + * + * @param image + * @param map: Array<{c: "a", width: 40}> + */ + initializeAsFontMap : function( image, chars ) { + this.initialize( image, 1, 1 ); + + var helper; + var x=0; + + for( var i=0;i> 0; + + for( var i=0;iy ) { + y=h; + } + } + + this.fontHeight= y; + return this.fontHeight; + }, + + drawString : function( ctx, str, x, y ) { + var i, l, charInfo, w; + var charArr = str.split(""); + + for( i=0; i + * A TimerTask is defined at least by: + *
      + *
    • startTime: since when the timer will be active + *
    • duration: from startTime to startTime+duration, the timerTask will be notifying (if set) the callback callback_tick. + *
    + *

    + * Upon TimerTask expiration, the TimerTask will notify (if set) the callback function callback_timeout. + * Upon a call to the method cancel, the timer will be set expired, and (if set) the callback to callback_cancel will be + * invoked. + *

    + * Timer notifications will be performed BEFORE scene loop. + * + * @constructor + * + */ + CAAT.TimerTask= function() { + return this; + }; + + CAAT.TimerTask.prototype= { + startTime: 0, + duration: 0, + callback_timeout: null, + callback_tick: null, + callback_cancel: null, + + scene: null, + taskId: 0, + remove: false, + + /** + * Create a TimerTask. + * The taskId will be set by the scene. + * @param startTime {number} an integer indicating TimerTask enable time. + * @param duration {number} an integer indicating TimerTask duration. + * @param callback_timeout {function( sceneTime {number}, timertaskTime{number}, timertask {CAAT.TimerTask} )} on timeout callback function. + * @param callback_tick {function( sceneTime {number}, timertaskTime{number}, timertask {CAAT.TimerTask} )} on tick callback function. + * @param callback_cancel {function( sceneTime {number}, timertaskTime{number}, timertask {CAAT.TimerTask} )} on cancel callback function. + * + * @return this + */ + create: function( startTime, duration, callback_timeout, callback_tick, callback_cancel ) { + this.startTime= startTime; + this.duration= duration; + this.callback_timeout= callback_timeout; + this.callback_tick= callback_tick; + this.callback_cancel= callback_cancel; + return this; + }, + /** + * Performs TimerTask operation. The task will check whether it is in frame time, and will + * either notify callback_timeout or callback_tick. + * + * @param time {number} an integer indicating scene time. + * @return this + * + * @protected + * + */ + checkTask : function(time) { + var ttime= time; + ttime-= this.startTime; + if ( ttime>=this.duration ) { + this.remove= true; + if( this.callback_timeout ) { + this.callback_timeout( time, ttime, this ); + } + } else { + if ( this.callback_tick ) { + this.callback_tick( time, ttime, this ); + } + } + return this; + }, + /** + * Reschedules this TimerTask by changing its startTime to current scene's time. + * @param time {number} an integer indicating scene time. + * @return this + */ + reset : function( time ) { + this.remove= false; + this.startTime= time; + this.scene.ensureTimerTask(this); + return this; + }, + /** + * Cancels this timer by removing it on scene's next frame. The function callback_cancel will + * be called. + * @return this + */ + cancel : function() { + this.remove= true; + if ( null!=this.callback_cancel ) { + this.callback_cancel( this.scene.time, this.scene.time-this.startTime, this ); + } + return this; + } + }; +})(); +/** +* See LICENSE file. + * + */ + +(function() { + /** + * Scene is the top level ActorContainer of the Director at any given time. + * The only time when 2 scenes could be active will be during scene change. + * An scene controls the way it enters/exits the scene graph. It is also the entry point for all + * input related and timed related events to every actor on screen. + * + * @constructor + * @extends CAAT.ActorContainer + * + */ + CAAT.Scene= function() { + CAAT.Scene.superclass.constructor.call(this); + this.timerList= []; + this.fillStyle= null; + return this; + }; + + CAAT.Scene.prototype= { + + easeContainerBehaviour: null, // Behavior container used uniquely for Scene switching. + easeContainerBehaviourListener: null, // who to notify about container behaviour events. Array. + easeIn: false, // When Scene switching, this boolean identifies whether the + // Scene is being brought in, or taken away. + + EASE_ROTATION: 1, // Constant values to identify the type of Scene transition + EASE_SCALE: 2, // to perform on Scene switching by the Director. + EASE_TRANSLATE: 3, + + timerList: null, // collection of CAAT.TimerTask objects. + timerSequence: 0, // incremental CAAT.TimerTask id. + + paused: false, + name: 'CAAT.Scene', + + isPaused : function() { + return this.paused; + }, + + setPaused : function( paused ) { + this.paused= paused; + }, + /** + * Check and apply timers in frame time. + * @param time {number} the current Scene time. + */ + checkTimers : function(time) { + var tl= this.timerList; + var i=tl.length-1; + while( i>=0 ) { + if ( !tl[i].remove ) { + tl[i].checkTask(time); + } + i--; + } + }, + /** + * Make sure the timertask is contained in the timer task list by adding it to the list in case it + * is not contained. + * @param timertask {CAAT.TimerTask} a CAAT.TimerTask object. + * @return this + */ + ensureTimerTask : function( timertask ) { + if ( !this.hasTimer(timertask) ) { + this.timerList.push(timertask); + } + return this; + }, + /** + * Check whether the timertask is in this scene's timer task list. + * @param timertask {CAAT.TimerTask} a CAAT.TimerTask object. + * @return {boolean} a boolean indicating whether the timertask is in this scene or not. + */ + hasTimer : function( timertask ) { + var tl= this.timerList; + var i=tl.length-1; + while( i>=0 ) { + if ( tl[i]===timertask ) { + return true; + } + i--; + } + + return false; + }, + /** + * Creates a timer task. Timertask object live and are related to scene's time, so when an Scene + * is taken out of the Director the timer task is paused, and resumed on Scene restoration. + * + * @param startTime {number} an integer indicating the scene time this task must start executing at. + * @param duration {number} an integer indicating the timerTask duration. + * @param callback_timeout {function} timer on timeout callback function. + * @param callback_tick {function} timer on tick callback function. + * @param callback_cancel {function} timer on cancel callback function. + * + * @return {CAAT.TimerTask} a CAAT.TimerTask class instance. + */ + createTimer : function( startTime, duration, callback_timeout, callback_tick, callback_cancel ) { + + var tt= new CAAT.TimerTask().create( + startTime, + duration, + callback_timeout, + callback_tick, + callback_cancel ); + + tt.taskId= this.timerSequence++; + tt.sceneTime = this.time; + tt.scene= this; + + this.timerList.push( tt ); + + return tt; + }, + /** + * Removes expired timers. This method must not be called directly. + */ + removeExpiredTimers : function() { + var i; + var tl= this.timerList; + for( i=0; iCAAT.Actor.prototype.ANCHOR_LEFT + *

  • CAAT.Actor.prototype.ANCHOR_RIGHT + *
  • CAAT.Actor.prototype.ANCHOR_TOP + *
  • CAAT.Actor.prototype.ANCHOR_BOTTOM + * if any other value is specified, any of the previous ones will be applied. + * + * @param time integer indicating time in milliseconds for the Scene. + * @param alpha boolean indicating whether fading will be applied to the Scene. + * @param anchor integer indicating the Scene switch anchor. + * @param isIn boolean indicating whether the scene will be brought in. + * @param interpolator {CAAT.Interpolator} a CAAT.Interpolator to apply to the Scene transition. + */ + easeTranslation : function( time, alpha, anchor, isIn, interpolator ) { + + this.easeContainerBehaviour= new CAAT.ContainerBehavior(); + this.easeIn= isIn; + + var pb= new CAAT.PathBehavior(); + if ( interpolator ) { + pb.setInterpolator( interpolator ); + } + + pb.setFrameTime( 0, time ); + + // BUGBUG anchors: 1..4 + if ( anchor<1 ) { + anchor=1; + } else if ( anchor>4 ) { + anchor= 4; + } + + + switch(anchor) { + case CAAT.Actor.prototype.ANCHOR_TOP: + if ( isIn ) { + pb.setPath( new CAAT.Path().setLinear( 0, -this.height, 0, 0) ); + } else { + pb.setPath( new CAAT.Path().setLinear( 0, 0, 0, -this.height) ); + } + break; + case CAAT.Actor.prototype.ANCHOR_BOTTOM: + if ( isIn ) { + pb.setPath( new CAAT.Path().setLinear( 0, this.height, 0, 0) ); + } else { + pb.setPath( new CAAT.Path().setLinear( 0, 0, 0, this.height) ); + } + break; + case CAAT.Actor.prototype.ANCHOR_LEFT: + if ( isIn ) { + pb.setPath( new CAAT.Path().setLinear( -this.width, 0, 0, 0) ); + } else { + pb.setPath( new CAAT.Path().setLinear( 0, 0, -this.width, 0) ); + } + break; + case CAAT.Actor.prototype.ANCHOR_RIGHT: + if ( isIn ) { + pb.setPath( new CAAT.Path().setLinear( this.width, 0, 0, 0) ); + } else { + pb.setPath( new CAAT.Path().setLinear( 0, 0, this.width, 0) ); + } + break; + } + + if (alpha) { + this.createAlphaBehaviour(time,isIn); + } + + this.easeContainerBehaviour.addBehavior(pb); + + this.easeContainerBehaviour.setFrameTime( this.time, time ); + this.easeContainerBehaviour.addListener(this); + + this.emptyBehaviorList(); + CAAT.Scene.superclass.addBehavior.call( this, this.easeContainerBehaviour ); + }, + /** + * Called from CAAT.Director to bring in a Scene. + * A helper method for easeScale. + * @param time integer indicating time in milliseconds for the Scene to be brought in. + * @param alpha boolean indicating whether fading will be applied to the Scene. + * @param anchor integer indicating the Scene switch anchor. + * @param interpolator {CAAT.Interpolator} a CAAT.Interpolator to apply to the Scene transition. + * @param starttime integer indicating in milliseconds from which scene time the behavior will be applied. + */ + easeScaleIn : function(starttime,time,alpha,anchor,interpolator) { + this.easeScale(starttime,time,alpha,anchor,true,interpolator); + this.easeIn= true; + }, + /** + * Called from CAAT.Director to take away a Scene. + * A helper method for easeScale. + * @param time integer indicating time in milliseconds for the Scene to be taken away. + * @param alpha boolean indicating whether fading will be applied to the Scene. + * @param anchor integer indicating the Scene switch anchor. + * @param interpolator {CAAT.Interpolator} a CAAT.Interpolator instance to apply to the Scene transition. + * @param starttime integer indicating in milliseconds from which scene time the behavior will be applied. + */ + easeScaleOut : function(starttime,time,alpha,anchor,interpolator) { + this.easeScale(starttime,time,alpha,anchor,false,interpolator); + this.easeIn= false; + }, + /** + * Called from CAAT.Director to bring in ot take away an Scene. + * @param time integer indicating time in milliseconds for the Scene to be taken away. + * @param alpha boolean indicating whether fading will be applied to the Scene. + * @param anchor integer indicating the Scene switch anchor. + * @param interpolator {CAAT.Interpolator} a CAAT.Interpolator to apply to the Scene transition. + * @param starttime integer indicating in milliseconds from which scene time the behavior will be applied. + * @param isIn boolean indicating whether the Scene is being brought in. + */ + easeScale : function(starttime,time,alpha,anchor,isIn,interpolator) { + this.easeContainerBehaviour= new CAAT.ContainerBehavior(); + + var x=0; + var y=0; + var x2=0; + var y2=0; + + switch(anchor) { + case CAAT.Actor.prototype.ANCHOR_TOP_LEFT: + case CAAT.Actor.prototype.ANCHOR_TOP_RIGHT: + case CAAT.Actor.prototype.ANCHOR_BOTTOM_LEFT: + case CAAT.Actor.prototype.ANCHOR_BOTTOM_RIGHT: + case CAAT.Actor.prototype.ANCHOR_CENTER: + x2=1; + y2=1; + break; + case CAAT.Actor.prototype.ANCHOR_TOP: + case CAAT.Actor.prototype.ANCHOR_BOTTOM: + x=1; + x2=1; + y=0; + y2=1; + break; + case CAAT.Actor.prototype.ANCHOR_LEFT: + case CAAT.Actor.prototype.ANCHOR_RIGHT: + y=1; + y2=1; + x=0; + x2=1; + break; + default: + alert('scale anchor ?? '+anchor); + } + + if ( !isIn ) { + var tmp; + tmp= x; + x= x2; + x2= tmp; + + tmp= y; + y= y2; + y2= tmp; + } + + if (alpha) { + this.createAlphaBehaviour(time,isIn); + } + + var anchorPercent= this.getAnchorPercent(anchor); + var sb= new CAAT.ScaleBehavior(). + setFrameTime( starttime, time ). + setValues(x,x2,y,y2, anchorPercent.x, anchorPercent.y); + + if ( interpolator ) { + sb.setInterpolator(interpolator); + } + + this.easeContainerBehaviour.addBehavior(sb); + + this.easeContainerBehaviour.setFrameTime( this.time, time ); + this.easeContainerBehaviour.addListener(this); + + this.emptyBehaviorList(); + CAAT.Scene.superclass.addBehavior.call( this, this.easeContainerBehaviour ); + }, + /** + * Overriden method to disallow default behavior. + * Do not use directly. + */ + addBehavior : function(behaviour) { + return this; + }, + /** + * Called from CAAT.Director to use Rotations for bringing in. + * This method is a Helper for the method easeRotation. + * @param time integer indicating time in milliseconds for the Scene to be brought in. + * @param alpha boolean indicating whether fading will be applied to the Scene. + * @param anchor integer indicating the Scene switch anchor. + * @param interpolator {CAAT.Interpolator} a CAAT.Interpolator to apply to the Scene transition. + */ + easeRotationIn : function(time,alpha,anchor,interpolator) { + this.easeRotation(time,alpha,anchor,true, interpolator); + this.easeIn= true; + }, + /** + * Called from CAAT.Director to use Rotations for taking Scenes away. + * This method is a Helper for the method easeRotation. + * @param time integer indicating time in milliseconds for the Scene to be taken away. + * @param alpha boolean indicating whether fading will be applied to the Scene. + * @param anchor integer indicating the Scene switch anchor. + * @param interpolator {CAAT.Interpolator} a CAAT.Interpolator to apply to the Scene transition. + */ + easeRotationOut : function(time,alpha,anchor,interpolator) { + this.easeRotation(time,alpha,anchor,false,interpolator); + this.easeIn= false; + }, + /** + * Called from CAAT.Director to use Rotations for taking away or bringing Scenes in. + * @param time integer indicating time in milliseconds for the Scene to be taken away or brought in. + * @param alpha boolean indicating whether fading will be applied to the Scene. + * @param anchor integer indicating the Scene switch anchor. + * @param interpolator {CAAT.Interpolator} a CAAT.Interpolator to apply to the Scene transition. + * @param isIn boolean indicating whehter the Scene is brought in. + */ + easeRotation : function(time,alpha,anchor,isIn,interpolator) { + this.easeContainerBehaviour= new CAAT.ContainerBehavior(); + + var start=0; + var end=0; + + if (anchor==CAAT.Actor.prototype.ANCHOR_CENTER ) { + anchor= CAAT.Actor.prototype.ANCHOR_TOP; + } + + switch(anchor) { + case CAAT.Actor.prototype.ANCHOR_TOP: + case CAAT.Actor.prototype.ANCHOR_BOTTOM: + case CAAT.Actor.prototype.ANCHOR_LEFT: + case CAAT.Actor.prototype.ANCHOR_RIGHT: + start= Math.PI * (Math.random()<0.5 ? 1 : -1); + break; + case CAAT.Actor.prototype.ANCHOR_TOP_LEFT: + case CAAT.Actor.prototype.ANCHOR_TOP_RIGHT: + case CAAT.Actor.prototype.ANCHOR_BOTTOM_LEFT: + case CAAT.Actor.prototype.ANCHOR_BOTTOM_RIGHT: + start= Math.PI/2 * (Math.random()<0.5 ? 1 : -1); + break; + default: + alert('rot anchor ?? '+anchor); + } + + if ( false===isIn ) { + var tmp= start; + start=end; + end= tmp; + } + + if ( alpha ) { + this.createAlphaBehaviour(time,isIn); + } + + var anchorPercent= this.getAnchorPercent(anchor); + var rb= new CAAT.RotateBehavior(). + setFrameTime( 0, time ). + setValues( start, end, anchorPercent.x, anchorPercent.y ); + + if ( interpolator ) { + rb.setInterpolator(interpolator); + } + this.easeContainerBehaviour.addBehavior(rb); + this.easeContainerBehaviour.setFrameTime( this.time, time ); + this.easeContainerBehaviour.addListener(this); + + this.emptyBehaviorList(); + CAAT.Scene.superclass.addBehavior.call( this, this.easeContainerBehaviour ); + }, + /** + * Registers a listener for listen for transitions events. + * Al least, the Director registers himself as Scene easing transition listener. + * When the transition is done, it restores the Scene's capability of receiving events. + * @param listener {function(caat_behavior,time,actor)} an object which contains a method of the form + * behaviorExpired( caat_behaviour, time, actor); + */ + setEaseListener : function( listener ) { + this.easeContainerBehaviourListener=listener; + }, + /** + * Private. + * listener for the Scene's easeContainerBehaviour. + * @param actor + */ + behaviorExpired : function(actor) { + this.easeContainerBehaviourListener.easeEnd(this, this.easeIn); + }, + /** + * This method should be overriden in case the developer wants to do some special actions when + * the scene has just been brought in. + */ + activated : function() { + }, + /** + * Scenes, do not expire the same way Actors do. + * It simply will be set expired=true, but the frameTime won't be modified. + */ + setExpired : function(bExpired) { + this.expired= bExpired; + }, + /** + * An scene by default does not paint anything because has not fillStyle set. + * @param director + * @param time + */ + paint : function(director, time) { + + if ( this.fillStyle ) { + var ctx= director.crc; + ctx.fillStyle= this.fillStyle; + ctx.fillRect(0,0,this.width,this.height ); + } + }, + /** + * Find a pointed actor at position point. + * This method tries lo find the correctly pointed actor in two different ways. + * + first of all, if inputList is defined, it will look for an actor in it. + * + if no inputList is defined, it will traverse the scene graph trying to find a pointed actor. + * @param point + */ + findActorAtPosition : function(point) { + var i,j; + + var p= new CAAT.Point(); + + if ( this.inputList ) { + var il= this.inputList; + for( i=0; i number of lists. + */ + enableInputList : function( size ) { + this.inputList= []; + for( var i=0; i an actor instance + * @param index the inputList index to add the actor to. This value will be clamped to the number of + * available lists. + * @param position the position on the selected inputList to add the actor at. This value will be + * clamped to the number of available lists. + */ + addActorToInputList : function( actor, index, position ) { + if ( index<0 ) index=0; else if ( index>=this.inputList.length ) index= this.inputList.length-1; + var il= this.inputList[index]; + + if ( typeof position==="undefined" || position>=il.length ) { + il.push( actor ); + } else if (position<=0) { + il.unshift( actor ); + } else { + il.splice( position, 0, actor ); + } + + return this; + }, + + /** + * Remove all elements from an input list. + * @param index the inputList index to add the actor to. This value will be clamped to the number of + * available lists so take care when emptying a non existant inputList index since you could end up emptying + * an undesired input list. + */ + emptyInputList : function( index ) { + if ( index<0 ) index=0; else if ( index>=this.inputList.length ) index= this.inputList.length-1; + this.inputList[index]= []; + return this; + }, + + /** + * remove an actor from a given input list index. + * If no index is supplied, the actor will be removed from every input list. + * @param actor + * @param index an optional input list index. This value will be clamped to the number of + * available lists. + */ + removeActorFromInputList : function( actor, index ) { + if ( typeof index==="undefined" ) { + var i,j; + for( i=0; i=this.inputList.length ) index= this.inputList.length-1; + var il= this.inputList[index]; + for( j=0; j this.bounds.right) { + aCircle.position.x = this.bounds.left + radius; + } else if(boundsRule & wrapXMask && xpos+diameter < this.bounds.left) { + aCircle.position.x = this.bounds.right - radius; + } + // Wrap Y + if(boundsRule & wrapYMask && ypos-diameter > this.bounds.bottom) { + aCircle.position.y = this.bounds.top - radius; + } else if(boundsRule & wrapYMask && ypos+diameter < this.bounds.top) { + aCircle.position.y = this.bounds.bottom + radius; + } + + // Constrain X + if(boundsRule & constrainXMask && xpos+radius >= this.bounds.right) { + aCircle.position.x = aCircle.position.x = this.bounds.right-radius; + } else if(boundsRule & constrainXMask && xpos-radius < this.bounds.left) { + aCircle.position.x = this.bounds.left + radius; + } + + // Constrain Y + if(boundsRule & constrainYMask && ypos+radius > this.bounds.bottom) { + aCircle.position.y = this.bounds.bottom - radius; + } else if(boundsRule & constrainYMask && ypos-radius < this.bounds.top) { + aCircle.position.y = this.bounds.top + radius; + } + }, + + /** + * Given an x,y position finds circle underneath and sets it to the currently grabbed circle + * @param {Number} xpos An x position + * @param {Number} ypos A y position + * @param {Number} buffer A radiusSquared around the point in question where something is considered to match + */ + getCircleAt: function(xpos, ypos, buffer) + { + var circleList = this.allCircles; + var len = circleList.length; + var grabVector = new CAAT.Point(xpos, ypos, 0); + + // These are set every time a better match i found + var closestCircle = null; + var closestDistance = Number.MAX_VALUE; + + // Loop thru and find the closest match + for(var i = 0; i < len; i++) + { + var aCircle = circleList[i]; + if(!aCircle) continue; + var distanceSquared = aCircle.position.getDistanceSquared(grabVector); + + if(distanceSquared < closestDistance && distanceSquared < aCircle.radiusSquared + buffer) + { + closestDistance = distanceSquared; + closestCircle = aCircle; + } + } + + return closestCircle; + }, + + circlesCanCollide: function(circleA, circleB) + { + if(!circleA || !circleB || circleA===circleB) return false; // one is null (will be deleted next loop), or both point to same obj. +// if(circleA.delegate == null || circleB.delegate == null) return false; // This circle will be removed next loop, it's entity is already removed + +// if(circleA.isFixed & circleB.isFixed) return false; +// if(circleA.delegate .clientID === circleB.delegate.clientID) return false; // Don't let something collide with stuff it owns + + // They dont want to collide +// if((circleA.collisionGroup & circleB.collisionMask) == 0) return false; +// if((circleB.collisionGroup & circleA.collisionMask) == 0) return false; + + return true; + }, +/** + * Accessors + */ + setBounds: function(x, y, w, h) + { + this.bounds.x = x; + this.bounds.y = y; + this.bounds.width = w; + this.bounds.height = h; + }, + + setNumberOfCollisionPasses: function(value) + { + this.numberOfCollisionPasses = value; + return this; + }, + + setNumberOfTargetingPasses: function(value) + { + this.numberOfTargetingPasses = value; + return this; + }, + +/** + * Helpers + */ + sortOnDistanceToTarget: function(circleA, circleB) + { + var valueA = circleA.getDistanceSquaredFromPosition(circleA.targetPosition); + var valueB = circleB.getDistanceSquaredFromPosition(circleA.targetPosition); + var comparisonResult = 0; + + if(valueA > valueB) comparisonResult = -1; + else if(valueA < valueB) comparisonResult = 1; + + return comparisonResult; + }, + +/** + * Memory Management + */ + removeExpiredElements: function() + { + // remove null elements + for (var k = this.allCircles.length; k >= 0; k--) { + if (this.allCircles[k] === null) + this.allCircles.splice(k, 1); + } + }, + + initialize : function(overrides) + { + if (overrides) + { + for (var i in overrides) + { + this[i] = overrides[i]; + } + } + + return this; + } + }; +})();/** + * See LICENSE file. + * + **/ + +(function() { + /** + * Local storage management. + * @constructor + */ + CAAT.modules.LocalStorage= function() { + return this; + }; + + CAAT.modules.LocalStorage.prototype= { + /** + * Stores an object in local storage. The data will be saved as JSON.stringify. + * @param key {string} key to store data under. + * @param data {object} an object. + * @return this + * + * @static + */ + save : function( key, data ) { + try { + localStorage.setItem( key, JSON.stringify(data) ); + } catch(e) { + // eat it + } + return this; + }, + /** + * Retrieve a value from local storage. + * @param key {string} the key to retrieve. + * @return {object} object stored under the key parameter. + * + * @static + */ + load : function( key ) { + try { + return JSON.parse(localStorage.getItem( key )); + } catch(e) { + return null; + } + }, + /** + * Removes a value stored in local storage. + * @param key {string} + * @return this + * + * @static + */ + remove : function( key ) { + try { + localStorage.removeItem(key); + } catch(e) { + // eat it + } + return this; + } + }; + +})(); +/** + * See LICENSE file. + */ + +(function() { + + CAAT.modules.ImageUtil= {}; + + CAAT.modules.ImageUtil.createAlphaSpriteSheet= function(maxAlpha, minAlpha, sheetSize, image, bg_fill_style ) { + + if ( maxAlpha, bottom, left }Ê} + */ + CAAT.modules.ImageUtil.optimize= function(image, threshold, areas ) { + threshold>>=0; + + var atop= true; + var abottom= true; + var aleft= true; + var aright= true; + if ( typeof areas!=='undefined' ) { + if ( typeof areas.top!=='undefined' ) { + atop= areas.top; + } + if ( typeof areas.bottom!=='undefined' ) { + abottom= areas.bottom; + } + if ( typeof areas.left!=='undefined' ) { + aleft= areas.left; + } + if ( typeof areas.right!=='undefined' ) { + aright= areas.right; + } + } + + + var canvas= document.createElement('canvas'); + canvas.width= image.width; + canvas.height=image.height; + var ctx= canvas.getContext('2d'); + + ctx.fillStyle='rgba(0,0,0,0)'; + ctx.fillRect(0,0,image.width,image.height); + ctx.drawImage( image, 0, 0 ); + + var imageData= ctx.getImageData(0,0,image.width,image.height); + var data= imageData.data; + + var i,j; + var miny= 0, maxy=canvas.height-1; + var minx= 0, maxx=canvas.width-1; + + var alpha= false; + + if ( atop ) { + for( i=0; ithreshold ) { + alpha= true; + break; + } + } + + if ( alpha ) { + break; + } + } + // i contiene el indice del ultimo scan que no es transparente total. + miny= i; + } + + if ( abottom ) { + alpha= false; + for( i=canvas.height-1; i>=miny; i-- ) { + for( j=0; jthreshold ) { + alpha= true; + break; + } + } + + if ( alpha ) { + break; + } + } + maxy= i; + } + + if ( aleft ) { + alpha= false; + for( j=0; jthreshold ) { + alpha= true; + break; + } + } + if ( alpha ) { + break; + } + } + minx= j; + } + + if ( aright ) { + alpha= false; + for( j=canvas.width-1; j>=minx; j-- ) { + for( i=miny; i<=maxy; i++ ) { + if ( data[i*canvas.width*4 + 3+j*4 ]>threshold ) { + alpha= true; + break; + } + } + if ( alpha ) { + break; + } + } + maxx= j; + } + + if ( 0===minx && 0===miny && canvas.width-1===maxx && canvas.height-1===maxy ) { + return canvas; + } + + var width= maxx-minx+1; + var height=maxy-miny+1; + var id2= ctx.getImageData( minx, miny, width, height ); + + canvas.width= width; + canvas.height= height; + ctx= canvas.getContext('2d'); + ctx.putImageData( id2, 0, 0 ); + + return canvas; + }; + + CAAT.modules.ImageUtil.createThumb= function(image, w, h, best_fit) { + w= w||24; + h= h||24; + var canvas= document.createElement('canvas'); + canvas.width= w; + canvas.height= h; + var ctx= canvas.getContext('2d'); + + if ( best_fit ) { + var max= Math.max( image.width, image.height ); + var ww= image.width/max*w; + var hh= image.height/max*h; + ctx.drawImage( image, (w-ww)/2,(h-hh)/2,ww,hh ); + } else { + ctx.drawImage( image, 0, 0, w, h ); + } + + return canvas; + } + +})();/** + * See LICENSE file. + */ + +(function() { + CAAT.modules.LayoutUtils= {}; + + CAAT.modules.LayoutUtils.row= function( dst, what_to_layout_array, constraint_object ) { + + var width= dst.width; + var x=0, y=0, i=0, l=0; + var actor_max_h= -Number.MAX_VALUE, actor_max_w= Number.MAX_VALUE; + + // compute max/min actor list size. + for( i=what_to_layout_array.length-1; i; i-=1 ) { + if ( actor_max_w>0)+1 ) + 2 * padding ; + + // var cw= Math.max( 1, (ctx.measureText( chars.charAt(i) ).width>>0)+1 ) + 2 * padding ; + var cw= Math.max( 1, (ctx.measureText( chars.charAt(i) ).width>>0)+1 ); + + charWidth.push(cw); + textWidth+= cw + 2 * padding; + } + + canvas.width= textWidth; + canvas.height= (this.fontSize*1.5)>>0; + ctx= canvas.getContext('2d'); + + ctx.textBaseline= 'top'; + ctx.font= this.fontStyle+' '+this.fontSize+""+this.fontSizeUnit+" "+ this.font; + ctx.fillStyle= this.fillStyle; + ctx.strokeStyle= this.strokeStyle; + + this.charMap= {}; + + x=padding; // x=0 + for( i=0; i + * It is implemented by all path segment types, ie: + *
      + *
    • LinearPath + *
    • CurvePath, base for all curves: quadric and cubic bezier. + *
    • Path. A path built of different PathSegment implementations. + *
    + * + * @constructor + */ + CAAT.PathSegment = function() { + this.bbox= new CAAT.Rectangle(); + return this; + }; + + CAAT.PathSegment.prototype = { + color: '#000', + length: 0, + bbox: null, + parent: null, + + /** + * Set a PathSegment's parent + * @param parent + */ + setParent : function(parent) { + this.parent= parent; + return this; + }, + setColor : function(color) { + if ( color ) { + this.color= color; + } + return this; + }, + /** + * Get path's last coordinate. + * @return {CAAT.Point} + */ + endCurvePosition : function() { }, + + /** + * Get path's starting coordinate. + * @return {CAAT.Point} + */ + startCurvePosition : function() { }, + + /** + * Set this path segment's points information. + * @param points {Array} + */ + setPoints : function( points ) { }, + + /** + * Set a point from this path segment. + * @param point {CAAT.Point} + * @param index {integer} a point index. + */ + setPoint : function( point, index ) { }, + + /** + * Get a coordinate on path. + * The parameter time is normalized, that is, its values range from zero to one. + * zero will mean startCurvePosition and one will be endCurvePosition. Other values + * will be a position on the path relative to the path length. if the value is greater that 1, if will be set + * to modulus 1. + * @param time a float with a value between zero and 1 inclusive both. + * + * @return {CAAT.Point} + */ + getPosition : function(time) { }, + + /** + * Gets Path length. + * @return {number} + */ + getLength : function() { + return this.length; + }, + + /** + * Gets the path bounding box (or the rectangle that contains the whole path). + * @param rectangle a CAAT.Rectangle instance with the bounding box. + * @return {CAAT.Rectangle} + */ + getBoundingBox : function() { + return this.bbox; + }, + + /** + * Gets the number of control points needed to create the path. + * Each PathSegment type can have different control points. + * @return {number} an integer with the number of control points. + */ + numControlPoints : function() { }, + + /** + * Gets CAAT.Point instance with the 2d position of a control point. + * @param index an integer indicating the desired control point coordinate. + * @return {CAAT.Point} + */ + getControlPoint: function(index) { }, + + /** + * Instruments the path has finished building, and that no more segments will be added to it. + * You could later add more PathSegments and endPath must be called again. + */ + endPath : function() {}, + + /** + * Gets a polyline describing the path contour. The contour will be defined by as mush as iSize segments. + * @param iSize an integer indicating the number of segments of the contour polyline. + * + * @return {[CAAT.Point]} + */ + getContour : function(iSize) {}, + + /** + * Recalculate internal path structures. + */ + updatePath : function(point) {}, + + /** + * Draw this path using RenderingContext2D drawing primitives. + * The intention is to set a path or pathsegment as a clipping region. + * + * @param ctx {RenderingContext2D} + */ + applyAsPath : function(director) {}, + + /** + * Transform this path with the given affinetransform matrix. + * @param matrix + */ + transform : function(matrix) {}, + + drawHandle : function( ctx, x, y ) { + var w= CAAT.Curve.prototype.HANDLE_SIZE/2; + ctx.fillRect( x-w, y-w, w*2, w*2 ); + /* + ctx.arc( + this.points[0].x, + this.points[0].y, + CAAT.Curve.prototype.HANDLE_SIZE/2, + 0, + 2*Math.PI, + false) ; + */ + } + }; + +})(); + +(function() { + + /** + * Straight line segment path between two given points. + * + * @constructor + * @extends CAAT.PathSegment + */ + CAAT.LinearPath = function() { + CAAT.LinearPath.superclass.constructor.call(this); + + this.points= []; + this.points.push( new CAAT.Point() ); + this.points.push( new CAAT.Point() ); + + this.newPosition= new CAAT.Point(0,0,0); + return this; + }; + + CAAT.LinearPath.prototype= { + points: null, + newPosition: null, // spare holder for getPosition coordinate return. + + applyAsPath : function(director) { + director.ctx.lineTo( this.points[0].x, this.points[1].y ); + }, + setPoint : function( point, index ) { + if ( index===0 ) { + this.points[0]= point; + } else if ( index===1 ) { + this.points[1]= point; + } + }, + /** + * Update this segments length and bounding box info. + */ + updatePath : function(point) { + var x= this.points[1].x - this.points[0].x; + var y= this.points[1].y - this.points[0].y; + this.length= Math.sqrt( x*x+y*y ); + + this.bbox.setEmpty(); + this.bbox.union( this.points[0].x, this.points[0].y ); + this.bbox.union( this.points[1].x, this.points[1].y ); + + return this; + }, + setPoints : function( points ) { + this.points[0]= points[0]; + this.points[1]= points[1]; + this.updatePath(); + return this; + }, + /** + * Set this path segment's starting position. + * @param x {number} + * @param y {number} + */ + setInitialPosition : function( x, y ) { + this.points[0].x= x; + this.points[0].y= y; + this.newPosition.set(x,y); + return this; + }, + /** + * Set this path segment's ending position. + * @param finalX {number} + * @param finalY {number} + */ + setFinalPosition : function( finalX, finalY ) { + this.points[1].x= finalX; + this.points[1].y= finalY; + return this; + }, + /** + * @inheritDoc + */ + endCurvePosition : function() { + return this.points[1]; + }, + /** + * @inheritsDoc + */ + startCurvePosition : function() { + return this.points[0]; + }, + /** + * @inheritsDoc + */ + getPosition : function(time) { + + if ( time>1 || time<0 ) { + time%=1; + } + if ( time<0 ) { + time= 1+time; + } + + this.newPosition.set( + (this.points[0].x+(this.points[1].x-this.points[0].x)*time), + (this.points[0].y+(this.points[1].y-this.points[0].y)*time) ); + + return this.newPosition; + }, + getPositionFromLength : function( len ) { + return this.getPosition( len/this.length ); + }, + /** + * Returns initial path segment point's x coordinate. + * @return {number} + */ + initialPositionX : function() { + return this.points[0].x; + }, + /** + * Returns final path segment point's x coordinate. + * @return {number} + */ + finalPositionX : function() { + return this.points[1].x; + }, + /** + * Draws this path segment on screen. Optionally it can draw handles for every control point, in + * this case, start and ending path segment points. + * @param director {CAAT.Director} + * @param bDrawHandles {boolean} + */ + paint : function(director, bDrawHandles) { + + var ctx= director.ctx; + + ctx.save(); + + ctx.strokeStyle= this.color; + ctx.beginPath(); + ctx.moveTo( this.points[0].x, this.points[0].y ); + ctx.lineTo( this.points[1].x, this.points[1].y ); + ctx.stroke(); + + if ( bDrawHandles ) { + ctx.globalAlpha=0.5; + ctx.fillStyle='#7f7f00'; + ctx.beginPath(); + this.drawHandle( ctx, this.points[0].x, this.points[0].y ); + this.drawHandle( ctx, this.points[1].x, this.points[1].y ); + /* + canvas.arc( + this.points[0].x, + this.points[0].y, + CAAT.Curve.prototype.HANDLE_SIZE/2, + 0, + 2*Math.PI, + false) ; + canvas.arc( + this.points[1].x, + this.points[1].y, + CAAT.Curve.prototype.HANDLE_SIZE/2, + 0, + 2*Math.PI, + false) ; + canvas.fill(); + */ + } + + ctx.restore(); + }, + /** + * Get the number of control points. For this type of path segment, start and + * ending path segment points. Defaults to 2. + * @return {number} + */ + numControlPoints : function() { + return 2; + }, + /** + * @inheritsDoc + */ + getControlPoint: function(index) { + if ( 0===index ) { + return this.points[0]; + } else if (1===index) { + return this.points[1]; + } + }, + /** + * @inheritsDoc + */ + getContour : function(iSize) { + var contour= []; + + contour.push( this.getPosition(0).clone() ); + contour.push( this.getPosition(1).clone() ); + + return contour; + } + }; + + extend( CAAT.LinearPath, CAAT.PathSegment ); +})(); + +(function() { + /** + * This class defines a Bezier cubic or quadric path segment. + * + * @constructor + * @extends CAAT.PathSegment + */ + CAAT.CurvePath = function() { + CAAT.CurvePath.superclass.constructor.call(this); + this.newPosition= new CAAT.Point(0,0,0); + return this; + }; + + CAAT.CurvePath.prototype= { + curve: null, // a CAAT.Bezier instance. + newPosition: null, // spare holder for getPosition coordinate return. + + applyAsPath : function(director) { + this.curve.applyAsPath(director); + return this; + }, + setPoint : function( point, index ) { + if ( this.curve ) { + this.curve.setPoint(point,index); + } + }, + /** + * Set this curve segment's points. + * @param points {Array} + */ + setPoints : function( points ) { + var curve = new CAAT.Bezier(); + curve.setPoints(points); + this.curve = curve; + return this; + }, + /** + * Set the pathSegment as a CAAT.Bezier quadric instance. + * Parameters are quadric coordinates control points. + * + * @param p0x {number} + * @param p0y {number} + * @param p1x {number} + * @param p1y {number} + * @param p2x {number} + * @param p2y {number} + * @return this + */ + setQuadric : function(p0x,p0y, p1x,p1y, p2x,p2y) { + var curve = new CAAT.Bezier(); + curve.setQuadric(p0x,p0y, p1x,p1y, p2x,p2y); + this.curve = curve; + this.updatePath(); + + return this; + }, + /** + * Set the pathSegment as a CAAT.Bezier cubic instance. + * Parameters are cubic coordinates control points. + * @param p0x {number} + * @param p0y {number} + * @param p1x {number} + * @param p1y {number} + * @param p2x {number} + * @param p2y {number} + * @param p3x {number} + * @param p3y {number} + * @return this + */ + setCubic : function(p0x,p0y, p1x,p1y, p2x,p2y, p3x,p3y) { + var curve = new CAAT.Bezier(); + curve.setCubic(p0x,p0y, p1x,p1y, p2x,p2y, p3x,p3y); + this.curve = curve; + this.updatePath(); + + return this; + }, + /** + * @inheritDoc + */ + updatePath : function(point) { + this.curve.update(); + this.length= this.curve.getLength(); + this.curve.getBoundingBox(this.bbox); + return this; + }, + /** + * @inheritDoc + */ + getPosition : function(time) { + + if ( time>1 || time<0 ) { + time%=1; + } + if ( time<0 ) { + time= 1+time; + } + + this.curve.solve(this.newPosition, time); + + return this.newPosition; + }, + /** + * Gets the coordinate on the path relative to the path length. + * @param iLength {number} the length at which the coordinate will be taken from. + * @return {CAAT.Point} a CAAT.Point instance with the coordinate on the path corresponding to the + * iLenght parameter relative to segment's length. + */ + getPositionFromLength : function(iLength) { + this.curve.solve( this.newPosition, iLength/this.length ); + return this.newPosition; + }, + /** + * Get path segment's first point's x coordinate. + * @return {number} + */ + initialPositionX : function() { + return this.curve.coordlist[0].x; + }, + /** + * Get path segment's last point's y coordinate. + * @return {number} + */ + finalPositionX : function() { + return this.curve.coordlist[this.curve.coordlist.length-1].x; + }, + /** + * @inheritDoc + * @param director {CAAT.Director} + * @param bDrawHandles {boolean} + */ + paint : function( director,bDrawHandles ) { + this.curve.drawHandles= bDrawHandles; + director.ctx.strokeStyle= this.color; + this.curve.paint(director,bDrawHandles); + }, + /** + * @inheritDoc + */ + numControlPoints : function() { + return this.curve.coordlist.length; + }, + /** + * @inheritDoc + * @param index + */ + getControlPoint : function(index) { + return this.curve.coordlist[index]; + }, + /** + * @inheritDoc + */ + endCurvePosition : function() { + return this.curve.endCurvePosition(); + }, + /** + * @inheritDoc + */ + startCurvePosition : function() { + return this.curve.startCurvePosition(); + }, + /** + * @inheritDoc + * @param iSize + */ + getContour : function(iSize) { + var contour=[]; + for( var i=0; i<=iSize; i++ ) { + contour.push( {x: i/iSize, y: this.getPosition(i/iSize).y} ); + } + + return contour; + } + }; + + extend( CAAT.CurvePath, CAAT.PathSegment, null); + +})(); + +(function() { + + CAAT.ShapePath= function() { + CAAT.ShapePath.superclass.constructor.call(this); + + this.points= []; + this.points.push( new CAAT.Point() ); + this.points.push( new CAAT.Point() ); + this.points.push( new CAAT.Point() ); + this.points.push( new CAAT.Point() ); + this.points.push( new CAAT.Point() ); + + this.newPosition= new CAAT.Point(); + + return this; + }; + + CAAT.ShapePath.prototype= { + points: null, + length: -1, + cw: true, // should be clock wise traversed ? + bbox: null, + newPosition: null, // spare point for calculations + + applyAsPath : function(director) { + var ctx= director.ctx; + //ctx.rect( this.bbox.x, this.bbox.y, this.bbox.width, this.bbox.height ); + if ( this.cw ) { + ctx.lineTo( this.points[0].x, this.points[0].y ); + ctx.lineTo( this.points[1].x, this.points[1].y ); + ctx.lineTo( this.points[2].x, this.points[2].y ); + ctx.lineTo( this.points[3].x, this.points[3].y ); + ctx.lineTo( this.points[4].x, this.points[4].y ); + } else { + ctx.lineTo( this.points[4].x, this.points[4].y ); + ctx.lineTo( this.points[3].x, this.points[3].y ); + ctx.lineTo( this.points[2].x, this.points[2].y ); + ctx.lineTo( this.points[1].x, this.points[1].y ); + ctx.lineTo( this.points[0].x, this.points[0].y ); + } + return this; + }, + setPoint : function( point, index ) { + if ( index>=0 && index} + */ + setPoints : function( points ) { + this.points= []; + this.points.push( points[0] ); + this.points.push( new CAAT.Point().set(points[1].x, points[0].y) ); + this.points.push( points[1] ); + this.points.push( new CAAT.Point().set(points[0].x, points[1].y) ); + this.points.push( points[0].clone() ); + this.updatePath(); + + return this; + }, + setClockWise : function(cw) { + this.cw= cw!==undefined ? cw : true; + return this; + }, + isClockWise : function() { + return this.cw; + }, + /** + * Set this path segment's starting position. + * This method should not be called again after setFinalPosition has been called. + * @param x {number} + * @param y {number} + */ + setInitialPosition : function( x, y ) { + for( var i=0, l= this.points.length; i1 || time<0 ) { + time%=1; + } + if ( time<0 ) { + time= 1+time; + } + + if ( -1===this.length ) { + this.newPosition.set(0,0); + } else { + var w= this.bbox.width / this.length; + var h= this.bbox.height / this.length; + var accTime= 0; + var times; + var segments; + var index= 0; + + if ( this.cw ) { + segments= [0,1,2,3,4]; + times= [w,h,w,h]; + } else { + segments= [4,3,2,1,0]; + times= [h,w,h,w]; + } + + while( index + * Every operation of the CAAT.PathSegment interface is performed for every path segment. In example, + * the method getLength will contain the sum of every path segment's length. + *

    + * An example of CAAT.Path will be as follows: + + * + * path.beginPath(x,y).
    + *   addLineTo(x1,y1).
    + *   addLineTo(x2,y2).
    + *   addQuadricTo(...).
    + *   addCubicTo(...).
    + *   endPath();
    + *
    + *

    + * This code creates a path composed of four chained segments, starting at (x,y) and having each + * segment starting where the previous one ended. + *

    + * This class is intended to wrap the other kind of path segment classes when just a one segmented + * path is to be defined. The methods setLinear, setCubic and setQuadrid will make + * a CAAT.Path instance to be defined by just one segment. + * + * @constructor + * @extends CAAT.PathSegment + */ + CAAT.Path= function() { + CAAT.Path.superclass.constructor.call(this); + + this.newPosition= new CAAT.Point(0,0,0); + this.pathSegments= []; + + this.behaviorList= []; + this.matrix= new CAAT.Matrix(); + this.tmpMatrix= new CAAT.Matrix(); + + return this; + }; + + CAAT.Path.prototype= { + + pathSegments: null, // a collection of CAAT.PathSegment instances. + pathSegmentDurationTime: null, // precomputed segment duration relative to segment legnth/path length + pathSegmentStartTime: null, // precomputed segment start time relative to segment legnth/path length and duration. + + newPosition: null, // spare CAAT.Point. + + pathLength: -1, // path length (sum of every segment length) + + /* + starting path position + */ + beginPathX: -1, + beginPathY: -1, + + /* + last path coordinates position (using when building the path). + */ + trackPathX: -1, + trackPathY: -1, + + /* + needed to drag control points. + */ + ax: -1, + ay: -1, + point: [], + + interactive: true, + + behaviorList: null, + + /** rotation behavior info **/ + rb_angle: 0, + rb_rotateAnchorX: .5, + rb_rotateAnchorY: .5, + + /** scale behavior info **/ + sb_scaleX: 1, + sb_scaleY: 1, + sb_scaleAnchorX: .5, + sb_scaleAnchorY: .5, + + tAnchorX: 0, + tAnchorY: 0, + + /** translate behavior info **/ + tb_x: 0, + tb_y: 0, + + /** behavior affine transformation matrix **/ + matrix: null, + tmpMatrix: null, + + /** if behaviors are to be applied, save original path points **/ + pathPoints: null, + + /** path width and height **/ + width: 0, + height: 0, + + clipOffsetX : 0, + clipOffsetY : 0, + + applyAsPath : function(director) { + var ctx= director.ctx; + + director.modelViewMatrix.transformRenderingContext( ctx ); + ctx.beginPath(); + ctx.globalCompositeOperation= 'source-out'; + ctx.moveTo( + this.getFirstPathSegment().startCurvePosition().x, + this.getFirstPathSegment().startCurvePosition().y + ); + for( var i=0; i + * If a call to any method of the form addTo is called before this calling + * this method, they will assume to start at -1,-1 and probably you'll get the wrong path. + * @param px0 {number} + * @param py0 {number} + * + * @return this + */ + beginPath : function( px0, py0 ) { + this.trackPathX= px0; + this.trackPathY= py0; + this.beginPathX= px0; + this.beginPathY= py0; + return this; + }, + /** + * Close the path by adding a line path segment from the current last path + * coordinate to startCurvePosition coordinate. + *

    + * This method closes a path by setting its last path segment's last control point + * to be the first path segment's first control point. + *

    + * This method also sets the path as finished, and calculates all path's information + * such as length and bounding box. + * + * @return this + */ + closePath : function() { + + this.getLastPathSegment().setPoint( + this.getFirstPathSegment().startCurvePosition(), + this.getLastPathSegment().numControlPoints()-1 ); + + + this.trackPathX= this.beginPathX; + this.trackPathY= this.beginPathY; + + this.endPath(); + return this; + }, + /** + * Finishes the process of building the path. It involves calculating each path segments length + * and proportional length related to a normalized path length of 1. + * It also sets current paths length. + * These calculi are needed to traverse the path appropriately. + *

    + * This method must be called explicitly, except when closing a path (that is, calling the + * method closePath) which calls this method as well. + * + * @return this + */ + endPath : function() { + + this.pathSegmentStartTime=[]; + this.pathSegmentDurationTime= []; + + this.updatePath(); + + return this; + }, + /** + * This method, returns a CAAT.Point instance indicating a coordinate in the path. + * The returned coordinate is the corresponding to normalizing the path's length to 1, + * and then finding what path segment and what coordinate in that path segment corresponds + * for the input time parameter. + *

    + * The parameter time must be a value ranging 0..1. + * If not constrained to these values, the parameter will be modulus 1, and then, if less + * than 0, be normalized to 1+time, so that the value always ranges from 0 to 1. + *

    + * This method is needed when traversing the path throughout a CAAT.Interpolator instance. + * + * @param time a value between 0 and 1 both inclusive. 0 will return path's starting coordinate. + * 1 will return path's end coordinate. + * + * @return {CAAT.Point} + */ + getPosition : function(time) { + + if ( time>1 || time<0 ) { + time%=1; + } + if ( time<0 ) { + time= 1+time; + } + + /* + var found= false; + for( var i=0; i=psstv )*/ { + l= m+1; + } + } + return this.endCurvePosition(); + + + }, + /** + * Analogously to the method getPosition, this method returns a CAAT.Point instance with + * the coordinate on the path that corresponds to the given length. The input length is + * related to path's length. + * + * @param iLength {number} a float with the target length. + * @return {CAAT.Point} + */ + getPositionFromLength : function(iLength) { + + iLength%=this.getLength(); + if (iLength<0 ) { + iLength+= this.getLength(); + } + + var accLength=0; + + for( var i=0; i0 ) { + this.pathSegmentStartTime[i]= this.pathSegmentStartTime[i-1]+this.pathSegmentDurationTime[i-1]; + } else { + this.pathSegmentStartTime[0]= 0; + } + + this.pathSegments[i].endPath(); + } + + this.extractPathPoints(); + + if ( typeof callback!=='undefined' ) { + callback(this); + } + + return this; + + }, + /** + * Sent by a CAAT.PathActor instance object to try to drag a path's control point. + * @param x {number} + * @param y {number} + */ + press: function(x,y) { + if (!this.interactive) { + return; + } + + var HS= CAAT.Curve.prototype.HANDLE_SIZE/2; + for( var i=0; i=point.x-HS && + y>=point.y-HS && + x} + */ + setPoints : function( points ) { + if ( this.points.length===points.length ) { + for( var i=0; i=0 && index + * This class pre-creates a canvas of the given dimensions and extracts an imageData object to + * hold the pixel manipulation. + * + * @constructor + */ + CAAT.ImageProcessor= function() { + return this; + }; + + CAAT.ImageProcessor.prototype= { + canvas: null, + ctx: null, + width: 0, + height: 0, + imageData: null, + bufferImage:null, + + /** + * Grabs an image pixels. + * + * @param image {HTMLImageElement} + * @return {ImageData} returns an ImageData object with the image representation or null in + * case the pixels can not be grabbed. + * + * @static + */ + grabPixels : function(image) { + var canvas= document.createElement('canvas'); + if ( canvas!==null ) { + canvas.width= image.width; + canvas.height= image.height; + var ctx= canvas.getContext('2d'); + ctx.drawImage(image,0,0); + try { + var imageData= ctx.getImageData(0,0,canvas.width,canvas.height); + return imageData; + } + catch(e) { + CAAT.log('error pixelgrabbing.', image); + return null; + } + } + return null; + }, + /** + * Helper method to create an array. + * + * @param size {number} integer number of elements in the array. + * @param initValue {number} initial array values. + * + * @return {[]} an array of 'initialValue' elements. + * + * @static + */ + makeArray : function(size, initValue) { + var a= []; + + for(var i=0; i + * This image processor creates a color ramp of 256 elements from the colors of the parameter 'colors'. + * Be aware of color definition since the alpha values count to create the ramp. + * + * @param width {number} + * @param height {number} + * @param colors {Array.} an array of color values. + * + * @return this + */ + initialize : function(width,height,colors) { + CAAT.IMPlasma.superclass.initialize.call(this,width,height); + + this.wavetable= []; + for (var x=0; x<256; x++) { + this.wavetable.push( Math.floor(32 * (1 + Math.cos(x*2 * Math.PI / 256))) ); + } + + this.pos1=Math.floor(255*Math.random()); + this.pos2=Math.floor(255*Math.random()); + this.pos3=Math.floor(255*Math.random()); + this.pos4=Math.floor(255*Math.random()); + + this.m_colorMap= CAAT.Color.prototype.makeRGBColorRamp( + colors!==null ? colors : this.color, + 256, + CAAT.Color.prototype.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY ); + + this.setB(); + + return this; + }, + /** + * Initialize internal plasma structures. Calling repeatedly this method will make the plasma + * look different. + */ + setB : function() { + + this.b1= Math.random()>0.5; + this.b2= Math.random()>0.5; + this.b3= Math.random()>0.5; + this.b4= Math.random()>0.5; + + this.spd1= Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1)); + this.spd2= Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1)); + this.spd3= Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1)); + this.spd4= Math.floor((Math.random()*3+1)*(Math.random()<0.5?1:-1)); + + this.i1= Math.floor((Math.random()*2.4+1)*(Math.random()<0.5?1:-1)); + this.i2= Math.floor((Math.random()*2.4+1)*(Math.random()<0.5?1:-1)); + this.i3= Math.floor((Math.random()*2.4+1)*(Math.random()<0.5?1:-1)); + this.i4= Math.floor((Math.random()*2.4+1)*(Math.random()<0.5?1:-1)); + }, + /** + * Apply image processing to create the plasma and call superclass's apply to make the result + * visible. + * @param director {CAAT.Director} + * @param time {number} + * + * @return this + */ + apply : function(director,time) { + + var v = 0; + this.tpos1 = this.pos1; + this.tpos2 = this.pos2; + + var bi= this.bufferImage; + var cm= this.m_colorMap; + var wt= this.wavetable; + var z; + var cmz; + + for (var x=0; x=this.m_radius) { + dx=this.m_radius-1; + } + if (dy>=this.m_radius) { + dy=this.m_radius-1; + } + + var c= this.phong[ dx ] [ dy ]; + var r=0; + var g=0; + var b=0; + + if ( c>=0 ) {// oscurecer + r= (this.m_lightcolor[k][0]*c/128); + g= (this.m_lightcolor[k][1]*c/128); + b= (this.m_lightcolor[k][2]*c/128); + } + else { // blanquear. + c=128+c; + var rr= (this.m_lightcolor[k][0]); + var gg= (this.m_lightcolor[k][1]); + var bb= (this.m_lightcolor[k][2]); + + r= Math.floor(rr+ (255-rr)*c/128); + g= Math.floor(gg+ (255-gg)*c/128); + b= Math.floor(bb+ (255-bb)*c/128); + } + + rrr+=r; + ggg+=g; + bbb+=b; + } + + if ( rrr>255 ) { + rrr=255; + } + if ( ggg>255 ) { + ggg=255; + } + if ( bbb>255 ) { + bbb=255; + } + + var pos= (j+this.m_tt[i])*4; + dstPixels[pos ]= rrr; + dstPixels[pos+1]= ggg; + dstPixels[pos+2]= bbb; + dstPixels[pos+3]= 255; + } + } + }, + /** + * Sets lights color. + * @param colors_rgb_array an array of arrays. Each internal array has three integers defining an RGB color. + * ie: + * [ + * [ 255,0,0 ], + * [ 0,255,0 ] + * ] + * @return this + */ + setLightColors : function( colors_rgb_array ) { + this.m_lightcolor= colors_rgb_array; + this.lightPosition= []; + for( var i=0; i> 1); + break; + case 2: + hh = this.height - 1; + break; + } + + switch (this.m_alignv) { + case 0: + ww = 0; + break; + case 1: + ww = (this.width >> 1); + break; + case 2: + ww = this.width - 1; + break; + } + + var i = (((this.width >> 1) << 8) - ddx * ww + ddy * hh)&0xffff; + var j = (((this.height >> 1) << 8) - ddy * ww - ddx * hh) & 0xffff; + + var srcwidth= this.sourceImageData.width; + var srcheight= this.sourceImageData.height; + var srcdata= this.sourceImageData.data; + var bi= this.bufferImage; + var dstoff; + var addx; + var addy; + + while (off < this.width * this.height * 4) { + addx = i; + addy = j; + + for (var m = 0; m < this.width; m++) { + dstoff = ((addy >> this.shift) & this.mask) * srcwidth + ((addx >> this.shift) & this.mask); + dstoff <<= 2; + + bi[ off++ ] = srcdata[ dstoff++ ]; + bi[ off++ ] = srcdata[ dstoff++ ]; + bi[ off++ ] = srcdata[ dstoff++ ]; + bi[ off++ ] = srcdata[ dstoff++ ]; + + addx += ddx; + addy += ddy; + + } + + dist += this.distortion; + i -= ddy; + j += ddx - dist; + } + }, + /** + * Perform and apply the rotozoom effect. + * @param director {CAAT.Director} + * @param time {number} + * @return this + */ + apply : function(director,time) { + if ( null!==this.sourceImageData ) { + this.rotoZoom(director,time); + } + return CAAT.IMRotoZoom.superclass.apply.call(this,director,time); + }, + /** + * Change the effect's rotation anchor. Call this method repeatedly to make the effect look + * different. + */ + setCenter: function() { + var d = Math.random(); + if (d < 0.33) { + this.m_alignv = 0; + } else if (d < 0.66) { + this.m_alignv = 1; + } else { + this.m_alignv = 2; + } + + d = Math.random(); + if (d < 0.33) { + this.m_alignh = 0; + } else if (d < 0.66) { + this.m_alignh = 1; + } else { + this.m_alignh = 2; + } + } + + }; + + extend( CAAT.IMRotoZoom, CAAT.ImageProcessor, null); + +})();/** + * See LICENSE file. + */ + + +(function() { + CAAT.Program= function(gl) { + this.gl= gl; + return this; + }; + + CAAT.Program.prototype= { + + shaderProgram: null, + gl: null, + + /** + * Set fragment shader's alpha composite value. + * @param alpha {number} float value 0..1. + */ + setAlpha : function( alpha ) { + + }, + getShader : function (gl,type,str) { + var shader; + if (type === "x-shader/x-fragment") { + shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (type === "x-shader/x-vertex") { + shader = gl.createShader(gl.VERTEX_SHADER); + } else { + return null; + } + + gl.shaderSource(shader, str); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert(gl.getShaderInfoLog(shader)); + return null; + } + + return shader; + + }, + getDomShader : function(gl, id) { + var shaderScript = document.getElementById(id); + if (!shaderScript) { + return null; + } + + var str = ""; + var k = shaderScript.firstChild; + while (k) { + if (k.nodeType === 3) { + str += k.textContent; + } + k = k.nextSibling; + } + + var shader; + if (shaderScript.type === "x-shader/x-fragment") { + shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (shaderScript.type === "x-shader/x-vertex") { + shader = gl.createShader(gl.VERTEX_SHADER); + } else { + return null; + } + + gl.shaderSource(shader, str); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert(gl.getShaderInfoLog(shader)); + return null; + } + + return shader; + }, + initialize : function() { + return this; + }, + getFragmentShader : function() { + return null; + }, + getVertexShader : function() { + return null; + }, + create : function() { + var gl= this.gl; + + this.shaderProgram = gl.createProgram(); + gl.attachShader(this.shaderProgram, this.getVertexShader()); + gl.attachShader(this.shaderProgram, this.getFragmentShader()); + gl.linkProgram(this.shaderProgram); + gl.useProgram(this.shaderProgram); + return this; + }, + setMatrixUniform : function( caatMatrix4 ) { + this.gl.uniformMatrix4fv( + this.shaderProgram.pMatrixUniform, + false, + new Float32Array(caatMatrix4.flatten())); + + }, + useProgram : function() { + this.gl.useProgram(this.shaderProgram); + return this; + } + }; +})(); + +(function() { + CAAT.ColorProgram= function(gl) { + CAAT.ColorProgram.superclass.constructor.call(this,gl); + return this; + }; + + CAAT.ColorProgram.prototype= { + + colorBuffer: null, + vertexPositionBuffer: null, + vertexPositionArray: null, + + getFragmentShader : function() { + return this.getShader(this.gl, "x-shader/x-fragment", + "#ifdef GL_ES \n"+ + "precision highp float; \n"+ + "#endif \n"+ + + "varying vec4 color; \n"+ + + "void main(void) { \n"+ + " gl_FragColor = color;\n"+ + "}\n" + ); + + }, + getVertexShader : function() { + return this.getShader(this.gl, "x-shader/x-vertex", + "attribute vec3 aVertexPosition; \n"+ + "attribute vec4 aColor; \n"+ + "uniform mat4 uPMatrix; \n"+ + "varying vec4 color; \n"+ + + "void main(void) { \n"+ + "gl_Position = uPMatrix * vec4(aVertexPosition, 1.0); \n"+ + "color= aColor; \n"+ + "}\n" + ); + }, + initialize : function() { + this.shaderProgram.vertexPositionAttribute = + this.gl.getAttribLocation(this.shaderProgram, "aVertexPosition"); + this.gl.enableVertexAttribArray( + this.shaderProgram.vertexPositionAttribute); + + this.shaderProgram.vertexColorAttribute = + this.gl.getAttribLocation(this.shaderProgram, "aColor"); + this.gl.enableVertexAttribArray( + this.shaderProgram.vertexColorAttribute); + + this.shaderProgram.pMatrixUniform = + this.gl.getUniformLocation(this.shaderProgram, "uPMatrix"); + + this.useProgram(); + + this.colorBuffer= this.gl.createBuffer(); + this.setColor( [1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1] ); + + var maxTris=512, i; + /// set vertex data + this.vertexPositionBuffer = this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer ); + this.vertexPositionArray= new Float32Array(maxTris*12); + this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertexPositionArray, this.gl.DYNAMIC_DRAW); + this.gl.vertexAttribPointer(this.shaderProgram.vertexPositionAttribute, 3, this.gl.FLOAT, false, 0, 0); + + return CAAT.ColorProgram.superclass.initialize.call(this); + }, + setColor : function( colorArray ) { + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.colorBuffer ); + this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(colorArray), this.gl.STATIC_DRAW); + + this.gl.vertexAttribPointer( + this.shaderProgram.vertexColorAttribute, + this.colorBuffer, + this.gl.FLOAT, + false, + 0, + 0); + } + }; + + extend(CAAT.ColorProgram, CAAT.Program, null ); +})(); + +(function() { + CAAT.TextureProgram= function(gl) { + CAAT.TextureProgram.superclass.constructor.call(this,gl); + return this; + }; + + CAAT.TextureProgram.prototype= { + + vertexPositionBuffer: null, + vertexPositionArray: null, + vertexUVBuffer: null, + vertexUVArray: null, + vertexIndexBuffer: null, + + linesBuffer: null, + + prevAlpha: -1, + prevR: -1, + prevG: -1, + prevB: -1, + prevA: -1, + prevTexture: null, + + getFragmentShader : function() { + return this.getShader( this.gl, "x-shader/x-fragment", + "#ifdef GL_ES \n"+ + "precision highp float; \n"+ + "#endif \n"+ + + "varying vec2 vTextureCoord; \n"+ + "uniform sampler2D uSampler; \n"+ + "uniform float alpha; \n"+ + "uniform bool uUseColor;\n"+ + "uniform vec4 uColor;\n"+ + + "void main(void) { \n"+ + + "if ( uUseColor ) {\n"+ + " gl_FragColor= vec4(uColor.r*alpha, uColor.g*alpha, uColor.b*alpha, uColor.a*alpha);\n"+ + "} else { \n"+ + " vec4 textureColor= texture2D(uSampler, vec2(vTextureCoord)); \n"+ +// Fix FF " gl_FragColor = vec4(textureColor.rgb, textureColor.a * alpha); \n"+ + " gl_FragColor = vec4(textureColor.r*alpha, textureColor.g*alpha, textureColor.b*alpha, textureColor.a * alpha ); \n"+ + "}\n"+ + + "}\n" + ); + }, + getVertexShader : function() { + return this.getShader(this.gl, "x-shader/x-vertex", + "attribute vec3 aVertexPosition; \n"+ + "attribute vec2 aTextureCoord; \n"+ + + "uniform mat4 uPMatrix; \n"+ + + "varying vec2 vTextureCoord; \n"+ + + "void main(void) { \n"+ + "gl_Position = uPMatrix * vec4(aVertexPosition, 1.0); \n"+ + "vTextureCoord = aTextureCoord;\n"+ + "}\n" + ); + }, + useProgram : function() { + CAAT.TextureProgram.superclass.useProgram.call(this); + + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer ); + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexUVBuffer); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer); + }, + initialize : function() { + + var i; + + this.linesBuffer= this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.linesBuffer ); + var arr= []; + for( i=0; i<1024; i++ ) { + arr[i]= i; + } + this.linesBufferArray= new Uint16Array(arr); + this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.linesBufferArray, this.gl.DYNAMIC_DRAW); + + + this.shaderProgram.vertexPositionAttribute = + this.gl.getAttribLocation(this.shaderProgram, "aVertexPosition"); + this.gl.enableVertexAttribArray( + this.shaderProgram.vertexPositionAttribute); + + this.shaderProgram.textureCoordAttribute = + this.gl.getAttribLocation(this.shaderProgram, "aTextureCoord"); + this.gl.enableVertexAttribArray( + this.shaderProgram.textureCoordAttribute); + + this.shaderProgram.pMatrixUniform = + this.gl.getUniformLocation(this.shaderProgram, "uPMatrix"); + this.shaderProgram.samplerUniform = + this.gl.getUniformLocation(this.shaderProgram, "uSampler"); + this.shaderProgram.alphaUniform = + this.gl.getUniformLocation(this.shaderProgram, "alpha"); + this.shaderProgram.useColor = + this.gl.getUniformLocation(this.shaderProgram, "uUseColor"); + this.shaderProgram.color = + this.gl.getUniformLocation(this.shaderProgram, "uColor"); + + this.setAlpha(1); + this.setUseColor(false); + + var maxTris=4096; + /// set vertex data + this.vertexPositionBuffer = this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer ); + this.vertexPositionArray= new Float32Array(maxTris*12); + this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertexPositionArray, this.gl.DYNAMIC_DRAW); + this.gl.vertexAttribPointer(this.shaderProgram.vertexPositionAttribute, 3, this.gl.FLOAT, false, 0, 0); + + // uv info + this.vertexUVBuffer= this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexUVBuffer); + this.vertexUVArray= new Float32Array(maxTris*8); + this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertexUVArray, this.gl.DYNAMIC_DRAW); + this.gl.vertexAttribPointer(this.shaderProgram.textureCoordAttribute, 2, this.gl.FLOAT, false, 0, 0); + + // vertex index + this.vertexIndexBuffer = this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer); + var vertexIndex = []; + for( i=0; i0 ) { + this.freeChunks.splice( i++,0,{position: lp, size:ls} ); + } + if ( rs>0 ) { + this.freeChunks.splice( i,0,{position: rp, size:rs} ); + } + + return true; + } + } + + return false; + }, + log : function(index) { + if ( 0===this.freeChunks.length ) { + CAAT.log('index '+index+' empty'); + } else { + var str='index '+index; + for( var i=0; ithis.width||height>this.height) { + return null; + } + + // find first fitting point + var i,j,initialPosition= 0; + + while( initialPosition<=this.scanMapHeight-height) { + + // para buscar sitio se buscara un sitio hasta el tamano de alto del trozo. + // mas abajo no va a caber. + + // fitHorizontalPosition es un array con todas las posiciones de este scan donde + // cabe un chunk de tamano width. + var fitHorizontalPositions= null; + var foundPositionOnScan= false; + + for( ; initialPosition<=this.scanMapHeight-height; initialPosition++ ) { + fitHorizontalPositions= this.scanMap[ initialPosition ].findWhereFits( width ); + + // si no es nulo el array de resultados, quiere decir que en alguno de los puntos + // nos cabe un trozo de tamano width. + if ( null!==fitHorizontalPositions && fitHorizontalPositions.length>0 ) { + foundPositionOnScan= true; + break; + } + } + + if ( foundPositionOnScan ) { + // j es el scan donde cabe un trozo de tamano width. + // comprobamos desde este scan que en todos los scan verticales cabe el trozo. + // se comprueba que cabe en alguno de los tamanos que la rutina de busqueda horizontal + // nos ha devuelto antes. + + var minInitialPosition=Number.MAX_VALUE; + for( j=0; jb.width ? -1 : 0; + } else if ( me.criteria==='height' ) { + return a.heightb.height ? -1 : 0; + } + return aareabarea ? -1 : 0; + }); + + for( i=0; i 0) { + this.setCursorPos(this.cursorPos -1); + } + }, + + moveRight : function( ) { + if (null!==this.text && this.cursorPos < this.text.length) { + this.setCursorPos(this.cursorPos +1); + } + }, + + deleteChar : function( ) { + if (null!==this.text && this.text.length > 0) { + var isModified = false; + var newText = this.text.substr(0 , this.cursorPos) + this.text.substr( this.cursorPos +1, this.text.length - this.cursorPos - 1); + this.setText(newText, true); + // cursorPos modified only if last character was deleted + if (this.cursorPos > this.text.length) { + this.setCursorPos(this.text.length); + // this.cursorPos = this.text.length; + } + isModified = true; + } + return isModified; + }, + + backspace : function( ) { + var isModified = false; + if (this.cursorPos > 0) { + var newText = this.text.substr(0 , this.cursorPos -1) + this.text.substr( this.cursorPos, this.text.length - this.cursorPos); + this.setText(newText, true); + this.setCursorPos(this.cursorPos - 1); + + isModified = true; // modified + } + return isModified; + }, + + insert : function( newChar ) { + if ( null!== this.text) { + var newText = this.text.substr(0 , this.cursorPos) + newChar + this.text.substr( this.cursorPos, this.text.length - this.cursorPos); + this.setText(newText, true); + } else { + this.setText(newChar, true); + } + this.setCursorPos(this.cursorPos+1); + }, + + setCursorPos : function( pos ) { + // console.log("setCursorPos : before " + this.cursorPos); + if ( null=== this.text) { + this.cursorPos = 0; + } else { + if (typeof(pos) === 'undefined' || null ===pos) { + this.cursorPos = this.text.length; + } else { + this.cursorPos = pos; + } + // console.log("setCursorPos : after " + this.cursorPos); + cursorPosx = this.font.stringWidth(this.text.substr(0 , this.cursorPos)); + cursorPoxy = this.font.height / 2; + + if (this.cursorActor != null) { + this.cursorActor.setPosition( cursorPosx , cursorPoxy); + } + } + }, + + + /** + * Set the text to be shown by the actor. + * @param sText a string with the text to be shown. + * @return this + */ + setText : function( sText, keepCursor) { + this.text= sText; + if ( null===this.text || this.text==="" ) { + this.width= this.height= 0; + } + this.calcTextSize( CAAT.director[0] ); + if (typeof(keepCursor) === 'undefined' || !keepCursor) { + this.setCursorPos(); + } + + // TODO ? notification ? + + return this; + }, + /** + * Sets the font to be applied for the text. + * @param font a string with a valid canvas rendering context font description. + * @return this + */ + setFont : function(font) { + + if ( !font ) { + this.setDefaultFont(); + } + + this.font= font; + this.calcTextSize( CAAT.director[0] ); + + // Update cursor to the same font + this.setDefaultCursor(); + + return this; + }, + /** + * Calculates the text dimension in pixels and stores the values in textWidth and textHeight + * attributes. + * If Actor's width and height were not set, the Actor's dimension will be set to these values. + * @return this + */ + calcTextSize : function() { + + if ( typeof this.text==='undefined' || null===this.text || ""===this.text ) { + this.textWidth= 0; + this.textHeight= 0; + return this; + } + + // The font provides stringWidth() + + this.textWidth= this.font.stringWidth(this.text); + this.width= this.textWidth; + + + this.lineHeight = this.font.height; + this.textHeight= this.lineHeight; + this.height= this.textHeight; + + return this; + }, + + /** + * Custom paint method for TextArea instances. + * If the path attribute is set, the text will be drawn traversing the path. + * + * @param director a valid CAAT.Director instance. + * @param time an integer with the Scene time the Actor is being drawn. + */ + paint : function(director, time) { + + CAAT.TextArea.superclass.paint.call(this, director, time ); + + // TextArea can be cached (but not editors) + if ( this.cached ) { + // cacheAsBitmap sets this actor's background image as a representation of itself. + // So if after drawing the background it was cached, we're done. + return; + } + + if ( null===this.text) { + return; + } + + if ( this.textWidth===0 || this.textHeight===0 ) { + this.calcTextSize(director); + } + + var ctx= director.ctx; + + // Is drawing on path useful here ? + if (typeof this.font === 'object') { + return this.drawSpriteText(director,time); + } + }, + + // Ou peut on conserver les méthodes héritées de TextActor? + + /** + * Private. + * Draw the text using a sprited font instead of a canvas font. + * @param director a valid CAAT.Director instance. + * @param time an integer with the Scene time the Actor is being drawn. + */ + drawSpriteText: function(director, time) { + this.font.drawString( director.ctx, this.text, 0, 0); + } + }; + + extend( CAAT.TextArea, CAAT.ActorContainer, null); +})(); + + +(function() { + + /** + * TextInputGroup + * Invisible Container managing the focus of a set of TextAreas + * childrenList order is used for navigation + * focus can also be set programatically + + * @constructor + * @extends CAAT.ActorContainer + * + */ + CAAT.TextInputGroup = function() { + CAAT.TextInputGroup.superclass.constructor.call(this); + + // A singleton is created to store a map between scenes and input groups + if (typeof(CAAT.TextInputGroup.SceneFocusManager) === 'undefined' ) { + CAAT.TextInputGroup.SceneFocusManager = {};// dictionnaire Scene -> TextInputGroup + } + + return this; + }; +///////////////////// +// CAAT.keyListeners= []; +// +// /** +// * Register key events notification function. +// * @param f {function(key {integer}, action {'down'|'up'})} +// */ +// CAAT.registerKeyListener= function(f) { +// CAAT.keyListeners.push(f); +// }; +// +// CAAT.registerKeyListenerIfNeeded= function(f) { +// for( var i=0; i TextInputGroup + CAAT.TextInputGroup.SceneFocusManager[sceneIndex] = this; + + // Key event callback must be defined only once, otherwise key events will be duplicated + CAAT.registerKeyListenerIfNeeded(this.___keyAction.bind(this)); + }, + + registerContentListener: function(listener) { + this.contentListeners.push(listener); + }, + + unregisterContentListener: function(listener) { + for( var i=0; i> 8) & 0xFF, + (num ) & 0xFF ); +}; +Array.prototype.push32 = function (num) { + this.push((num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + (num ) & 0xFF ); +}; + +// IE does not support map (even in IE9) +//This prototype is provided by the Mozilla foundation and +//is distributed under the MIT license. +//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license +if (!Array.prototype.map) +{ + Array.prototype.map = function(fun /*, thisp*/) + { + var len = this.length; + if (typeof fun != "function") + throw new TypeError(); + + var res = new Array(len); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + { + if (i in this) + res[i] = fun.call(thisp, this[i], i, this); + } + + return res; + }; +} + +/* + * ------------------------------------------------------ + * Namespaced in Util + * ------------------------------------------------------ + */ + +/* + * Logging/debug routines + */ + +Util._log_level = 'warn'; +Util.init_logging = function (level) { + if (typeof level === 'undefined') { + level = Util._log_level; + } else { + Util._log_level = level; + } + if (typeof window.console === "undefined") { + if (typeof window.opera !== "undefined") { + window.console = { + 'log' : window.opera.postError, + 'warn' : window.opera.postError, + 'error': window.opera.postError }; + } else { + window.console = { + 'log' : function(m) {}, + 'warn' : function(m) {}, + 'error': function(m) {}}; + } + } + + Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; + switch (level) { + case 'debug': Util.Debug = function (msg) { console.log(msg); }; + case 'info': Util.Info = function (msg) { console.log(msg); }; + case 'warn': Util.Warn = function (msg) { console.warn(msg); }; + case 'error': Util.Error = function (msg) { console.error(msg); }; + case 'none': + break; + default: + throw("invalid logging type '" + level + "'"); + } +}; +Util.get_logging = function () { + return Util._log_level; +}; +// Initialize logging level +Util.init_logging(); + + +// Set configuration default for Crockford style function namespaces +Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) { + var getter, setter; + + // Default getter function + getter = function (idx) { + if ((type in {'arr':1, 'array':1}) && + (typeof idx !== 'undefined')) { + return cfg[v][idx]; + } else { + return cfg[v]; + } + }; + + // Default setter function + setter = function (val, idx) { + if (type in {'boolean':1, 'bool':1}) { + if ((!val) || (val in {'0':1, 'no':1, 'false':1})) { + val = false; + } else { + val = true; + } + } else if (type in {'integer':1, 'int':1}) { + val = parseInt(val, 10); + } else if (type === 'func') { + if (!val) { + val = function () {}; + } + } + if (typeof idx !== 'undefined') { + cfg[v][idx] = val; + } else { + cfg[v] = val; + } + }; + + // Set the description + api[v + '_description'] = desc; + + // Set the getter function + if (typeof api['get_' + v] === 'undefined') { + api['get_' + v] = getter; + } + + // Set the setter function with extra sanity checks + if (typeof api['set_' + v] === 'undefined') { + api['set_' + v] = function (val, idx) { + if (mode in {'RO':1, 'ro':1}) { + throw(v + " is read-only"); + } else if ((mode in {'WO':1, 'wo':1}) && + (typeof cfg[v] !== 'undefined')) { + throw(v + " can only be set once"); + } + setter(val, idx); + }; + } + + // Set the default value + if (typeof defaults[v] !== 'undefined') { + defval = defaults[v]; + } else if ((type in {'arr':1, 'array':1}) && + (! (defval instanceof Array))) { + defval = []; + } + // Coerce existing setting to the right type + //Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]); + setter(defval); +}; + +// Set group of configuration defaults +Util.conf_defaults = function(cfg, api, defaults, arr) { + var i; + for (i = 0; i < arr.length; i++) { + Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1], + arr[i][2], arr[i][3], arr[i][4]); + } +}; + + +/* + * Cross-browser routines + */ + +// Get DOM element position on page +Util.getPosition = function (obj) { + var x = 0, y = 0; + if (obj.offsetParent) { + do { + x += obj.offsetLeft; + y += obj.offsetTop; + obj = obj.offsetParent; + } while (obj); + } + return {'x': x, 'y': y}; +}; + +// Get mouse event position in DOM element +Util.getEventPosition = function (e, obj, scale) { + var evt, docX, docY, pos; + //if (!e) evt = window.event; + evt = (e ? e : window.event); + evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt); + if (evt.pageX || evt.pageY) { + docX = evt.pageX; + docY = evt.pageY; + } else if (evt.clientX || evt.clientY) { + docX = evt.clientX + document.body.scrollLeft + + document.documentElement.scrollLeft; + docY = evt.clientY + document.body.scrollTop + + document.documentElement.scrollTop; + } + pos = Util.getPosition(obj); + if (typeof scale === "undefined") { + scale = 1; + } + return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale}; +}; + + +// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events +Util.addEvent = function (obj, evType, fn){ + if (obj.attachEvent){ + var r = obj.attachEvent("on"+evType, fn); + return r; + } else if (obj.addEventListener){ + obj.addEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be attached"); + } +}; + +Util.removeEvent = function(obj, evType, fn){ + if (obj.detachEvent){ + var r = obj.detachEvent("on"+evType, fn); + return r; + } else if (obj.removeEventListener){ + obj.removeEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be removed"); + } +}; + +Util.stopEvent = function(e) { + if (e.stopPropagation) { e.stopPropagation(); } + else { e.cancelBubble = true; } + + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } +}; + + +// Set browser engine versions. Based on mootools. +Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; + +Util.Engine = { + // Version detection break in Opera 11.60 (errors on arguments.callee.caller reference) + //'presto': (function() { + // return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), + 'presto': (function() { return (!window.opera) ? false : true; }()), + + 'trident': (function() { + return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()), + 'webkit': (function() { + try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), + //'webkit': (function() { + // return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()), + 'gecko': (function() { + return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }()) +}; +if (Util.Engine.webkit) { + // Extract actual webkit version if available + Util.Engine.webkit = (function(v) { + var re = new RegExp('WebKit/([0-9\.]*) '); + v = (navigator.userAgent.match(re) || ['', v])[1]; + return parseFloat(v, 10); + })(Util.Engine.webkit); +} + +Util.Flash = (function(){ + var v, version; + try { + v = navigator.plugins['Shockwave Flash'].description; + } catch(err1) { + try { + v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch(err2) { + v = '0 r0'; + } + } + version = v.match(/\d+/g); + return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; +}()); +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2011 Joel Martin + * Licensed under LGPL-2 or any later version (see LICENSE.txt) + */ + +/*jslint browser: true, white: false, bitwise: false */ +/*global window, Util */ + + +// +// Keyboard event handler +// + +function Keyboard(defaults) { +//"use strict"; + +var that = {}, // Public API methods + conf = {}, // Configuration attributes + + keyDownList = []; // List of depressed keys + // (even if they are happy) + +// Configuration attributes +Util.conf_defaults(conf, that, defaults, [ + ['target', 'wo', 'dom', document, 'DOM element that captures keyboard input'], + ['focused', 'rw', 'bool', true, 'Capture and send key events'], + + ['onKeyPress', 'rw', 'func', null, 'Handler for key press/release'] + ]); + + +// +// Private functions +// + +// From the event keyCode return the keysym value for keys that need +// to be suppressed otherwise they may trigger unintended browser +// actions +function getKeysymSpecial(evt) { + var keysym = null; + + switch ( evt.keyCode ) { + // These generate a keyDown and keyPress in Firefox and Opera + case 8 : keysym = 0xFF08; break; // BACKSPACE + case 13 : keysym = 0xFF0D; break; // ENTER + + // This generates a keyDown and keyPress in Opera + case 9 : keysym = 0xFF09; break; // TAB + default : break; + } + + if (evt.type === 'keydown') { + switch ( evt.keyCode ) { + case 27 : keysym = 0xFF1B; break; // ESCAPE + case 46 : keysym = 0xFFFF; break; // DELETE + + case 36 : keysym = 0xFF50; break; // HOME + case 35 : keysym = 0xFF57; break; // END + case 33 : keysym = 0xFF55; break; // PAGE_UP + case 34 : keysym = 0xFF56; break; // PAGE_DOWN + case 45 : keysym = 0xFF63; break; // INSERT + // '-' during keyPress + case 37 : keysym = 0xFF51; break; // LEFT + case 38 : keysym = 0xFF52; break; // UP + case 39 : keysym = 0xFF53; break; // RIGHT + case 40 : keysym = 0xFF54; break; // DOWN + case 16 : keysym = 0xFFE1; break; // SHIFT + case 17 : keysym = 0xFFE3; break; // CONTROL + //case 18 : keysym = 0xFFE7; break; // Left Meta (Mac Option) + case 18 : keysym = 0xFFE9; break; // Left ALT (Mac Command) + + case 112 : keysym = 0xFFBE; break; // F1 + case 113 : keysym = 0xFFBF; break; // F2 + case 114 : keysym = 0xFFC0; break; // F3 + case 115 : keysym = 0xFFC1; break; // F4 + case 116 : keysym = 0xFFC2; break; // F5 + case 117 : keysym = 0xFFC3; break; // F6 + case 118 : keysym = 0xFFC4; break; // F7 + case 119 : keysym = 0xFFC5; break; // F8 + case 120 : keysym = 0xFFC6; break; // F9 + case 121 : keysym = 0xFFC7; break; // F10 + case 122 : keysym = 0xFFC8; break; // F11 + case 123 : keysym = 0xFFC9; break; // F12 + + default : break; + } + } + + if ((!keysym) && (evt.ctrlKey || evt.altKey)) { + if ((typeof(evt.which) !== "undefined") && (evt.which > 0)) { + keysym = evt.which; + } else { + // IE9 always + // Firefox and Opera when ctrl/alt + special + Util.Warn("which not set, using keyCode"); + keysym = evt.keyCode; + } + + /* Remap symbols */ + switch (keysym) { + case 186 : keysym = 59; break; // ; (IE) + case 187 : keysym = 61; break; // = (IE) + case 188 : keysym = 44; break; // , (Mozilla, IE) + case 109 : // - (Mozilla, Opera) + if (Util.Engine.gecko || Util.Engine.presto) { + keysym = 45; } + break; + case 189 : keysym = 45; break; // - (IE) + case 190 : keysym = 46; break; // . (Mozilla, IE) + case 191 : keysym = 47; break; // / (Mozilla, IE) + case 192 : keysym = 96; break; // ` (Mozilla, IE) + case 219 : keysym = 91; break; // [ (Mozilla, IE) + case 220 : keysym = 92; break; // \ (Mozilla, IE) + case 221 : keysym = 93; break; // ] (Mozilla, IE) + case 222 : keysym = 39; break; // ' (Mozilla, IE) + } + + /* Remap shifted and unshifted keys */ + if (!!evt.shiftKey) { + switch (keysym) { + case 48 : keysym = 41 ; break; // ) (shifted 0) + case 49 : keysym = 33 ; break; // ! (shifted 1) + case 50 : keysym = 64 ; break; // @ (shifted 2) + case 51 : keysym = 35 ; break; // # (shifted 3) + case 52 : keysym = 36 ; break; // $ (shifted 4) + case 53 : keysym = 37 ; break; // % (shifted 5) + case 54 : keysym = 94 ; break; // ^ (shifted 6) + case 55 : keysym = 38 ; break; // & (shifted 7) + case 56 : keysym = 42 ; break; // * (shifted 8) + case 57 : keysym = 40 ; break; // ( (shifted 9) + + case 59 : keysym = 58 ; break; // : (shifted `) + case 61 : keysym = 43 ; break; // + (shifted ;) + case 44 : keysym = 60 ; break; // < (shifted ,) + case 45 : keysym = 95 ; break; // _ (shifted -) + case 46 : keysym = 62 ; break; // > (shifted .) + case 47 : keysym = 63 ; break; // ? (shifted /) + case 96 : keysym = 126; break; // ~ (shifted `) + case 91 : keysym = 123; break; // { (shifted [) + case 92 : keysym = 124; break; // | (shifted \) + case 93 : keysym = 125; break; // } (shifted ]) + case 39 : keysym = 34 ; break; // " (shifted ') + } + } else if ((keysym >= 65) && (keysym <=90)) { + /* Remap unshifted A-Z */ + keysym += 32; + } else if (evt.keyLocation === 3) { + // numpad keys + switch (keysym) { + case 96 : keysym = 48; break; // 0 + case 97 : keysym = 49; break; // 1 + case 98 : keysym = 50; break; // 2 + case 99 : keysym = 51; break; // 3 + case 100: keysym = 52; break; // 4 + case 101: keysym = 53; break; // 5 + case 102: keysym = 54; break; // 6 + case 103: keysym = 55; break; // 7 + case 104: keysym = 56; break; // 8 + case 105: keysym = 57; break; // 9 + case 109: keysym = 45; break; // - + case 110: keysym = 46; break; // . + case 111: keysym = 47; break; // / + } + } + } + + return keysym; +} + +/* Translate DOM keyPress event to keysym value */ +function getKeysym(evt) { + var keysym, msg; + + if (typeof(evt.which) !== "undefined") { + // WebKit, Firefox, Opera + keysym = evt.which; + } else { + // IE9 + Util.Warn("which not set, using keyCode"); + keysym = evt.keyCode; + } + + if ((keysym > 255) && (keysym < 0xFF00)) { + msg = "Mapping character code " + keysym; + // Map Unicode outside Latin 1 to X11 keysyms + keysym = unicodeTable[keysym]; + if (typeof(keysym) === 'undefined') { + keysym = 0; + } + Util.Debug(msg + " to " + keysym); + } + + return keysym; +} + +function show_keyDownList(kind) { + var c; + var msg = "keyDownList (" + kind + "):\n"; + for (c = 0; c < keyDownList.length; c++) { + msg = msg + " " + c + " - keyCode: " + keyDownList[c].keyCode + + " - which: " + keyDownList[c].which + "\n"; + } + Util.Debug(msg); +} + +function copyKeyEvent(evt) { + var members = ['type', 'keyCode', 'charCode', 'which', + 'altKey', 'ctrlKey', 'shiftKey', + 'keyLocation', 'keyIdentifier'], i, obj = {}; + for (i = 0; i < members.length; i++) { + if (typeof(evt[members[i]]) !== "undefined") { + obj[members[i]] = evt[members[i]]; + } + } + return obj; +} + +function pushKeyEvent(fevt) { + keyDownList.push(fevt); +} + +function getKeyEvent(keyCode, pop) { + var i, fevt = null; + for (i = keyDownList.length-1; i >= 0; i--) { + if (keyDownList[i].keyCode === keyCode) { + if ((typeof(pop) !== "undefined") && (pop)) { + fevt = keyDownList.splice(i, 1)[0]; + } else { + fevt = keyDownList[i]; + } + break; + } + } + return fevt; +} + +function ignoreKeyEvent(evt) { + // Blarg. Some keys have a different keyCode on keyDown vs keyUp + if (evt.keyCode === 229) { + // French AZERTY keyboard dead key. + // Lame thing is that the respective keyUp is 219 so we can't + // properly ignore the keyUp event + return true; + } + return false; +} + + +// +// Key Event Handling: +// +// There are several challenges when dealing with key events: +// - The meaning and use of keyCode, charCode and which depends on +// both the browser and the event type (keyDown/Up vs keyPress). +// - We cannot automatically determine the keyboard layout +// - The keyDown and keyUp events have a keyCode value that has not +// been translated by modifier keys. +// - The keyPress event has a translated (for layout and modifiers) +// character code but the attribute containing it differs. keyCode +// contains the translated value in WebKit (Chrome/Safari), Opera +// 11 and IE9. charCode contains the value in WebKit and Firefox. +// The which attribute contains the value on WebKit, Firefox and +// Opera 11. +// - The keyDown/Up keyCode value indicates (sort of) the physical +// key was pressed but only for standard US layout. On a US +// keyboard, the '-' and '_' characters are on the same key and +// generate a keyCode value of 189. But on an AZERTY keyboard even +// though they are different physical keys they both still +// generate a keyCode of 189! +// - To prevent a key event from propagating to the browser and +// causing unwanted default actions (such as closing a tab, +// opening a menu, shifting focus, etc) we must suppress this +// event in both keyDown and keyPress because not all key strokes +// generate on a keyPress event. Also, in WebKit and IE9 +// suppressing the keyDown prevents a keyPress but other browsers +// still generated a keyPress even if keyDown is suppressed. +// +// For safe key events, we wait until the keyPress event before +// reporting a key down event. For unsafe key events, we report a key +// down event when the keyDown event fires and we suppress any further +// actions (including keyPress). +// +// In order to report a key up event that matches what we reported +// for the key down event, we keep a list of keys that are currently +// down. When the keyDown event happens, we add the key event to the +// list. If it is a safe key event, then we update the which attribute +// in the most recent item on the list when we received a keyPress +// event (keyPress should immediately follow keyDown). When we +// received a keyUp event we search for the event on the list with +// a matching keyCode and we report the character code using the value +// in the 'which' attribute that was stored with that key. +// + +function onKeyDown(e) { + if (! conf.focused) { + return true; + } + var fevt = null, evt = (e ? e : window.event), + keysym = null, suppress = false; + //Util.Debug("onKeyDown kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + fevt = copyKeyEvent(evt); + + keysym = getKeysymSpecial(evt); + // Save keysym decoding for use in keyUp + fevt.keysym = keysym; + if (keysym) { + // If it is a key or key combination that might trigger + // browser behaviors or it has no corresponding keyPress + // event, then send it immediately + if (conf.onKeyPress && !ignoreKeyEvent(evt)) { + Util.Debug("onKeyPress down, keysym: " + keysym + + " (onKeyDown key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 1, evt); + } + suppress = true; + } + + if (! ignoreKeyEvent(evt)) { + // Add it to the list of depressed keys + pushKeyEvent(fevt); + //show_keyDownList('down'); + } + + if (suppress) { + // Suppress bubbling/default actions + Util.stopEvent(e); + return false; + } else { + // Allow the event to bubble and become a keyPress event which + // will have the character code translated + return true; + } +} + +function onKeyPress(e) { + if (! conf.focused) { + return true; + } + var evt = (e ? e : window.event), + kdlen = keyDownList.length, keysym = null; + //Util.Debug("onKeyPress kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + if (((evt.which !== "undefined") && (evt.which === 0)) || + (getKeysymSpecial(evt))) { + // Firefox and Opera generate a keyPress event even if keyDown + // is suppressed. But the keys we want to suppress will have + // either: + // - the which attribute set to 0 + // - getKeysymSpecial() will identify it + Util.Debug("Ignoring special key in keyPress"); + Util.stopEvent(e); + return false; + } + + keysym = getKeysym(evt); + + // Modify the the which attribute in the depressed keys list so + // that the keyUp event will be able to have the character code + // translation available. + if (kdlen > 0) { + keyDownList[kdlen-1].keysym = keysym; + } else { + Util.Warn("keyDownList empty when keyPress triggered"); + } + + //show_keyDownList('press'); + + // Send the translated keysym + if (conf.onKeyPress && (keysym > 0)) { + Util.Debug("onKeyPress down, keysym: " + keysym + + " (onKeyPress key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 1, evt); + } + + // Stop keypress events just in case + Util.stopEvent(e); + return false; +} + +function onKeyUp(e) { + if (! conf.focused) { + return true; + } + var fevt = null, evt = (e ? e : window.event), keysym; + //Util.Debug("onKeyUp kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); + + fevt = getKeyEvent(evt.keyCode, true); + + if (fevt) { + keysym = fevt.keysym; + } else { + Util.Warn("Key event (keyCode = " + evt.keyCode + + ") not found on keyDownList"); + keysym = 0; + } + + //show_keyDownList('up'); + + if (conf.onKeyPress && (keysym > 0)) { + //Util.Debug("keyPress up, keysym: " + keysym + + // " (key: " + evt.keyCode + ", which: " + evt.which + ")"); + Util.Debug("onKeyPress up, keysym: " + keysym + + " (onKeyPress key: " + evt.keyCode + + ", which: " + evt.which + ")"); + conf.onKeyPress(keysym, 0, evt); + } + Util.stopEvent(e); + return false; +} + +// +// Public API interface functions +// + +that.grab = function() { + //Util.Debug(">> Keyboard.grab"); + var c = conf.target; + + Util.addEvent(c, 'keydown', onKeyDown); + Util.addEvent(c, 'keyup', onKeyUp); + Util.addEvent(c, 'keypress', onKeyPress); + + //Util.Debug("<< Keyboard.grab"); +}; + +that.ungrab = function() { + //Util.Debug(">> Keyboard.ungrab"); + var c = conf.target; + + Util.removeEvent(c, 'keydown', onKeyDown); + Util.removeEvent(c, 'keyup', onKeyUp); + Util.removeEvent(c, 'keypress', onKeyPress); + + //Util.Debug(">> Keyboard.ungrab"); +}; + +return that; // Return the public API interface + +} // End of Keyboard() + + +// +// Mouse event handler +// + +function Mouse(defaults) { +//"use strict"; + +var that = {}, // Public API methods + conf = {}; // Configuration attributes + +// Configuration attributes +Util.conf_defaults(conf, that, defaults, [ + ['target', 'ro', 'dom', document, 'DOM element that captures mouse input'], + ['focused', 'rw', 'bool', true, 'Capture and send mouse clicks/movement'], + ['scale', 'rw', 'float', 1.0, 'Viewport scale factor 0.0 - 1.0'], + + ['onMouseButton', 'rw', 'func', null, 'Handler for mouse button click/release'], + ['onMouseMove', 'rw', 'func', null, 'Handler for mouse movement'], + ['touchButton', 'rw', 'int', 1, 'Button mask (1, 2, 4) for touch devices (0 means ignore clicks)'] + ]); + + +// +// Private functions +// + +function onMouseButton(e, down) { + var evt, pos, bmask; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + if (e.touches || e.changedTouches) { + // Touch device + bmask = conf.touchButton; + // If bmask is set + } else if (evt.which) { + /* everything except IE */ + bmask = 1 << evt.button; + } else { + /* IE including 9 */ + bmask = (evt.button & 0x1) + // Left + (evt.button & 0x2) * 2 + // Right + (evt.button & 0x4) / 2; // Middle + } + //Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down + + // " bmask: " + bmask + "(evt.button: " + evt.button + ")"); + if (bmask > 0 && conf.onMouseButton) { + Util.Debug("onMouseButton " + (down ? "down" : "up") + + ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); + conf.onMouseButton(pos.x, pos.y, down, bmask); + } + Util.stopEvent(e); + return false; +} + +function onMouseDown(e) { + onMouseButton(e, 1); +} + +function onMouseUp(e) { + onMouseButton(e, 0); +} + +function onMouseWheel(e) { + var evt, pos, bmask, wheelData; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40; + if (wheelData > 0) { + bmask = 1 << 3; + } else { + bmask = 1 << 4; + } + //Util.Debug('mouse scroll by ' + wheelData + ':' + pos.x + "," + pos.y); + if (conf.onMouseButton) { + conf.onMouseButton(pos.x, pos.y, 1, bmask); + conf.onMouseButton(pos.x, pos.y, 0, bmask); + } + Util.stopEvent(e); + return false; +} + +function onMouseMove(e) { + var evt, pos; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + //Util.Debug('mouse ' + evt.which + '/' + evt.button + ' up:' + pos.x + "," + pos.y); + if (conf.onMouseMove) { + conf.onMouseMove(pos.x, pos.y); + } + Util.stopEvent(e); + return false; +} + +function onMouseDisable(e) { + var evt, pos; + if (! conf.focused) { + return true; + } + evt = (e ? e : window.event); + pos = Util.getEventPosition(e, conf.target, conf.scale); + /* Stop propagation if inside canvas area */ + if ((pos.x >= 0) && (pos.y >= 0) && + (pos.x < conf.target.offsetWidth) && + (pos.y < conf.target.offsetHeight)) { + //Util.Debug("mouse event disabled"); + Util.stopEvent(e); + return false; + } + //Util.Debug("mouse event not disabled"); + return true; +} + +// +// Public API interface functions +// + +that.grab = function() { + //Util.Debug(">> Mouse.grab"); + var c = conf.target; + + if ('ontouchstart' in document.documentElement) { + Util.addEvent(c, 'touchstart', onMouseDown); + Util.addEvent(c, 'touchend', onMouseUp); + Util.addEvent(c, 'touchmove', onMouseMove); + } else { + Util.addEvent(c, 'mousedown', onMouseDown); + Util.addEvent(c, 'mouseup', onMouseUp); + Util.addEvent(c, 'mousemove', onMouseMove); + Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } + + /* Work around right and middle click browser behaviors */ + Util.addEvent(document, 'click', onMouseDisable); + Util.addEvent(document.body, 'contextmenu', onMouseDisable); + + //Util.Debug("<< Mouse.grab"); +}; + +that.ungrab = function() { + //Util.Debug(">> Mouse.ungrab"); + var c = conf.target; + + if ('ontouchstart' in document.documentElement) { + Util.removeEvent(c, 'touchstart', onMouseDown); + Util.removeEvent(c, 'touchend', onMouseUp); + Util.removeEvent(c, 'touchmove', onMouseMove); + } else { + Util.removeEvent(c, 'mousedown', onMouseDown); + Util.removeEvent(c, 'mouseup', onMouseUp); + Util.removeEvent(c, 'mousemove', onMouseMove); + Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } + + /* Work around right and middle click browser behaviors */ + Util.removeEvent(document, 'click', onMouseDisable); + Util.removeEvent(document.body, 'contextmenu', onMouseDisable); + + //Util.Debug(">> Mouse.ungrab"); +}; + +return that; // Return the public API interface + +} // End of Mouse() + + +/* + * Browser keypress to X11 keysym for Unicode characters > U+00FF + */ +unicodeTable = { + 0x0104 : 0x01a1, + 0x02D8 : 0x01a2, + 0x0141 : 0x01a3, + 0x013D : 0x01a5, + 0x015A : 0x01a6, + 0x0160 : 0x01a9, + 0x015E : 0x01aa, + 0x0164 : 0x01ab, + 0x0179 : 0x01ac, + 0x017D : 0x01ae, + 0x017B : 0x01af, + 0x0105 : 0x01b1, + 0x02DB : 0x01b2, + 0x0142 : 0x01b3, + 0x013E : 0x01b5, + 0x015B : 0x01b6, + 0x02C7 : 0x01b7, + 0x0161 : 0x01b9, + 0x015F : 0x01ba, + 0x0165 : 0x01bb, + 0x017A : 0x01bc, + 0x02DD : 0x01bd, + 0x017E : 0x01be, + 0x017C : 0x01bf, + 0x0154 : 0x01c0, + 0x0102 : 0x01c3, + 0x0139 : 0x01c5, + 0x0106 : 0x01c6, + 0x010C : 0x01c8, + 0x0118 : 0x01ca, + 0x011A : 0x01cc, + 0x010E : 0x01cf, + 0x0110 : 0x01d0, + 0x0143 : 0x01d1, + 0x0147 : 0x01d2, + 0x0150 : 0x01d5, + 0x0158 : 0x01d8, + 0x016E : 0x01d9, + 0x0170 : 0x01db, + 0x0162 : 0x01de, + 0x0155 : 0x01e0, + 0x0103 : 0x01e3, + 0x013A : 0x01e5, + 0x0107 : 0x01e6, + 0x010D : 0x01e8, + 0x0119 : 0x01ea, + 0x011B : 0x01ec, + 0x010F : 0x01ef, + 0x0111 : 0x01f0, + 0x0144 : 0x01f1, + 0x0148 : 0x01f2, + 0x0151 : 0x01f5, + 0x0171 : 0x01fb, + 0x0159 : 0x01f8, + 0x016F : 0x01f9, + 0x0163 : 0x01fe, + 0x02D9 : 0x01ff, + 0x0126 : 0x02a1, + 0x0124 : 0x02a6, + 0x0130 : 0x02a9, + 0x011E : 0x02ab, + 0x0134 : 0x02ac, + 0x0127 : 0x02b1, + 0x0125 : 0x02b6, + 0x0131 : 0x02b9, + 0x011F : 0x02bb, + 0x0135 : 0x02bc, + 0x010A : 0x02c5, + 0x0108 : 0x02c6, + 0x0120 : 0x02d5, + 0x011C : 0x02d8, + 0x016C : 0x02dd, + 0x015C : 0x02de, + 0x010B : 0x02e5, + 0x0109 : 0x02e6, + 0x0121 : 0x02f5, + 0x011D : 0x02f8, + 0x016D : 0x02fd, + 0x015D : 0x02fe, + 0x0138 : 0x03a2, + 0x0156 : 0x03a3, + 0x0128 : 0x03a5, + 0x013B : 0x03a6, + 0x0112 : 0x03aa, + 0x0122 : 0x03ab, + 0x0166 : 0x03ac, + 0x0157 : 0x03b3, + 0x0129 : 0x03b5, + 0x013C : 0x03b6, + 0x0113 : 0x03ba, + 0x0123 : 0x03bb, + 0x0167 : 0x03bc, + 0x014A : 0x03bd, + 0x014B : 0x03bf, + 0x0100 : 0x03c0, + 0x012E : 0x03c7, + 0x0116 : 0x03cc, + 0x012A : 0x03cf, + 0x0145 : 0x03d1, + 0x014C : 0x03d2, + 0x0136 : 0x03d3, + 0x0172 : 0x03d9, + 0x0168 : 0x03dd, + 0x016A : 0x03de, + 0x0101 : 0x03e0, + 0x012F : 0x03e7, + 0x0117 : 0x03ec, + 0x012B : 0x03ef, + 0x0146 : 0x03f1, + 0x014D : 0x03f2, + 0x0137 : 0x03f3, + 0x0173 : 0x03f9, + 0x0169 : 0x03fd, + 0x016B : 0x03fe, + 0x1E02 : 0x1001e02, + 0x1E03 : 0x1001e03, + 0x1E0A : 0x1001e0a, + 0x1E80 : 0x1001e80, + 0x1E82 : 0x1001e82, + 0x1E0B : 0x1001e0b, + 0x1EF2 : 0x1001ef2, + 0x1E1E : 0x1001e1e, + 0x1E1F : 0x1001e1f, + 0x1E40 : 0x1001e40, + 0x1E41 : 0x1001e41, + 0x1E56 : 0x1001e56, + 0x1E81 : 0x1001e81, + 0x1E57 : 0x1001e57, + 0x1E83 : 0x1001e83, + 0x1E60 : 0x1001e60, + 0x1EF3 : 0x1001ef3, + 0x1E84 : 0x1001e84, + 0x1E85 : 0x1001e85, + 0x1E61 : 0x1001e61, + 0x0174 : 0x1000174, + 0x1E6A : 0x1001e6a, + 0x0176 : 0x1000176, + 0x0175 : 0x1000175, + 0x1E6B : 0x1001e6b, + 0x0177 : 0x1000177, + 0x0152 : 0x13bc, + 0x0153 : 0x13bd, + 0x0178 : 0x13be, + 0x203E : 0x047e, + 0x3002 : 0x04a1, + 0x300C : 0x04a2, + 0x300D : 0x04a3, + 0x3001 : 0x04a4, + 0x30FB : 0x04a5, + 0x30F2 : 0x04a6, + 0x30A1 : 0x04a7, + 0x30A3 : 0x04a8, + 0x30A5 : 0x04a9, + 0x30A7 : 0x04aa, + 0x30A9 : 0x04ab, + 0x30E3 : 0x04ac, + 0x30E5 : 0x04ad, + 0x30E7 : 0x04ae, + 0x30C3 : 0x04af, + 0x30FC : 0x04b0, + 0x30A2 : 0x04b1, + 0x30A4 : 0x04b2, + 0x30A6 : 0x04b3, + 0x30A8 : 0x04b4, + 0x30AA : 0x04b5, + 0x30AB : 0x04b6, + 0x30AD : 0x04b7, + 0x30AF : 0x04b8, + 0x30B1 : 0x04b9, + 0x30B3 : 0x04ba, + 0x30B5 : 0x04bb, + 0x30B7 : 0x04bc, + 0x30B9 : 0x04bd, + 0x30BB : 0x04be, + 0x30BD : 0x04bf, + 0x30BF : 0x04c0, + 0x30C1 : 0x04c1, + 0x30C4 : 0x04c2, + 0x30C6 : 0x04c3, + 0x30C8 : 0x04c4, + 0x30CA : 0x04c5, + 0x30CB : 0x04c6, + 0x30CC : 0x04c7, + 0x30CD : 0x04c8, + 0x30CE : 0x04c9, + 0x30CF : 0x04ca, + 0x30D2 : 0x04cb, + 0x30D5 : 0x04cc, + 0x30D8 : 0x04cd, + 0x30DB : 0x04ce, + 0x30DE : 0x04cf, + 0x30DF : 0x04d0, + 0x30E0 : 0x04d1, + 0x30E1 : 0x04d2, + 0x30E2 : 0x04d3, + 0x30E4 : 0x04d4, + 0x30E6 : 0x04d5, + 0x30E8 : 0x04d6, + 0x30E9 : 0x04d7, + 0x30EA : 0x04d8, + 0x30EB : 0x04d9, + 0x30EC : 0x04da, + 0x30ED : 0x04db, + 0x30EF : 0x04dc, + 0x30F3 : 0x04dd, + 0x309B : 0x04de, + 0x309C : 0x04df, + 0x06F0 : 0x10006f0, + 0x06F1 : 0x10006f1, + 0x06F2 : 0x10006f2, + 0x06F3 : 0x10006f3, + 0x06F4 : 0x10006f4, + 0x06F5 : 0x10006f5, + 0x06F6 : 0x10006f6, + 0x06F7 : 0x10006f7, + 0x06F8 : 0x10006f8, + 0x06F9 : 0x10006f9, + 0x066A : 0x100066a, + 0x0670 : 0x1000670, + 0x0679 : 0x1000679, + 0x067E : 0x100067e, + 0x0686 : 0x1000686, + 0x0688 : 0x1000688, + 0x0691 : 0x1000691, + 0x060C : 0x05ac, + 0x06D4 : 0x10006d4, + 0x0660 : 0x1000660, + 0x0661 : 0x1000661, + 0x0662 : 0x1000662, + 0x0663 : 0x1000663, + 0x0664 : 0x1000664, + 0x0665 : 0x1000665, + 0x0666 : 0x1000666, + 0x0667 : 0x1000667, + 0x0668 : 0x1000668, + 0x0669 : 0x1000669, + 0x061B : 0x05bb, + 0x061F : 0x05bf, + 0x0621 : 0x05c1, + 0x0622 : 0x05c2, + 0x0623 : 0x05c3, + 0x0624 : 0x05c4, + 0x0625 : 0x05c5, + 0x0626 : 0x05c6, + 0x0627 : 0x05c7, + 0x0628 : 0x05c8, + 0x0629 : 0x05c9, + 0x062A : 0x05ca, + 0x062B : 0x05cb, + 0x062C : 0x05cc, + 0x062D : 0x05cd, + 0x062E : 0x05ce, + 0x062F : 0x05cf, + 0x0630 : 0x05d0, + 0x0631 : 0x05d1, + 0x0632 : 0x05d2, + 0x0633 : 0x05d3, + 0x0634 : 0x05d4, + 0x0635 : 0x05d5, + 0x0636 : 0x05d6, + 0x0637 : 0x05d7, + 0x0638 : 0x05d8, + 0x0639 : 0x05d9, + 0x063A : 0x05da, + 0x0640 : 0x05e0, + 0x0641 : 0x05e1, + 0x0642 : 0x05e2, + 0x0643 : 0x05e3, + 0x0644 : 0x05e4, + 0x0645 : 0x05e5, + 0x0646 : 0x05e6, + 0x0647 : 0x05e7, + 0x0648 : 0x05e8, + 0x0649 : 0x05e9, + 0x064A : 0x05ea, + 0x064B : 0x05eb, + 0x064C : 0x05ec, + 0x064D : 0x05ed, + 0x064E : 0x05ee, + 0x064F : 0x05ef, + 0x0650 : 0x05f0, + 0x0651 : 0x05f1, + 0x0652 : 0x05f2, + 0x0653 : 0x1000653, + 0x0654 : 0x1000654, + 0x0655 : 0x1000655, + 0x0698 : 0x1000698, + 0x06A4 : 0x10006a4, + 0x06A9 : 0x10006a9, + 0x06AF : 0x10006af, + 0x06BA : 0x10006ba, + 0x06BE : 0x10006be, + 0x06CC : 0x10006cc, + 0x06D2 : 0x10006d2, + 0x06C1 : 0x10006c1, + 0x0492 : 0x1000492, + 0x0493 : 0x1000493, + 0x0496 : 0x1000496, + 0x0497 : 0x1000497, + 0x049A : 0x100049a, + 0x049B : 0x100049b, + 0x049C : 0x100049c, + 0x049D : 0x100049d, + 0x04A2 : 0x10004a2, + 0x04A3 : 0x10004a3, + 0x04AE : 0x10004ae, + 0x04AF : 0x10004af, + 0x04B0 : 0x10004b0, + 0x04B1 : 0x10004b1, + 0x04B2 : 0x10004b2, + 0x04B3 : 0x10004b3, + 0x04B6 : 0x10004b6, + 0x04B7 : 0x10004b7, + 0x04B8 : 0x10004b8, + 0x04B9 : 0x10004b9, + 0x04BA : 0x10004ba, + 0x04BB : 0x10004bb, + 0x04D8 : 0x10004d8, + 0x04D9 : 0x10004d9, + 0x04E2 : 0x10004e2, + 0x04E3 : 0x10004e3, + 0x04E8 : 0x10004e8, + 0x04E9 : 0x10004e9, + 0x04EE : 0x10004ee, + 0x04EF : 0x10004ef, + 0x0452 : 0x06a1, + 0x0453 : 0x06a2, + 0x0451 : 0x06a3, + 0x0454 : 0x06a4, + 0x0455 : 0x06a5, + 0x0456 : 0x06a6, + 0x0457 : 0x06a7, + 0x0458 : 0x06a8, + 0x0459 : 0x06a9, + 0x045A : 0x06aa, + 0x045B : 0x06ab, + 0x045C : 0x06ac, + 0x0491 : 0x06ad, + 0x045E : 0x06ae, + 0x045F : 0x06af, + 0x2116 : 0x06b0, + 0x0402 : 0x06b1, + 0x0403 : 0x06b2, + 0x0401 : 0x06b3, + 0x0404 : 0x06b4, + 0x0405 : 0x06b5, + 0x0406 : 0x06b6, + 0x0407 : 0x06b7, + 0x0408 : 0x06b8, + 0x0409 : 0x06b9, + 0x040A : 0x06ba, + 0x040B : 0x06bb, + 0x040C : 0x06bc, + 0x0490 : 0x06bd, + 0x040E : 0x06be, + 0x040F : 0x06bf, + 0x044E : 0x06c0, + 0x0430 : 0x06c1, + 0x0431 : 0x06c2, + 0x0446 : 0x06c3, + 0x0434 : 0x06c4, + 0x0435 : 0x06c5, + 0x0444 : 0x06c6, + 0x0433 : 0x06c7, + 0x0445 : 0x06c8, + 0x0438 : 0x06c9, + 0x0439 : 0x06ca, + 0x043A : 0x06cb, + 0x043B : 0x06cc, + 0x043C : 0x06cd, + 0x043D : 0x06ce, + 0x043E : 0x06cf, + 0x043F : 0x06d0, + 0x044F : 0x06d1, + 0x0440 : 0x06d2, + 0x0441 : 0x06d3, + 0x0442 : 0x06d4, + 0x0443 : 0x06d5, + 0x0436 : 0x06d6, + 0x0432 : 0x06d7, + 0x044C : 0x06d8, + 0x044B : 0x06d9, + 0x0437 : 0x06da, + 0x0448 : 0x06db, + 0x044D : 0x06dc, + 0x0449 : 0x06dd, + 0x0447 : 0x06de, + 0x044A : 0x06df, + 0x042E : 0x06e0, + 0x0410 : 0x06e1, + 0x0411 : 0x06e2, + 0x0426 : 0x06e3, + 0x0414 : 0x06e4, + 0x0415 : 0x06e5, + 0x0424 : 0x06e6, + 0x0413 : 0x06e7, + 0x0425 : 0x06e8, + 0x0418 : 0x06e9, + 0x0419 : 0x06ea, + 0x041A : 0x06eb, + 0x041B : 0x06ec, + 0x041C : 0x06ed, + 0x041D : 0x06ee, + 0x041E : 0x06ef, + 0x041F : 0x06f0, + 0x042F : 0x06f1, + 0x0420 : 0x06f2, + 0x0421 : 0x06f3, + 0x0422 : 0x06f4, + 0x0423 : 0x06f5, + 0x0416 : 0x06f6, + 0x0412 : 0x06f7, + 0x042C : 0x06f8, + 0x042B : 0x06f9, + 0x0417 : 0x06fa, + 0x0428 : 0x06fb, + 0x042D : 0x06fc, + 0x0429 : 0x06fd, + 0x0427 : 0x06fe, + 0x042A : 0x06ff, + 0x0386 : 0x07a1, + 0x0388 : 0x07a2, + 0x0389 : 0x07a3, + 0x038A : 0x07a4, + 0x03AA : 0x07a5, + 0x038C : 0x07a7, + 0x038E : 0x07a8, + 0x03AB : 0x07a9, + 0x038F : 0x07ab, + 0x0385 : 0x07ae, + 0x2015 : 0x07af, + 0x03AC : 0x07b1, + 0x03AD : 0x07b2, + 0x03AE : 0x07b3, + 0x03AF : 0x07b4, + 0x03CA : 0x07b5, + 0x0390 : 0x07b6, + 0x03CC : 0x07b7, + 0x03CD : 0x07b8, + 0x03CB : 0x07b9, + 0x03B0 : 0x07ba, + 0x03CE : 0x07bb, + 0x0391 : 0x07c1, + 0x0392 : 0x07c2, + 0x0393 : 0x07c3, + 0x0394 : 0x07c4, + 0x0395 : 0x07c5, + 0x0396 : 0x07c6, + 0x0397 : 0x07c7, + 0x0398 : 0x07c8, + 0x0399 : 0x07c9, + 0x039A : 0x07ca, + 0x039B : 0x07cb, + 0x039C : 0x07cc, + 0x039D : 0x07cd, + 0x039E : 0x07ce, + 0x039F : 0x07cf, + 0x03A0 : 0x07d0, + 0x03A1 : 0x07d1, + 0x03A3 : 0x07d2, + 0x03A4 : 0x07d4, + 0x03A5 : 0x07d5, + 0x03A6 : 0x07d6, + 0x03A7 : 0x07d7, + 0x03A8 : 0x07d8, + 0x03A9 : 0x07d9, + 0x03B1 : 0x07e1, + 0x03B2 : 0x07e2, + 0x03B3 : 0x07e3, + 0x03B4 : 0x07e4, + 0x03B5 : 0x07e5, + 0x03B6 : 0x07e6, + 0x03B7 : 0x07e7, + 0x03B8 : 0x07e8, + 0x03B9 : 0x07e9, + 0x03BA : 0x07ea, + 0x03BB : 0x07eb, + 0x03BC : 0x07ec, + 0x03BD : 0x07ed, + 0x03BE : 0x07ee, + 0x03BF : 0x07ef, + 0x03C0 : 0x07f0, + 0x03C1 : 0x07f1, + 0x03C3 : 0x07f2, + 0x03C2 : 0x07f3, + 0x03C4 : 0x07f4, + 0x03C5 : 0x07f5, + 0x03C6 : 0x07f6, + 0x03C7 : 0x07f7, + 0x03C8 : 0x07f8, + 0x03C9 : 0x07f9, + 0x23B7 : 0x08a1, + 0x2320 : 0x08a4, + 0x2321 : 0x08a5, + 0x23A1 : 0x08a7, + 0x23A3 : 0x08a8, + 0x23A4 : 0x08a9, + 0x23A6 : 0x08aa, + 0x239B : 0x08ab, + 0x239D : 0x08ac, + 0x239E : 0x08ad, + 0x23A0 : 0x08ae, + 0x23A8 : 0x08af, + 0x23AC : 0x08b0, + 0x2264 : 0x08bc, + 0x2260 : 0x08bd, + 0x2265 : 0x08be, + 0x222B : 0x08bf, + 0x2234 : 0x08c0, + 0x221D : 0x08c1, + 0x221E : 0x08c2, + 0x2207 : 0x08c5, + 0x223C : 0x08c8, + 0x2243 : 0x08c9, + 0x21D4 : 0x08cd, + 0x21D2 : 0x08ce, + 0x2261 : 0x08cf, + 0x221A : 0x08d6, + 0x2282 : 0x08da, + 0x2283 : 0x08db, + 0x2229 : 0x08dc, + 0x222A : 0x08dd, + 0x2227 : 0x08de, + 0x2228 : 0x08df, + 0x2202 : 0x08ef, + 0x0192 : 0x08f6, + 0x2190 : 0x08fb, + 0x2191 : 0x08fc, + 0x2192 : 0x08fd, + 0x2193 : 0x08fe, + 0x25C6 : 0x09e0, + 0x2592 : 0x09e1, + 0x2409 : 0x09e2, + 0x240C : 0x09e3, + 0x240D : 0x09e4, + 0x240A : 0x09e5, + 0x2424 : 0x09e8, + 0x240B : 0x09e9, + 0x2518 : 0x09ea, + 0x2510 : 0x09eb, + 0x250C : 0x09ec, + 0x2514 : 0x09ed, + 0x253C : 0x09ee, + 0x23BA : 0x09ef, + 0x23BB : 0x09f0, + 0x2500 : 0x09f1, + 0x23BC : 0x09f2, + 0x23BD : 0x09f3, + 0x251C : 0x09f4, + 0x2524 : 0x09f5, + 0x2534 : 0x09f6, + 0x252C : 0x09f7, + 0x2502 : 0x09f8, + 0x2003 : 0x0aa1, + 0x2002 : 0x0aa2, + 0x2004 : 0x0aa3, + 0x2005 : 0x0aa4, + 0x2007 : 0x0aa5, + 0x2008 : 0x0aa6, + 0x2009 : 0x0aa7, + 0x200A : 0x0aa8, + 0x2014 : 0x0aa9, + 0x2013 : 0x0aaa, + 0x2026 : 0x0aae, + 0x2025 : 0x0aaf, + 0x2153 : 0x0ab0, + 0x2154 : 0x0ab1, + 0x2155 : 0x0ab2, + 0x2156 : 0x0ab3, + 0x2157 : 0x0ab4, + 0x2158 : 0x0ab5, + 0x2159 : 0x0ab6, + 0x215A : 0x0ab7, + 0x2105 : 0x0ab8, + 0x2012 : 0x0abb, + 0x215B : 0x0ac3, + 0x215C : 0x0ac4, + 0x215D : 0x0ac5, + 0x215E : 0x0ac6, + 0x2122 : 0x0ac9, + 0x2018 : 0x0ad0, + 0x2019 : 0x0ad1, + 0x201C : 0x0ad2, + 0x201D : 0x0ad3, + 0x211E : 0x0ad4, + 0x2032 : 0x0ad6, + 0x2033 : 0x0ad7, + 0x271D : 0x0ad9, + 0x2663 : 0x0aec, + 0x2666 : 0x0aed, + 0x2665 : 0x0aee, + 0x2720 : 0x0af0, + 0x2020 : 0x0af1, + 0x2021 : 0x0af2, + 0x2713 : 0x0af3, + 0x2717 : 0x0af4, + 0x266F : 0x0af5, + 0x266D : 0x0af6, + 0x2642 : 0x0af7, + 0x2640 : 0x0af8, + 0x260E : 0x0af9, + 0x2315 : 0x0afa, + 0x2117 : 0x0afb, + 0x2038 : 0x0afc, + 0x201A : 0x0afd, + 0x201E : 0x0afe, + 0x22A4 : 0x0bc2, + 0x230A : 0x0bc4, + 0x2218 : 0x0bca, + 0x2395 : 0x0bcc, + 0x22A5 : 0x0bce, + 0x25CB : 0x0bcf, + 0x2308 : 0x0bd3, + 0x22A3 : 0x0bdc, + 0x22A2 : 0x0bfc, + 0x2017 : 0x0cdf, + 0x05D0 : 0x0ce0, + 0x05D1 : 0x0ce1, + 0x05D2 : 0x0ce2, + 0x05D3 : 0x0ce3, + 0x05D4 : 0x0ce4, + 0x05D5 : 0x0ce5, + 0x05D6 : 0x0ce6, + 0x05D7 : 0x0ce7, + 0x05D8 : 0x0ce8, + 0x05D9 : 0x0ce9, + 0x05DA : 0x0cea, + 0x05DB : 0x0ceb, + 0x05DC : 0x0cec, + 0x05DD : 0x0ced, + 0x05DE : 0x0cee, + 0x05DF : 0x0cef, + 0x05E0 : 0x0cf0, + 0x05E1 : 0x0cf1, + 0x05E2 : 0x0cf2, + 0x05E3 : 0x0cf3, + 0x05E4 : 0x0cf4, + 0x05E5 : 0x0cf5, + 0x05E6 : 0x0cf6, + 0x05E7 : 0x0cf7, + 0x05E8 : 0x0cf8, + 0x05E9 : 0x0cf9, + 0x05EA : 0x0cfa, + 0x0E01 : 0x0da1, + 0x0E02 : 0x0da2, + 0x0E03 : 0x0da3, + 0x0E04 : 0x0da4, + 0x0E05 : 0x0da5, + 0x0E06 : 0x0da6, + 0x0E07 : 0x0da7, + 0x0E08 : 0x0da8, + 0x0E09 : 0x0da9, + 0x0E0A : 0x0daa, + 0x0E0B : 0x0dab, + 0x0E0C : 0x0dac, + 0x0E0D : 0x0dad, + 0x0E0E : 0x0dae, + 0x0E0F : 0x0daf, + 0x0E10 : 0x0db0, + 0x0E11 : 0x0db1, + 0x0E12 : 0x0db2, + 0x0E13 : 0x0db3, + 0x0E14 : 0x0db4, + 0x0E15 : 0x0db5, + 0x0E16 : 0x0db6, + 0x0E17 : 0x0db7, + 0x0E18 : 0x0db8, + 0x0E19 : 0x0db9, + 0x0E1A : 0x0dba, + 0x0E1B : 0x0dbb, + 0x0E1C : 0x0dbc, + 0x0E1D : 0x0dbd, + 0x0E1E : 0x0dbe, + 0x0E1F : 0x0dbf, + 0x0E20 : 0x0dc0, + 0x0E21 : 0x0dc1, + 0x0E22 : 0x0dc2, + 0x0E23 : 0x0dc3, + 0x0E24 : 0x0dc4, + 0x0E25 : 0x0dc5, + 0x0E26 : 0x0dc6, + 0x0E27 : 0x0dc7, + 0x0E28 : 0x0dc8, + 0x0E29 : 0x0dc9, + 0x0E2A : 0x0dca, + 0x0E2B : 0x0dcb, + 0x0E2C : 0x0dcc, + 0x0E2D : 0x0dcd, + 0x0E2E : 0x0dce, + 0x0E2F : 0x0dcf, + 0x0E30 : 0x0dd0, + 0x0E31 : 0x0dd1, + 0x0E32 : 0x0dd2, + 0x0E33 : 0x0dd3, + 0x0E34 : 0x0dd4, + 0x0E35 : 0x0dd5, + 0x0E36 : 0x0dd6, + 0x0E37 : 0x0dd7, + 0x0E38 : 0x0dd8, + 0x0E39 : 0x0dd9, + 0x0E3A : 0x0dda, + 0x0E3F : 0x0ddf, + 0x0E40 : 0x0de0, + 0x0E41 : 0x0de1, + 0x0E42 : 0x0de2, + 0x0E43 : 0x0de3, + 0x0E44 : 0x0de4, + 0x0E45 : 0x0de5, + 0x0E46 : 0x0de6, + 0x0E47 : 0x0de7, + 0x0E48 : 0x0de8, + 0x0E49 : 0x0de9, + 0x0E4A : 0x0dea, + 0x0E4B : 0x0deb, + 0x0E4C : 0x0dec, + 0x0E4D : 0x0ded, + 0x0E50 : 0x0df0, + 0x0E51 : 0x0df1, + 0x0E52 : 0x0df2, + 0x0E53 : 0x0df3, + 0x0E54 : 0x0df4, + 0x0E55 : 0x0df5, + 0x0E56 : 0x0df6, + 0x0E57 : 0x0df7, + 0x0E58 : 0x0df8, + 0x0E59 : 0x0df9, + 0x0587 : 0x1000587, + 0x0589 : 0x1000589, + 0x055D : 0x100055d, + 0x058A : 0x100058a, + 0x055C : 0x100055c, + 0x055B : 0x100055b, + 0x055E : 0x100055e, + 0x0531 : 0x1000531, + 0x0561 : 0x1000561, + 0x0532 : 0x1000532, + 0x0562 : 0x1000562, + 0x0533 : 0x1000533, + 0x0563 : 0x1000563, + 0x0534 : 0x1000534, + 0x0564 : 0x1000564, + 0x0535 : 0x1000535, + 0x0565 : 0x1000565, + 0x0536 : 0x1000536, + 0x0566 : 0x1000566, + 0x0537 : 0x1000537, + 0x0567 : 0x1000567, + 0x0538 : 0x1000538, + 0x0568 : 0x1000568, + 0x0539 : 0x1000539, + 0x0569 : 0x1000569, + 0x053A : 0x100053a, + 0x056A : 0x100056a, + 0x053B : 0x100053b, + 0x056B : 0x100056b, + 0x053C : 0x100053c, + 0x056C : 0x100056c, + 0x053D : 0x100053d, + 0x056D : 0x100056d, + 0x053E : 0x100053e, + 0x056E : 0x100056e, + 0x053F : 0x100053f, + 0x056F : 0x100056f, + 0x0540 : 0x1000540, + 0x0570 : 0x1000570, + 0x0541 : 0x1000541, + 0x0571 : 0x1000571, + 0x0542 : 0x1000542, + 0x0572 : 0x1000572, + 0x0543 : 0x1000543, + 0x0573 : 0x1000573, + 0x0544 : 0x1000544, + 0x0574 : 0x1000574, + 0x0545 : 0x1000545, + 0x0575 : 0x1000575, + 0x0546 : 0x1000546, + 0x0576 : 0x1000576, + 0x0547 : 0x1000547, + 0x0577 : 0x1000577, + 0x0548 : 0x1000548, + 0x0578 : 0x1000578, + 0x0549 : 0x1000549, + 0x0579 : 0x1000579, + 0x054A : 0x100054a, + 0x057A : 0x100057a, + 0x054B : 0x100054b, + 0x057B : 0x100057b, + 0x054C : 0x100054c, + 0x057C : 0x100057c, + 0x054D : 0x100054d, + 0x057D : 0x100057d, + 0x054E : 0x100054e, + 0x057E : 0x100057e, + 0x054F : 0x100054f, + 0x057F : 0x100057f, + 0x0550 : 0x1000550, + 0x0580 : 0x1000580, + 0x0551 : 0x1000551, + 0x0581 : 0x1000581, + 0x0552 : 0x1000552, + 0x0582 : 0x1000582, + 0x0553 : 0x1000553, + 0x0583 : 0x1000583, + 0x0554 : 0x1000554, + 0x0584 : 0x1000584, + 0x0555 : 0x1000555, + 0x0585 : 0x1000585, + 0x0556 : 0x1000556, + 0x0586 : 0x1000586, + 0x055A : 0x100055a, + 0x10D0 : 0x10010d0, + 0x10D1 : 0x10010d1, + 0x10D2 : 0x10010d2, + 0x10D3 : 0x10010d3, + 0x10D4 : 0x10010d4, + 0x10D5 : 0x10010d5, + 0x10D6 : 0x10010d6, + 0x10D7 : 0x10010d7, + 0x10D8 : 0x10010d8, + 0x10D9 : 0x10010d9, + 0x10DA : 0x10010da, + 0x10DB : 0x10010db, + 0x10DC : 0x10010dc, + 0x10DD : 0x10010dd, + 0x10DE : 0x10010de, + 0x10DF : 0x10010df, + 0x10E0 : 0x10010e0, + 0x10E1 : 0x10010e1, + 0x10E2 : 0x10010e2, + 0x10E3 : 0x10010e3, + 0x10E4 : 0x10010e4, + 0x10E5 : 0x10010e5, + 0x10E6 : 0x10010e6, + 0x10E7 : 0x10010e7, + 0x10E8 : 0x10010e8, + 0x10E9 : 0x10010e9, + 0x10EA : 0x10010ea, + 0x10EB : 0x10010eb, + 0x10EC : 0x10010ec, + 0x10ED : 0x10010ed, + 0x10EE : 0x10010ee, + 0x10EF : 0x10010ef, + 0x10F0 : 0x10010f0, + 0x10F1 : 0x10010f1, + 0x10F2 : 0x10010f2, + 0x10F3 : 0x10010f3, + 0x10F4 : 0x10010f4, + 0x10F5 : 0x10010f5, + 0x10F6 : 0x10010f6, + 0x1E8A : 0x1001e8a, + 0x012C : 0x100012c, + 0x01B5 : 0x10001b5, + 0x01E6 : 0x10001e6, + 0x01D2 : 0x10001d1, + 0x019F : 0x100019f, + 0x1E8B : 0x1001e8b, + 0x012D : 0x100012d, + 0x01B6 : 0x10001b6, + 0x01E7 : 0x10001e7, + 0x01D2 : 0x10001d2, + 0x0275 : 0x1000275, + 0x018F : 0x100018f, + 0x0259 : 0x1000259, + 0x1E36 : 0x1001e36, + 0x1E37 : 0x1001e37, + 0x1EA0 : 0x1001ea0, + 0x1EA1 : 0x1001ea1, + 0x1EA2 : 0x1001ea2, + 0x1EA3 : 0x1001ea3, + 0x1EA4 : 0x1001ea4, + 0x1EA5 : 0x1001ea5, + 0x1EA6 : 0x1001ea6, + 0x1EA7 : 0x1001ea7, + 0x1EA8 : 0x1001ea8, + 0x1EA9 : 0x1001ea9, + 0x1EAA : 0x1001eaa, + 0x1EAB : 0x1001eab, + 0x1EAC : 0x1001eac, + 0x1EAD : 0x1001ead, + 0x1EAE : 0x1001eae, + 0x1EAF : 0x1001eaf, + 0x1EB0 : 0x1001eb0, + 0x1EB1 : 0x1001eb1, + 0x1EB2 : 0x1001eb2, + 0x1EB3 : 0x1001eb3, + 0x1EB4 : 0x1001eb4, + 0x1EB5 : 0x1001eb5, + 0x1EB6 : 0x1001eb6, + 0x1EB7 : 0x1001eb7, + 0x1EB8 : 0x1001eb8, + 0x1EB9 : 0x1001eb9, + 0x1EBA : 0x1001eba, + 0x1EBB : 0x1001ebb, + 0x1EBC : 0x1001ebc, + 0x1EBD : 0x1001ebd, + 0x1EBE : 0x1001ebe, + 0x1EBF : 0x1001ebf, + 0x1EC0 : 0x1001ec0, + 0x1EC1 : 0x1001ec1, + 0x1EC2 : 0x1001ec2, + 0x1EC3 : 0x1001ec3, + 0x1EC4 : 0x1001ec4, + 0x1EC5 : 0x1001ec5, + 0x1EC6 : 0x1001ec6, + 0x1EC7 : 0x1001ec7, + 0x1EC8 : 0x1001ec8, + 0x1EC9 : 0x1001ec9, + 0x1ECA : 0x1001eca, + 0x1ECB : 0x1001ecb, + 0x1ECC : 0x1001ecc, + 0x1ECD : 0x1001ecd, + 0x1ECE : 0x1001ece, + 0x1ECF : 0x1001ecf, + 0x1ED0 : 0x1001ed0, + 0x1ED1 : 0x1001ed1, + 0x1ED2 : 0x1001ed2, + 0x1ED3 : 0x1001ed3, + 0x1ED4 : 0x1001ed4, + 0x1ED5 : 0x1001ed5, + 0x1ED6 : 0x1001ed6, + 0x1ED7 : 0x1001ed7, + 0x1ED8 : 0x1001ed8, + 0x1ED9 : 0x1001ed9, + 0x1EDA : 0x1001eda, + 0x1EDB : 0x1001edb, + 0x1EDC : 0x1001edc, + 0x1EDD : 0x1001edd, + 0x1EDE : 0x1001ede, + 0x1EDF : 0x1001edf, + 0x1EE0 : 0x1001ee0, + 0x1EE1 : 0x1001ee1, + 0x1EE2 : 0x1001ee2, + 0x1EE3 : 0x1001ee3, + 0x1EE4 : 0x1001ee4, + 0x1EE5 : 0x1001ee5, + 0x1EE6 : 0x1001ee6, + 0x1EE7 : 0x1001ee7, + 0x1EE8 : 0x1001ee8, + 0x1EE9 : 0x1001ee9, + 0x1EEA : 0x1001eea, + 0x1EEB : 0x1001eeb, + 0x1EEC : 0x1001eec, + 0x1EED : 0x1001eed, + 0x1EEE : 0x1001eee, + 0x1EEF : 0x1001eef, + 0x1EF0 : 0x1001ef0, + 0x1EF1 : 0x1001ef1, + 0x1EF4 : 0x1001ef4, + 0x1EF5 : 0x1001ef5, + 0x1EF6 : 0x1001ef6, + 0x1EF7 : 0x1001ef7, + 0x1EF8 : 0x1001ef8, + 0x1EF9 : 0x1001ef9, + 0x01A0 : 0x10001a0, + 0x01A1 : 0x10001a1, + 0x01AF : 0x10001af, + 0x01B0 : 0x10001b0, + 0x20A0 : 0x10020a0, + 0x20A1 : 0x10020a1, + 0x20A2 : 0x10020a2, + 0x20A3 : 0x10020a3, + 0x20A4 : 0x10020a4, + 0x20A5 : 0x10020a5, + 0x20A6 : 0x10020a6, + 0x20A7 : 0x10020a7, + 0x20A8 : 0x10020a8, + 0x20A9 : 0x10020a9, + 0x20AA : 0x10020aa, + 0x20AB : 0x10020ab, + 0x20AC : 0x20ac, + 0x2070 : 0x1002070, + 0x2074 : 0x1002074, + 0x2075 : 0x1002075, + 0x2076 : 0x1002076, + 0x2077 : 0x1002077, + 0x2078 : 0x1002078, + 0x2079 : 0x1002079, + 0x2080 : 0x1002080, + 0x2081 : 0x1002081, + 0x2082 : 0x1002082, + 0x2083 : 0x1002083, + 0x2084 : 0x1002084, + 0x2085 : 0x1002085, + 0x2086 : 0x1002086, + 0x2087 : 0x1002087, + 0x2088 : 0x1002088, + 0x2089 : 0x1002089, + 0x2202 : 0x1002202, + 0x2205 : 0x1002205, + 0x2208 : 0x1002208, + 0x2209 : 0x1002209, + 0x220B : 0x100220B, + 0x221A : 0x100221A, + 0x221B : 0x100221B, + 0x221C : 0x100221C, + 0x222C : 0x100222C, + 0x222D : 0x100222D, + 0x2235 : 0x1002235, + 0x2245 : 0x1002248, + 0x2247 : 0x1002247, + 0x2262 : 0x1002262, + 0x2263 : 0x1002263, + 0x2800 : 0x1002800, + 0x2801 : 0x1002801, + 0x2802 : 0x1002802, + 0x2803 : 0x1002803, + 0x2804 : 0x1002804, + 0x2805 : 0x1002805, + 0x2806 : 0x1002806, + 0x2807 : 0x1002807, + 0x2808 : 0x1002808, + 0x2809 : 0x1002809, + 0x280a : 0x100280a, + 0x280b : 0x100280b, + 0x280c : 0x100280c, + 0x280d : 0x100280d, + 0x280e : 0x100280e, + 0x280f : 0x100280f, + 0x2810 : 0x1002810, + 0x2811 : 0x1002811, + 0x2812 : 0x1002812, + 0x2813 : 0x1002813, + 0x2814 : 0x1002814, + 0x2815 : 0x1002815, + 0x2816 : 0x1002816, + 0x2817 : 0x1002817, + 0x2818 : 0x1002818, + 0x2819 : 0x1002819, + 0x281a : 0x100281a, + 0x281b : 0x100281b, + 0x281c : 0x100281c, + 0x281d : 0x100281d, + 0x281e : 0x100281e, + 0x281f : 0x100281f, + 0x2820 : 0x1002820, + 0x2821 : 0x1002821, + 0x2822 : 0x1002822, + 0x2823 : 0x1002823, + 0x2824 : 0x1002824, + 0x2825 : 0x1002825, + 0x2826 : 0x1002826, + 0x2827 : 0x1002827, + 0x2828 : 0x1002828, + 0x2829 : 0x1002829, + 0x282a : 0x100282a, + 0x282b : 0x100282b, + 0x282c : 0x100282c, + 0x282d : 0x100282d, + 0x282e : 0x100282e, + 0x282f : 0x100282f, + 0x2830 : 0x1002830, + 0x2831 : 0x1002831, + 0x2832 : 0x1002832, + 0x2833 : 0x1002833, + 0x2834 : 0x1002834, + 0x2835 : 0x1002835, + 0x2836 : 0x1002836, + 0x2837 : 0x1002837, + 0x2838 : 0x1002838, + 0x2839 : 0x1002839, + 0x283a : 0x100283a, + 0x283b : 0x100283b, + 0x283c : 0x100283c, + 0x283d : 0x100283d, + 0x283e : 0x100283e, + 0x283f : 0x100283f, + 0x2840 : 0x1002840, + 0x2841 : 0x1002841, + 0x2842 : 0x1002842, + 0x2843 : 0x1002843, + 0x2844 : 0x1002844, + 0x2845 : 0x1002845, + 0x2846 : 0x1002846, + 0x2847 : 0x1002847, + 0x2848 : 0x1002848, + 0x2849 : 0x1002849, + 0x284a : 0x100284a, + 0x284b : 0x100284b, + 0x284c : 0x100284c, + 0x284d : 0x100284d, + 0x284e : 0x100284e, + 0x284f : 0x100284f, + 0x2850 : 0x1002850, + 0x2851 : 0x1002851, + 0x2852 : 0x1002852, + 0x2853 : 0x1002853, + 0x2854 : 0x1002854, + 0x2855 : 0x1002855, + 0x2856 : 0x1002856, + 0x2857 : 0x1002857, + 0x2858 : 0x1002858, + 0x2859 : 0x1002859, + 0x285a : 0x100285a, + 0x285b : 0x100285b, + 0x285c : 0x100285c, + 0x285d : 0x100285d, + 0x285e : 0x100285e, + 0x285f : 0x100285f, + 0x2860 : 0x1002860, + 0x2861 : 0x1002861, + 0x2862 : 0x1002862, + 0x2863 : 0x1002863, + 0x2864 : 0x1002864, + 0x2865 : 0x1002865, + 0x2866 : 0x1002866, + 0x2867 : 0x1002867, + 0x2868 : 0x1002868, + 0x2869 : 0x1002869, + 0x286a : 0x100286a, + 0x286b : 0x100286b, + 0x286c : 0x100286c, + 0x286d : 0x100286d, + 0x286e : 0x100286e, + 0x286f : 0x100286f, + 0x2870 : 0x1002870, + 0x2871 : 0x1002871, + 0x2872 : 0x1002872, + 0x2873 : 0x1002873, + 0x2874 : 0x1002874, + 0x2875 : 0x1002875, + 0x2876 : 0x1002876, + 0x2877 : 0x1002877, + 0x2878 : 0x1002878, + 0x2879 : 0x1002879, + 0x287a : 0x100287a, + 0x287b : 0x100287b, + 0x287c : 0x100287c, + 0x287d : 0x100287d, + 0x287e : 0x100287e, + 0x287f : 0x100287f, + 0x2880 : 0x1002880, + 0x2881 : 0x1002881, + 0x2882 : 0x1002882, + 0x2883 : 0x1002883, + 0x2884 : 0x1002884, + 0x2885 : 0x1002885, + 0x2886 : 0x1002886, + 0x2887 : 0x1002887, + 0x2888 : 0x1002888, + 0x2889 : 0x1002889, + 0x288a : 0x100288a, + 0x288b : 0x100288b, + 0x288c : 0x100288c, + 0x288d : 0x100288d, + 0x288e : 0x100288e, + 0x288f : 0x100288f, + 0x2890 : 0x1002890, + 0x2891 : 0x1002891, + 0x2892 : 0x1002892, + 0x2893 : 0x1002893, + 0x2894 : 0x1002894, + 0x2895 : 0x1002895, + 0x2896 : 0x1002896, + 0x2897 : 0x1002897, + 0x2898 : 0x1002898, + 0x2899 : 0x1002899, + 0x289a : 0x100289a, + 0x289b : 0x100289b, + 0x289c : 0x100289c, + 0x289d : 0x100289d, + 0x289e : 0x100289e, + 0x289f : 0x100289f, + 0x28a0 : 0x10028a0, + 0x28a1 : 0x10028a1, + 0x28a2 : 0x10028a2, + 0x28a3 : 0x10028a3, + 0x28a4 : 0x10028a4, + 0x28a5 : 0x10028a5, + 0x28a6 : 0x10028a6, + 0x28a7 : 0x10028a7, + 0x28a8 : 0x10028a8, + 0x28a9 : 0x10028a9, + 0x28aa : 0x10028aa, + 0x28ab : 0x10028ab, + 0x28ac : 0x10028ac, + 0x28ad : 0x10028ad, + 0x28ae : 0x10028ae, + 0x28af : 0x10028af, + 0x28b0 : 0x10028b0, + 0x28b1 : 0x10028b1, + 0x28b2 : 0x10028b2, + 0x28b3 : 0x10028b3, + 0x28b4 : 0x10028b4, + 0x28b5 : 0x10028b5, + 0x28b6 : 0x10028b6, + 0x28b7 : 0x10028b7, + 0x28b8 : 0x10028b8, + 0x28b9 : 0x10028b9, + 0x28ba : 0x10028ba, + 0x28bb : 0x10028bb, + 0x28bc : 0x10028bc, + 0x28bd : 0x10028bd, + 0x28be : 0x10028be, + 0x28bf : 0x10028bf, + 0x28c0 : 0x10028c0, + 0x28c1 : 0x10028c1, + 0x28c2 : 0x10028c2, + 0x28c3 : 0x10028c3, + 0x28c4 : 0x10028c4, + 0x28c5 : 0x10028c5, + 0x28c6 : 0x10028c6, + 0x28c7 : 0x10028c7, + 0x28c8 : 0x10028c8, + 0x28c9 : 0x10028c9, + 0x28ca : 0x10028ca, + 0x28cb : 0x10028cb, + 0x28cc : 0x10028cc, + 0x28cd : 0x10028cd, + 0x28ce : 0x10028ce, + 0x28cf : 0x10028cf, + 0x28d0 : 0x10028d0, + 0x28d1 : 0x10028d1, + 0x28d2 : 0x10028d2, + 0x28d3 : 0x10028d3, + 0x28d4 : 0x10028d4, + 0x28d5 : 0x10028d5, + 0x28d6 : 0x10028d6, + 0x28d7 : 0x10028d7, + 0x28d8 : 0x10028d8, + 0x28d9 : 0x10028d9, + 0x28da : 0x10028da, + 0x28db : 0x10028db, + 0x28dc : 0x10028dc, + 0x28dd : 0x10028dd, + 0x28de : 0x10028de, + 0x28df : 0x10028df, + 0x28e0 : 0x10028e0, + 0x28e1 : 0x10028e1, + 0x28e2 : 0x10028e2, + 0x28e3 : 0x10028e3, + 0x28e4 : 0x10028e4, + 0x28e5 : 0x10028e5, + 0x28e6 : 0x10028e6, + 0x28e7 : 0x10028e7, + 0x28e8 : 0x10028e8, + 0x28e9 : 0x10028e9, + 0x28ea : 0x10028ea, + 0x28eb : 0x10028eb, + 0x28ec : 0x10028ec, + 0x28ed : 0x10028ed, + 0x28ee : 0x10028ee, + 0x28ef : 0x10028ef, + 0x28f0 : 0x10028f0, + 0x28f1 : 0x10028f1, + 0x28f2 : 0x10028f2, + 0x28f3 : 0x10028f3, + 0x28f4 : 0x10028f4, + 0x28f5 : 0x10028f5, + 0x28f6 : 0x10028f6, + 0x28f7 : 0x10028f7, + 0x28f8 : 0x10028f8, + 0x28f9 : 0x10028f9, + 0x28fa : 0x10028fa, + 0x28fb : 0x10028fb, + 0x28fc : 0x10028fc, + 0x28fd : 0x10028fd, + 0x28fe : 0x10028fe, + 0x28ff : 0x10028ff +}; /** * See LICENSE file. * @@ -5535,6 +7722,17 @@ var cp1= proxy( this.parent= parent; return this; }, + + getScene : function() { + if ( typeof this.parent ==='undefined' || this.parent === null) { + return null; + } + if (this.parent.name === 'CAAT.Scene') { + return this.parent; + } + return this.parent.getScene(); + }, + /** * Set this actor's background image. * The need of a background image is to kept compatibility with the new CSSDirector class. @@ -7421,13 +9619,13 @@ var cp1= proxy( * @param child a CAAT.Actor object instance. * @return this */ - addChild : function(child) { + addChild : function(child) { if ( child.parent!=null ) { throw('adding to a container an element with parent.'); } - child.parent= this; + child.setParent(this); // For TextArea this.childrenList.push(child); child.dirty= true; @@ -8475,7 +10673,8 @@ var cp1= proxy( }; extend( CAAT.IMActor, CAAT.ActorContainer, null); -})();/** +})(); +/** * See LICENSE file. * * Sound implementation. @@ -11439,26 +13638,53 @@ CAAT.registerKeyListener= function(f) { CAAT.keyListeners.push(f); }; + + +// Redefinitions of keyboard event to use noVNC code + +CAAT.registerKeyListenerIfNeeded= function(f) { + for( var i=0; i>0)+1 ) + 2 * padding ; + + // var cw= Math.max( 1, (ctx.measureText( chars.charAt(i) ).width>>0)+1 ) + 2 * padding ; + var cw= Math.max( 1, (ctx.measureText( chars.charAt(i) ).width>>0)+1 ); + charWidth.push(cw); - textWidth+= cw; + textWidth+= cw + 2 * padding; } canvas.width= textWidth; @@ -14390,19 +16650,19 @@ CAAT.modules.CircleManager = CAAT.modules.CircleManager || {};/** this.charMap= {}; - x=0; + x=padding; // x=0 for( i=0; i